@defend-tech/opencode-optima 0.1.17 → 0.1.18

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
  }
@@ -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
  }
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.18",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@github.com/defend-tech/opencode-optima.git"