@defend-tech/opencode-optima 0.1.43 → 0.1.45

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
@@ -9564,25 +9564,60 @@ function clearClickUpPendingSessionMetadata(metadata, metadataKey) {
9564
9564
  return JSON.stringify(sortJsonValue(root), null, 2);
9565
9565
  }
9566
9566
  async function openCodeSessionExists(client, sessionId) {
9567
- try {
9568
- if (typeof client?.session?.get === "function") {
9569
- await client.session.get({ path: { id: sessionId } });
9570
- return true;
9567
+ const getAttempts = [
9568
+ { sessionID: sessionId },
9569
+ { id: sessionId },
9570
+ { path: { sessionID: sessionId } },
9571
+ { path: { id: sessionId } }
9572
+ ];
9573
+ if (typeof client?.session?.get === "function") {
9574
+ for (const attempt of getAttempts) {
9575
+ try {
9576
+ await client.session.get(attempt);
9577
+ return true;
9578
+ } catch {
9579
+ }
9571
9580
  }
9572
- if (typeof client?.session?.messages === "function") {
9573
- await client.session.messages({ path: { id: sessionId }, query: { limit: 1 } });
9574
- return true;
9581
+ }
9582
+ const messageAttempts = [
9583
+ { sessionID: sessionId, limit: 1 },
9584
+ { id: sessionId, limit: 1 },
9585
+ { path: { sessionID: sessionId }, query: { limit: 1 } },
9586
+ { path: { id: sessionId }, query: { limit: 1 } }
9587
+ ];
9588
+ if (typeof client?.session?.messages === "function") {
9589
+ for (const attempt of messageAttempts) {
9590
+ try {
9591
+ await client.session.messages(attempt);
9592
+ return true;
9593
+ } catch {
9594
+ }
9575
9595
  }
9576
- } catch {
9577
- return false;
9578
9596
  }
9579
9597
  return false;
9580
9598
  }
9599
+ function extractOpenCodeSessionId(result) {
9600
+ const data = result?.data ?? result;
9601
+ return data?.id || data?.sessionID || data?.sessionId || result?.id || result?.sessionID || result?.sessionId;
9602
+ }
9581
9603
  async function createOpenCodeSession(client, { title, directory, agent } = {}) {
9604
+ const flatPayload = { directory, title };
9605
+ if (agent) flatPayload.agent = agent;
9582
9606
  const body = { title };
9583
9607
  if (agent) body.agent = agent;
9584
- const result = await client.session.create({ query: { directory }, body });
9585
- return result?.data?.id || result?.id;
9608
+ const attempts = [flatPayload, { query: { directory }, body }];
9609
+ let firstError = null;
9610
+ for (const attempt of attempts) {
9611
+ try {
9612
+ const result = await client.session.create(attempt);
9613
+ const sessionId = extractOpenCodeSessionId(result);
9614
+ if (sessionId) return sessionId;
9615
+ firstError ??= new Error("OpenCode session create response did not include a session id.");
9616
+ } catch (error) {
9617
+ firstError ??= error;
9618
+ }
9619
+ }
9620
+ throw firstError || new Error("OpenCode session create failed.");
9586
9621
  }
9587
9622
  function assertOpenCodePromptAccepted(result) {
9588
9623
  const status = Number(result?.status || result?.response?.status || result?.error?.status || 0);
@@ -9592,6 +9627,18 @@ function assertOpenCodePromptAccepted(result) {
9592
9627
  }
9593
9628
  return result;
9594
9629
  }
9630
+ function openCodePromptAdmissionVerification(result, sessionId) {
9631
+ const response = result?.response ?? result;
9632
+ const data = response?.data ?? result?.data ?? null;
9633
+ const promptId = data?.id ?? response?.id ?? result?.id;
9634
+ const admittedSessionId = response?.sessionID ?? response?.sessionId ?? data?.sessionID ?? data?.sessionId ?? result?.sessionID ?? result?.sessionId;
9635
+ const admittedSeq = response?.admittedSeq ?? data?.admittedSeq ?? result?.admittedSeq;
9636
+ if (!promptId || admittedSeq === void 0 || admittedSeq === null || !admittedSessionId) return null;
9637
+ if (String(admittedSessionId) !== String(sessionId)) {
9638
+ throw new Error(`OpenCode prompt admission targeted foreign session ${admittedSessionId}.`);
9639
+ }
9640
+ return { ok: true, method: "prompt_admission", promptId: String(promptId), sessionId: String(admittedSessionId), admittedSeq };
9641
+ }
9595
9642
  function responseLooksLikeHtml(contentType = "", raw = "") {
9596
9643
  return String(contentType || "").toLowerCase().includes("text/html") || /^\s*<!doctype\s+html\b/i.test(raw) || /^\s*<html\b/i.test(raw);
9597
9644
  }
@@ -9621,7 +9668,7 @@ async function sendOpenCodeSessionEventDirect({ baseUrl, sessionId, text, agent,
9621
9668
  body: { prompt: { text }, delivery: "queue", resume: true },
9622
9669
  accept: (response, data) => {
9623
9670
  if (!response.ok) return null;
9624
- if (!data?.data?.id) throw new Error("OpenCode v2 prompt response did not include data.id.");
9671
+ if (!openCodePromptAdmissionVerification(data, sessionId)) throw new Error("OpenCode v2 prompt response did not include a valid prompt admission.");
9625
9672
  return { ok: true, method: "http", endpoint: "/api/session/{sessionID}/prompt", status: response.status, data: data.data, response: data };
9626
9673
  }
9627
9674
  },
@@ -9651,21 +9698,49 @@ async function sendOpenCodeSessionEventDirect({ baseUrl, sessionId, text, agent,
9651
9698
  }
9652
9699
  throw firstError || new Error("OpenCode direct prompt delivery failed.");
9653
9700
  }
9701
+ async function callOpenCodePromptWithFallbacks(method, sessionId, flatPayload, structuredPayload) {
9702
+ const attempts = [
9703
+ { sessionID: sessionId, ...flatPayload },
9704
+ { id: sessionId, ...flatPayload },
9705
+ { ...structuredPayload, path: { id: sessionId } },
9706
+ { ...structuredPayload, path: { sessionID: sessionId } }
9707
+ ];
9708
+ let firstError = null;
9709
+ for (const attempt of attempts) {
9710
+ try {
9711
+ return assertOpenCodePromptAccepted(await method(attempt));
9712
+ } catch (error) {
9713
+ firstError ??= error;
9714
+ }
9715
+ }
9716
+ throw firstError;
9717
+ }
9654
9718
  async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, directory, opencodeBaseUrl, baseUrl, fetchImpl, direct = false } = {}) {
9655
9719
  const directBaseUrl = opencodeBaseUrl || baseUrl;
9656
9720
  const parts = [{ type: "text", text }];
9721
+ const flatPayload = { directory, agent, parts };
9657
9722
  const structuredPayload = {
9658
9723
  path: { id: sessionId },
9659
9724
  query: { directory },
9660
9725
  body: { agent, parts }
9661
9726
  };
9727
+ let firstError = null;
9662
9728
  if (!direct && typeof client?.session?.promptAsync === "function") {
9663
- return assertOpenCodePromptAccepted(await client.session.promptAsync(structuredPayload));
9729
+ try {
9730
+ return await callOpenCodePromptWithFallbacks(client.session.promptAsync.bind(client.session), sessionId, flatPayload, structuredPayload);
9731
+ } catch (error) {
9732
+ firstError ??= error;
9733
+ }
9664
9734
  }
9665
9735
  if (!direct && typeof client?.session?.prompt === "function") {
9666
- return assertOpenCodePromptAccepted(await client.session.prompt(structuredPayload));
9736
+ try {
9737
+ return await callOpenCodePromptWithFallbacks(client.session.prompt.bind(client.session), sessionId, flatPayload, structuredPayload);
9738
+ } catch (error) {
9739
+ firstError ??= error;
9740
+ }
9667
9741
  }
9668
9742
  if (directBaseUrl) return sendOpenCodeSessionEventDirect({ baseUrl: directBaseUrl, sessionId, text, agent, fetchImpl });
9743
+ if (firstError) throw firstError;
9669
9744
  throw new Error("OpenCode client does not expose session.prompt or session.promptAsync.");
9670
9745
  }
9671
9746
  function normalizeOpenCodeSessionMessages(result) {
@@ -9678,10 +9753,10 @@ function normalizeOpenCodeSessionMessages(result) {
9678
9753
  async function readOpenCodeSessionMessages(client, { sessionId, limit = 20 } = {}) {
9679
9754
  if (typeof client?.session?.messages !== "function") return null;
9680
9755
  const attempts = [
9681
- { path: { id: sessionId }, query: { limit } },
9682
- { path: { sessionID: sessionId }, query: { limit } },
9756
+ { sessionID: sessionId, limit },
9683
9757
  { id: sessionId, limit },
9684
- { sessionID: sessionId, limit }
9758
+ { path: { id: sessionId }, query: { limit } },
9759
+ { path: { sessionID: sessionId }, query: { limit } }
9685
9760
  ];
9686
9761
  let firstError = null;
9687
9762
  for (const attempt of attempts) {
@@ -9735,13 +9810,29 @@ async function applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason,
9735
9810
  }
9736
9811
  async function deliverClickUpSessionEventWithVerification({ openCodeClient, sendSessionEvent, clickupClient, worktree, taskId, sessionId, agent, text, directory, opencodeBaseUrl, eventMarkers = [], verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, applyBlockerOnFailure = true } = {}) {
9737
9812
  const beforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => null);
9738
- await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
9813
+ const sendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
9814
+ let admissionVerification = null;
9815
+ try {
9816
+ admissionVerification = openCodePromptAdmissionVerification(sendResult, sessionId);
9817
+ } catch (error) {
9818
+ appendClickUpWebhookLocalLog(worktree, { type: "message_delivery_failed", taskId, sessionId, reason: error.message, fallbackAttempted: false });
9819
+ if (!applyBlockerOnFailure) return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false };
9820
+ const blocker2 = await applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason: error.message, source: "delivery_admission_failed" });
9821
+ return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false, blockerTag: blocker2 };
9822
+ }
9823
+ if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: false };
9739
9824
  let verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages, expectedText: text, markers: eventMarkers });
9740
9825
  if (verification?.ok) return { ok: true, verification, fallback: false };
9741
9826
  const canFallbackDirect = Boolean(opencodeBaseUrl);
9742
9827
  if (canFallbackDirect) {
9743
9828
  const retryBeforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => beforeMessages);
9744
- await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
9829
+ const retrySendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
9830
+ try {
9831
+ admissionVerification = openCodePromptAdmissionVerification(retrySendResult, sessionId);
9832
+ } catch (error) {
9833
+ verification = { ok: false, reason: error.message };
9834
+ }
9835
+ if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: true };
9745
9836
  verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages: retryBeforeMessages, expectedText: text, markers: eventMarkers });
9746
9837
  if (verification?.ok) return { ok: true, verification, fallback: true };
9747
9838
  }
@@ -11979,7 +12070,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
11979
12070
  }
11980
12071
  };
11981
12072
  }
11982
- 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, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, readClickUpCommentLedger, readClickUpWebhookState, reconcileClickUpStartup, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, 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 };
12073
+ 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, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionMessages, reconcileClickUpStartup, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, 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 };
11983
12074
  export {
11984
12075
  OptimaPlugin as default
11985
12076
  };
@@ -9571,25 +9571,60 @@ function clearClickUpPendingSessionMetadata(metadata, metadataKey) {
9571
9571
  return JSON.stringify(sortJsonValue(root), null, 2);
9572
9572
  }
9573
9573
  async function openCodeSessionExists(client, sessionId) {
9574
- try {
9575
- if (typeof client?.session?.get === "function") {
9576
- await client.session.get({ path: { id: sessionId } });
9577
- return true;
9574
+ const getAttempts = [
9575
+ { sessionID: sessionId },
9576
+ { id: sessionId },
9577
+ { path: { sessionID: sessionId } },
9578
+ { path: { id: sessionId } }
9579
+ ];
9580
+ if (typeof client?.session?.get === "function") {
9581
+ for (const attempt of getAttempts) {
9582
+ try {
9583
+ await client.session.get(attempt);
9584
+ return true;
9585
+ } catch {
9586
+ }
9578
9587
  }
9579
- if (typeof client?.session?.messages === "function") {
9580
- await client.session.messages({ path: { id: sessionId }, query: { limit: 1 } });
9581
- return true;
9588
+ }
9589
+ const messageAttempts = [
9590
+ { sessionID: sessionId, limit: 1 },
9591
+ { id: sessionId, limit: 1 },
9592
+ { path: { sessionID: sessionId }, query: { limit: 1 } },
9593
+ { path: { id: sessionId }, query: { limit: 1 } }
9594
+ ];
9595
+ if (typeof client?.session?.messages === "function") {
9596
+ for (const attempt of messageAttempts) {
9597
+ try {
9598
+ await client.session.messages(attempt);
9599
+ return true;
9600
+ } catch {
9601
+ }
9582
9602
  }
9583
- } catch {
9584
- return false;
9585
9603
  }
9586
9604
  return false;
9587
9605
  }
9606
+ function extractOpenCodeSessionId(result) {
9607
+ const data = result?.data ?? result;
9608
+ return data?.id || data?.sessionID || data?.sessionId || result?.id || result?.sessionID || result?.sessionId;
9609
+ }
9588
9610
  async function createOpenCodeSession(client, { title, directory, agent } = {}) {
9611
+ const flatPayload = { directory, title };
9612
+ if (agent) flatPayload.agent = agent;
9589
9613
  const body = { title };
9590
9614
  if (agent) body.agent = agent;
9591
- const result = await client.session.create({ query: { directory }, body });
9592
- return result?.data?.id || result?.id;
9615
+ const attempts = [flatPayload, { query: { directory }, body }];
9616
+ let firstError = null;
9617
+ for (const attempt of attempts) {
9618
+ try {
9619
+ const result = await client.session.create(attempt);
9620
+ const sessionId = extractOpenCodeSessionId(result);
9621
+ if (sessionId) return sessionId;
9622
+ firstError ??= new Error("OpenCode session create response did not include a session id.");
9623
+ } catch (error) {
9624
+ firstError ??= error;
9625
+ }
9626
+ }
9627
+ throw firstError || new Error("OpenCode session create failed.");
9593
9628
  }
9594
9629
  function assertOpenCodePromptAccepted(result) {
9595
9630
  const status = Number(result?.status || result?.response?.status || result?.error?.status || 0);
@@ -9599,6 +9634,18 @@ function assertOpenCodePromptAccepted(result) {
9599
9634
  }
9600
9635
  return result;
9601
9636
  }
9637
+ function openCodePromptAdmissionVerification(result, sessionId) {
9638
+ const response = result?.response ?? result;
9639
+ const data = response?.data ?? result?.data ?? null;
9640
+ const promptId = data?.id ?? response?.id ?? result?.id;
9641
+ const admittedSessionId = response?.sessionID ?? response?.sessionId ?? data?.sessionID ?? data?.sessionId ?? result?.sessionID ?? result?.sessionId;
9642
+ const admittedSeq = response?.admittedSeq ?? data?.admittedSeq ?? result?.admittedSeq;
9643
+ if (!promptId || admittedSeq === void 0 || admittedSeq === null || !admittedSessionId) return null;
9644
+ if (String(admittedSessionId) !== String(sessionId)) {
9645
+ throw new Error(`OpenCode prompt admission targeted foreign session ${admittedSessionId}.`);
9646
+ }
9647
+ return { ok: true, method: "prompt_admission", promptId: String(promptId), sessionId: String(admittedSessionId), admittedSeq };
9648
+ }
9602
9649
  function responseLooksLikeHtml(contentType = "", raw = "") {
9603
9650
  return String(contentType || "").toLowerCase().includes("text/html") || /^\s*<!doctype\s+html\b/i.test(raw) || /^\s*<html\b/i.test(raw);
9604
9651
  }
@@ -9628,7 +9675,7 @@ async function sendOpenCodeSessionEventDirect({ baseUrl, sessionId, text, agent,
9628
9675
  body: { prompt: { text }, delivery: "queue", resume: true },
9629
9676
  accept: (response, data) => {
9630
9677
  if (!response.ok) return null;
9631
- if (!data?.data?.id) throw new Error("OpenCode v2 prompt response did not include data.id.");
9678
+ if (!openCodePromptAdmissionVerification(data, sessionId)) throw new Error("OpenCode v2 prompt response did not include a valid prompt admission.");
9632
9679
  return { ok: true, method: "http", endpoint: "/api/session/{sessionID}/prompt", status: response.status, data: data.data, response: data };
9633
9680
  }
9634
9681
  },
@@ -9658,21 +9705,49 @@ async function sendOpenCodeSessionEventDirect({ baseUrl, sessionId, text, agent,
9658
9705
  }
9659
9706
  throw firstError || new Error("OpenCode direct prompt delivery failed.");
9660
9707
  }
9708
+ async function callOpenCodePromptWithFallbacks(method, sessionId, flatPayload, structuredPayload) {
9709
+ const attempts = [
9710
+ { sessionID: sessionId, ...flatPayload },
9711
+ { id: sessionId, ...flatPayload },
9712
+ { ...structuredPayload, path: { id: sessionId } },
9713
+ { ...structuredPayload, path: { sessionID: sessionId } }
9714
+ ];
9715
+ let firstError = null;
9716
+ for (const attempt of attempts) {
9717
+ try {
9718
+ return assertOpenCodePromptAccepted(await method(attempt));
9719
+ } catch (error) {
9720
+ firstError ??= error;
9721
+ }
9722
+ }
9723
+ throw firstError;
9724
+ }
9661
9725
  async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, directory, opencodeBaseUrl, baseUrl, fetchImpl, direct = false } = {}) {
9662
9726
  const directBaseUrl = opencodeBaseUrl || baseUrl;
9663
9727
  const parts = [{ type: "text", text }];
9728
+ const flatPayload = { directory, agent, parts };
9664
9729
  const structuredPayload = {
9665
9730
  path: { id: sessionId },
9666
9731
  query: { directory },
9667
9732
  body: { agent, parts }
9668
9733
  };
9734
+ let firstError = null;
9669
9735
  if (!direct && typeof client?.session?.promptAsync === "function") {
9670
- return assertOpenCodePromptAccepted(await client.session.promptAsync(structuredPayload));
9736
+ try {
9737
+ return await callOpenCodePromptWithFallbacks(client.session.promptAsync.bind(client.session), sessionId, flatPayload, structuredPayload);
9738
+ } catch (error) {
9739
+ firstError ??= error;
9740
+ }
9671
9741
  }
9672
9742
  if (!direct && typeof client?.session?.prompt === "function") {
9673
- return assertOpenCodePromptAccepted(await client.session.prompt(structuredPayload));
9743
+ try {
9744
+ return await callOpenCodePromptWithFallbacks(client.session.prompt.bind(client.session), sessionId, flatPayload, structuredPayload);
9745
+ } catch (error) {
9746
+ firstError ??= error;
9747
+ }
9674
9748
  }
9675
9749
  if (directBaseUrl) return sendOpenCodeSessionEventDirect({ baseUrl: directBaseUrl, sessionId, text, agent, fetchImpl });
9750
+ if (firstError) throw firstError;
9676
9751
  throw new Error("OpenCode client does not expose session.prompt or session.promptAsync.");
9677
9752
  }
9678
9753
  function normalizeOpenCodeSessionMessages(result) {
@@ -9685,10 +9760,10 @@ function normalizeOpenCodeSessionMessages(result) {
9685
9760
  async function readOpenCodeSessionMessages(client, { sessionId, limit = 20 } = {}) {
9686
9761
  if (typeof client?.session?.messages !== "function") return null;
9687
9762
  const attempts = [
9688
- { path: { id: sessionId }, query: { limit } },
9689
- { path: { sessionID: sessionId }, query: { limit } },
9763
+ { sessionID: sessionId, limit },
9690
9764
  { id: sessionId, limit },
9691
- { sessionID: sessionId, limit }
9765
+ { path: { id: sessionId }, query: { limit } },
9766
+ { path: { sessionID: sessionId }, query: { limit } }
9692
9767
  ];
9693
9768
  let firstError = null;
9694
9769
  for (const attempt of attempts) {
@@ -9742,13 +9817,29 @@ async function applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason,
9742
9817
  }
9743
9818
  async function deliverClickUpSessionEventWithVerification({ openCodeClient, sendSessionEvent, clickupClient, worktree, taskId, sessionId, agent, text, directory, opencodeBaseUrl, eventMarkers = [], verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, applyBlockerOnFailure = true } = {}) {
9744
9819
  const beforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => null);
9745
- await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
9820
+ const sendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
9821
+ let admissionVerification = null;
9822
+ try {
9823
+ admissionVerification = openCodePromptAdmissionVerification(sendResult, sessionId);
9824
+ } catch (error) {
9825
+ appendClickUpWebhookLocalLog(worktree, { type: "message_delivery_failed", taskId, sessionId, reason: error.message, fallbackAttempted: false });
9826
+ if (!applyBlockerOnFailure) return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false };
9827
+ const blocker2 = await applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason: error.message, source: "delivery_admission_failed" });
9828
+ return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false, blockerTag: blocker2 };
9829
+ }
9830
+ if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: false };
9746
9831
  let verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages, expectedText: text, markers: eventMarkers });
9747
9832
  if (verification?.ok) return { ok: true, verification, fallback: false };
9748
9833
  const canFallbackDirect = Boolean(opencodeBaseUrl);
9749
9834
  if (canFallbackDirect) {
9750
9835
  const retryBeforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => beforeMessages);
9751
- await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
9836
+ const retrySendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
9837
+ try {
9838
+ admissionVerification = openCodePromptAdmissionVerification(retrySendResult, sessionId);
9839
+ } catch (error) {
9840
+ verification = { ok: false, reason: error.message };
9841
+ }
9842
+ if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: true };
9752
9843
  verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages: retryBeforeMessages, expectedText: text, markers: eventMarkers });
9753
9844
  if (verification?.ok) return { ok: true, verification, fallback: true };
9754
9845
  }
@@ -11986,7 +12077,7 @@ Follow-up: use optima_prompt_workflow with session_id '${sessionId}' to check in
11986
12077
  }
11987
12078
  };
11988
12079
  }
11989
- 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, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, readClickUpCommentLedger, readClickUpWebhookState, reconcileClickUpStartup, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, 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 };
12080
+ 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, deliveryEvidencePathForClickUpTask, ensureClickUpTaskWorktree, ensureClickUpWebhookSubscription, handleClickUpWebhookRequest, isClickUpWebhookStateActive, normalizeClickUpWebhookConfig, normalizeClickUpWebhookLogLevel, normalizeOpenCodeBaseUrl, openCodeSessionExists, readClickUpCommentLedger, readClickUpWebhookState, readOpenCodeSessionMessages, reconcileClickUpStartup, recordClickUpCommentVersionProcessed, resyncClickUpWebhookForSignatureDrift, resolveOptimaPluginOptions, resolveSecretReference, routeClickUpWebhookEvent, sendOpenCodeSessionEvent, sendOpenCodeSessionEventDirect, 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 };
11990
12081
 
11991
12082
  // src/sanitize_cli.js
11992
12083
  var { migrateLegacyOptimaLayout: migrateLegacyOptimaLayout2 } = OptimaPlugin.__internals;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defend-tech/opencode-optima",
3
- "version": "0.1.43",
3
+ "version": "0.1.45",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@github.com/defend-tech/opencode-optima.git"