@fdcn/sourcefed 0.2.8 → 0.2.9
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/README.md +2 -2
- package/dist/{chunk-DK3LZ5RU.js → chunk-QHT4DCW7.js} +26 -18
- package/dist/cli.js +53 -37
- package/dist/daemon.js +26 -18
- package/dist/data/core/SKILL.md +4 -2
- package/dist/data/core/references/commands.md +2 -2
- package/dist/data/sourcefed/SKILL.md +4 -4
- package/dist/mcp.js +2 -2
- package/dist/opencode.js +4 -4
- package/dist/pi.js +2 -2
- package/dist/tui-compiled.mjs +3 -2
- package/dist.dts/providers/slack/src/monitor.d.ts +1 -1
- package/dist.dts/providers/slack/src/poll/utils/parse-slack-read-result.d.ts +1 -1
- package/dist.dts/providers/slack/src/poll/utils/slack-api.d.ts +4 -0
- package/dist.dts/providers/slack/src/schema.d.ts +1 -1
- package/dist.dts/providers/slack/src/types/source-record.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -33,12 +33,12 @@ OpenCode loads this package as both a server and a TUI plugin:
|
|
|
33
33
|
|
|
34
34
|
```json
|
|
35
35
|
// opencode.json
|
|
36
|
-
{ "plugin": ["@fdcn/sourcefed@0.2.
|
|
36
|
+
{ "plugin": ["@fdcn/sourcefed@0.2.9"] }
|
|
37
37
|
```
|
|
38
38
|
|
|
39
39
|
```json
|
|
40
40
|
// tui.json
|
|
41
|
-
{ "plugin": ["@fdcn/sourcefed@0.2.
|
|
41
|
+
{ "plugin": ["@fdcn/sourcefed@0.2.9"] }
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
The package exposes `./server`, `./tui`, `./opencode`, `./opencode/tui`, and `./pi` entrypoints for hosts that load them directly.
|
|
@@ -11008,7 +11008,7 @@ function safeParse24(schema, input, config$1) {
|
|
|
11008
11008
|
var SlackSourceSchema = /* @__PURE__ */ object23({
|
|
11009
11009
|
type: /* @__PURE__ */ literal3("slack"),
|
|
11010
11010
|
channelId: /* @__PURE__ */ string24(),
|
|
11011
|
-
threadTs: /* @__PURE__ */ string24()
|
|
11011
|
+
threadTs: /* @__PURE__ */ optional22(/* @__PURE__ */ string24())
|
|
11012
11012
|
});
|
|
11013
11013
|
var SlackCursorSchema = /* @__PURE__ */ object23({
|
|
11014
11014
|
primed: /* @__PURE__ */ boolean23(),
|
|
@@ -11025,7 +11025,7 @@ function messageAt(ts) {
|
|
|
11025
11025
|
if (value > 0) return new Date(value * 1e3).toISOString();
|
|
11026
11026
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
11027
11027
|
}
|
|
11028
|
-
function parseSlackReadResult(result, cursorRaw) {
|
|
11028
|
+
function parseSlackReadResult(result, cursorRaw, location = "thread") {
|
|
11029
11029
|
const parsedCursor = /* @__PURE__ */ safeParse24(SlackCursorSchema, cursorRaw);
|
|
11030
11030
|
let previous = {};
|
|
11031
11031
|
if (parsedCursor.success) previous = parsedCursor.output;
|
|
@@ -11053,7 +11053,7 @@ function parseSlackReadResult(result, cursorRaw) {
|
|
|
11053
11053
|
kind: "message",
|
|
11054
11054
|
id: `message:${message.ts}`,
|
|
11055
11055
|
at: messageAt(message.ts),
|
|
11056
|
-
summary: `Slack
|
|
11056
|
+
summary: `Slack ${location} message by ${author}`,
|
|
11057
11057
|
body: text,
|
|
11058
11058
|
actionable: true
|
|
11059
11059
|
};
|
|
@@ -11074,15 +11074,19 @@ function slackToken() {
|
|
|
11074
11074
|
return process.env.SOURCEFED_SLACK_TOKEN;
|
|
11075
11075
|
}
|
|
11076
11076
|
async function fetchSlackThread(channelId, threadTs) {
|
|
11077
|
+
return fetchSlackMessages("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
|
|
11078
|
+
}
|
|
11079
|
+
async function fetchSlackDm(channelId) {
|
|
11080
|
+
return fetchSlackMessages("conversations.history", { channel: channelId });
|
|
11081
|
+
}
|
|
11082
|
+
async function fetchSlackMessages(method, params) {
|
|
11077
11083
|
const messages = [];
|
|
11078
11084
|
let cursor = "";
|
|
11079
11085
|
let received = false;
|
|
11080
11086
|
do {
|
|
11081
|
-
const page = await slackApi(
|
|
11082
|
-
|
|
11083
|
-
ts: threadTs,
|
|
11087
|
+
const page = await slackApi(method, {
|
|
11088
|
+
...params,
|
|
11084
11089
|
limit: "1000",
|
|
11085
|
-
inclusive: "false",
|
|
11086
11090
|
...cursor ? { cursor } : {}
|
|
11087
11091
|
});
|
|
11088
11092
|
if (!page) break;
|
|
@@ -11106,8 +11110,7 @@ async function fetchSlackThread(channelId, threadTs) {
|
|
|
11106
11110
|
}
|
|
11107
11111
|
usersCursor = page.response_metadata?.next_cursor ?? "";
|
|
11108
11112
|
} while (usersCursor);
|
|
11109
|
-
|
|
11110
|
-
return result;
|
|
11113
|
+
return { messages, users };
|
|
11111
11114
|
}
|
|
11112
11115
|
async function slackApi(method, params) {
|
|
11113
11116
|
const token = slackToken();
|
|
@@ -11132,9 +11135,9 @@ async function slackApi(method, params) {
|
|
|
11132
11135
|
}
|
|
11133
11136
|
}
|
|
11134
11137
|
async function pollSlack(source, cursorRaw) {
|
|
11135
|
-
const result = await fetchSlackThread(source.channelId, source.threadTs);
|
|
11138
|
+
const result = source.threadTs ? await fetchSlackThread(source.channelId, source.threadTs) : await fetchSlackDm(source.channelId);
|
|
11136
11139
|
if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
|
|
11137
|
-
const parsed = parseSlackReadResult(result, cursorRaw);
|
|
11140
|
+
const parsed = parseSlackReadResult(result, cursorRaw, source.threadTs ? "thread" : "DM");
|
|
11138
11141
|
return { ...parsed, terminal: false };
|
|
11139
11142
|
}
|
|
11140
11143
|
var slackPollMonitor = new PollMonitor3({
|
|
@@ -11151,7 +11154,8 @@ function parseSlackWebhook(payload, _eventName, deliveryId) {
|
|
|
11151
11154
|
const event = payload.event;
|
|
11152
11155
|
const channelId = event?.channel;
|
|
11153
11156
|
const threadTs = event?.thread_ts;
|
|
11154
|
-
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId
|
|
11157
|
+
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId) return void 0;
|
|
11158
|
+
if (!threadTs && !channelId.startsWith("D")) return void 0;
|
|
11155
11159
|
let text = "[message without text]";
|
|
11156
11160
|
if (event.text?.trim()) text = event.text.trim();
|
|
11157
11161
|
let author = event.username;
|
|
@@ -11160,12 +11164,14 @@ function parseSlackWebhook(payload, _eventName, deliveryId) {
|
|
|
11160
11164
|
if (!author) author = "someone";
|
|
11161
11165
|
let at = messageAt(event.event_ts);
|
|
11162
11166
|
if (!event.event_ts) at = messageAt(event.ts);
|
|
11167
|
+
const source = threadTs ? { type: "slack", channelId, threadTs } : { type: "slack", channelId };
|
|
11168
|
+
const location = threadTs ? "thread" : "DM";
|
|
11163
11169
|
return {
|
|
11164
|
-
source
|
|
11170
|
+
source,
|
|
11165
11171
|
kind: "message",
|
|
11166
11172
|
id: event.ts === void 0 ? void 0 : `message:${event.ts}`,
|
|
11167
11173
|
at,
|
|
11168
|
-
summary: `Slack
|
|
11174
|
+
summary: `Slack ${location} message by ${author}`,
|
|
11169
11175
|
body: `${text}
|
|
11170
11176
|
|
|
11171
11177
|
Slack event: ${deliveryId}`,
|
|
@@ -11218,14 +11224,16 @@ var SlackMonitor = class extends Monitor3 {
|
|
|
11218
11224
|
constructor() {
|
|
11219
11225
|
super({ type: "slack", schema: SlackSourceSchema });
|
|
11220
11226
|
}
|
|
11221
|
-
key = (source) => `slack:${source.channelId}#${source.threadTs}`;
|
|
11227
|
+
key = (source) => source.threadTs ? `slack:${source.channelId}#${source.threadTs}` : `slack:${source.channelId}`;
|
|
11222
11228
|
icon = "\u{F04B1}";
|
|
11223
|
-
label = () => "thread";
|
|
11229
|
+
label = (source) => source.threadTs ? "thread" : "DM";
|
|
11224
11230
|
detail = (source) => ` ${source.channelId}`;
|
|
11225
|
-
describe = (source) => `Slack ${source.channelId} thread ${source.threadTs}`;
|
|
11231
|
+
describe = (source) => source.threadTs ? `Slack ${source.channelId} thread ${source.threadTs}` : `Slack DM ${source.channelId}`;
|
|
11226
11232
|
build(input) {
|
|
11227
11233
|
if (input.channelId && input.threadTs) return { type: "slack", channelId: input.channelId, threadTs: input.threadTs };
|
|
11228
|
-
if (
|
|
11234
|
+
if (input.channelId?.startsWith("D")) return { type: "slack", channelId: input.channelId };
|
|
11235
|
+
if (input.channelId) return { error: "threadTs is required unless channelId is a Slack DM ID" };
|
|
11236
|
+
if (!input.threadUrl) return { error: "channelId or threadUrl is required for a slack monitor" };
|
|
11229
11237
|
let url;
|
|
11230
11238
|
try {
|
|
11231
11239
|
url = new URL(input.threadUrl);
|
package/dist/cli.js
CHANGED
|
@@ -11014,7 +11014,7 @@ function safeParse24(schema, input, config$1) {
|
|
|
11014
11014
|
var SlackSourceSchema = /* @__PURE__ */ object23({
|
|
11015
11015
|
type: /* @__PURE__ */ literal3("slack"),
|
|
11016
11016
|
channelId: /* @__PURE__ */ string24(),
|
|
11017
|
-
threadTs: /* @__PURE__ */ string24()
|
|
11017
|
+
threadTs: /* @__PURE__ */ optional22(/* @__PURE__ */ string24())
|
|
11018
11018
|
});
|
|
11019
11019
|
var SlackCursorSchema = /* @__PURE__ */ object23({
|
|
11020
11020
|
primed: /* @__PURE__ */ boolean23(),
|
|
@@ -11031,7 +11031,7 @@ function messageAt(ts) {
|
|
|
11031
11031
|
if (value > 0) return new Date(value * 1e3).toISOString();
|
|
11032
11032
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
11033
11033
|
}
|
|
11034
|
-
function parseSlackReadResult(result, cursorRaw) {
|
|
11034
|
+
function parseSlackReadResult(result, cursorRaw, location = "thread") {
|
|
11035
11035
|
const parsedCursor = /* @__PURE__ */ safeParse24(SlackCursorSchema, cursorRaw);
|
|
11036
11036
|
let previous = {};
|
|
11037
11037
|
if (parsedCursor.success) previous = parsedCursor.output;
|
|
@@ -11059,7 +11059,7 @@ function parseSlackReadResult(result, cursorRaw) {
|
|
|
11059
11059
|
kind: "message",
|
|
11060
11060
|
id: `message:${message.ts}`,
|
|
11061
11061
|
at: messageAt(message.ts),
|
|
11062
|
-
summary: `Slack
|
|
11062
|
+
summary: `Slack ${location} message by ${author}`,
|
|
11063
11063
|
body: text,
|
|
11064
11064
|
actionable: true
|
|
11065
11065
|
};
|
|
@@ -11080,15 +11080,19 @@ function slackToken() {
|
|
|
11080
11080
|
return process.env.SOURCEFED_SLACK_TOKEN;
|
|
11081
11081
|
}
|
|
11082
11082
|
async function fetchSlackThread(channelId, threadTs) {
|
|
11083
|
+
return fetchSlackMessages("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
|
|
11084
|
+
}
|
|
11085
|
+
async function fetchSlackDm(channelId) {
|
|
11086
|
+
return fetchSlackMessages("conversations.history", { channel: channelId });
|
|
11087
|
+
}
|
|
11088
|
+
async function fetchSlackMessages(method, params) {
|
|
11083
11089
|
const messages = [];
|
|
11084
11090
|
let cursor = "";
|
|
11085
11091
|
let received = false;
|
|
11086
11092
|
do {
|
|
11087
|
-
const page = await slackApi(
|
|
11088
|
-
|
|
11089
|
-
ts: threadTs,
|
|
11093
|
+
const page = await slackApi(method, {
|
|
11094
|
+
...params,
|
|
11090
11095
|
limit: "1000",
|
|
11091
|
-
inclusive: "false",
|
|
11092
11096
|
...cursor ? { cursor } : {}
|
|
11093
11097
|
});
|
|
11094
11098
|
if (!page) break;
|
|
@@ -11112,8 +11116,7 @@ async function fetchSlackThread(channelId, threadTs) {
|
|
|
11112
11116
|
}
|
|
11113
11117
|
usersCursor = page.response_metadata?.next_cursor ?? "";
|
|
11114
11118
|
} while (usersCursor);
|
|
11115
|
-
|
|
11116
|
-
return result;
|
|
11119
|
+
return { messages, users };
|
|
11117
11120
|
}
|
|
11118
11121
|
async function slackApi(method, params) {
|
|
11119
11122
|
const token = slackToken();
|
|
@@ -11138,9 +11141,9 @@ async function slackApi(method, params) {
|
|
|
11138
11141
|
}
|
|
11139
11142
|
}
|
|
11140
11143
|
async function pollSlack(source, cursorRaw) {
|
|
11141
|
-
const result = await fetchSlackThread(source.channelId, source.threadTs);
|
|
11144
|
+
const result = source.threadTs ? await fetchSlackThread(source.channelId, source.threadTs) : await fetchSlackDm(source.channelId);
|
|
11142
11145
|
if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
|
|
11143
|
-
const parsed = parseSlackReadResult(result, cursorRaw);
|
|
11146
|
+
const parsed = parseSlackReadResult(result, cursorRaw, source.threadTs ? "thread" : "DM");
|
|
11144
11147
|
return { ...parsed, terminal: false };
|
|
11145
11148
|
}
|
|
11146
11149
|
var slackPollMonitor = new PollMonitor3({
|
|
@@ -11157,7 +11160,8 @@ function parseSlackWebhook(payload, _eventName, deliveryId) {
|
|
|
11157
11160
|
const event = payload.event;
|
|
11158
11161
|
const channelId = event?.channel;
|
|
11159
11162
|
const threadTs = event?.thread_ts;
|
|
11160
|
-
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId
|
|
11163
|
+
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId) return void 0;
|
|
11164
|
+
if (!threadTs && !channelId.startsWith("D")) return void 0;
|
|
11161
11165
|
let text = "[message without text]";
|
|
11162
11166
|
if (event.text?.trim()) text = event.text.trim();
|
|
11163
11167
|
let author = event.username;
|
|
@@ -11166,12 +11170,14 @@ function parseSlackWebhook(payload, _eventName, deliveryId) {
|
|
|
11166
11170
|
if (!author) author = "someone";
|
|
11167
11171
|
let at = messageAt(event.event_ts);
|
|
11168
11172
|
if (!event.event_ts) at = messageAt(event.ts);
|
|
11173
|
+
const source = threadTs ? { type: "slack", channelId, threadTs } : { type: "slack", channelId };
|
|
11174
|
+
const location = threadTs ? "thread" : "DM";
|
|
11169
11175
|
return {
|
|
11170
|
-
source
|
|
11176
|
+
source,
|
|
11171
11177
|
kind: "message",
|
|
11172
11178
|
id: event.ts === void 0 ? void 0 : `message:${event.ts}`,
|
|
11173
11179
|
at,
|
|
11174
|
-
summary: `Slack
|
|
11180
|
+
summary: `Slack ${location} message by ${author}`,
|
|
11175
11181
|
body: `${text}
|
|
11176
11182
|
|
|
11177
11183
|
Slack event: ${deliveryId}`,
|
|
@@ -11224,14 +11230,16 @@ var SlackMonitor = class extends Monitor3 {
|
|
|
11224
11230
|
constructor() {
|
|
11225
11231
|
super({ type: "slack", schema: SlackSourceSchema });
|
|
11226
11232
|
}
|
|
11227
|
-
key = (source) => `slack:${source.channelId}#${source.threadTs}`;
|
|
11233
|
+
key = (source) => source.threadTs ? `slack:${source.channelId}#${source.threadTs}` : `slack:${source.channelId}`;
|
|
11228
11234
|
icon = "\u{F04B1}";
|
|
11229
|
-
label = () => "thread";
|
|
11235
|
+
label = (source) => source.threadTs ? "thread" : "DM";
|
|
11230
11236
|
detail = (source) => ` ${source.channelId}`;
|
|
11231
|
-
describe = (source) => `Slack ${source.channelId} thread ${source.threadTs}`;
|
|
11237
|
+
describe = (source) => source.threadTs ? `Slack ${source.channelId} thread ${source.threadTs}` : `Slack DM ${source.channelId}`;
|
|
11232
11238
|
build(input) {
|
|
11233
11239
|
if (input.channelId && input.threadTs) return { type: "slack", channelId: input.channelId, threadTs: input.threadTs };
|
|
11234
|
-
if (
|
|
11240
|
+
if (input.channelId?.startsWith("D")) return { type: "slack", channelId: input.channelId };
|
|
11241
|
+
if (input.channelId) return { error: "threadTs is required unless channelId is a Slack DM ID" };
|
|
11242
|
+
if (!input.threadUrl) return { error: "channelId or threadUrl is required for a slack monitor" };
|
|
11235
11243
|
let url2;
|
|
11236
11244
|
try {
|
|
11237
11245
|
url2 = new URL(input.threadUrl);
|
|
@@ -43501,7 +43509,7 @@ function safeParse242(schema, input, config$1) {
|
|
|
43501
43509
|
var SlackSourceSchema2 = /* @__PURE__ */ object232({
|
|
43502
43510
|
type: /* @__PURE__ */ literal32("slack"),
|
|
43503
43511
|
channelId: /* @__PURE__ */ string242(),
|
|
43504
|
-
threadTs: /* @__PURE__ */ string242()
|
|
43512
|
+
threadTs: /* @__PURE__ */ optional2222(/* @__PURE__ */ string242())
|
|
43505
43513
|
});
|
|
43506
43514
|
var SlackCursorSchema2 = /* @__PURE__ */ object232({
|
|
43507
43515
|
primed: /* @__PURE__ */ boolean232(),
|
|
@@ -43518,7 +43526,7 @@ function messageAt2(ts) {
|
|
|
43518
43526
|
if (value > 0) return new Date(value * 1e3).toISOString();
|
|
43519
43527
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
43520
43528
|
}
|
|
43521
|
-
function parseSlackReadResult2(result, cursorRaw) {
|
|
43529
|
+
function parseSlackReadResult2(result, cursorRaw, location = "thread") {
|
|
43522
43530
|
const parsedCursor = /* @__PURE__ */ safeParse242(SlackCursorSchema2, cursorRaw);
|
|
43523
43531
|
let previous = {};
|
|
43524
43532
|
if (parsedCursor.success) previous = parsedCursor.output;
|
|
@@ -43546,7 +43554,7 @@ function parseSlackReadResult2(result, cursorRaw) {
|
|
|
43546
43554
|
kind: "message",
|
|
43547
43555
|
id: `message:${message.ts}`,
|
|
43548
43556
|
at: messageAt2(message.ts),
|
|
43549
|
-
summary: `Slack
|
|
43557
|
+
summary: `Slack ${location} message by ${author}`,
|
|
43550
43558
|
body: text,
|
|
43551
43559
|
actionable: true
|
|
43552
43560
|
};
|
|
@@ -43567,15 +43575,19 @@ function slackToken2() {
|
|
|
43567
43575
|
return process.env.SOURCEFED_SLACK_TOKEN;
|
|
43568
43576
|
}
|
|
43569
43577
|
async function fetchSlackThread2(channelId, threadTs) {
|
|
43578
|
+
return fetchSlackMessages2("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
|
|
43579
|
+
}
|
|
43580
|
+
async function fetchSlackDm2(channelId) {
|
|
43581
|
+
return fetchSlackMessages2("conversations.history", { channel: channelId });
|
|
43582
|
+
}
|
|
43583
|
+
async function fetchSlackMessages2(method, params) {
|
|
43570
43584
|
const messages = [];
|
|
43571
43585
|
let cursor = "";
|
|
43572
43586
|
let received = false;
|
|
43573
43587
|
do {
|
|
43574
|
-
const page = await slackApi2(
|
|
43575
|
-
|
|
43576
|
-
ts: threadTs,
|
|
43588
|
+
const page = await slackApi2(method, {
|
|
43589
|
+
...params,
|
|
43577
43590
|
limit: "1000",
|
|
43578
|
-
inclusive: "false",
|
|
43579
43591
|
...cursor ? { cursor } : {}
|
|
43580
43592
|
});
|
|
43581
43593
|
if (!page) break;
|
|
@@ -43599,8 +43611,7 @@ async function fetchSlackThread2(channelId, threadTs) {
|
|
|
43599
43611
|
}
|
|
43600
43612
|
usersCursor = page.response_metadata?.next_cursor ?? "";
|
|
43601
43613
|
} while (usersCursor);
|
|
43602
|
-
|
|
43603
|
-
return result;
|
|
43614
|
+
return { messages, users };
|
|
43604
43615
|
}
|
|
43605
43616
|
async function slackApi2(method, params) {
|
|
43606
43617
|
const token = slackToken2();
|
|
@@ -43625,9 +43636,9 @@ async function slackApi2(method, params) {
|
|
|
43625
43636
|
}
|
|
43626
43637
|
}
|
|
43627
43638
|
async function pollSlack2(source, cursorRaw) {
|
|
43628
|
-
const result = await fetchSlackThread2(source.channelId, source.threadTs);
|
|
43639
|
+
const result = source.threadTs ? await fetchSlackThread2(source.channelId, source.threadTs) : await fetchSlackDm2(source.channelId);
|
|
43629
43640
|
if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
|
|
43630
|
-
const parsed = parseSlackReadResult2(result, cursorRaw);
|
|
43641
|
+
const parsed = parseSlackReadResult2(result, cursorRaw, source.threadTs ? "thread" : "DM");
|
|
43631
43642
|
return { ...parsed, terminal: false };
|
|
43632
43643
|
}
|
|
43633
43644
|
var slackPollMonitor2 = new PollMonitor32({
|
|
@@ -43644,7 +43655,8 @@ function parseSlackWebhook2(payload, _eventName, deliveryId) {
|
|
|
43644
43655
|
const event = payload.event;
|
|
43645
43656
|
const channelId = event?.channel;
|
|
43646
43657
|
const threadTs = event?.thread_ts;
|
|
43647
|
-
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId
|
|
43658
|
+
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId) return void 0;
|
|
43659
|
+
if (!threadTs && !channelId.startsWith("D")) return void 0;
|
|
43648
43660
|
let text = "[message without text]";
|
|
43649
43661
|
if (event.text?.trim()) text = event.text.trim();
|
|
43650
43662
|
let author = event.username;
|
|
@@ -43653,12 +43665,14 @@ function parseSlackWebhook2(payload, _eventName, deliveryId) {
|
|
|
43653
43665
|
if (!author) author = "someone";
|
|
43654
43666
|
let at = messageAt2(event.event_ts);
|
|
43655
43667
|
if (!event.event_ts) at = messageAt2(event.ts);
|
|
43668
|
+
const source = threadTs ? { type: "slack", channelId, threadTs } : { type: "slack", channelId };
|
|
43669
|
+
const location = threadTs ? "thread" : "DM";
|
|
43656
43670
|
return {
|
|
43657
|
-
source
|
|
43671
|
+
source,
|
|
43658
43672
|
kind: "message",
|
|
43659
43673
|
id: event.ts === void 0 ? void 0 : `message:${event.ts}`,
|
|
43660
43674
|
at,
|
|
43661
|
-
summary: `Slack
|
|
43675
|
+
summary: `Slack ${location} message by ${author}`,
|
|
43662
43676
|
body: `${text}
|
|
43663
43677
|
|
|
43664
43678
|
Slack event: ${deliveryId}`,
|
|
@@ -43711,14 +43725,16 @@ var SlackMonitor2 = class extends Monitor32 {
|
|
|
43711
43725
|
constructor() {
|
|
43712
43726
|
super({ type: "slack", schema: SlackSourceSchema2 });
|
|
43713
43727
|
}
|
|
43714
|
-
key = (source) => `slack:${source.channelId}#${source.threadTs}`;
|
|
43728
|
+
key = (source) => source.threadTs ? `slack:${source.channelId}#${source.threadTs}` : `slack:${source.channelId}`;
|
|
43715
43729
|
icon = "\u{F04B1}";
|
|
43716
|
-
label = () => "thread";
|
|
43730
|
+
label = (source) => source.threadTs ? "thread" : "DM";
|
|
43717
43731
|
detail = (source) => ` ${source.channelId}`;
|
|
43718
|
-
describe = (source) => `Slack ${source.channelId} thread ${source.threadTs}`;
|
|
43732
|
+
describe = (source) => source.threadTs ? `Slack ${source.channelId} thread ${source.threadTs}` : `Slack DM ${source.channelId}`;
|
|
43719
43733
|
build(input) {
|
|
43720
43734
|
if (input.channelId && input.threadTs) return { type: "slack", channelId: input.channelId, threadTs: input.threadTs };
|
|
43721
|
-
if (
|
|
43735
|
+
if (input.channelId?.startsWith("D")) return { type: "slack", channelId: input.channelId };
|
|
43736
|
+
if (input.channelId) return { error: "threadTs is required unless channelId is a Slack DM ID" };
|
|
43737
|
+
if (!input.threadUrl) return { error: "channelId or threadUrl is required for a slack monitor" };
|
|
43722
43738
|
let url2;
|
|
43723
43739
|
try {
|
|
43724
43740
|
url2 = new URL(input.threadUrl);
|
|
@@ -43817,7 +43833,7 @@ function buildServer(daemon) {
|
|
|
43817
43833
|
server.registerTool(
|
|
43818
43834
|
"monitor_create",
|
|
43819
43835
|
{
|
|
43820
|
-
description: "Create or reuse a monitor for a Jira issue, GitHub pull request, or Slack
|
|
43836
|
+
description: "Create or reuse a monitor for a Jira issue, GitHub pull request, Slack thread, or Slack DM.",
|
|
43821
43837
|
inputSchema: createSchema,
|
|
43822
43838
|
annotations: { idempotentHint: true, readOnlyHint: false }
|
|
43823
43839
|
},
|
package/dist/daemon.js
CHANGED
|
@@ -11010,7 +11010,7 @@ function safeParse24(schema, input, config$1) {
|
|
|
11010
11010
|
var SlackSourceSchema = /* @__PURE__ */ object23({
|
|
11011
11011
|
type: /* @__PURE__ */ literal3("slack"),
|
|
11012
11012
|
channelId: /* @__PURE__ */ string24(),
|
|
11013
|
-
threadTs: /* @__PURE__ */ string24()
|
|
11013
|
+
threadTs: /* @__PURE__ */ optional22(/* @__PURE__ */ string24())
|
|
11014
11014
|
});
|
|
11015
11015
|
var SlackCursorSchema = /* @__PURE__ */ object23({
|
|
11016
11016
|
primed: /* @__PURE__ */ boolean23(),
|
|
@@ -11027,7 +11027,7 @@ function messageAt(ts) {
|
|
|
11027
11027
|
if (value > 0) return new Date(value * 1e3).toISOString();
|
|
11028
11028
|
return (/* @__PURE__ */ new Date()).toISOString();
|
|
11029
11029
|
}
|
|
11030
|
-
function parseSlackReadResult(result, cursorRaw) {
|
|
11030
|
+
function parseSlackReadResult(result, cursorRaw, location = "thread") {
|
|
11031
11031
|
const parsedCursor = /* @__PURE__ */ safeParse24(SlackCursorSchema, cursorRaw);
|
|
11032
11032
|
let previous = {};
|
|
11033
11033
|
if (parsedCursor.success) previous = parsedCursor.output;
|
|
@@ -11055,7 +11055,7 @@ function parseSlackReadResult(result, cursorRaw) {
|
|
|
11055
11055
|
kind: "message",
|
|
11056
11056
|
id: `message:${message.ts}`,
|
|
11057
11057
|
at: messageAt(message.ts),
|
|
11058
|
-
summary: `Slack
|
|
11058
|
+
summary: `Slack ${location} message by ${author}`,
|
|
11059
11059
|
body: text,
|
|
11060
11060
|
actionable: true
|
|
11061
11061
|
};
|
|
@@ -11076,15 +11076,19 @@ function slackToken() {
|
|
|
11076
11076
|
return process.env.SOURCEFED_SLACK_TOKEN;
|
|
11077
11077
|
}
|
|
11078
11078
|
async function fetchSlackThread(channelId, threadTs) {
|
|
11079
|
+
return fetchSlackMessages("conversations.replies", { channel: channelId, ts: threadTs, inclusive: "false" });
|
|
11080
|
+
}
|
|
11081
|
+
async function fetchSlackDm(channelId) {
|
|
11082
|
+
return fetchSlackMessages("conversations.history", { channel: channelId });
|
|
11083
|
+
}
|
|
11084
|
+
async function fetchSlackMessages(method, params) {
|
|
11079
11085
|
const messages = [];
|
|
11080
11086
|
let cursor = "";
|
|
11081
11087
|
let received = false;
|
|
11082
11088
|
do {
|
|
11083
|
-
const page = await slackApi(
|
|
11084
|
-
|
|
11085
|
-
ts: threadTs,
|
|
11089
|
+
const page = await slackApi(method, {
|
|
11090
|
+
...params,
|
|
11086
11091
|
limit: "1000",
|
|
11087
|
-
inclusive: "false",
|
|
11088
11092
|
...cursor ? { cursor } : {}
|
|
11089
11093
|
});
|
|
11090
11094
|
if (!page) break;
|
|
@@ -11108,8 +11112,7 @@ async function fetchSlackThread(channelId, threadTs) {
|
|
|
11108
11112
|
}
|
|
11109
11113
|
usersCursor = page.response_metadata?.next_cursor ?? "";
|
|
11110
11114
|
} while (usersCursor);
|
|
11111
|
-
|
|
11112
|
-
return result;
|
|
11115
|
+
return { messages, users };
|
|
11113
11116
|
}
|
|
11114
11117
|
async function slackApi(method, params) {
|
|
11115
11118
|
const token = slackToken();
|
|
@@ -11134,9 +11137,9 @@ async function slackApi(method, params) {
|
|
|
11134
11137
|
}
|
|
11135
11138
|
}
|
|
11136
11139
|
async function pollSlack(source, cursorRaw) {
|
|
11137
|
-
const result = await fetchSlackThread(source.channelId, source.threadTs);
|
|
11140
|
+
const result = source.threadTs ? await fetchSlackThread(source.channelId, source.threadTs) : await fetchSlackDm(source.channelId);
|
|
11138
11141
|
if (!result) throw new Error("slack API request failed; check SOURCEFED_SLACK_TOKEN");
|
|
11139
|
-
const parsed = parseSlackReadResult(result, cursorRaw);
|
|
11142
|
+
const parsed = parseSlackReadResult(result, cursorRaw, source.threadTs ? "thread" : "DM");
|
|
11140
11143
|
return { ...parsed, terminal: false };
|
|
11141
11144
|
}
|
|
11142
11145
|
var slackPollMonitor = new PollMonitor3({
|
|
@@ -11153,7 +11156,8 @@ function parseSlackWebhook(payload, _eventName, deliveryId) {
|
|
|
11153
11156
|
const event = payload.event;
|
|
11154
11157
|
const channelId = event?.channel;
|
|
11155
11158
|
const threadTs = event?.thread_ts;
|
|
11156
|
-
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId
|
|
11159
|
+
if (payload.type !== "event_callback" || event?.type !== "message" || !channelId) return void 0;
|
|
11160
|
+
if (!threadTs && !channelId.startsWith("D")) return void 0;
|
|
11157
11161
|
let text = "[message without text]";
|
|
11158
11162
|
if (event.text?.trim()) text = event.text.trim();
|
|
11159
11163
|
let author = event.username;
|
|
@@ -11162,12 +11166,14 @@ function parseSlackWebhook(payload, _eventName, deliveryId) {
|
|
|
11162
11166
|
if (!author) author = "someone";
|
|
11163
11167
|
let at = messageAt(event.event_ts);
|
|
11164
11168
|
if (!event.event_ts) at = messageAt(event.ts);
|
|
11169
|
+
const source = threadTs ? { type: "slack", channelId, threadTs } : { type: "slack", channelId };
|
|
11170
|
+
const location = threadTs ? "thread" : "DM";
|
|
11165
11171
|
return {
|
|
11166
|
-
source
|
|
11172
|
+
source,
|
|
11167
11173
|
kind: "message",
|
|
11168
11174
|
id: event.ts === void 0 ? void 0 : `message:${event.ts}`,
|
|
11169
11175
|
at,
|
|
11170
|
-
summary: `Slack
|
|
11176
|
+
summary: `Slack ${location} message by ${author}`,
|
|
11171
11177
|
body: `${text}
|
|
11172
11178
|
|
|
11173
11179
|
Slack event: ${deliveryId}`,
|
|
@@ -11220,14 +11226,16 @@ var SlackMonitor = class extends Monitor3 {
|
|
|
11220
11226
|
constructor() {
|
|
11221
11227
|
super({ type: "slack", schema: SlackSourceSchema });
|
|
11222
11228
|
}
|
|
11223
|
-
key = (source) => `slack:${source.channelId}#${source.threadTs}`;
|
|
11229
|
+
key = (source) => source.threadTs ? `slack:${source.channelId}#${source.threadTs}` : `slack:${source.channelId}`;
|
|
11224
11230
|
icon = "\u{F04B1}";
|
|
11225
|
-
label = () => "thread";
|
|
11231
|
+
label = (source) => source.threadTs ? "thread" : "DM";
|
|
11226
11232
|
detail = (source) => ` ${source.channelId}`;
|
|
11227
|
-
describe = (source) => `Slack ${source.channelId} thread ${source.threadTs}`;
|
|
11233
|
+
describe = (source) => source.threadTs ? `Slack ${source.channelId} thread ${source.threadTs}` : `Slack DM ${source.channelId}`;
|
|
11228
11234
|
build(input) {
|
|
11229
11235
|
if (input.channelId && input.threadTs) return { type: "slack", channelId: input.channelId, threadTs: input.threadTs };
|
|
11230
|
-
if (
|
|
11236
|
+
if (input.channelId?.startsWith("D")) return { type: "slack", channelId: input.channelId };
|
|
11237
|
+
if (input.channelId) return { error: "threadTs is required unless channelId is a Slack DM ID" };
|
|
11238
|
+
if (!input.threadUrl) return { error: "channelId or threadUrl is required for a slack monitor" };
|
|
11231
11239
|
let url;
|
|
11232
11240
|
try {
|
|
11233
11241
|
url = new URL(input.threadUrl);
|
package/dist/data/core/SKILL.md
CHANGED
|
@@ -6,7 +6,7 @@ description: Core sourcefed usage guide. Read this before creating monitors. Cov
|
|
|
6
6
|
# Sourcefed core
|
|
7
7
|
|
|
8
8
|
Sourcefed lets you create **monitors** that watch a Jira issue, GitHub PR, or
|
|
9
|
-
Slack thread and route NEW events into the session you're currently working in,
|
|
9
|
+
Slack thread or direct-message conversation and route NEW events into the session you're currently working in,
|
|
10
10
|
so you can react to them as they happen.
|
|
11
11
|
|
|
12
12
|
Every monitor is detect-only: it routes events into the session and never
|
|
@@ -20,13 +20,15 @@ affect that session's monitors.
|
|
|
20
20
|
- **Jira issue**: `monitor_create({ name: "PROJ-12345", sourceType: "jira", issueKey: "PROJ-12345" })`
|
|
21
21
|
- **GitHub PR**: `monitor_create({ name: "PR #42", sourceType: "github", repo: "owner/repo", prNumber: 42 })`
|
|
22
22
|
- **Slack thread**: `monitor_create({ name: "thread", sourceType: "slack", threadUrl: "<thread-url>" })`
|
|
23
|
+
- **Whole Slack DM**: `monitor_create({ name: "DM with Alex", sourceType: "slack", channelId: "D0123456789" })`
|
|
23
24
|
|
|
24
25
|
You will be notified of:
|
|
25
26
|
|
|
26
27
|
- **Jira**: new comments, description edits, and summary/status/assignee/priority/label changes.
|
|
27
28
|
- **GitHub**: new reviews (including bot reviews), PR and line-level comments,
|
|
28
29
|
CI failures, merge conflicts, and the PR being merged or closed.
|
|
29
|
-
- **Slack**: new replies in the thread.
|
|
30
|
+
- **Slack thread**: new replies in the thread.
|
|
31
|
+
- **Slack DM**: new top-level messages in the DM. Slack monitors are always detect-only
|
|
30
32
|
and never reply.
|
|
31
33
|
|
|
32
34
|
GitHub and Slack use webhook delivery when configured and fall back to polling
|
|
@@ -30,8 +30,8 @@ sourcefed skills path [name] Print skill directory path
|
|
|
30
30
|
--issue-key KEY Jira issue key (jira)
|
|
31
31
|
--repo OWNER/NAME GitHub repository (github)
|
|
32
32
|
--pr-number N GitHub PR number (github)
|
|
33
|
-
--channel-id ID Slack channel
|
|
34
|
-
--thread-ts TS Slack parent message timestamp
|
|
33
|
+
--channel-id ID Slack channel or DM ID; a D… ID alone monitors the whole DM
|
|
34
|
+
--thread-ts TS Slack parent message timestamp; omit for a whole-DM monitor
|
|
35
35
|
--thread-url URL Slack thread URL (slack)
|
|
36
36
|
--poll-interval-sec N Poll interval in seconds (min 15)
|
|
37
37
|
--target-kind KIND Target kind for ownership scoping (default: cli)
|
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: sourcefed
|
|
3
|
-
description: Live Jira, GitHub, and Slack monitoring for agent hosts. Create monitors that route new issue comments, PR reviews, CI failures, and Slack thread messages into the current session as they happen.
|
|
3
|
+
description: Live Jira, GitHub, and Slack monitoring for agent hosts. Create monitors that route new issue comments, PR reviews, CI failures, and Slack thread or DM messages into the current session as they happen.
|
|
4
4
|
hidden: true
|
|
5
5
|
---
|
|
6
6
|
|
|
7
7
|
# Sourcefed
|
|
8
8
|
|
|
9
9
|
Sourcefed turns external collaboration threads into live agent input: create a
|
|
10
|
-
monitor for a Jira issue, GitHub PR, or Slack
|
|
10
|
+
monitor for a Jira issue, GitHub PR, Slack thread, or Slack DM and NEW events are routed
|
|
11
11
|
into the session you are working in, so you can react to them as they happen.
|
|
12
12
|
|
|
13
13
|
This file is a discovery stub, not the usage guide. Before running any
|
|
@@ -24,8 +24,8 @@ releases, which is why it just points at `skills get core`.
|
|
|
24
24
|
|
|
25
25
|
## When to load this skill
|
|
26
26
|
|
|
27
|
-
- A user asks to monitor a Jira ticket, GitHub PR, or Slack
|
|
28
|
-
- You found or are working on a Jira ticket, PR, or
|
|
27
|
+
- A user asks to monitor a Jira ticket, GitHub PR, Slack thread, or Slack DM.
|
|
28
|
+
- You found or are working on a Jira ticket, PR, thread, or DM and want new
|
|
29
29
|
activity routed into your session.
|
|
30
30
|
- You opened a PR and want to be notified of reviews, comments, CI failures,
|
|
31
31
|
merge conflicts, or the merge itself.
|
package/dist/mcp.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
2
|
decodeTarget,
|
|
3
3
|
encodeTarget
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-QHT4DCW7.js";
|
|
5
5
|
import {
|
|
6
6
|
__export
|
|
7
7
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -4693,7 +4693,7 @@ function buildServer(daemon) {
|
|
|
4693
4693
|
server.registerTool(
|
|
4694
4694
|
"monitor_create",
|
|
4695
4695
|
{
|
|
4696
|
-
description: "Create or reuse a monitor for a Jira issue, GitHub pull request, or Slack
|
|
4696
|
+
description: "Create or reuse a monitor for a Jira issue, GitHub pull request, Slack thread, or Slack DM.",
|
|
4697
4697
|
inputSchema: createSchema,
|
|
4698
4698
|
annotations: { idempotentHint: true, readOnlyHint: false }
|
|
4699
4699
|
},
|
package/dist/opencode.js
CHANGED
|
@@ -4,7 +4,7 @@ import {
|
|
|
4
4
|
daemonCommand,
|
|
5
5
|
daemonEnvironment,
|
|
6
6
|
spawnLocalDaemon
|
|
7
|
-
} from "./chunk-
|
|
7
|
+
} from "./chunk-QHT4DCW7.js";
|
|
8
8
|
import {
|
|
9
9
|
__export
|
|
10
10
|
} from "./chunk-MLKGABMK.js";
|
|
@@ -12555,15 +12555,15 @@ async function callMonitorTool(name, arguments_, sessionID) {
|
|
|
12555
12555
|
|
|
12556
12556
|
// adapters/opencode/tools/monitor_create.ts
|
|
12557
12557
|
var definition = tool({
|
|
12558
|
-
description: "Create a detect-only monitor that watches a Jira issue, GitHub PR, or Slack
|
|
12558
|
+
description: "Create a detect-only monitor that watches a Jira issue, GitHub PR, Slack thread, or Slack DM and routes NEW events into the current session. Slack monitors only read and notify; they never reply. GitHub and Slack use webhooks when configured and polling otherwise; Jira uses polling.",
|
|
12559
12559
|
args: {
|
|
12560
12560
|
name: tool.schema.string().describe("Human-readable monitor name, e.g. 'PROJ-12345', 'PR #42'"),
|
|
12561
12561
|
sourceType: tool.schema.enum(SOURCE_TYPES).describe("What to watch"),
|
|
12562
12562
|
issueKey: tool.schema.string().describe("Jira issue key, e.g. PROJ-12345 (required if sourceType=jira)").optional(),
|
|
12563
12563
|
repo: tool.schema.string().describe("GitHub owner/name, e.g. owner/repository (required if sourceType=github)").optional(),
|
|
12564
12564
|
prNumber: tool.schema.number().describe("GitHub PR number (required if sourceType=github)").optional(),
|
|
12565
|
-
channelId: tool.schema.string().describe("Slack channel or DM ID
|
|
12566
|
-
threadTs: tool.schema.string().describe("Slack parent message timestamp
|
|
12565
|
+
channelId: tool.schema.string().describe("Slack channel or DM ID. A DM ID without threadTs monitors the whole DM conversation.").optional(),
|
|
12566
|
+
threadTs: tool.schema.string().describe("Slack parent message timestamp. Omit it with a DM ID to monitor the whole DM conversation.").optional(),
|
|
12567
12567
|
threadUrl: tool.schema.string().describe("Slack thread URL (alternative to channelId + threadTs)").optional(),
|
|
12568
12568
|
pollIntervalSec: tool.schema.number().describe("Optional polling interval in seconds (min 15, default 60)").optional()
|
|
12569
12569
|
},
|
package/dist/pi.js
CHANGED
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
daemonCommand,
|
|
4
4
|
daemonEnvironment,
|
|
5
5
|
spawnLocalDaemon
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-QHT4DCW7.js";
|
|
7
7
|
import "./chunk-MLKGABMK.js";
|
|
8
8
|
|
|
9
9
|
// adapters/pi/src/index.ts
|
|
@@ -110,7 +110,7 @@ async function sourcefedExtension(pi) {
|
|
|
110
110
|
pi.registerTool({
|
|
111
111
|
name: "sourcefed_monitor_create",
|
|
112
112
|
label: "Sourcefed monitor create",
|
|
113
|
-
description: "Create or reuse a
|
|
113
|
+
description: "Create or reuse a Jira, GitHub PR, Slack thread, or Slack DM monitor for the current Pi session.",
|
|
114
114
|
parameters: Type.Object({
|
|
115
115
|
name: Type.String(),
|
|
116
116
|
sourceType: Type.Unsafe({ type: "string", enum: ["jira", "github", "slack"] }),
|
package/dist/tui-compiled.mjs
CHANGED
|
@@ -102,13 +102,14 @@ function MonitorRows(props) {
|
|
|
102
102
|
},
|
|
103
103
|
get children() {
|
|
104
104
|
return visible().map((monitor) => (() => {
|
|
105
|
-
var _el$11 = _$createElement("box"), _el$12 = _$createElement("text"), _el$13 = _$createElement("text");
|
|
105
|
+
var _el$11 = _$createElement("box"), _el$12 = _$createElement("text"), _el$13 = _$createElement("text"), _el$14 = _$createTextNode(` `);
|
|
106
106
|
_$insertNode(_el$11, _el$12);
|
|
107
107
|
_$insertNode(_el$11, _el$13);
|
|
108
108
|
_$setProp(_el$11, "flexDirection", "row");
|
|
109
109
|
_$setProp(_el$11, "width", "100%");
|
|
110
110
|
_$insert(_el$12, () => monitor.icon);
|
|
111
|
-
_$
|
|
111
|
+
_$insertNode(_el$13, _el$14);
|
|
112
|
+
_$insert(_el$13, () => monitor.name, null);
|
|
112
113
|
_$effect((_p$) => {
|
|
113
114
|
var _v$3 = monitorTone(monitor, props.theme), _v$4 = props.theme.textMuted;
|
|
114
115
|
_v$3 !== _p$.e && (_p$.e = _$setProp(_el$12, "fg", _v$3, _p$.e));
|
|
@@ -8,7 +8,7 @@ export declare class SlackMonitor extends Monitor<SlackSourceRecord> {
|
|
|
8
8
|
constructor();
|
|
9
9
|
readonly key: (source: SlackSourceRecord) => string;
|
|
10
10
|
readonly icon = "\uDB81\uDCB1";
|
|
11
|
-
readonly label: () => string;
|
|
11
|
+
readonly label: (source: SlackSourceRecord) => string;
|
|
12
12
|
readonly detail: (source: SlackSourceRecord) => string;
|
|
13
13
|
readonly describe: (source: SlackSourceRecord) => string;
|
|
14
14
|
build(input: MonitorCreateInput): SourceInput;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { SlackCursor, SlackEvent, SlackReadResult } from "../../types";
|
|
2
|
-
export declare function parseSlackReadResult(result: SlackReadResult, cursorRaw: unknown): {
|
|
2
|
+
export declare function parseSlackReadResult(result: SlackReadResult, cursorRaw: unknown, location?: "thread" | "DM"): {
|
|
3
3
|
events: SlackEvent[];
|
|
4
4
|
cursor: SlackCursor;
|
|
5
5
|
};
|
|
@@ -2,7 +2,7 @@ import * as v from "valibot";
|
|
|
2
2
|
export declare const SlackSourceSchema: v.ObjectSchema<{
|
|
3
3
|
readonly type: v.LiteralSchema<"slack", undefined>;
|
|
4
4
|
readonly channelId: v.StringSchema<undefined>;
|
|
5
|
-
readonly threadTs: v.StringSchema<undefined>;
|
|
5
|
+
readonly threadTs: v.OptionalSchema<v.StringSchema<undefined>, undefined>;
|
|
6
6
|
}, undefined>;
|
|
7
7
|
export declare const SlackCursorSchema: v.ObjectSchema<{
|
|
8
8
|
readonly primed: v.BooleanSchema<undefined>;
|