@fdcn/sourcefed 0.3.2 → 0.3.5

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.
@@ -11034,7 +11034,7 @@ function parseSlackReadResult(result, cursorRaw, location = "thread") {
11034
11034
  messageIds: previous.messageIds ?? [],
11035
11035
  latestTs: previous.latestTs
11036
11036
  };
11037
- const users = new Map((result.users ?? []).map((user) => [user.id, user.real_name ?? user.name ?? user.id ?? "someone"]));
11037
+ const users2 = new Map((result.users ?? []).map((user) => [user.id, user.real_name ?? user.name ?? user.id ?? "someone"]));
11038
11038
  const messages = (result.messages ?? []).filter((message) => message.ts);
11039
11039
  const freshMessages = messages.filter((message) => {
11040
11040
  if (cursor.messageIds.includes(message.ts)) return false;
@@ -11046,7 +11046,7 @@ function parseSlackReadResult(result, cursorRaw, location = "thread") {
11046
11046
  events = freshMessages.map((message) => {
11047
11047
  let text = "[message without text]";
11048
11048
  if (message.text?.trim()) text = message.text.trim();
11049
- let author = users.get(message.user);
11049
+ let author = users2.get(message.user);
11050
11050
  if (!author) author = message.user;
11051
11051
  if (!author) author = "someone";
11052
11052
  return {
@@ -11069,10 +11069,9 @@ function parseSlackReadResult(result, cursorRaw, location = "thread") {
11069
11069
  return { events, cursor };
11070
11070
  }
11071
11071
  var SLACK_API = "https://slack.com/api";
11072
- var warnedMissingToken2 = false;
11073
- function slackToken() {
11074
- return process.env.SOURCEFED_SLACK_TOKEN;
11075
- }
11072
+ var USERS_TTL_MS = 60 * 60 * 1e3;
11073
+ var users;
11074
+ var refreshing;
11076
11075
  async function fetchSlackThread(channelId, threadTs) {
11077
11076
  return fetchSlackMessages("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
11078
11077
  }
@@ -11082,61 +11081,57 @@ async function fetchSlackDm(channelId) {
11082
11081
  async function fetchSlackMessages(method, params) {
11083
11082
  const messages = [];
11084
11083
  let cursor = "";
11085
- let received = false;
11086
11084
  do {
11087
- const page = await slackApi(method, {
11088
- ...params,
11089
- limit: "1000",
11090
- ...cursor ? { cursor } : {}
11091
- });
11092
- if (!page) break;
11093
- received = true;
11094
- if (Array.isArray(page.messages)) messages.push(...page.messages);
11095
- cursor = page.response_metadata?.next_cursor ?? "";
11085
+ const page = await slackApi(method, { ...params, limit: "1000", ...cursor ? { cursor } : {} });
11086
+ if (!page.ok) {
11087
+ if (messages.length > 0) break;
11088
+ throw new Error(`slack ${method} failed: ${page.error}`);
11089
+ }
11090
+ if (Array.isArray(page.result.messages)) messages.push(...page.result.messages);
11091
+ cursor = page.result.response_metadata?.next_cursor ?? "";
11096
11092
  if (messages.length >= 1e4) break;
11097
11093
  } while (cursor);
11098
- if (!received) return void 0;
11099
- const users = [];
11100
- let usersCursor = "";
11094
+ return { messages, users: await slackUsers() };
11095
+ }
11096
+ async function slackUsers() {
11097
+ if (users && Date.now() - users.fetchedAt < USERS_TTL_MS) return users.list;
11098
+ refreshing ??= refreshUsers().finally(() => {
11099
+ refreshing = void 0;
11100
+ });
11101
+ return refreshing;
11102
+ }
11103
+ async function refreshUsers() {
11104
+ const list = [];
11105
+ let cursor = "";
11101
11106
  do {
11102
- const page = await slackApi("users.list", { limit: "200", ...usersCursor ? { cursor: usersCursor } : {} });
11103
- if (!page) break;
11104
- if (Array.isArray(page.members)) {
11105
- users.push(...page.members.map((member) => ({
11106
- id: member.id,
11107
- name: member.name,
11108
- real_name: member.real_name
11109
- })));
11110
- }
11111
- usersCursor = page.response_metadata?.next_cursor ?? "";
11112
- } while (usersCursor);
11113
- return { messages, users };
11107
+ const page = await slackApi("users.list", { limit: "200", ...cursor ? { cursor } : {} });
11108
+ if (!page.ok) return users?.list ?? list;
11109
+ if (Array.isArray(page.result.members)) {
11110
+ list.push(...page.result.members.map((member) => ({ id: member.id, name: member.name, real_name: member.real_name })));
11111
+ }
11112
+ cursor = page.result.response_metadata?.next_cursor ?? "";
11113
+ } while (cursor);
11114
+ users = { list, fetchedAt: Date.now() };
11115
+ return list;
11114
11116
  }
11115
11117
  async function slackApi(method, params) {
11116
- const token = slackToken();
11117
- if (!token) {
11118
- if (!warnedMissingToken2) {
11119
- warnedMissingToken2 = true;
11120
- console.warn("[sourcefed] SOURCEFED_SLACK_TOKEN is not set; Slack monitors will not poll");
11121
- }
11122
- return void 0;
11123
- }
11118
+ const token = process.env.SOURCEFED_SLACK_TOKEN;
11119
+ if (!token) return { ok: false, error: "SOURCEFED_SLACK_TOKEN is not set" };
11124
11120
  try {
11125
11121
  const response = await fetch(`${SLACK_API}/${method}`, {
11126
11122
  method: "POST",
11127
11123
  headers: { authorization: `Bearer ${token}`, "content-type": "application/x-www-form-urlencoded" },
11128
11124
  body: new URLSearchParams(params)
11129
11125
  });
11130
- const result = await response.json();
11131
- if (!response.ok || result?.ok !== true) return void 0;
11132
- return result;
11133
- } catch {
11134
- return void 0;
11126
+ const result = await response.json().catch(() => void 0);
11127
+ if (response.ok && result?.ok === true) return { ok: true, result };
11128
+ return { ok: false, error: result?.error ?? `HTTP ${response.status}` };
11129
+ } catch (error) {
11130
+ return { ok: false, error: error instanceof Error ? error.message : String(error) };
11135
11131
  }
11136
11132
  }
11137
11133
  async function pollSlack(source, cursorRaw) {
11138
11134
  const result = source.threadTs ? await fetchSlackThread(source.channelId, source.threadTs) : await fetchSlackDm(source.channelId);
11139
- if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
11140
11135
  const parsed = parseSlackReadResult(result, cursorRaw, source.threadTs ? "thread" : "DM");
11141
11136
  return { ...parsed, terminal: false };
11142
11137
  }
@@ -11595,6 +11590,18 @@ var SourcefedDaemon = class {
11595
11590
  const monitors = (await this.service.list()).filter((monitor) => sameTarget(monitor.target, target));
11596
11591
  return { ok: true, monitors: monitors.map(monitorView) };
11597
11592
  }
11593
+ /**
11594
+ * Every target of `kind` with an enabled monitor, so a host that restarts can
11595
+ * resubscribe the sessions whose monitors outlived it.
11596
+ */
11597
+ async listTargets(kind) {
11598
+ const targets = /* @__PURE__ */ new Map();
11599
+ for (const monitor of await this.service.list()) {
11600
+ if (!monitor.enabled || monitor.target.kind !== kind) continue;
11601
+ targets.set(targetKey(monitor.target), { kind: monitor.target.kind, id: monitor.target.id });
11602
+ }
11603
+ return [...targets.values()];
11604
+ }
11598
11605
  async getMonitor(target, id) {
11599
11606
  const monitor = await ownedMonitor(this.service, id, target);
11600
11607
  if (!monitor) return { ok: false, error: `monitor ${id} was not found for this target` };
@@ -11961,6 +11968,9 @@ async function dispatchDaemonRequest(daemon, method, params) {
11961
11968
  return daemon.createMonitor(createTarget(params), createCreateInput(params));
11962
11969
  case "monitor.list":
11963
11970
  return daemon.listMonitors(createTarget(params));
11971
+ case "monitor.targets":
11972
+ if (typeof params.kind !== "string" || !params.kind) throw new Error("monitor.targets requires params.kind");
11973
+ return { targets: await daemon.listTargets(params.kind) };
11964
11974
  case "monitor.status":
11965
11975
  return daemon.getMonitor(createTarget(params), String(params.id));
11966
11976
  case "monitor.stop":
package/dist/cli.js CHANGED
@@ -11040,7 +11040,7 @@ function parseSlackReadResult(result, cursorRaw, location = "thread") {
11040
11040
  messageIds: previous.messageIds ?? [],
11041
11041
  latestTs: previous.latestTs
11042
11042
  };
11043
- const users = new Map((result.users ?? []).map((user) => [user.id, user.real_name ?? user.name ?? user.id ?? "someone"]));
11043
+ const users22 = new Map((result.users ?? []).map((user) => [user.id, user.real_name ?? user.name ?? user.id ?? "someone"]));
11044
11044
  const messages = (result.messages ?? []).filter((message) => message.ts);
11045
11045
  const freshMessages = messages.filter((message) => {
11046
11046
  if (cursor.messageIds.includes(message.ts)) return false;
@@ -11052,7 +11052,7 @@ function parseSlackReadResult(result, cursorRaw, location = "thread") {
11052
11052
  events2 = freshMessages.map((message) => {
11053
11053
  let text = "[message without text]";
11054
11054
  if (message.text?.trim()) text = message.text.trim();
11055
- let author = users.get(message.user);
11055
+ let author = users22.get(message.user);
11056
11056
  if (!author) author = message.user;
11057
11057
  if (!author) author = "someone";
11058
11058
  return {
@@ -11075,10 +11075,9 @@ function parseSlackReadResult(result, cursorRaw, location = "thread") {
11075
11075
  return { events: events2, cursor };
11076
11076
  }
11077
11077
  var SLACK_API = "https://slack.com/api";
11078
- var warnedMissingToken2 = false;
11079
- function slackToken() {
11080
- return process.env.SOURCEFED_SLACK_TOKEN;
11081
- }
11078
+ var USERS_TTL_MS = 60 * 60 * 1e3;
11079
+ var users;
11080
+ var refreshing;
11082
11081
  async function fetchSlackThread(channelId, threadTs) {
11083
11082
  return fetchSlackMessages("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
11084
11083
  }
@@ -11088,61 +11087,57 @@ async function fetchSlackDm(channelId) {
11088
11087
  async function fetchSlackMessages(method, params) {
11089
11088
  const messages = [];
11090
11089
  let cursor = "";
11091
- let received = false;
11092
11090
  do {
11093
- const page = await slackApi(method, {
11094
- ...params,
11095
- limit: "1000",
11096
- ...cursor ? { cursor } : {}
11097
- });
11098
- if (!page) break;
11099
- received = true;
11100
- if (Array.isArray(page.messages)) messages.push(...page.messages);
11101
- cursor = page.response_metadata?.next_cursor ?? "";
11091
+ const page = await slackApi(method, { ...params, limit: "1000", ...cursor ? { cursor } : {} });
11092
+ if (!page.ok) {
11093
+ if (messages.length > 0) break;
11094
+ throw new Error(`slack ${method} failed: ${page.error}`);
11095
+ }
11096
+ if (Array.isArray(page.result.messages)) messages.push(...page.result.messages);
11097
+ cursor = page.result.response_metadata?.next_cursor ?? "";
11102
11098
  if (messages.length >= 1e4) break;
11103
11099
  } while (cursor);
11104
- if (!received) return void 0;
11105
- const users = [];
11106
- let usersCursor = "";
11100
+ return { messages, users: await slackUsers() };
11101
+ }
11102
+ async function slackUsers() {
11103
+ if (users && Date.now() - users.fetchedAt < USERS_TTL_MS) return users.list;
11104
+ refreshing ??= refreshUsers().finally(() => {
11105
+ refreshing = void 0;
11106
+ });
11107
+ return refreshing;
11108
+ }
11109
+ async function refreshUsers() {
11110
+ const list2 = [];
11111
+ let cursor = "";
11107
11112
  do {
11108
- const page = await slackApi("users.list", { limit: "200", ...usersCursor ? { cursor: usersCursor } : {} });
11109
- if (!page) break;
11110
- if (Array.isArray(page.members)) {
11111
- users.push(...page.members.map((member) => ({
11112
- id: member.id,
11113
- name: member.name,
11114
- real_name: member.real_name
11115
- })));
11116
- }
11117
- usersCursor = page.response_metadata?.next_cursor ?? "";
11118
- } while (usersCursor);
11119
- return { messages, users };
11113
+ const page = await slackApi("users.list", { limit: "200", ...cursor ? { cursor } : {} });
11114
+ if (!page.ok) return users?.list ?? list2;
11115
+ if (Array.isArray(page.result.members)) {
11116
+ list2.push(...page.result.members.map((member) => ({ id: member.id, name: member.name, real_name: member.real_name })));
11117
+ }
11118
+ cursor = page.result.response_metadata?.next_cursor ?? "";
11119
+ } while (cursor);
11120
+ users = { list: list2, fetchedAt: Date.now() };
11121
+ return list2;
11120
11122
  }
11121
11123
  async function slackApi(method, params) {
11122
- const token = slackToken();
11123
- if (!token) {
11124
- if (!warnedMissingToken2) {
11125
- warnedMissingToken2 = true;
11126
- console.warn("[sourcefed] SOURCEFED_SLACK_TOKEN is not set; Slack monitors will not poll");
11127
- }
11128
- return void 0;
11129
- }
11124
+ const token = process.env.SOURCEFED_SLACK_TOKEN;
11125
+ if (!token) return { ok: false, error: "SOURCEFED_SLACK_TOKEN is not set" };
11130
11126
  try {
11131
11127
  const response = await fetch(`${SLACK_API}/${method}`, {
11132
11128
  method: "POST",
11133
11129
  headers: { authorization: `Bearer ${token}`, "content-type": "application/x-www-form-urlencoded" },
11134
11130
  body: new URLSearchParams(params)
11135
11131
  });
11136
- const result = await response.json();
11137
- if (!response.ok || result?.ok !== true) return void 0;
11138
- return result;
11139
- } catch {
11140
- return void 0;
11132
+ const result = await response.json().catch(() => void 0);
11133
+ if (response.ok && result?.ok === true) return { ok: true, result };
11134
+ return { ok: false, error: result?.error ?? `HTTP ${response.status}` };
11135
+ } catch (error2) {
11136
+ return { ok: false, error: error2 instanceof Error ? error2.message : String(error2) };
11141
11137
  }
11142
11138
  }
11143
11139
  async function pollSlack(source, cursorRaw) {
11144
11140
  const result = source.threadTs ? await fetchSlackThread(source.channelId, source.threadTs) : await fetchSlackDm(source.channelId);
11145
- if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
11146
11141
  const parsed = parseSlackReadResult(result, cursorRaw, source.threadTs ? "thread" : "DM");
11147
11142
  return { ...parsed, terminal: false };
11148
11143
  }
@@ -11518,6 +11513,18 @@ var SourcefedDaemon = class {
11518
11513
  const monitors = (await this.service.list()).filter((monitor) => sameTarget(monitor.target, target));
11519
11514
  return { ok: true, monitors: monitors.map(monitorView) };
11520
11515
  }
11516
+ /**
11517
+ * Every target of `kind` with an enabled monitor, so a host that restarts can
11518
+ * resubscribe the sessions whose monitors outlived it.
11519
+ */
11520
+ async listTargets(kind) {
11521
+ const targets = /* @__PURE__ */ new Map();
11522
+ for (const monitor of await this.service.list()) {
11523
+ if (!monitor.enabled || monitor.target.kind !== kind) continue;
11524
+ targets.set(targetKey(monitor.target), { kind: monitor.target.kind, id: monitor.target.id });
11525
+ }
11526
+ return [...targets.values()];
11527
+ }
11521
11528
  async getMonitor(target, id) {
11522
11529
  const monitor = await ownedMonitor(this.service, id, target);
11523
11530
  if (!monitor) return { ok: false, error: `monitor ${id} was not found for this target` };
@@ -11884,6 +11891,9 @@ async function dispatchDaemonRequest(daemon, method, params) {
11884
11891
  return daemon.createMonitor(createTarget(params), createCreateInput(params));
11885
11892
  case "monitor.list":
11886
11893
  return daemon.listMonitors(createTarget(params));
11894
+ case "monitor.targets":
11895
+ if (typeof params.kind !== "string" || !params.kind) throw new Error("monitor.targets requires params.kind");
11896
+ return { targets: await daemon.listTargets(params.kind) };
11887
11897
  case "monitor.status":
11888
11898
  return daemon.getMonitor(createTarget(params), String(params.id));
11889
11899
  case "monitor.stop":
@@ -12002,6 +12012,9 @@ function flag(args, name) {
12002
12012
  const index = args.indexOf(`--${name}`);
12003
12013
  return index >= 0 ? args[index + 1] : void 0;
12004
12014
  }
12015
+ function flags(args, name) {
12016
+ return args.flatMap((arg, index) => arg === `--${name}` && index + 1 < args.length ? [args[index + 1]] : []);
12017
+ }
12005
12018
 
12006
12019
  // packages/cli/src/utils/net.ts
12007
12020
  function isLoopback(hostname) {
@@ -27008,7 +27021,7 @@ var require_core$3 = /* @__PURE__ */ __commonJSMin(((exports) => {
27008
27021
  const util_1 = require_util();
27009
27022
  const $dataRefSchema = require_data();
27010
27023
  const uri_1 = require_uri();
27011
- const defaultRegExp = (str, flags) => new RegExp(str, flags);
27024
+ const defaultRegExp = (str, flags2) => new RegExp(str, flags2);
27012
27025
  defaultRegExp.code = "new RegExp";
27013
27026
  const META_IGNORE_OPTIONS = [
27014
27027
  "removeAdditional",
@@ -41681,7 +41694,7 @@ function emptyGithubCursor2() {
41681
41694
  prState: ""
41682
41695
  };
41683
41696
  }
41684
- var warnedMissingToken3 = false;
41697
+ var warnedMissingToken2 = false;
41685
41698
  async function pollGithub2(repo, prNumber, cursorRaw) {
41686
41699
  const parsedCursor = /* @__PURE__ */ safeParse2222(GithubCursorSchema2, cursorRaw);
41687
41700
  let cursor = emptyGithubCursor2();
@@ -41689,8 +41702,8 @@ async function pollGithub2(repo, prNumber, cursorRaw) {
41689
41702
  const events2 = [];
41690
41703
  const ref = `#${prNumber}`;
41691
41704
  if (!githubToken2()) {
41692
- if (!warnedMissingToken3) {
41693
- warnedMissingToken3 = true;
41705
+ if (!warnedMissingToken2) {
41706
+ warnedMissingToken2 = true;
41694
41707
  console.warn("[sourcefed] GH_TOKEN or GITHUB_TOKEN is not set; GitHub monitors will not poll");
41695
41708
  }
41696
41709
  return { events: events2, cursor, terminal: false };
@@ -43553,7 +43566,7 @@ function parseSlackReadResult2(result, cursorRaw, location = "thread") {
43553
43566
  messageIds: previous.messageIds ?? [],
43554
43567
  latestTs: previous.latestTs
43555
43568
  };
43556
- const users = new Map((result.users ?? []).map((user) => [user.id, user.real_name ?? user.name ?? user.id ?? "someone"]));
43569
+ const users22 = new Map((result.users ?? []).map((user) => [user.id, user.real_name ?? user.name ?? user.id ?? "someone"]));
43557
43570
  const messages = (result.messages ?? []).filter((message) => message.ts);
43558
43571
  const freshMessages = messages.filter((message) => {
43559
43572
  if (cursor.messageIds.includes(message.ts)) return false;
@@ -43565,7 +43578,7 @@ function parseSlackReadResult2(result, cursorRaw, location = "thread") {
43565
43578
  events2 = freshMessages.map((message) => {
43566
43579
  let text = "[message without text]";
43567
43580
  if (message.text?.trim()) text = message.text.trim();
43568
- let author = users.get(message.user);
43581
+ let author = users22.get(message.user);
43569
43582
  if (!author) author = message.user;
43570
43583
  if (!author) author = "someone";
43571
43584
  return {
@@ -43588,10 +43601,9 @@ function parseSlackReadResult2(result, cursorRaw, location = "thread") {
43588
43601
  return { events: events2, cursor };
43589
43602
  }
43590
43603
  var SLACK_API2 = "https://slack.com/api";
43591
- var warnedMissingToken22 = false;
43592
- function slackToken2() {
43593
- return process.env.SOURCEFED_SLACK_TOKEN;
43594
- }
43604
+ var USERS_TTL_MS2 = 60 * 60 * 1e3;
43605
+ var users2;
43606
+ var refreshing2;
43595
43607
  async function fetchSlackThread2(channelId, threadTs) {
43596
43608
  return fetchSlackMessages2("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
43597
43609
  }
@@ -43601,61 +43613,57 @@ async function fetchSlackDm2(channelId) {
43601
43613
  async function fetchSlackMessages2(method, params) {
43602
43614
  const messages = [];
43603
43615
  let cursor = "";
43604
- let received = false;
43605
43616
  do {
43606
- const page = await slackApi2(method, {
43607
- ...params,
43608
- limit: "1000",
43609
- ...cursor ? { cursor } : {}
43610
- });
43611
- if (!page) break;
43612
- received = true;
43613
- if (Array.isArray(page.messages)) messages.push(...page.messages);
43614
- cursor = page.response_metadata?.next_cursor ?? "";
43617
+ const page = await slackApi2(method, { ...params, limit: "1000", ...cursor ? { cursor } : {} });
43618
+ if (!page.ok) {
43619
+ if (messages.length > 0) break;
43620
+ throw new Error(`slack ${method} failed: ${page.error}`);
43621
+ }
43622
+ if (Array.isArray(page.result.messages)) messages.push(...page.result.messages);
43623
+ cursor = page.result.response_metadata?.next_cursor ?? "";
43615
43624
  if (messages.length >= 1e4) break;
43616
43625
  } while (cursor);
43617
- if (!received) return void 0;
43618
- const users = [];
43619
- let usersCursor = "";
43626
+ return { messages, users: await slackUsers2() };
43627
+ }
43628
+ async function slackUsers2() {
43629
+ if (users2 && Date.now() - users2.fetchedAt < USERS_TTL_MS2) return users2.list;
43630
+ refreshing2 ??= refreshUsers2().finally(() => {
43631
+ refreshing2 = void 0;
43632
+ });
43633
+ return refreshing2;
43634
+ }
43635
+ async function refreshUsers2() {
43636
+ const list2 = [];
43637
+ let cursor = "";
43620
43638
  do {
43621
- const page = await slackApi2("users.list", { limit: "200", ...usersCursor ? { cursor: usersCursor } : {} });
43622
- if (!page) break;
43623
- if (Array.isArray(page.members)) {
43624
- users.push(...page.members.map((member) => ({
43625
- id: member.id,
43626
- name: member.name,
43627
- real_name: member.real_name
43628
- })));
43629
- }
43630
- usersCursor = page.response_metadata?.next_cursor ?? "";
43631
- } while (usersCursor);
43632
- return { messages, users };
43639
+ const page = await slackApi2("users.list", { limit: "200", ...cursor ? { cursor } : {} });
43640
+ if (!page.ok) return users2?.list ?? list2;
43641
+ if (Array.isArray(page.result.members)) {
43642
+ list2.push(...page.result.members.map((member) => ({ id: member.id, name: member.name, real_name: member.real_name })));
43643
+ }
43644
+ cursor = page.result.response_metadata?.next_cursor ?? "";
43645
+ } while (cursor);
43646
+ users2 = { list: list2, fetchedAt: Date.now() };
43647
+ return list2;
43633
43648
  }
43634
43649
  async function slackApi2(method, params) {
43635
- const token = slackToken2();
43636
- if (!token) {
43637
- if (!warnedMissingToken22) {
43638
- warnedMissingToken22 = true;
43639
- console.warn("[sourcefed] SOURCEFED_SLACK_TOKEN is not set; Slack monitors will not poll");
43640
- }
43641
- return void 0;
43642
- }
43650
+ const token = process.env.SOURCEFED_SLACK_TOKEN;
43651
+ if (!token) return { ok: false, error: "SOURCEFED_SLACK_TOKEN is not set" };
43643
43652
  try {
43644
43653
  const response = await fetch(`${SLACK_API2}/${method}`, {
43645
43654
  method: "POST",
43646
43655
  headers: { authorization: `Bearer ${token}`, "content-type": "application/x-www-form-urlencoded" },
43647
43656
  body: new URLSearchParams(params)
43648
43657
  });
43649
- const result = await response.json();
43650
- if (!response.ok || result?.ok !== true) return void 0;
43651
- return result;
43652
- } catch {
43653
- return void 0;
43658
+ const result = await response.json().catch(() => void 0);
43659
+ if (response.ok && result?.ok === true) return { ok: true, result };
43660
+ return { ok: false, error: result?.error ?? `HTTP ${response.status}` };
43661
+ } catch (error2) {
43662
+ return { ok: false, error: error2 instanceof Error ? error2.message : String(error2) };
43654
43663
  }
43655
43664
  }
43656
43665
  async function pollSlack2(source, cursorRaw) {
43657
43666
  const result = source.threadTs ? await fetchSlackThread2(source.channelId, source.threadTs) : await fetchSlackDm2(source.channelId);
43658
- if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
43659
43667
  const parsed = parseSlackReadResult2(result, cursorRaw, source.threadTs ? "thread" : "DM");
43660
43668
  return { ...parsed, terminal: false };
43661
43669
  }
@@ -44043,8 +44051,8 @@ function dim(text) {
44043
44051
 
44044
44052
  // packages/cli/src/commands/monitor/ack.ts
44045
44053
  async function ack(context) {
44046
- const eventIDs = (flag(context.args, "event-id") ?? "").split(",").filter(Boolean);
44047
- if (eventIDs.length === 0) throw new Error("ack requires --event-id <id>[,<id>...]");
44054
+ const eventIDs = flags(context.args, "event-id").filter(Boolean);
44055
+ if (eventIDs.length === 0) throw new Error("ack requires --event-id <id> (repeat it for several events)");
44048
44056
  printResult(await context.client.request("monitor.ack", { target: context.target, eventIDs }));
44049
44057
  }
44050
44058