@defend-tech/opencode-optima 0.1.65 → 0.1.66

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
@@ -9978,17 +9978,11 @@ function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
9978
9978
  body: JSON.stringify({ value })
9979
9979
  });
9980
9980
  },
9981
- async postTaskComment({ taskId, comment }) {
9982
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/comment`, {
9983
- method: "POST",
9984
- body: JSON.stringify({ comment_text: comment })
9985
- });
9981
+ async postTaskComment() {
9982
+ throw new Error("Optima runtime does not post ClickUp task comments; use local logs for process failures.");
9986
9983
  },
9987
- async addTaskTag({ taskId, tagName = CLICKUP_BLOCKER_TAG_NAME } = {}) {
9988
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/tag/${encodeURIComponent(tagName)}`, {
9989
- method: "POST",
9990
- body: JSON.stringify({})
9991
- });
9984
+ async addTaskTag() {
9985
+ throw new Error("Optima runtime does not add ClickUp task tags; use local logs for process failures.");
9992
9986
  },
9993
9987
  async listAssignedTasks({ assigneeId, statuses = [], limit = CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT } = {}) {
9994
9988
  const params = new URLSearchParams();
@@ -10548,15 +10542,54 @@ async function createOpenCodeSession(client, { title, directory, agent } = {}) {
10548
10542
  throw error || new Error("OpenCode session create failed.");
10549
10543
  }
10550
10544
  }
10551
- async function waitForOpenCodeReadiness(client, { worktree = process.cwd(), attempts = 10, delayMs = 500, now = () => /* @__PURE__ */ new Date() } = {}) {
10552
- if (typeof client?.session?.create !== "function") return { ok: true, skipped: true, reason: "session_create_probe_unavailable" };
10545
+ function normalizeOpenCodeSessionCollection(value) {
10546
+ if (Array.isArray(value)) return value;
10547
+ if (!isPlainObject(value)) return [];
10548
+ for (const key of ["sessions", "items", "data", "result", "results"]) {
10549
+ const nested = value[key];
10550
+ if (Array.isArray(nested)) return nested;
10551
+ if (isPlainObject(nested)) {
10552
+ const normalized = normalizeOpenCodeSessionCollection(nested);
10553
+ if (normalized.length > 0) return normalized;
10554
+ }
10555
+ }
10556
+ return [];
10557
+ }
10558
+ async function listOpenCodeSessionsReadiness(client, { directory = "" } = {}) {
10559
+ if (typeof client?.session?.list !== "function") return null;
10560
+ const attempts = [
10561
+ { query: directory ? { directory } : {} },
10562
+ directory ? { directory } : {}
10563
+ ];
10564
+ for (const attempt of attempts) {
10565
+ try {
10566
+ const result = await client.session.list(attempt);
10567
+ return { ok: true, method: "session_list", sessions: normalizeOpenCodeSessionCollection(result?.data ?? result).length };
10568
+ } catch {
10569
+ }
10570
+ }
10571
+ return null;
10572
+ }
10573
+ async function listOpenCodeSessionsReadinessHttp({ baseUrl, directory = "", fetchImpl = globalThis.fetch } = {}) {
10574
+ const root = normalizeOpenCodeBaseUrl(baseUrl, "");
10575
+ if (!root || typeof fetchImpl !== "function") return null;
10576
+ const url = openChamberUrl(root, "/session", directory ? { directory } : {});
10577
+ const response = await fetchImpl(url, { method: "GET" });
10578
+ const contentType = response.headers?.get?.("content-type") || "";
10579
+ const raw = await response.text();
10580
+ if (!response.ok) throw new Error(`OpenCode session list readiness failed with status ${response.status}.`);
10581
+ if (responseLooksLikeHtml(contentType, raw)) throw new Error("OpenCode session list readiness returned an HTML app shell.");
10582
+ const data = raw.trim() ? JSON.parse(raw) : [];
10583
+ return { ok: true, method: "session_list_http", sessions: normalizeOpenCodeSessionCollection(data).length };
10584
+ }
10585
+ async function waitForOpenCodeReadiness(client, { worktree = process.cwd(), attempts = 10, delayMs = 500, opencodeBaseUrl = "", fetchImpl = globalThis.fetch } = {}) {
10553
10586
  let lastError = "opencode_not_ready";
10554
10587
  const maxAttempts = Math.max(1, Number(attempts) || 1);
10555
10588
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
10556
10589
  try {
10557
- const sessionId = await createOpenCodeSession(client, { title: `Optima startup readiness probe ${now().toISOString()}`, directory: worktree });
10558
- if (await openCodeSessionExists(client, sessionId)) return { ok: true, method: "session_create_probe", sessionId, attempts: attempt };
10559
- lastError = "readiness_probe_session_not_visible";
10590
+ const listed = await listOpenCodeSessionsReadiness(client, { directory: worktree }) || await listOpenCodeSessionsReadinessHttp({ baseUrl: opencodeBaseUrl, directory: worktree, fetchImpl });
10591
+ if (listed?.ok) return { ...listed, attempts: attempt };
10592
+ return { ok: true, skipped: true, reason: "session_list_probe_unavailable", attempts: attempt };
10560
10593
  } catch (error) {
10561
10594
  lastError = error.message || "opencode_not_ready";
10562
10595
  }
@@ -10929,18 +10962,9 @@ async function postClickUpLaunchFailureComment({ clickupClient, worktree, taskId
10929
10962
  return { ok: false, skipped: true, reason: "local_log_only" };
10930
10963
  }
10931
10964
  async function applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason, source, tagName = CLICKUP_BLOCKER_TAG_NAME } = {}) {
10932
- if (typeof clickupClient?.addTaskTag !== "function") {
10933
- appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_unavailable", taskId, reason, source, tagName });
10934
- return { ok: false, skipped: true, reason: "add_task_tag_unavailable", tagName };
10935
- }
10936
- try {
10937
- await clickupClient.addTaskTag({ taskId, tagName });
10938
- appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_applied", taskId, reason, source, tagName });
10939
- return { ok: true, tagName };
10940
- } catch (error) {
10941
- appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_failed", taskId, reason, source, tagName, message: error.message });
10942
- return { ok: false, error: error.message, tagName };
10943
- }
10965
+ void clickupClient;
10966
+ appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_skipped", taskId, reason, source, tagName, policy: "metadata_only_task_writes" });
10967
+ return { ok: false, skipped: true, reason: "metadata_only_task_writes", tagName };
10944
10968
  }
10945
10969
  function openCodeBlockingPromptVerification(result, sessionId) {
10946
10970
  if (result?.__optimaPromptDelivery !== "prompt") return null;
@@ -11430,7 +11454,7 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
11430
11454
  clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_finished", ...skipped });
11431
11455
  return skipped;
11432
11456
  }
11433
- const readiness = await waitForReadiness(openCodeClient, { worktree, now });
11457
+ const readiness = await waitForReadiness(openCodeClient, { worktree, now, opencodeBaseUrl: config.opencode?.baseUrl });
11434
11458
  appendClickUpWebhookLocalLog(worktree, { type: readiness.ok ? "startup_reconciliation_readiness_ready" : "startup_reconciliation_readiness_failed", ...readiness });
11435
11459
  if (!readiness.ok) {
11436
11460
  const failed = { ok: false, skipped: true, reason: "opencode_not_ready", readiness, assigned: 0, comments: 0, ignored: 0, errors: 1, undelivered: 1, tasks: [], validation: { undelivered: 1, emptyPromptSessions: [] } };
@@ -9985,17 +9985,11 @@ function createClickUpApiClient(config, fetchImpl = globalThis.fetch) {
9985
9985
  body: JSON.stringify({ value })
9986
9986
  });
9987
9987
  },
9988
- async postTaskComment({ taskId, comment }) {
9989
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/comment`, {
9990
- method: "POST",
9991
- body: JSON.stringify({ comment_text: comment })
9992
- });
9988
+ async postTaskComment() {
9989
+ throw new Error("Optima runtime does not post ClickUp task comments; use local logs for process failures.");
9993
9990
  },
9994
- async addTaskTag({ taskId, tagName = CLICKUP_BLOCKER_TAG_NAME } = {}) {
9995
- return request(`https://api.clickup.com/api/v2/task/${encodeURIComponent(taskId)}/tag/${encodeURIComponent(tagName)}`, {
9996
- method: "POST",
9997
- body: JSON.stringify({})
9998
- });
9991
+ async addTaskTag() {
9992
+ throw new Error("Optima runtime does not add ClickUp task tags; use local logs for process failures.");
9999
9993
  },
10000
9994
  async listAssignedTasks({ assigneeId, statuses = [], limit = CLICKUP_WEBHOOK_STARTUP_TASK_LIMIT } = {}) {
10001
9995
  const params = new URLSearchParams();
@@ -10555,15 +10549,54 @@ async function createOpenCodeSession(client, { title, directory, agent } = {}) {
10555
10549
  throw error || new Error("OpenCode session create failed.");
10556
10550
  }
10557
10551
  }
10558
- async function waitForOpenCodeReadiness(client, { worktree = process.cwd(), attempts = 10, delayMs = 500, now = () => /* @__PURE__ */ new Date() } = {}) {
10559
- if (typeof client?.session?.create !== "function") return { ok: true, skipped: true, reason: "session_create_probe_unavailable" };
10552
+ function normalizeOpenCodeSessionCollection(value) {
10553
+ if (Array.isArray(value)) return value;
10554
+ if (!isPlainObject(value)) return [];
10555
+ for (const key of ["sessions", "items", "data", "result", "results"]) {
10556
+ const nested = value[key];
10557
+ if (Array.isArray(nested)) return nested;
10558
+ if (isPlainObject(nested)) {
10559
+ const normalized = normalizeOpenCodeSessionCollection(nested);
10560
+ if (normalized.length > 0) return normalized;
10561
+ }
10562
+ }
10563
+ return [];
10564
+ }
10565
+ async function listOpenCodeSessionsReadiness(client, { directory = "" } = {}) {
10566
+ if (typeof client?.session?.list !== "function") return null;
10567
+ const attempts = [
10568
+ { query: directory ? { directory } : {} },
10569
+ directory ? { directory } : {}
10570
+ ];
10571
+ for (const attempt of attempts) {
10572
+ try {
10573
+ const result = await client.session.list(attempt);
10574
+ return { ok: true, method: "session_list", sessions: normalizeOpenCodeSessionCollection(result?.data ?? result).length };
10575
+ } catch {
10576
+ }
10577
+ }
10578
+ return null;
10579
+ }
10580
+ async function listOpenCodeSessionsReadinessHttp({ baseUrl, directory = "", fetchImpl = globalThis.fetch } = {}) {
10581
+ const root = normalizeOpenCodeBaseUrl(baseUrl, "");
10582
+ if (!root || typeof fetchImpl !== "function") return null;
10583
+ const url = openChamberUrl(root, "/session", directory ? { directory } : {});
10584
+ const response = await fetchImpl(url, { method: "GET" });
10585
+ const contentType = response.headers?.get?.("content-type") || "";
10586
+ const raw = await response.text();
10587
+ if (!response.ok) throw new Error(`OpenCode session list readiness failed with status ${response.status}.`);
10588
+ if (responseLooksLikeHtml(contentType, raw)) throw new Error("OpenCode session list readiness returned an HTML app shell.");
10589
+ const data = raw.trim() ? JSON.parse(raw) : [];
10590
+ return { ok: true, method: "session_list_http", sessions: normalizeOpenCodeSessionCollection(data).length };
10591
+ }
10592
+ async function waitForOpenCodeReadiness(client, { worktree = process.cwd(), attempts = 10, delayMs = 500, opencodeBaseUrl = "", fetchImpl = globalThis.fetch } = {}) {
10560
10593
  let lastError = "opencode_not_ready";
10561
10594
  const maxAttempts = Math.max(1, Number(attempts) || 1);
10562
10595
  for (let attempt = 1; attempt <= maxAttempts; attempt += 1) {
10563
10596
  try {
10564
- const sessionId = await createOpenCodeSession(client, { title: `Optima startup readiness probe ${now().toISOString()}`, directory: worktree });
10565
- if (await openCodeSessionExists(client, sessionId)) return { ok: true, method: "session_create_probe", sessionId, attempts: attempt };
10566
- lastError = "readiness_probe_session_not_visible";
10597
+ const listed = await listOpenCodeSessionsReadiness(client, { directory: worktree }) || await listOpenCodeSessionsReadinessHttp({ baseUrl: opencodeBaseUrl, directory: worktree, fetchImpl });
10598
+ if (listed?.ok) return { ...listed, attempts: attempt };
10599
+ return { ok: true, skipped: true, reason: "session_list_probe_unavailable", attempts: attempt };
10567
10600
  } catch (error) {
10568
10601
  lastError = error.message || "opencode_not_ready";
10569
10602
  }
@@ -10936,18 +10969,9 @@ async function postClickUpLaunchFailureComment({ clickupClient, worktree, taskId
10936
10969
  return { ok: false, skipped: true, reason: "local_log_only" };
10937
10970
  }
10938
10971
  async function applyClickUpBlockerTag({ clickupClient, worktree, taskId, reason, source, tagName = CLICKUP_BLOCKER_TAG_NAME } = {}) {
10939
- if (typeof clickupClient?.addTaskTag !== "function") {
10940
- appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_unavailable", taskId, reason, source, tagName });
10941
- return { ok: false, skipped: true, reason: "add_task_tag_unavailable", tagName };
10942
- }
10943
- try {
10944
- await clickupClient.addTaskTag({ taskId, tagName });
10945
- appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_applied", taskId, reason, source, tagName });
10946
- return { ok: true, tagName };
10947
- } catch (error) {
10948
- appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_failed", taskId, reason, source, tagName, message: error.message });
10949
- return { ok: false, error: error.message, tagName };
10950
- }
10972
+ void clickupClient;
10973
+ appendClickUpWebhookLocalLog(worktree, { type: "blocker_tag_skipped", taskId, reason, source, tagName, policy: "metadata_only_task_writes" });
10974
+ return { ok: false, skipped: true, reason: "metadata_only_task_writes", tagName };
10951
10975
  }
10952
10976
  function openCodeBlockingPromptVerification(result, sessionId) {
10953
10977
  if (result?.__optimaPromptDelivery !== "prompt") return null;
@@ -11437,7 +11461,7 @@ async function reconcileClickUpStartup({ config, state = {}, worktree = process.
11437
11461
  clickUpWebhookLifecycleLog(worktree, { type: "startup_reconciliation_finished", ...skipped });
11438
11462
  return skipped;
11439
11463
  }
11440
- const readiness = await waitForReadiness(openCodeClient, { worktree, now });
11464
+ const readiness = await waitForReadiness(openCodeClient, { worktree, now, opencodeBaseUrl: config.opencode?.baseUrl });
11441
11465
  appendClickUpWebhookLocalLog(worktree, { type: readiness.ok ? "startup_reconciliation_readiness_ready" : "startup_reconciliation_readiness_failed", ...readiness });
11442
11466
  if (!readiness.ok) {
11443
11467
  const failed = { ok: false, skipped: true, reason: "opencode_not_ready", readiness, assigned: 0, comments: 0, ignored: 0, errors: 1, undelivered: 1, tasks: [], validation: { undelivered: 1, emptyPromptSessions: [] } };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@defend-tech/opencode-optima",
3
- "version": "0.1.65",
3
+ "version": "0.1.66",
4
4
  "repository": {
5
5
  "type": "git",
6
6
  "url": "git+ssh://git@github.com/defend-tech/opencode-optima.git"