@defend-tech/opencode-optima 0.1.17 → 0.1.19

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
@@ -9020,6 +9020,26 @@ function clickUpWebhookListItems(response = {}) {
9020
9020
  if (Array.isArray(response?.data?.webhooks)) return response.data.webhooks;
9021
9021
  return [];
9022
9022
  }
9023
+ function clickUpWebhookLocationCompatible(webhook = {}, config = {}) {
9024
+ const location = config?.webhook?.location || {};
9025
+ for (const key of ["space_id", "folder_id", "list_id"]) {
9026
+ const expected = String(location[key] || "").trim();
9027
+ if (expected && String(webhook[key] || webhook.location?.[key] || "").trim() !== expected) return false;
9028
+ }
9029
+ return true;
9030
+ }
9031
+ async function findReusableClickUpWebhook(config, clickupClient = null) {
9032
+ if (!clickupClient?.listWebhooks) return null;
9033
+ const listed = await clickupClient.listWebhooks({ teamId: config.teamId });
9034
+ for (const webhook of clickUpWebhookListItems(listed)) {
9035
+ const remote = normalizeClickUpWebhookApiResponse(webhook, config);
9036
+ if (remote.publicUrl !== config.webhook.publicUrl) continue;
9037
+ if (!clickUpWebhookLocationCompatible(webhook, config)) continue;
9038
+ if (!isClickUpWebhookStateActive(remote, config)) continue;
9039
+ return remote;
9040
+ }
9041
+ return null;
9042
+ }
9023
9043
  async function validateClickUpWebhookState(state, config, clickupClient = null) {
9024
9044
  if (!isClickUpWebhookStateActive(state, config)) return { valid: false, reason: "state_incomplete" };
9025
9045
  if (clickupClient?.listWebhooks) {
@@ -9051,6 +9071,12 @@ async function ensureClickUpWebhookSubscription({ validation, worktree, clickupC
9051
9071
  await deleteClickUpWebhookBestEffort({ webhookId: existing.webhookId, clickupClient, worktree, reason: existingValidation.reason || "startup_self_heal" });
9052
9072
  markClickUpWebhookInactive(worktree, existing, config);
9053
9073
  }
9074
+ const reusableRemote = await findReusableClickUpWebhook(config, clickupClient);
9075
+ if (reusableRemote) {
9076
+ const state = writeClickUpWebhookState(worktree, { ...reusableRemote, recentEventKeys: existing.recentEventKeys || [] }, config);
9077
+ clickUpWebhookLifecycleLog(worktree, { type: "remote_webhook_reused", webhookId: state.webhookId, mode: "remote_discovered" });
9078
+ return { active: true, valid: true, mode: "remote_discovered", state };
9079
+ }
9054
9080
  if (!clickupClient?.createWebhook) {
9055
9081
  return { active: false, valid: false, reason: "clickup_client_unavailable", state: existing };
9056
9082
  }
@@ -9212,20 +9238,30 @@ async function createOpenCodeSession(client, { title, directory } = {}) {
9212
9238
  const result = await client.session.create({ query: { directory }, body: { title } });
9213
9239
  return result?.data?.id || result?.id;
9214
9240
  }
9241
+ function assertOpenCodePromptAccepted(result) {
9242
+ const status = Number(result?.status || result?.response?.status || result?.error?.status || 0);
9243
+ if (status >= 400 || result?.ok === false || result?.error) {
9244
+ const message = result?.error?.message || result?.message || `OpenCode prompt request failed${status ? ` with status ${status}` : ""}.`;
9245
+ throw new Error(message);
9246
+ }
9247
+ return result;
9248
+ }
9215
9249
  async function callOpenCodePromptWithFallbacks(method, sessionId, flatPayload, structuredPayload) {
9216
- try {
9217
- return await method({ sessionID: sessionId, ...flatPayload });
9218
- } catch (flatError) {
9250
+ const attempts = [
9251
+ { id: sessionId, ...flatPayload },
9252
+ { sessionID: sessionId, ...flatPayload },
9253
+ { ...structuredPayload, path: { sessionID: sessionId } },
9254
+ { ...structuredPayload, path: { id: sessionId } }
9255
+ ];
9256
+ let firstError = null;
9257
+ for (const attempt of attempts) {
9219
9258
  try {
9220
- return await method({ ...structuredPayload, path: { sessionID: sessionId } });
9221
- } catch {
9222
- try {
9223
- return await method({ ...structuredPayload, path: { id: sessionId } });
9224
- } catch {
9225
- throw flatError;
9226
- }
9259
+ return assertOpenCodePromptAccepted(await method(attempt));
9260
+ } catch (error) {
9261
+ firstError ??= error;
9227
9262
  }
9228
9263
  }
9264
+ throw firstError;
9229
9265
  }
9230
9266
  async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, directory } = {}) {
9231
9267
  const parts = [{ type: "text", text }];
@@ -9027,6 +9027,26 @@ function clickUpWebhookListItems(response = {}) {
9027
9027
  if (Array.isArray(response?.data?.webhooks)) return response.data.webhooks;
9028
9028
  return [];
9029
9029
  }
9030
+ function clickUpWebhookLocationCompatible(webhook = {}, config = {}) {
9031
+ const location = config?.webhook?.location || {};
9032
+ for (const key of ["space_id", "folder_id", "list_id"]) {
9033
+ const expected = String(location[key] || "").trim();
9034
+ if (expected && String(webhook[key] || webhook.location?.[key] || "").trim() !== expected) return false;
9035
+ }
9036
+ return true;
9037
+ }
9038
+ async function findReusableClickUpWebhook(config, clickupClient = null) {
9039
+ if (!clickupClient?.listWebhooks) return null;
9040
+ const listed = await clickupClient.listWebhooks({ teamId: config.teamId });
9041
+ for (const webhook of clickUpWebhookListItems(listed)) {
9042
+ const remote = normalizeClickUpWebhookApiResponse(webhook, config);
9043
+ if (remote.publicUrl !== config.webhook.publicUrl) continue;
9044
+ if (!clickUpWebhookLocationCompatible(webhook, config)) continue;
9045
+ if (!isClickUpWebhookStateActive(remote, config)) continue;
9046
+ return remote;
9047
+ }
9048
+ return null;
9049
+ }
9030
9050
  async function validateClickUpWebhookState(state, config, clickupClient = null) {
9031
9051
  if (!isClickUpWebhookStateActive(state, config)) return { valid: false, reason: "state_incomplete" };
9032
9052
  if (clickupClient?.listWebhooks) {
@@ -9058,6 +9078,12 @@ async function ensureClickUpWebhookSubscription({ validation, worktree, clickupC
9058
9078
  await deleteClickUpWebhookBestEffort({ webhookId: existing.webhookId, clickupClient, worktree, reason: existingValidation.reason || "startup_self_heal" });
9059
9079
  markClickUpWebhookInactive(worktree, existing, config);
9060
9080
  }
9081
+ const reusableRemote = await findReusableClickUpWebhook(config, clickupClient);
9082
+ if (reusableRemote) {
9083
+ const state = writeClickUpWebhookState(worktree, { ...reusableRemote, recentEventKeys: existing.recentEventKeys || [] }, config);
9084
+ clickUpWebhookLifecycleLog(worktree, { type: "remote_webhook_reused", webhookId: state.webhookId, mode: "remote_discovered" });
9085
+ return { active: true, valid: true, mode: "remote_discovered", state };
9086
+ }
9061
9087
  if (!clickupClient?.createWebhook) {
9062
9088
  return { active: false, valid: false, reason: "clickup_client_unavailable", state: existing };
9063
9089
  }
@@ -9219,20 +9245,30 @@ async function createOpenCodeSession(client, { title, directory } = {}) {
9219
9245
  const result = await client.session.create({ query: { directory }, body: { title } });
9220
9246
  return result?.data?.id || result?.id;
9221
9247
  }
9248
+ function assertOpenCodePromptAccepted(result) {
9249
+ const status = Number(result?.status || result?.response?.status || result?.error?.status || 0);
9250
+ if (status >= 400 || result?.ok === false || result?.error) {
9251
+ const message = result?.error?.message || result?.message || `OpenCode prompt request failed${status ? ` with status ${status}` : ""}.`;
9252
+ throw new Error(message);
9253
+ }
9254
+ return result;
9255
+ }
9222
9256
  async function callOpenCodePromptWithFallbacks(method, sessionId, flatPayload, structuredPayload) {
9223
- try {
9224
- return await method({ sessionID: sessionId, ...flatPayload });
9225
- } catch (flatError) {
9257
+ const attempts = [
9258
+ { id: sessionId, ...flatPayload },
9259
+ { sessionID: sessionId, ...flatPayload },
9260
+ { ...structuredPayload, path: { sessionID: sessionId } },
9261
+ { ...structuredPayload, path: { id: sessionId } }
9262
+ ];
9263
+ let firstError = null;
9264
+ for (const attempt of attempts) {
9226
9265
  try {
9227
- return await method({ ...structuredPayload, path: { sessionID: sessionId } });
9228
- } catch {
9229
- try {
9230
- return await method({ ...structuredPayload, path: { id: sessionId } });
9231
- } catch {
9232
- throw flatError;
9233
- }
9266
+ return assertOpenCodePromptAccepted(await method(attempt));
9267
+ } catch (error) {
9268
+ firstError ??= error;
9234
9269
  }
9235
9270
  }
9271
+ throw firstError;
9236
9272
  }
9237
9273
  async function sendOpenCodeSessionEvent(client, { sessionId, agent, text, directory } = {}) {
9238
9274
  const parts = [{ type: "text", text }];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defend-tech/opencode-optima",
3
- "version": "0.1.17",
3
+ "version": "0.1.19",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@github.com/defend-tech/opencode-optima.git"