@defend-tech/opencode-optima 0.1.42 → 0.1.44
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 +84 -23
- package/dist/sanitize_cli.js +84 -23
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9592,31 +9592,76 @@ function assertOpenCodePromptAccepted(result) {
|
|
|
9592
9592
|
}
|
|
9593
9593
|
return result;
|
|
9594
9594
|
}
|
|
9595
|
-
|
|
9595
|
+
function openCodePromptAdmissionVerification(result, sessionId) {
|
|
9596
|
+
const response = result?.response ?? result;
|
|
9597
|
+
const data = response?.data ?? result?.data ?? null;
|
|
9598
|
+
const promptId = data?.id ?? response?.id ?? result?.id;
|
|
9599
|
+
const admittedSessionId = response?.sessionID ?? response?.sessionId ?? data?.sessionID ?? data?.sessionId ?? result?.sessionID ?? result?.sessionId;
|
|
9600
|
+
const admittedSeq = response?.admittedSeq ?? data?.admittedSeq ?? result?.admittedSeq;
|
|
9601
|
+
if (!promptId || admittedSeq === void 0 || admittedSeq === null || !admittedSessionId) return null;
|
|
9602
|
+
if (String(admittedSessionId) !== String(sessionId)) {
|
|
9603
|
+
throw new Error(`OpenCode prompt admission targeted foreign session ${admittedSessionId}.`);
|
|
9604
|
+
}
|
|
9605
|
+
return { ok: true, method: "prompt_admission", promptId: String(promptId), sessionId: String(admittedSessionId), admittedSeq };
|
|
9606
|
+
}
|
|
9607
|
+
function responseLooksLikeHtml(contentType = "", raw = "") {
|
|
9608
|
+
return String(contentType || "").toLowerCase().includes("text/html") || /^\s*<!doctype\s+html\b/i.test(raw) || /^\s*<html\b/i.test(raw);
|
|
9609
|
+
}
|
|
9610
|
+
async function readOpenCodeJsonResponse(response, endpointName) {
|
|
9611
|
+
const contentType = response.headers?.get?.("content-type") || "";
|
|
9612
|
+
const raw = await response.text();
|
|
9613
|
+
if (responseLooksLikeHtml(contentType, raw)) {
|
|
9614
|
+
throw new Error(`OpenCode ${endpointName} returned the HTML app shell instead of an API response.`);
|
|
9615
|
+
}
|
|
9616
|
+
if (!raw) return null;
|
|
9617
|
+
try {
|
|
9618
|
+
return JSON.parse(raw);
|
|
9619
|
+
} catch (error) {
|
|
9620
|
+
if (response.ok) throw new Error(`OpenCode ${endpointName} response was not JSON: ${error.message}`);
|
|
9621
|
+
return { raw };
|
|
9622
|
+
}
|
|
9623
|
+
}
|
|
9624
|
+
async function sendOpenCodeSessionEventDirect({ baseUrl, sessionId, text, agent, fetchImpl = globalThis.fetch } = {}) {
|
|
9596
9625
|
if (typeof fetchImpl !== "function") throw new Error("OpenCode direct prompt delivery requires fetch.");
|
|
9597
9626
|
const root = normalizeOpenCodeBaseUrl(baseUrl, "");
|
|
9598
9627
|
if (!root) throw new Error("OpenCode direct prompt delivery requires a base URL.");
|
|
9599
|
-
const
|
|
9600
|
-
const
|
|
9601
|
-
|
|
9602
|
-
|
|
9603
|
-
|
|
9604
|
-
|
|
9605
|
-
|
|
9606
|
-
|
|
9607
|
-
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
}
|
|
9611
|
-
|
|
9628
|
+
const encodedSession = encodeURIComponent(sessionId);
|
|
9629
|
+
const attempts = [
|
|
9630
|
+
{
|
|
9631
|
+
name: "v2 prompt",
|
|
9632
|
+
url: `${root}/api/session/${encodedSession}/prompt`,
|
|
9633
|
+
body: { prompt: { text }, delivery: "queue", resume: true },
|
|
9634
|
+
accept: (response, data) => {
|
|
9635
|
+
if (!response.ok) return null;
|
|
9636
|
+
if (!openCodePromptAdmissionVerification(data, sessionId)) throw new Error("OpenCode v2 prompt response did not include a valid prompt admission.");
|
|
9637
|
+
return { ok: true, method: "http", endpoint: "/api/session/{sessionID}/prompt", status: response.status, data: data.data, response: data };
|
|
9638
|
+
}
|
|
9639
|
+
},
|
|
9640
|
+
{
|
|
9641
|
+
name: "legacy async prompt",
|
|
9642
|
+
url: `${root}/session/${encodedSession}/prompt_async`,
|
|
9643
|
+
body: { agent, parts: [{ type: "text", text }] },
|
|
9644
|
+
accept: (response, data) => {
|
|
9645
|
+
if (response.status !== 204 && !response.ok) return null;
|
|
9646
|
+
return { ok: true, method: "http", endpoint: "/session/{sessionID}/prompt_async", status: response.status, data: data?.data || null, response: data };
|
|
9647
|
+
}
|
|
9612
9648
|
}
|
|
9649
|
+
];
|
|
9650
|
+
let firstError = null;
|
|
9651
|
+
for (const attempt of attempts) {
|
|
9652
|
+
const response = await fetchImpl(attempt.url, {
|
|
9653
|
+
method: "POST",
|
|
9654
|
+
headers: { "content-type": "application/json" },
|
|
9655
|
+
body: JSON.stringify(attempt.body)
|
|
9656
|
+
});
|
|
9657
|
+
const data = await readOpenCodeJsonResponse(response, attempt.name);
|
|
9658
|
+
const accepted = attempt.accept(response, data);
|
|
9659
|
+
if (accepted) return accepted;
|
|
9660
|
+
const message = data?.error?.message || data?.message || data?.raw || `OpenCode ${attempt.name} request failed with status ${response.status}.`;
|
|
9661
|
+
firstError ??= new Error(message);
|
|
9662
|
+
if (![404, 405].includes(Number(response.status))) break;
|
|
9613
9663
|
}
|
|
9614
|
-
|
|
9615
|
-
const message = data?.error?.message || data?.message || raw || `OpenCode prompt request failed with status ${response.status}.`;
|
|
9616
|
-
throw new Error(message);
|
|
9617
|
-
}
|
|
9618
|
-
if (!data?.data?.id) throw new Error("OpenCode prompt response did not include data.id.");
|
|
9619
|
-
return { ok: true, method: "http", status: response.status, data: data.data, response: data };
|
|
9664
|
+
throw firstError || new Error("OpenCode direct prompt delivery failed.");
|
|
9620
9665
|
}
|
|
9621
9666
|
async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, directory, opencodeBaseUrl, baseUrl, fetchImpl, direct = false } = {}) {
|
|
9622
9667
|
const directBaseUrl = opencodeBaseUrl || baseUrl;
|
|
@@ -9632,7 +9677,7 @@ async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, direct
|
|
|
9632
9677
|
if (!direct && typeof client?.session?.prompt === "function") {
|
|
9633
9678
|
return assertOpenCodePromptAccepted(await client.session.prompt(structuredPayload));
|
|
9634
9679
|
}
|
|
9635
|
-
if (directBaseUrl) return sendOpenCodeSessionEventDirect({ baseUrl: directBaseUrl, sessionId, text, fetchImpl });
|
|
9680
|
+
if (directBaseUrl) return sendOpenCodeSessionEventDirect({ baseUrl: directBaseUrl, sessionId, text, agent, fetchImpl });
|
|
9636
9681
|
throw new Error("OpenCode client does not expose session.prompt or session.promptAsync.");
|
|
9637
9682
|
}
|
|
9638
9683
|
function normalizeOpenCodeSessionMessages(result) {
|
|
@@ -9702,13 +9747,29 @@ async function applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason,
|
|
|
9702
9747
|
}
|
|
9703
9748
|
async function deliverClickUpSessionEventWithVerification({ openCodeClient, sendSessionEvent, clickupClient, worktree, taskId, sessionId, agent, text, directory, opencodeBaseUrl, eventMarkers = [], verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, applyBlockerOnFailure = true } = {}) {
|
|
9704
9749
|
const beforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => null);
|
|
9705
|
-
await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
|
|
9750
|
+
const sendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
|
|
9751
|
+
let admissionVerification = null;
|
|
9752
|
+
try {
|
|
9753
|
+
admissionVerification = openCodePromptAdmissionVerification(sendResult, sessionId);
|
|
9754
|
+
} catch (error) {
|
|
9755
|
+
appendClickUpWebhookLocalLog(worktree, { type: "message_delivery_failed", taskId, sessionId, reason: error.message, fallbackAttempted: false });
|
|
9756
|
+
if (!applyBlockerOnFailure) return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false };
|
|
9757
|
+
const blocker2 = await applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason: error.message, source: "delivery_admission_failed" });
|
|
9758
|
+
return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false, blockerTag: blocker2 };
|
|
9759
|
+
}
|
|
9760
|
+
if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: false };
|
|
9706
9761
|
let verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages, expectedText: text, markers: eventMarkers });
|
|
9707
9762
|
if (verification?.ok) return { ok: true, verification, fallback: false };
|
|
9708
9763
|
const canFallbackDirect = Boolean(opencodeBaseUrl);
|
|
9709
9764
|
if (canFallbackDirect) {
|
|
9710
9765
|
const retryBeforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => beforeMessages);
|
|
9711
|
-
await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
|
|
9766
|
+
const retrySendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
|
|
9767
|
+
try {
|
|
9768
|
+
admissionVerification = openCodePromptAdmissionVerification(retrySendResult, sessionId);
|
|
9769
|
+
} catch (error) {
|
|
9770
|
+
verification = { ok: false, reason: error.message };
|
|
9771
|
+
}
|
|
9772
|
+
if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: true };
|
|
9712
9773
|
verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages: retryBeforeMessages, expectedText: text, markers: eventMarkers });
|
|
9713
9774
|
if (verification?.ok) return { ok: true, verification, fallback: true };
|
|
9714
9775
|
}
|
package/dist/sanitize_cli.js
CHANGED
|
@@ -9599,31 +9599,76 @@ function assertOpenCodePromptAccepted(result) {
|
|
|
9599
9599
|
}
|
|
9600
9600
|
return result;
|
|
9601
9601
|
}
|
|
9602
|
-
|
|
9602
|
+
function openCodePromptAdmissionVerification(result, sessionId) {
|
|
9603
|
+
const response = result?.response ?? result;
|
|
9604
|
+
const data = response?.data ?? result?.data ?? null;
|
|
9605
|
+
const promptId = data?.id ?? response?.id ?? result?.id;
|
|
9606
|
+
const admittedSessionId = response?.sessionID ?? response?.sessionId ?? data?.sessionID ?? data?.sessionId ?? result?.sessionID ?? result?.sessionId;
|
|
9607
|
+
const admittedSeq = response?.admittedSeq ?? data?.admittedSeq ?? result?.admittedSeq;
|
|
9608
|
+
if (!promptId || admittedSeq === void 0 || admittedSeq === null || !admittedSessionId) return null;
|
|
9609
|
+
if (String(admittedSessionId) !== String(sessionId)) {
|
|
9610
|
+
throw new Error(`OpenCode prompt admission targeted foreign session ${admittedSessionId}.`);
|
|
9611
|
+
}
|
|
9612
|
+
return { ok: true, method: "prompt_admission", promptId: String(promptId), sessionId: String(admittedSessionId), admittedSeq };
|
|
9613
|
+
}
|
|
9614
|
+
function responseLooksLikeHtml(contentType = "", raw = "") {
|
|
9615
|
+
return String(contentType || "").toLowerCase().includes("text/html") || /^\s*<!doctype\s+html\b/i.test(raw) || /^\s*<html\b/i.test(raw);
|
|
9616
|
+
}
|
|
9617
|
+
async function readOpenCodeJsonResponse(response, endpointName) {
|
|
9618
|
+
const contentType = response.headers?.get?.("content-type") || "";
|
|
9619
|
+
const raw = await response.text();
|
|
9620
|
+
if (responseLooksLikeHtml(contentType, raw)) {
|
|
9621
|
+
throw new Error(`OpenCode ${endpointName} returned the HTML app shell instead of an API response.`);
|
|
9622
|
+
}
|
|
9623
|
+
if (!raw) return null;
|
|
9624
|
+
try {
|
|
9625
|
+
return JSON.parse(raw);
|
|
9626
|
+
} catch (error) {
|
|
9627
|
+
if (response.ok) throw new Error(`OpenCode ${endpointName} response was not JSON: ${error.message}`);
|
|
9628
|
+
return { raw };
|
|
9629
|
+
}
|
|
9630
|
+
}
|
|
9631
|
+
async function sendOpenCodeSessionEventDirect({ baseUrl, sessionId, text, agent, fetchImpl = globalThis.fetch } = {}) {
|
|
9603
9632
|
if (typeof fetchImpl !== "function") throw new Error("OpenCode direct prompt delivery requires fetch.");
|
|
9604
9633
|
const root = normalizeOpenCodeBaseUrl(baseUrl, "");
|
|
9605
9634
|
if (!root) throw new Error("OpenCode direct prompt delivery requires a base URL.");
|
|
9606
|
-
const
|
|
9607
|
-
const
|
|
9608
|
-
|
|
9609
|
-
|
|
9610
|
-
|
|
9611
|
-
|
|
9612
|
-
|
|
9613
|
-
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
-
|
|
9617
|
-
}
|
|
9618
|
-
|
|
9635
|
+
const encodedSession = encodeURIComponent(sessionId);
|
|
9636
|
+
const attempts = [
|
|
9637
|
+
{
|
|
9638
|
+
name: "v2 prompt",
|
|
9639
|
+
url: `${root}/api/session/${encodedSession}/prompt`,
|
|
9640
|
+
body: { prompt: { text }, delivery: "queue", resume: true },
|
|
9641
|
+
accept: (response, data) => {
|
|
9642
|
+
if (!response.ok) return null;
|
|
9643
|
+
if (!openCodePromptAdmissionVerification(data, sessionId)) throw new Error("OpenCode v2 prompt response did not include a valid prompt admission.");
|
|
9644
|
+
return { ok: true, method: "http", endpoint: "/api/session/{sessionID}/prompt", status: response.status, data: data.data, response: data };
|
|
9645
|
+
}
|
|
9646
|
+
},
|
|
9647
|
+
{
|
|
9648
|
+
name: "legacy async prompt",
|
|
9649
|
+
url: `${root}/session/${encodedSession}/prompt_async`,
|
|
9650
|
+
body: { agent, parts: [{ type: "text", text }] },
|
|
9651
|
+
accept: (response, data) => {
|
|
9652
|
+
if (response.status !== 204 && !response.ok) return null;
|
|
9653
|
+
return { ok: true, method: "http", endpoint: "/session/{sessionID}/prompt_async", status: response.status, data: data?.data || null, response: data };
|
|
9654
|
+
}
|
|
9619
9655
|
}
|
|
9656
|
+
];
|
|
9657
|
+
let firstError = null;
|
|
9658
|
+
for (const attempt of attempts) {
|
|
9659
|
+
const response = await fetchImpl(attempt.url, {
|
|
9660
|
+
method: "POST",
|
|
9661
|
+
headers: { "content-type": "application/json" },
|
|
9662
|
+
body: JSON.stringify(attempt.body)
|
|
9663
|
+
});
|
|
9664
|
+
const data = await readOpenCodeJsonResponse(response, attempt.name);
|
|
9665
|
+
const accepted = attempt.accept(response, data);
|
|
9666
|
+
if (accepted) return accepted;
|
|
9667
|
+
const message = data?.error?.message || data?.message || data?.raw || `OpenCode ${attempt.name} request failed with status ${response.status}.`;
|
|
9668
|
+
firstError ??= new Error(message);
|
|
9669
|
+
if (![404, 405].includes(Number(response.status))) break;
|
|
9620
9670
|
}
|
|
9621
|
-
|
|
9622
|
-
const message = data?.error?.message || data?.message || raw || `OpenCode prompt request failed with status ${response.status}.`;
|
|
9623
|
-
throw new Error(message);
|
|
9624
|
-
}
|
|
9625
|
-
if (!data?.data?.id) throw new Error("OpenCode prompt response did not include data.id.");
|
|
9626
|
-
return { ok: true, method: "http", status: response.status, data: data.data, response: data };
|
|
9671
|
+
throw firstError || new Error("OpenCode direct prompt delivery failed.");
|
|
9627
9672
|
}
|
|
9628
9673
|
async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, directory, opencodeBaseUrl, baseUrl, fetchImpl, direct = false } = {}) {
|
|
9629
9674
|
const directBaseUrl = opencodeBaseUrl || baseUrl;
|
|
@@ -9639,7 +9684,7 @@ async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, direct
|
|
|
9639
9684
|
if (!direct && typeof client?.session?.prompt === "function") {
|
|
9640
9685
|
return assertOpenCodePromptAccepted(await client.session.prompt(structuredPayload));
|
|
9641
9686
|
}
|
|
9642
|
-
if (directBaseUrl) return sendOpenCodeSessionEventDirect({ baseUrl: directBaseUrl, sessionId, text, fetchImpl });
|
|
9687
|
+
if (directBaseUrl) return sendOpenCodeSessionEventDirect({ baseUrl: directBaseUrl, sessionId, text, agent, fetchImpl });
|
|
9643
9688
|
throw new Error("OpenCode client does not expose session.prompt or session.promptAsync.");
|
|
9644
9689
|
}
|
|
9645
9690
|
function normalizeOpenCodeSessionMessages(result) {
|
|
@@ -9709,13 +9754,29 @@ async function applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason,
|
|
|
9709
9754
|
}
|
|
9710
9755
|
async function deliverClickUpSessionEventWithVerification({ openCodeClient, sendSessionEvent, clickupClient, worktree, taskId, sessionId, agent, text, directory, opencodeBaseUrl, eventMarkers = [], verifySessionEventDelivery = verifyOpenCodeSessionEventDelivery, applyBlockerOnFailure = true } = {}) {
|
|
9711
9756
|
const beforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => null);
|
|
9712
|
-
await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
|
|
9757
|
+
const sendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl });
|
|
9758
|
+
let admissionVerification = null;
|
|
9759
|
+
try {
|
|
9760
|
+
admissionVerification = openCodePromptAdmissionVerification(sendResult, sessionId);
|
|
9761
|
+
} catch (error) {
|
|
9762
|
+
appendClickUpWebhookLocalLog(worktree, { type: "message_delivery_failed", taskId, sessionId, reason: error.message, fallbackAttempted: false });
|
|
9763
|
+
if (!applyBlockerOnFailure) return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false };
|
|
9764
|
+
const blocker2 = await applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason: error.message, source: "delivery_admission_failed" });
|
|
9765
|
+
return { ok: false, action: "message_delivery_failed", reason: error.message, taskId, sessionId, fallbackAttempted: false, blockerTag: blocker2 };
|
|
9766
|
+
}
|
|
9767
|
+
if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: false };
|
|
9713
9768
|
let verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages, expectedText: text, markers: eventMarkers });
|
|
9714
9769
|
if (verification?.ok) return { ok: true, verification, fallback: false };
|
|
9715
9770
|
const canFallbackDirect = Boolean(opencodeBaseUrl);
|
|
9716
9771
|
if (canFallbackDirect) {
|
|
9717
9772
|
const retryBeforeMessages = await readOpenCodeSessionMessages(openCodeClient, { sessionId, limit: 50 }).catch(() => beforeMessages);
|
|
9718
|
-
await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
|
|
9773
|
+
const retrySendResult = await sendSessionEvent(openCodeClient, { sessionId, agent, text, directory, opencodeBaseUrl, direct: true });
|
|
9774
|
+
try {
|
|
9775
|
+
admissionVerification = openCodePromptAdmissionVerification(retrySendResult, sessionId);
|
|
9776
|
+
} catch (error) {
|
|
9777
|
+
verification = { ok: false, reason: error.message };
|
|
9778
|
+
}
|
|
9779
|
+
if (admissionVerification) return { ok: true, verification: admissionVerification, fallback: true };
|
|
9719
9780
|
verification = await verifySessionEventDelivery(openCodeClient, { sessionId, beforeMessages: retryBeforeMessages, expectedText: text, markers: eventMarkers });
|
|
9720
9781
|
if (verification?.ok) return { ok: true, verification, fallback: true };
|
|
9721
9782
|
}
|