@defend-tech/opencode-optima 0.1.34 → 0.1.35
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 +24 -10
- package/dist/sanitize_cli.js +24 -10
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -9194,7 +9194,7 @@ async function findReusableClickUpWebhook(config, clickupClient = null) {
|
|
|
9194
9194
|
}
|
|
9195
9195
|
return null;
|
|
9196
9196
|
}
|
|
9197
|
-
async function validateClickUpWebhookState(state, config, clickupClient = null) {
|
|
9197
|
+
async function validateClickUpWebhookState(state, config, clickupClient = null, { allowRemoteUnhealthyLocalRecovery = false } = {}) {
|
|
9198
9198
|
if (!isClickUpWebhookStateActive(state, config)) return { valid: false, reason: "state_incomplete" };
|
|
9199
9199
|
if (clickupClient?.listWebhooks) {
|
|
9200
9200
|
const listed = await clickupClient.listWebhooks({ teamId: config.teamId });
|
|
@@ -9202,10 +9202,22 @@ async function validateClickUpWebhookState(state, config, clickupClient = null)
|
|
|
9202
9202
|
if (!match) return { valid: false, reason: "remote_state_missing" };
|
|
9203
9203
|
const remote = normalizeClickUpWebhookApiResponse(match, config);
|
|
9204
9204
|
const remoteWithLocalSecret = { ...remote, secret: state.secret };
|
|
9205
|
-
if (
|
|
9206
|
-
return { valid:
|
|
9205
|
+
if (isClickUpWebhookStateActive(remoteWithLocalSecret, config) && remote.webhookId === state.webhookId) {
|
|
9206
|
+
return { valid: true, mode: "remote", state: { ...remoteWithLocalSecret, recentEventKeys: state.recentEventKeys || [], lastValidatedAt: (/* @__PURE__ */ new Date()).toISOString() } };
|
|
9207
9207
|
}
|
|
9208
|
-
|
|
9208
|
+
const localStateValidation = await validateClickUpWebhookState(state, config, null);
|
|
9209
|
+
if (allowRemoteUnhealthyLocalRecovery && localStateValidation.valid && remote.webhookId === state.webhookId) {
|
|
9210
|
+
const remoteConfigMatches = remote.publicUrl === config.webhook.publicUrl && [...new Set(config.webhook.events || [])].every((event) => new Set(remote.events || []).has(event));
|
|
9211
|
+
if (remoteConfigMatches) {
|
|
9212
|
+
return {
|
|
9213
|
+
...localStateValidation,
|
|
9214
|
+
mode: "local_state_remote_unhealthy",
|
|
9215
|
+
limitation: "ClickUp remote webhook is present but unhealthy; Optima starts the local listener from matching local id/secret/config so delivery can recover.",
|
|
9216
|
+
remote
|
|
9217
|
+
};
|
|
9218
|
+
}
|
|
9219
|
+
}
|
|
9220
|
+
return { valid: false, reason: "remote_state_mismatch", remote };
|
|
9209
9221
|
}
|
|
9210
9222
|
return { valid: true, mode: "local_state", state: { ...state, lastValidatedAt: (/* @__PURE__ */ new Date()).toISOString() }, limitation: "ClickUp API validation unavailable; Optima trusts ignored local runtime state only after id/secret/config checks." };
|
|
9211
9223
|
}
|
|
@@ -9215,7 +9227,7 @@ async function ensureClickUpWebhookSubscription({ validation, worktree, clickupC
|
|
|
9215
9227
|
}
|
|
9216
9228
|
const { config } = validation;
|
|
9217
9229
|
const existing = readClickUpWebhookState(worktree, config);
|
|
9218
|
-
const existingValidation = await validateClickUpWebhookState(existing, config, clickupClient);
|
|
9230
|
+
const existingValidation = await validateClickUpWebhookState(existing, config, clickupClient, { allowRemoteUnhealthyLocalRecovery: true });
|
|
9219
9231
|
if (existingValidation.valid) {
|
|
9220
9232
|
const state = writeClickUpWebhookState(worktree, { ...existingValidation.state, recentEventKeys: existing.recentEventKeys || [] }, config);
|
|
9221
9233
|
clickUpWebhookLifecycleLog(worktree, { type: "remote_webhook_reused", webhookId: state.webhookId, mode: existingValidation.mode });
|
|
@@ -9758,12 +9770,18 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9758
9770
|
if (!taskId) return { ok: false, action: "error", reason: "missing_task_id" };
|
|
9759
9771
|
let task = payload.task || (clickupClient?.getTask ? await clickupClient.getTask(taskId) : null);
|
|
9760
9772
|
if (!task) return { ok: false, action: "error", reason: "task_unavailable", taskId };
|
|
9773
|
+
if (clickupClient?.getTask) {
|
|
9774
|
+
const latestTask = await clickupClient.getTask(taskId);
|
|
9775
|
+
if (latestTask) task = latestTask;
|
|
9776
|
+
}
|
|
9761
9777
|
const isCommentEvent = eventType === "taskCommentPosted" || eventType === "taskCommentUpdated";
|
|
9762
9778
|
if (isCommentEvent) {
|
|
9763
9779
|
const comment = clickUpCommentFromPayload(payload);
|
|
9764
9780
|
const authorId = clickUpCommentAuthorId(comment);
|
|
9765
9781
|
if (authorId && authorId === config.routing.ignoredCommentAuthorId) return finish({ ok: true, action: "ignored", reason: "self_authored_comment", taskId });
|
|
9766
|
-
|
|
9782
|
+
const mentionsProductManager = clickUpCommentMentionsProductManager(comment, config.routing);
|
|
9783
|
+
const assignedToProductManager = isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId);
|
|
9784
|
+
if (!mentionsProductManager && !assignedToProductManager) return finish({ ok: true, action: "ignored", reason: "missing_product_manager_mention_or_assignment", taskId });
|
|
9767
9785
|
commentLedgerKey = clickUpCommentLedgerKey({ taskId, eventType, payload });
|
|
9768
9786
|
try {
|
|
9769
9787
|
if (isClickUpCommentVersionProcessed({ ledgerPath: commentLedgerPath, key: commentLedgerKey, worktree })) {
|
|
@@ -9775,10 +9793,6 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9775
9793
|
}
|
|
9776
9794
|
if (!isCommentEvent && !isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId)) return finish({ ok: true, action: "ignored", reason: "not_assigned_to_product_manager", taskId });
|
|
9777
9795
|
if (isClickUpTaskTerminal(task, payload, config.routing.ignoredStatuses)) return finish({ ok: true, action: "ignored", reason: "terminal_status", taskId });
|
|
9778
|
-
if (clickupClient?.getTask) {
|
|
9779
|
-
const latestTask = await clickupClient.getTask(taskId);
|
|
9780
|
-
if (latestTask) task = latestTask;
|
|
9781
|
-
}
|
|
9782
9796
|
const sessionTitle = formatClickUpSessionTitle({ taskId, payloadTask: payload.task, task });
|
|
9783
9797
|
const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
|
|
9784
9798
|
const metadata = normalizeAgentMetadataJson(existingMetadata);
|
package/dist/sanitize_cli.js
CHANGED
|
@@ -9201,7 +9201,7 @@ async function findReusableClickUpWebhook(config, clickupClient = null) {
|
|
|
9201
9201
|
}
|
|
9202
9202
|
return null;
|
|
9203
9203
|
}
|
|
9204
|
-
async function validateClickUpWebhookState(state, config, clickupClient = null) {
|
|
9204
|
+
async function validateClickUpWebhookState(state, config, clickupClient = null, { allowRemoteUnhealthyLocalRecovery = false } = {}) {
|
|
9205
9205
|
if (!isClickUpWebhookStateActive(state, config)) return { valid: false, reason: "state_incomplete" };
|
|
9206
9206
|
if (clickupClient?.listWebhooks) {
|
|
9207
9207
|
const listed = await clickupClient.listWebhooks({ teamId: config.teamId });
|
|
@@ -9209,10 +9209,22 @@ async function validateClickUpWebhookState(state, config, clickupClient = null)
|
|
|
9209
9209
|
if (!match) return { valid: false, reason: "remote_state_missing" };
|
|
9210
9210
|
const remote = normalizeClickUpWebhookApiResponse(match, config);
|
|
9211
9211
|
const remoteWithLocalSecret = { ...remote, secret: state.secret };
|
|
9212
|
-
if (
|
|
9213
|
-
return { valid:
|
|
9212
|
+
if (isClickUpWebhookStateActive(remoteWithLocalSecret, config) && remote.webhookId === state.webhookId) {
|
|
9213
|
+
return { valid: true, mode: "remote", state: { ...remoteWithLocalSecret, recentEventKeys: state.recentEventKeys || [], lastValidatedAt: (/* @__PURE__ */ new Date()).toISOString() } };
|
|
9214
9214
|
}
|
|
9215
|
-
|
|
9215
|
+
const localStateValidation = await validateClickUpWebhookState(state, config, null);
|
|
9216
|
+
if (allowRemoteUnhealthyLocalRecovery && localStateValidation.valid && remote.webhookId === state.webhookId) {
|
|
9217
|
+
const remoteConfigMatches = remote.publicUrl === config.webhook.publicUrl && [...new Set(config.webhook.events || [])].every((event) => new Set(remote.events || []).has(event));
|
|
9218
|
+
if (remoteConfigMatches) {
|
|
9219
|
+
return {
|
|
9220
|
+
...localStateValidation,
|
|
9221
|
+
mode: "local_state_remote_unhealthy",
|
|
9222
|
+
limitation: "ClickUp remote webhook is present but unhealthy; Optima starts the local listener from matching local id/secret/config so delivery can recover.",
|
|
9223
|
+
remote
|
|
9224
|
+
};
|
|
9225
|
+
}
|
|
9226
|
+
}
|
|
9227
|
+
return { valid: false, reason: "remote_state_mismatch", remote };
|
|
9216
9228
|
}
|
|
9217
9229
|
return { valid: true, mode: "local_state", state: { ...state, lastValidatedAt: (/* @__PURE__ */ new Date()).toISOString() }, limitation: "ClickUp API validation unavailable; Optima trusts ignored local runtime state only after id/secret/config checks." };
|
|
9218
9230
|
}
|
|
@@ -9222,7 +9234,7 @@ async function ensureClickUpWebhookSubscription({ validation, worktree, clickupC
|
|
|
9222
9234
|
}
|
|
9223
9235
|
const { config } = validation;
|
|
9224
9236
|
const existing = readClickUpWebhookState(worktree, config);
|
|
9225
|
-
const existingValidation = await validateClickUpWebhookState(existing, config, clickupClient);
|
|
9237
|
+
const existingValidation = await validateClickUpWebhookState(existing, config, clickupClient, { allowRemoteUnhealthyLocalRecovery: true });
|
|
9226
9238
|
if (existingValidation.valid) {
|
|
9227
9239
|
const state = writeClickUpWebhookState(worktree, { ...existingValidation.state, recentEventKeys: existing.recentEventKeys || [] }, config);
|
|
9228
9240
|
clickUpWebhookLifecycleLog(worktree, { type: "remote_webhook_reused", webhookId: state.webhookId, mode: existingValidation.mode });
|
|
@@ -9765,12 +9777,18 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9765
9777
|
if (!taskId) return { ok: false, action: "error", reason: "missing_task_id" };
|
|
9766
9778
|
let task = payload.task || (clickupClient?.getTask ? await clickupClient.getTask(taskId) : null);
|
|
9767
9779
|
if (!task) return { ok: false, action: "error", reason: "task_unavailable", taskId };
|
|
9780
|
+
if (clickupClient?.getTask) {
|
|
9781
|
+
const latestTask = await clickupClient.getTask(taskId);
|
|
9782
|
+
if (latestTask) task = latestTask;
|
|
9783
|
+
}
|
|
9768
9784
|
const isCommentEvent = eventType === "taskCommentPosted" || eventType === "taskCommentUpdated";
|
|
9769
9785
|
if (isCommentEvent) {
|
|
9770
9786
|
const comment = clickUpCommentFromPayload(payload);
|
|
9771
9787
|
const authorId = clickUpCommentAuthorId(comment);
|
|
9772
9788
|
if (authorId && authorId === config.routing.ignoredCommentAuthorId) return finish({ ok: true, action: "ignored", reason: "self_authored_comment", taskId });
|
|
9773
|
-
|
|
9789
|
+
const mentionsProductManager = clickUpCommentMentionsProductManager(comment, config.routing);
|
|
9790
|
+
const assignedToProductManager = isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId);
|
|
9791
|
+
if (!mentionsProductManager && !assignedToProductManager) return finish({ ok: true, action: "ignored", reason: "missing_product_manager_mention_or_assignment", taskId });
|
|
9774
9792
|
commentLedgerKey = clickUpCommentLedgerKey({ taskId, eventType, payload });
|
|
9775
9793
|
try {
|
|
9776
9794
|
if (isClickUpCommentVersionProcessed({ ledgerPath: commentLedgerPath, key: commentLedgerKey, worktree })) {
|
|
@@ -9782,10 +9800,6 @@ async function routeClickUpWebhookEventUnlocked({ payload, config, state = {}, w
|
|
|
9782
9800
|
}
|
|
9783
9801
|
if (!isCommentEvent && !isClickUpTaskAssignedToProductManager(task, config.routing.productManagerAssigneeId)) return finish({ ok: true, action: "ignored", reason: "not_assigned_to_product_manager", taskId });
|
|
9784
9802
|
if (isClickUpTaskTerminal(task, payload, config.routing.ignoredStatuses)) return finish({ ok: true, action: "ignored", reason: "terminal_status", taskId });
|
|
9785
|
-
if (clickupClient?.getTask) {
|
|
9786
|
-
const latestTask = await clickupClient.getTask(taskId);
|
|
9787
|
-
if (latestTask) task = latestTask;
|
|
9788
|
-
}
|
|
9789
9803
|
const sessionTitle = formatClickUpSessionTitle({ taskId, payloadTask: payload.task, task });
|
|
9790
9804
|
const existingMetadata = clickUpTaskAgentMetadata(task, config.routing.metadataFieldId);
|
|
9791
9805
|
const metadata = normalizeAgentMetadataJson(existingMetadata);
|