sparkecoder 0.1.142 → 0.1.143

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.
Files changed (111) hide show
  1. package/dist/agent/index.d.ts +3 -3
  2. package/dist/agent/index.js +105 -19
  3. package/dist/agent/index.js.map +1 -1
  4. package/dist/cli.js +109 -23
  5. package/dist/cli.js.map +1 -1
  6. package/dist/db/index.d.ts +2 -2
  7. package/dist/{index-Cl_eUatM.d.ts → index-BAsQWqZj.d.ts} +96 -96
  8. package/dist/index.d.ts +5 -5
  9. package/dist/index.js +109 -23
  10. package/dist/index.js.map +1 -1
  11. package/dist/{schema-BSz4MzhJ.d.ts → schema-Dz-wABVY.d.ts} +3 -3
  12. package/dist/{search-DOzC4ojH.d.ts → search-CVVfuBPZ.d.ts} +4 -4
  13. package/dist/server/index.js +109 -23
  14. package/dist/server/index.js.map +1 -1
  15. package/dist/tools/index.d.ts +3 -3
  16. package/package.json +1 -1
  17. package/web/.next/BUILD_ID +1 -1
  18. package/web/.next/standalone/web/.next/BUILD_ID +1 -1
  19. package/web/.next/standalone/web/.next/build-manifest.json +2 -2
  20. package/web/.next/standalone/web/.next/prerender-manifest.json +3 -3
  21. package/web/.next/standalone/web/.next/server/app/_global-error.html +2 -2
  22. package/web/.next/standalone/web/.next/server/app/_global-error.rsc +1 -1
  23. package/web/.next/standalone/web/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  24. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  25. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  26. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  27. package/web/.next/standalone/web/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  28. package/web/.next/standalone/web/.next/server/app/_not-found.html +1 -1
  29. package/web/.next/standalone/web/.next/server/app/_not-found.rsc +1 -1
  30. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_full.segment.rsc +1 -1
  31. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  32. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_index.segment.rsc +1 -1
  33. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  34. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  35. package/web/.next/standalone/web/.next/server/app/_not-found.segments/_tree.segment.rsc +1 -1
  36. package/web/.next/standalone/web/.next/server/app/agents.html +1 -1
  37. package/web/.next/standalone/web/.next/server/app/agents.rsc +1 -1
  38. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents/__PAGE__.segment.rsc +1 -1
  39. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p/agents.segment.rsc +1 -1
  40. package/web/.next/standalone/web/.next/server/app/agents.segments/!KG1haW4p.segment.rsc +1 -1
  41. package/web/.next/standalone/web/.next/server/app/agents.segments/_full.segment.rsc +1 -1
  42. package/web/.next/standalone/web/.next/server/app/agents.segments/_head.segment.rsc +1 -1
  43. package/web/.next/standalone/web/.next/server/app/agents.segments/_index.segment.rsc +1 -1
  44. package/web/.next/standalone/web/.next/server/app/agents.segments/_tree.segment.rsc +1 -1
  45. package/web/.next/standalone/web/.next/server/app/docs/installation.html +2 -2
  46. package/web/.next/standalone/web/.next/server/app/docs/installation.rsc +1 -1
  47. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_full.segment.rsc +1 -1
  48. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_head.segment.rsc +1 -1
  49. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_index.segment.rsc +1 -1
  50. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/_tree.segment.rsc +1 -1
  51. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation/__PAGE__.segment.rsc +1 -1
  52. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs/installation.segment.rsc +1 -1
  53. package/web/.next/standalone/web/.next/server/app/docs/installation.segments/docs.segment.rsc +1 -1
  54. package/web/.next/standalone/web/.next/server/app/docs/skills.html +2 -2
  55. package/web/.next/standalone/web/.next/server/app/docs/skills.rsc +1 -1
  56. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_full.segment.rsc +1 -1
  57. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_head.segment.rsc +1 -1
  58. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_index.segment.rsc +1 -1
  59. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/_tree.segment.rsc +1 -1
  60. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills/__PAGE__.segment.rsc +1 -1
  61. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs/skills.segment.rsc +1 -1
  62. package/web/.next/standalone/web/.next/server/app/docs/skills.segments/docs.segment.rsc +1 -1
  63. package/web/.next/standalone/web/.next/server/app/docs/tools.html +2 -2
  64. package/web/.next/standalone/web/.next/server/app/docs/tools.rsc +1 -1
  65. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_full.segment.rsc +1 -1
  66. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_head.segment.rsc +1 -1
  67. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_index.segment.rsc +1 -1
  68. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/_tree.segment.rsc +1 -1
  69. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools/__PAGE__.segment.rsc +1 -1
  70. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs/tools.segment.rsc +1 -1
  71. package/web/.next/standalone/web/.next/server/app/docs/tools.segments/docs.segment.rsc +1 -1
  72. package/web/.next/standalone/web/.next/server/app/docs.html +2 -2
  73. package/web/.next/standalone/web/.next/server/app/docs.rsc +1 -1
  74. package/web/.next/standalone/web/.next/server/app/docs.segments/_full.segment.rsc +1 -1
  75. package/web/.next/standalone/web/.next/server/app/docs.segments/_head.segment.rsc +1 -1
  76. package/web/.next/standalone/web/.next/server/app/docs.segments/_index.segment.rsc +1 -1
  77. package/web/.next/standalone/web/.next/server/app/docs.segments/_tree.segment.rsc +1 -1
  78. package/web/.next/standalone/web/.next/server/app/docs.segments/docs/__PAGE__.segment.rsc +1 -1
  79. package/web/.next/standalone/web/.next/server/app/docs.segments/docs.segment.rsc +1 -1
  80. package/web/.next/standalone/web/.next/server/app/index.html +1 -1
  81. package/web/.next/standalone/web/.next/server/app/index.rsc +1 -1
  82. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p/__PAGE__.segment.rsc +1 -1
  83. package/web/.next/standalone/web/.next/server/app/index.segments/!KG1haW4p.segment.rsc +1 -1
  84. package/web/.next/standalone/web/.next/server/app/index.segments/_full.segment.rsc +1 -1
  85. package/web/.next/standalone/web/.next/server/app/index.segments/_head.segment.rsc +1 -1
  86. package/web/.next/standalone/web/.next/server/app/index.segments/_index.segment.rsc +1 -1
  87. package/web/.next/standalone/web/.next/server/app/index.segments/_tree.segment.rsc +1 -1
  88. package/web/.next/standalone/web/.next/server/app/settings.html +1 -1
  89. package/web/.next/standalone/web/.next/server/app/settings.rsc +1 -1
  90. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings/__PAGE__.segment.rsc +1 -1
  91. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p/settings.segment.rsc +1 -1
  92. package/web/.next/standalone/web/.next/server/app/settings.segments/!KG1haW4p.segment.rsc +1 -1
  93. package/web/.next/standalone/web/.next/server/app/settings.segments/_full.segment.rsc +1 -1
  94. package/web/.next/standalone/web/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  95. package/web/.next/standalone/web/.next/server/app/settings.segments/_index.segment.rsc +1 -1
  96. package/web/.next/standalone/web/.next/server/app/settings.segments/_tree.segment.rsc +1 -1
  97. package/web/.next/standalone/web/.next/server/pages/404.html +1 -1
  98. package/web/.next/standalone/web/.next/server/pages/500.html +2 -2
  99. package/web/.next/standalone/web/.next/server/server-reference-manifest.js +1 -1
  100. package/web/.next/standalone/web/.next/server/server-reference-manifest.json +1 -1
  101. package/web/.next/standalone/web/runtime-config.json +2 -2
  102. package/web/.next/standalone/web/src/app/(main)/settings/page.tsx +1 -1
  103. /package/web/.next/standalone/web/.next/static/{EH_lLivb0xQQlTlBqPnCj → static/ySf1FIgV1p24IEJCK27zG}/_buildManifest.js +0 -0
  104. /package/web/.next/standalone/web/.next/static/{EH_lLivb0xQQlTlBqPnCj → static/ySf1FIgV1p24IEJCK27zG}/_clientMiddlewareManifest.json +0 -0
  105. /package/web/.next/standalone/web/.next/static/{EH_lLivb0xQQlTlBqPnCj → static/ySf1FIgV1p24IEJCK27zG}/_ssgManifest.js +0 -0
  106. /package/web/.next/standalone/web/.next/static/{static/EH_lLivb0xQQlTlBqPnCj → ySf1FIgV1p24IEJCK27zG}/_buildManifest.js +0 -0
  107. /package/web/.next/standalone/web/.next/static/{static/EH_lLivb0xQQlTlBqPnCj → ySf1FIgV1p24IEJCK27zG}/_clientMiddlewareManifest.json +0 -0
  108. /package/web/.next/standalone/web/.next/static/{static/EH_lLivb0xQQlTlBqPnCj → ySf1FIgV1p24IEJCK27zG}/_ssgManifest.js +0 -0
  109. /package/web/.next/static/{EH_lLivb0xQQlTlBqPnCj → ySf1FIgV1p24IEJCK27zG}/_buildManifest.js +0 -0
  110. /package/web/.next/static/{EH_lLivb0xQQlTlBqPnCj → ySf1FIgV1p24IEJCK27zG}/_clientMiddlewareManifest.json +0 -0
  111. /package/web/.next/static/{EH_lLivb0xQQlTlBqPnCj → ySf1FIgV1p24IEJCK27zG}/_ssgManifest.js +0 -0
package/dist/index.js CHANGED
@@ -9475,9 +9475,9 @@ function slackEventToInboundResult(event, opts = {}) {
9475
9475
  if (event.type === "message" && event.subtype && IGNORED_MESSAGE_SUBTYPES.has(event.subtype)) {
9476
9476
  return { event: null, dropReason: "ignored_subtype" };
9477
9477
  }
9478
- const isDm = event.type === "message" && event.channel_type === "im";
9478
+ const isDm = event.type === "message" && (event.channel_type === "im" || event.channel_type === "mpim");
9479
9479
  const isThreadReply = event.type === "message" && !isDm && typeof event.thread_ts === "string" && event.thread_ts !== event.ts;
9480
- const isNonThreadChannelMsg = event.type === "message" && !isDm && !isThreadReply && (event.channel_type === "channel" || event.channel_type === "group" || event.channel_type === "mpim" || // Some payload shapes omit channel_type for channel messages.
9480
+ const isNonThreadChannelMsg = event.type === "message" && !isDm && !isThreadReply && (event.channel_type === "channel" || event.channel_type === "group" || // Some payload shapes omit channel_type for channel messages.
9481
9481
  typeof event.channel === "string");
9482
9482
  if (event.type !== "app_mention" && !isDm && !isThreadReply) {
9483
9483
  if (isNonThreadChannelMsg) {
@@ -9783,8 +9783,31 @@ function formatBytes(n) {
9783
9783
  if (n < 1024 * 1024) return `${(n / 1024).toFixed(1)} KB`;
9784
9784
  return `${(n / 1024 / 1024).toFixed(2)} MB`;
9785
9785
  }
9786
- function sleep(ms) {
9787
- return new Promise((resolve13) => setTimeout(resolve13, ms));
9786
+ function abortError() {
9787
+ const err = new Error("aborted");
9788
+ err.name = "AbortError";
9789
+ return err;
9790
+ }
9791
+ function throwIfAborted(signal) {
9792
+ if (signal?.aborted) throw abortError();
9793
+ }
9794
+ function isAbortLike(err) {
9795
+ return err?.name === "AbortError" || String(err?.message || err).toLowerCase().includes("aborted");
9796
+ }
9797
+ function sleep(ms, signal) {
9798
+ throwIfAborted(signal);
9799
+ return new Promise((resolve13, reject) => {
9800
+ const t = setTimeout(() => {
9801
+ signal?.removeEventListener("abort", onAbort);
9802
+ resolve13();
9803
+ }, ms);
9804
+ const onAbort = () => {
9805
+ clearTimeout(t);
9806
+ signal?.removeEventListener("abort", onAbort);
9807
+ reject(abortError());
9808
+ };
9809
+ signal?.addEventListener("abort", onAbort, { once: true });
9810
+ });
9788
9811
  }
9789
9812
  function imageMagic(bytes) {
9790
9813
  if (bytes.length < 12) return null;
@@ -9804,19 +9827,21 @@ function validateDownloadedBytes(bytes, declaredContentType) {
9804
9827
  if (!actual) return "invalid_image_bytes";
9805
9828
  return null;
9806
9829
  }
9807
- async function fetchSlackPrivateFile(sourceUrl, botToken) {
9830
+ async function fetchSlackPrivateFile(sourceUrl, botToken, signal) {
9808
9831
  let lastError = "unknown";
9809
9832
  for (let attempt = 0; attempt < 3; attempt++) {
9810
9833
  try {
9834
+ throwIfAborted(signal);
9811
9835
  const res = await fetch(sourceUrl, {
9812
- headers: { Authorization: `Bearer ${botToken}` }
9836
+ headers: { Authorization: `Bearer ${botToken}` },
9837
+ signal
9813
9838
  });
9814
9839
  if (res.status === 429 || res.status >= 500) {
9815
9840
  lastError = `slack_fetch_${res.status}`;
9816
9841
  const retryAfter = Number(res.headers.get("retry-after"));
9817
9842
  const waitMs = Number.isFinite(retryAfter) && retryAfter > 0 ? Math.min(retryAfter * 1e3, 2e3) : 250 * (attempt + 1);
9818
9843
  if (attempt < 2) {
9819
- await sleep(waitMs);
9844
+ await sleep(waitMs, signal);
9820
9845
  continue;
9821
9846
  }
9822
9847
  }
@@ -9827,25 +9852,58 @@ async function fetchSlackPrivateFile(sourceUrl, botToken) {
9827
9852
  if (Number.isFinite(contentLength) && contentLength > MAX_BYTES) {
9828
9853
  return { ok: false, error: "size_exceeded" };
9829
9854
  }
9830
- const ab = await res.arrayBuffer();
9831
- if (ab.byteLength > MAX_BYTES) {
9832
- return { ok: false, error: "size_exceeded" };
9833
- }
9834
- return { ok: true, bytes: Buffer.from(ab) };
9855
+ return await readResponseBodyWithCap(res, signal);
9835
9856
  } catch (err) {
9857
+ if (isAbortLike(err) || signal?.aborted) {
9858
+ return { ok: false, error: "aborted" };
9859
+ }
9836
9860
  lastError = `slack_fetch_error:${err?.message || "unknown"}`;
9837
9861
  if (attempt < 2) {
9838
- await sleep(250 * (attempt + 1));
9862
+ await sleep(250 * (attempt + 1), signal);
9839
9863
  continue;
9840
9864
  }
9841
9865
  }
9842
9866
  }
9843
9867
  return { ok: false, error: lastError };
9844
9868
  }
9845
- function withTimeout(p, ms, label) {
9869
+ async function readResponseBodyWithCap(res, signal) {
9870
+ const body = res.body;
9871
+ if (!body) {
9872
+ const ab = await res.arrayBuffer();
9873
+ if (ab.byteLength > MAX_BYTES) return { ok: false, error: "size_exceeded" };
9874
+ return { ok: true, bytes: Buffer.from(ab) };
9875
+ }
9876
+ const reader = body.getReader();
9877
+ const chunks = [];
9878
+ let total = 0;
9879
+ try {
9880
+ while (true) {
9881
+ throwIfAborted(signal);
9882
+ const { done, value } = await reader.read();
9883
+ if (done) break;
9884
+ if (!value) continue;
9885
+ total += value.byteLength;
9886
+ if (total > MAX_BYTES) {
9887
+ await reader.cancel().catch(() => void 0);
9888
+ return { ok: false, error: "size_exceeded" };
9889
+ }
9890
+ chunks.push(Buffer.from(value));
9891
+ }
9892
+ } catch (err) {
9893
+ await reader.cancel().catch(() => void 0);
9894
+ if (isAbortLike(err) || signal?.aborted) return { ok: false, error: "aborted" };
9895
+ throw err;
9896
+ }
9897
+ return { ok: true, bytes: Buffer.concat(chunks, total) };
9898
+ }
9899
+ function withAbortTimeout(run, ms, label) {
9846
9900
  return new Promise((resolve13, reject) => {
9847
- const t = setTimeout(() => reject(new Error(`${label}_timeout`)), ms);
9848
- p.then(
9901
+ const controller = new AbortController();
9902
+ const t = setTimeout(() => {
9903
+ controller.abort();
9904
+ reject(new Error(`${label}_timeout`));
9905
+ }, ms);
9906
+ run(controller.signal).then(
9849
9907
  (v) => {
9850
9908
  clearTimeout(t);
9851
9909
  resolve13(v);
@@ -9857,7 +9915,8 @@ function withTimeout(p, ms, label) {
9857
9915
  );
9858
9916
  });
9859
9917
  }
9860
- async function ingestOne(file, sessionId, botToken) {
9918
+ async function ingestOne(file, sessionId, botToken, signal) {
9919
+ throwIfAborted(signal);
9861
9920
  const fileName = inferFileName(file);
9862
9921
  const contentType = inferContentType(file);
9863
9922
  const declaredSize = typeof file.size === "number" ? file.size : 0;
@@ -9875,7 +9934,8 @@ async function ingestOne(file, sessionId, botToken) {
9875
9934
  return { ...base, shortUrl: null, error: "size_exceeded" };
9876
9935
  }
9877
9936
  let bytes;
9878
- const fetched = await fetchSlackPrivateFile(sourceUrl, botToken);
9937
+ const fetched = await fetchSlackPrivateFile(sourceUrl, botToken, signal);
9938
+ throwIfAborted(signal);
9879
9939
  if (!fetched.ok) {
9880
9940
  return { ...base, shortUrl: null, error: fetched.error };
9881
9941
  }
@@ -9888,18 +9948,27 @@ async function ingestOne(file, sessionId, botToken) {
9888
9948
  return { ...base, sizeBytes: bytes.length, shortUrl: null, error: byteError };
9889
9949
  }
9890
9950
  const { storageQueries: storageQueries2 } = await Promise.resolve().then(() => (init_remote(), remote_exports));
9891
- let upload;
9951
+ let upload = null;
9892
9952
  try {
9953
+ throwIfAborted(signal);
9893
9954
  upload = await storageQueries2.getUploadUrl(sessionId, fileName, contentType, "slack");
9955
+ throwIfAborted(signal);
9894
9956
  } catch (err) {
9957
+ if (isAbortLike(err) || signal.aborted) {
9958
+ if (upload?.fileId) await cleanupAbortedUpload(storageQueries2, upload.fileId);
9959
+ throw err;
9960
+ }
9895
9961
  return { ...base, sizeBytes: bytes.length, shortUrl: null, error: `presign_failed:${err?.message || "unknown"}` };
9896
9962
  }
9897
9963
  try {
9964
+ throwIfAborted(signal);
9898
9965
  const putRes = await fetch(upload.uploadUrl, {
9899
9966
  method: "PUT",
9900
9967
  headers: { "Content-Type": contentType },
9901
- body: bytes
9968
+ body: bytes,
9969
+ signal
9902
9970
  });
9971
+ throwIfAborted(signal);
9903
9972
  if (!putRes.ok) {
9904
9973
  return {
9905
9974
  ...base,
@@ -9909,6 +9978,10 @@ async function ingestOne(file, sessionId, botToken) {
9909
9978
  };
9910
9979
  }
9911
9980
  } catch (err) {
9981
+ if (isAbortLike(err) || signal.aborted) {
9982
+ await cleanupAbortedUpload(storageQueries2, upload.fileId);
9983
+ throw err;
9984
+ }
9912
9985
  return {
9913
9986
  ...base,
9914
9987
  sizeBytes: bytes.length,
@@ -9917,8 +9990,13 @@ async function ingestOne(file, sessionId, botToken) {
9917
9990
  };
9918
9991
  }
9919
9992
  try {
9993
+ throwIfAborted(signal);
9920
9994
  await storageQueries2.updateFile(upload.fileId, { sizeBytes: bytes.length });
9921
9995
  } catch (err) {
9996
+ if (isAbortLike(err) || signal.aborted) {
9997
+ await cleanupAbortedUpload(storageQueries2, upload.fileId);
9998
+ throw err;
9999
+ }
9922
10000
  console.warn(`[slack-files] sizeBytes patch failed for ${upload.fileId}:`, err?.message || err);
9923
10001
  }
9924
10002
  const shortUrl = upload.shortUrl || // Defensive fallback: build it from the upload URL's origin if the
@@ -9930,6 +10008,14 @@ async function ingestOne(file, sessionId, botToken) {
9930
10008
  shortUrl
9931
10009
  };
9932
10010
  }
10011
+ async function cleanupAbortedUpload(storageQueries2, fileId) {
10012
+ if (typeof storageQueries2?.deleteFile !== "function") return;
10013
+ try {
10014
+ await storageQueries2.deleteFile(fileId);
10015
+ } catch (err) {
10016
+ console.warn(`[slack-files] cleanup after aborted upload failed for ${fileId}:`, err?.message || err);
10017
+ }
10018
+ }
9933
10019
  function inferShortUrlFromUploadUrl(uploadUrl, fileId) {
9934
10020
  try {
9935
10021
  const u = new URL(uploadUrl);
@@ -9969,7 +10055,7 @@ async function ingestSlackFiles(files, sessionId, options = {}) {
9969
10055
  const startedAt = Date.now();
9970
10056
  const pipeline = Promise.allSettled(
9971
10057
  files.map(
9972
- (f) => withTimeout(ingestOne(f, sessionId, botToken), timeoutMs, `ingest:${f.id}`).catch((err) => {
10058
+ (f) => withAbortTimeout((signal) => ingestOne(f, sessionId, botToken, signal), timeoutMs, `ingest:${f.id}`).catch((err) => {
9973
10059
  if (String(err?.message || err).includes("_timeout")) {
9974
10060
  return {
9975
10061
  slackFileId: f.id,
@@ -16449,7 +16535,7 @@ slack.post("/events", async (c) => {
16449
16535
  const self = await ensureSlackSelfIdentity();
16450
16536
  const { event: inbound, dropReason } = slackEventToInboundResult(ev, { self });
16451
16537
  if (inbound) {
16452
- const isThreadReply = ev.type === "message" && ev.channel_type !== "im" && typeof ev.thread_ts === "string" && ev.thread_ts !== ev.ts;
16538
+ const isThreadReply = ev.type === "message" && ev.channel_type !== "im" && ev.channel_type !== "mpim" && typeof ev.thread_ts === "string" && ev.thread_ts !== ev.ts;
16453
16539
  if (isThreadReply) {
16454
16540
  const ours = isThreadOwned(ev.channel, ev.thread_ts) || await botParticipatedInThread(ev.channel, ev.thread_ts);
16455
16541
  if (!ours) {
@@ -16462,7 +16548,7 @@ slack.post("/events", async (c) => {
16462
16548
  if (ev.type === "app_mention" && ev.channel && (ev.thread_ts || ev.ts)) {
16463
16549
  markThreadOwned(ev.channel, ev.thread_ts || ev.ts);
16464
16550
  }
16465
- if (ev.type === "message" && ev.channel_type === "im" && ev.channel && (ev.thread_ts || ev.ts)) {
16551
+ if (ev.type === "message" && (ev.channel_type === "im" || ev.channel_type === "mpim") && ev.channel && (ev.thread_ts || ev.ts)) {
16466
16552
  markThreadOwned(ev.channel, ev.thread_ts || ev.ts);
16467
16553
  }
16468
16554
  if (wasHandled(ev.channel, ev.ts)) {