@fdcn/sourcefed 0.3.7 → 0.4.0
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 +36 -1
- package/dist/{chunk-E6J3BAXP.js → chunk-L4SMC2NT.js} +1165 -251
- package/dist/cli.js +12578 -8814
- package/dist/daemon.js +1025 -107
- package/dist/data/core/SKILL.md +9 -4
- package/dist/data/core/references/commands.md +6 -1
- package/dist/data/sourcefed/SKILL.md +3 -2
- package/dist/guidance.md +6 -2
- package/dist/mcp.js +2286 -1106
- package/dist/opencode.js +6 -2
- package/dist/pi.js +161 -39
- package/dist/tui-compiled.mjs +306 -166
- package/dist.dts/adapters/opencode/bridge.d.ts +1 -1
- package/dist.dts/adapters/opencode/subscriptions.d.ts +2 -2
- package/dist.dts/adapters/opencode/tools/monitor_create.d.ts +16 -0
- package/dist.dts/adapters/opencode/tui/sidebar.d.ts +1 -1
- package/dist.dts/adapters/pi/src/dialog.d.ts +1 -2
- package/dist.dts/adapters/pi/src/monitors-dialog.d.ts +32 -0
- package/dist.dts/adapters/pi/src/monitors-dialog.test.d.ts +1 -0
- package/dist.dts/packages/cli/src/commands/monitor/index.d.ts +1 -1
- package/dist.dts/packages/cli/src/utils/daemon.d.ts +1 -1
- package/dist.dts/packages/cli/src/utils/format.d.ts +1 -1
- package/dist.dts/packages/cli/src/utils/webhooks.d.ts +1 -1
- package/dist.dts/packages/core/src/events.d.ts +2 -2
- package/dist.dts/packages/core/src/index.d.ts +4 -4
- package/dist.dts/packages/core/src/monitors/index.d.ts +3 -3
- package/dist.dts/packages/core/src/monitors/monitor.d.ts +6 -6
- package/dist.dts/packages/core/src/monitors/poll/monitor.d.ts +5 -5
- package/dist.dts/packages/core/src/monitors/poll/types/poll-monitor-options.d.ts +1 -1
- package/dist.dts/packages/core/src/monitors/poll/types/poll-runner.d.ts +2 -2
- package/dist.dts/packages/core/src/monitors/poll/utils/event-delivery-id.d.ts +1 -1
- package/dist.dts/packages/core/src/monitors/poll/utils/tick.d.ts +1 -1
- package/dist.dts/packages/core/src/monitors/service.d.ts +3 -3
- package/dist.dts/packages/core/src/monitors/utils/monitor-identity.d.ts +3 -3
- package/dist.dts/packages/core/src/monitors/webhook/monitor.d.ts +5 -5
- package/dist.dts/packages/core/src/monitors/webhook/types/pending-webhook-event.d.ts +1 -1
- package/dist.dts/packages/core/src/monitors/webhook/types/webhook-monitor-options.d.ts +1 -1
- package/dist.dts/packages/core/src/monitors/webhook/utils/deliver-webhook.d.ts +2 -2
- package/dist.dts/packages/core/src/monitors/webhook/utils/handle-webhook.d.ts +1 -1
- package/dist.dts/packages/core/src/monitors/webhook/utils/heartbeat-webhooks.d.ts +2 -2
- package/dist.dts/packages/core/src/runtime.d.ts +3 -3
- package/dist.dts/packages/core/src/sources/index.d.ts +1 -1
- package/dist.dts/packages/core/src/sources/types/source-registry.d.ts +1 -1
- package/dist.dts/packages/core/src/storage/json.d.ts +2 -2
- package/dist.dts/packages/core/src/types/monitor-context.d.ts +2 -2
- package/dist.dts/packages/core/src/types/monitor-create-input.d.ts +4 -0
- package/dist.dts/packages/core/src/types/monitor-options.d.ts +1 -1
- package/dist.dts/packages/core/src/utils/event-to-text.d.ts +1 -1
- package/dist.dts/packages/core/src/utils/to-monitor-event.d.ts +2 -2
- package/dist.dts/packages/daemon/src/client.d.ts +1 -1
- package/dist.dts/packages/daemon/src/daemon.d.ts +3 -3
- package/dist.dts/packages/daemon/src/event-stream.d.ts +1 -1
- package/dist.dts/packages/daemon/src/event-transport.d.ts +4 -0
- package/dist.dts/packages/daemon/src/event-transport.test.d.ts +1 -0
- package/dist.dts/packages/daemon/src/fetch-isolation.test.d.ts +1 -0
- package/dist.dts/packages/daemon/src/index.d.ts +3 -3
- package/dist.dts/packages/daemon/src/registry.d.ts +6 -4
- package/dist.dts/packages/daemon/src/types/client.d.ts +1 -1
- package/dist.dts/packages/daemon/src/types/daemon.d.ts +5 -1
- package/dist.dts/packages/daemon/src/types/protocol.d.ts +1 -1
- package/dist.dts/packages/daemon/src/utils/sink.d.ts +2 -2
- package/dist.dts/packages/daemon/src/utils/target.d.ts +1 -1
- package/dist.dts/packages/mcp/src/server.d.ts +1 -1
- package/dist.dts/packages/mcp/src/uris.d.ts +2 -2
- package/dist.dts/providers/github/src/index.d.ts +1 -1
- package/dist.dts/providers/github/src/monitor.d.ts +6 -6
- package/dist.dts/providers/github/src/poll/index.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/monitor.d.ts +2 -2
- package/dist.dts/providers/github/src/poll/utils/append-comments.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/utils/append-github-ci-event.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/utils/append-github-conflict-event.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/utils/append-github-reviews.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/utils/append-github-state-event.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/utils/empty-cursor.d.ts +1 -1
- package/dist.dts/providers/github/src/poll/utils/poll-github.d.ts +1 -1
- package/dist.dts/providers/github/src/webhook/index.d.ts +2 -2
- package/dist.dts/providers/github/src/webhook/monitor.d.ts +2 -2
- package/dist.dts/providers/github/src/webhook/utils/github-event-handlers.d.ts +1 -1
- package/dist.dts/providers/github/src/webhook/utils/parse-github-webhook.d.ts +1 -1
- package/dist.dts/providers/github/src/webhook/utils/update-github-cursor.d.ts +2 -2
- package/dist.dts/providers/jira/src/index.d.ts +1 -1
- package/dist.dts/providers/jira/src/monitor.d.ts +5 -5
- package/dist.dts/providers/jira/src/poll/index.d.ts +1 -1
- package/dist.dts/providers/jira/src/poll/monitor.d.ts +2 -2
- package/dist.dts/providers/jira/src/poll/utils/append-jira-changelog.d.ts +1 -1
- package/dist.dts/providers/jira/src/poll/utils/append-jira-comments.d.ts +1 -1
- package/dist.dts/providers/jira/src/poll/utils/append-jira-description.d.ts +1 -1
- package/dist.dts/providers/jira/src/poll/utils/empty-cursor.d.ts +1 -1
- package/dist.dts/providers/jira/src/poll/utils/jira-changelog-event.d.ts +1 -1
- package/dist.dts/providers/jira/src/poll/utils/poll-jira.d.ts +1 -1
- package/dist.dts/providers/slack/src/index.d.ts +1 -1
- package/dist.dts/providers/slack/src/monitor.d.ts +6 -6
- package/dist.dts/providers/slack/src/poll/index.d.ts +1 -1
- package/dist.dts/providers/slack/src/poll/monitor.d.ts +2 -2
- package/dist.dts/providers/slack/src/poll/utils/parse-slack-read-result.d.ts +1 -1
- package/dist.dts/providers/slack/src/poll/utils/poll-slack.d.ts +1 -1
- package/dist.dts/providers/slack/src/webhook/index.d.ts +1 -1
- package/dist.dts/providers/slack/src/webhook/monitor.d.ts +2 -2
- package/dist.dts/providers/slack/src/webhook/utils/parse-slack-webhook.d.ts +1 -1
- package/dist.dts/providers/slack/src/webhook/utils/update-slack-cursor.d.ts +2 -2
- package/dist.dts/providers/yab/src/index.d.ts +2 -0
- package/dist.dts/providers/yab/src/monitor.d.ts +14 -0
- package/dist.dts/providers/yab/src/poll/index.d.ts +2 -0
- package/dist.dts/providers/yab/src/poll/monitor.d.ts +3 -0
- package/dist.dts/providers/yab/src/poll/utils/feed-events.d.ts +5 -0
- package/dist.dts/providers/yab/src/poll/utils/index.d.ts +4 -0
- package/dist.dts/providers/yab/src/poll/utils/parse-feed.d.ts +3 -0
- package/dist.dts/providers/yab/src/poll/utils/poll-yab.d.ts +7 -0
- package/dist.dts/providers/yab/src/poll/utils/yab-mcp.d.ts +10 -0
- package/dist.dts/providers/yab/src/schema.d.ts +12 -0
- package/dist.dts/providers/yab/src/types/cursor.d.ts +4 -0
- package/dist.dts/providers/yab/src/types/event.d.ts +8 -0
- package/dist.dts/providers/yab/src/types/feed-entry.d.ts +8 -0
- package/dist.dts/providers/yab/src/types/index.d.ts +5 -0
- package/dist.dts/providers/yab/src/types/page.d.ts +6 -0
- package/dist.dts/providers/yab/src/types/source-record.d.ts +7 -0
- package/dist.dts/providers/yab/src/yab.test.d.ts +1 -0
- package/package.json +27 -9
package/dist/opencode.js
CHANGED
|
@@ -7,7 +7,7 @@ import {
|
|
|
7
7
|
daemonCommand,
|
|
8
8
|
daemonEnvironment,
|
|
9
9
|
spawnLocalDaemon
|
|
10
|
-
} from "./chunk-
|
|
10
|
+
} from "./chunk-L4SMC2NT.js";
|
|
11
11
|
import "./chunk-MLKGABMK.js";
|
|
12
12
|
|
|
13
13
|
// packages/sourcefed/src/server.ts
|
|
@@ -357,7 +357,7 @@ async function callMonitorTool(bridge, name, arguments_, sessionID) {
|
|
|
357
357
|
// adapters/opencode/tools/monitor_create.ts
|
|
358
358
|
var monitor_create_default = (bridge) => ({
|
|
359
359
|
name: "monitor_create",
|
|
360
|
-
description: "Create a detect-only monitor that watches a Jira issue, GitHub PR, Slack thread,
|
|
360
|
+
description: "Create a detect-only monitor that watches a Jira issue, GitHub PR, Slack thread, Slack DM, or a feed read through Yab (the user's browser, with their sign-ins) 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 and Yab use polling.",
|
|
361
361
|
input: {
|
|
362
362
|
type: "object",
|
|
363
363
|
properties: {
|
|
@@ -369,6 +369,10 @@ var monitor_create_default = (bridge) => ({
|
|
|
369
369
|
channelId: { type: "string", description: "Slack channel or DM ID. A DM ID without threadTs monitors the whole DM conversation." },
|
|
370
370
|
threadTs: { type: "string", description: "Slack parent message timestamp. Omit it with a DM ID to monitor the whole DM conversation." },
|
|
371
371
|
threadUrl: { type: "string", description: "Slack thread URL (alternative to channelId + threadTs)" },
|
|
372
|
+
url: { type: "string", description: "Atom, RSS or JSON feed URL read through Yab with the user's sign-ins, e.g. https://mail.google.com/mail/u/0/feed/atom (required if sourceType=yab)" },
|
|
373
|
+
space: { type: "string", description: "Yab space whose sign-ins to use (yab); omit to use wherever the site is signed in" },
|
|
374
|
+
match: { type: "string", description: "Case-insensitive regex; only entries whose title, summary or author match are delivered (yab)" },
|
|
375
|
+
exclude: { type: "string", description: "Case-insensitive regex; entries that match are skipped (yab)" },
|
|
372
376
|
pollIntervalSec: { type: "number", description: "Optional polling interval in seconds (min 15, default 60)" }
|
|
373
377
|
},
|
|
374
378
|
required: ["name", "sourceType"],
|
package/dist/pi.js
CHANGED
|
@@ -6,7 +6,7 @@ import {
|
|
|
6
6
|
daemonCommand,
|
|
7
7
|
daemonEnvironment,
|
|
8
8
|
spawnLocalDaemon
|
|
9
|
-
} from "./chunk-
|
|
9
|
+
} from "./chunk-L4SMC2NT.js";
|
|
10
10
|
import "./chunk-MLKGABMK.js";
|
|
11
11
|
|
|
12
12
|
// adapters/pi/src/index.ts
|
|
@@ -39,35 +39,6 @@ function showSourcefedDialog(_tui, theme, done, title, lines) {
|
|
|
39
39
|
}
|
|
40
40
|
};
|
|
41
41
|
}
|
|
42
|
-
function monitorLines(monitors, theme) {
|
|
43
|
-
const active = monitors.filter((monitor) => monitor.enabled);
|
|
44
|
-
if (active.length === 0) return [{ text: theme.fg("dim", "No active monitors") }];
|
|
45
|
-
return active.flatMap((monitor) => {
|
|
46
|
-
const status = monitor.unresponsive ? theme.fg("error", "\u25CF") : theme.fg("success", "\u25CF");
|
|
47
|
-
const describe = theme.fg("text", monitor.describe);
|
|
48
|
-
const detail = monitor.detail ? theme.fg("muted", monitor.detail) : "";
|
|
49
|
-
const statusLabel = monitor.unresponsive ? "recovering connection" : "healthy";
|
|
50
|
-
const rows = [
|
|
51
|
-
["Name", monitor.name],
|
|
52
|
-
["Delivery", monitor.delivery],
|
|
53
|
-
["Poll interval", `${monitor.pollIntervalSec}s`],
|
|
54
|
-
["Created", formatTime(monitor.createdAt)],
|
|
55
|
-
["Updated", formatTime(monitor.updatedAt)],
|
|
56
|
-
["Last poll", formatTime(monitor.lastPolledAt)],
|
|
57
|
-
["Webhook heartbeat", formatTime(monitor.webhookHeartbeatAt)]
|
|
58
|
-
];
|
|
59
|
-
return [
|
|
60
|
-
{ text: `${status} ${monitor.icon} ${describe}${detail} [${statusLabel}]` },
|
|
61
|
-
...rows.map(([label, value]) => ({ text: theme.fg("muted", ` ${label}: ${value}`) }))
|
|
62
|
-
];
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
function formatTime(value) {
|
|
66
|
-
if (!value) return "never";
|
|
67
|
-
const date = new Date(value);
|
|
68
|
-
if (Number.isNaN(date.getTime())) return value;
|
|
69
|
-
return date.toLocaleString();
|
|
70
|
-
}
|
|
71
42
|
function logLines(logs, theme) {
|
|
72
43
|
if (logs.length === 0) return [{ text: theme.fg("dim", "No notifications sent yet") }];
|
|
73
44
|
return logs.flatMap((entry) => {
|
|
@@ -80,12 +51,145 @@ function logLines(logs, theme) {
|
|
|
80
51
|
});
|
|
81
52
|
}
|
|
82
53
|
|
|
54
|
+
// adapters/pi/src/monitors-dialog.ts
|
|
55
|
+
import { truncateToWidth as truncateToWidth2 } from "@earendil-works/pi-tui";
|
|
56
|
+
var PROGRESS = { stop: "Stopping", start: "Starting", remove: "Deleting" };
|
|
57
|
+
var MonitorManager = class {
|
|
58
|
+
constructor(monitors, deps) {
|
|
59
|
+
this.deps = deps;
|
|
60
|
+
this.monitors = monitors;
|
|
61
|
+
}
|
|
62
|
+
monitors;
|
|
63
|
+
selected = 0;
|
|
64
|
+
mode = { kind: "browse" };
|
|
65
|
+
error;
|
|
66
|
+
handleInput(data) {
|
|
67
|
+
switch (this.mode.kind) {
|
|
68
|
+
case "busy":
|
|
69
|
+
return;
|
|
70
|
+
case "confirm-remove":
|
|
71
|
+
return this.handleConfirm(data, this.mode.monitor);
|
|
72
|
+
case "browse":
|
|
73
|
+
return this.handleBrowse(data);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
render(width) {
|
|
77
|
+
const { theme } = this.deps;
|
|
78
|
+
const active = this.monitors.filter((monitor) => monitor.enabled).length;
|
|
79
|
+
const border = theme.fg("accent", "\u2500".repeat(Math.max(0, width)));
|
|
80
|
+
const lines = [
|
|
81
|
+
border,
|
|
82
|
+
` ${theme.fg("accent", theme.bold(`Sourcefed monitors (${active} active)`))}`,
|
|
83
|
+
"",
|
|
84
|
+
...this.listLines(),
|
|
85
|
+
"",
|
|
86
|
+
...this.statusLines(),
|
|
87
|
+
border
|
|
88
|
+
];
|
|
89
|
+
return lines.map((line) => truncateToWidth2(line, width));
|
|
90
|
+
}
|
|
91
|
+
invalidate() {
|
|
92
|
+
}
|
|
93
|
+
handleBrowse(data) {
|
|
94
|
+
if (this.matches(data, "tui.select.cancel") || this.matches(data, "tui.select.confirm")) return this.deps.close();
|
|
95
|
+
if (this.matches(data, "tui.select.up")) return this.select(this.selected - 1);
|
|
96
|
+
if (this.matches(data, "tui.select.down")) return this.select(this.selected + 1);
|
|
97
|
+
const monitor = this.monitors[this.selected];
|
|
98
|
+
if (!monitor) return;
|
|
99
|
+
if (data === "s") void this.perform(monitor.enabled ? "stop" : "start", monitor);
|
|
100
|
+
if (data === "d") this.setMode({ kind: "confirm-remove", monitor });
|
|
101
|
+
}
|
|
102
|
+
handleConfirm(data, monitor) {
|
|
103
|
+
if (data === "y") void this.perform("remove", monitor);
|
|
104
|
+
else if (data === "n" || this.matches(data, "tui.select.cancel")) this.setMode({ kind: "browse" });
|
|
105
|
+
}
|
|
106
|
+
async perform(action, monitor) {
|
|
107
|
+
this.error = void 0;
|
|
108
|
+
this.setMode({ kind: "busy", label: `${PROGRESS[action]} ${monitor.name}\u2026` });
|
|
109
|
+
try {
|
|
110
|
+
this.monitors = await this.deps.run(action, monitor.id);
|
|
111
|
+
const kept = this.monitors.findIndex((candidate) => candidate.id === monitor.id);
|
|
112
|
+
this.selected = clamp(kept >= 0 ? kept : this.selected, this.monitors.length);
|
|
113
|
+
} catch (error) {
|
|
114
|
+
this.error = error instanceof Error ? error.message : String(error);
|
|
115
|
+
}
|
|
116
|
+
this.setMode({ kind: "browse" });
|
|
117
|
+
}
|
|
118
|
+
select(index) {
|
|
119
|
+
this.selected = clamp(index, this.monitors.length);
|
|
120
|
+
this.deps.requestRender();
|
|
121
|
+
}
|
|
122
|
+
setMode(mode) {
|
|
123
|
+
this.mode = mode;
|
|
124
|
+
this.deps.requestRender();
|
|
125
|
+
}
|
|
126
|
+
matches(data, keybinding) {
|
|
127
|
+
return this.deps.keys.matches(data, keybinding);
|
|
128
|
+
}
|
|
129
|
+
listLines() {
|
|
130
|
+
const { theme } = this.deps;
|
|
131
|
+
if (this.monitors.length === 0) return [` ${theme.fg("dim", "No monitors")}`];
|
|
132
|
+
return this.monitors.flatMap((monitor, index) => {
|
|
133
|
+
const selected = index === this.selected;
|
|
134
|
+
const marker = selected ? theme.fg("accent", "\u203A") : " ";
|
|
135
|
+
const header = ` ${marker} ${statusDot(monitor, theme)} ${monitor.icon} ${theme.fg("text", monitor.describe)} [${statusLabel(monitor)}]`;
|
|
136
|
+
return selected ? [header, ...detailLines(monitor, theme)] : [header];
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
statusLines() {
|
|
140
|
+
const { theme } = this.deps;
|
|
141
|
+
const lines = [];
|
|
142
|
+
if (this.error) lines.push(` ${theme.fg("error", this.error)}`);
|
|
143
|
+
switch (this.mode.kind) {
|
|
144
|
+
case "busy":
|
|
145
|
+
lines.push(` ${theme.fg("muted", this.mode.label)}`);
|
|
146
|
+
break;
|
|
147
|
+
case "confirm-remove":
|
|
148
|
+
lines.push(` ${theme.fg("warning", `Delete ${this.mode.monitor.name}? It stops watching and its record is removed. y/n`)}`);
|
|
149
|
+
break;
|
|
150
|
+
case "browse":
|
|
151
|
+
lines.push(` ${theme.fg("dim", "\u2191\u2193 select \xB7 s stop/start \xB7 d delete \xB7 esc close")}`);
|
|
152
|
+
}
|
|
153
|
+
return lines;
|
|
154
|
+
}
|
|
155
|
+
};
|
|
156
|
+
function clamp(index, length) {
|
|
157
|
+
return Math.min(Math.max(index, 0), Math.max(length - 1, 0));
|
|
158
|
+
}
|
|
159
|
+
function statusLabel(monitor) {
|
|
160
|
+
if (!monitor.enabled) return "stopped";
|
|
161
|
+
return monitor.unresponsive ? "recovering connection" : "healthy";
|
|
162
|
+
}
|
|
163
|
+
function statusDot(monitor, theme) {
|
|
164
|
+
if (!monitor.enabled) return theme.fg("dim", "\u25CF");
|
|
165
|
+
return theme.fg(monitor.unresponsive ? "error" : "success", "\u25CF");
|
|
166
|
+
}
|
|
167
|
+
function detailLines(monitor, theme) {
|
|
168
|
+
const rows = [
|
|
169
|
+
["Name", monitor.name],
|
|
170
|
+
["Delivery", monitor.delivery],
|
|
171
|
+
["Poll interval", `${monitor.pollIntervalSec}s`],
|
|
172
|
+
["Created", formatTime(monitor.createdAt)],
|
|
173
|
+
["Updated", formatTime(monitor.updatedAt)],
|
|
174
|
+
["Last poll", formatTime(monitor.lastPolledAt)],
|
|
175
|
+
["Webhook heartbeat", formatTime(monitor.webhookHeartbeatAt)]
|
|
176
|
+
];
|
|
177
|
+
return rows.map(([label, value]) => theme.fg("muted", ` ${label}: ${value}`));
|
|
178
|
+
}
|
|
179
|
+
function formatTime(value) {
|
|
180
|
+
if (!value) return "never";
|
|
181
|
+
const date = new Date(value);
|
|
182
|
+
if (Number.isNaN(date.getTime())) return value;
|
|
183
|
+
return date.toLocaleString();
|
|
184
|
+
}
|
|
185
|
+
|
|
83
186
|
// adapters/pi/src/index.ts
|
|
84
187
|
var STATUS_REFRESH_MS = 3e3;
|
|
85
188
|
var SOURCE_ICONS = {
|
|
86
189
|
jira: "\u{F0303}",
|
|
87
190
|
github: "\u{F02A4}",
|
|
88
|
-
slack: "\u{F04B1}"
|
|
191
|
+
slack: "\u{F04B1}",
|
|
192
|
+
yab: "\u{F059F}"
|
|
89
193
|
};
|
|
90
194
|
async function sourcefedExtension(pi) {
|
|
91
195
|
const listeners = /* @__PURE__ */ new Map();
|
|
@@ -113,16 +217,20 @@ async function sourcefedExtension(pi) {
|
|
|
113
217
|
pi.registerTool({
|
|
114
218
|
name: "sourcefed_monitor_create",
|
|
115
219
|
label: "Sourcefed monitor create",
|
|
116
|
-
description: "Create or reuse a Jira, GitHub PR, Slack thread,
|
|
220
|
+
description: "Create or reuse a Jira, GitHub PR, Slack thread, Slack DM, or Yab feed monitor for the current Pi session.",
|
|
117
221
|
parameters: Type.Object({
|
|
118
222
|
name: Type.String(),
|
|
119
|
-
sourceType: Type.Unsafe({ type: "string", enum: ["jira", "github", "slack"] }),
|
|
223
|
+
sourceType: Type.Unsafe({ type: "string", enum: ["jira", "github", "slack", "yab"] }),
|
|
120
224
|
issueKey: Type.Optional(Type.String()),
|
|
121
225
|
repo: Type.Optional(Type.String()),
|
|
122
226
|
prNumber: Type.Optional(Type.Number()),
|
|
123
227
|
channelId: Type.Optional(Type.String()),
|
|
124
228
|
threadTs: Type.Optional(Type.String()),
|
|
125
229
|
threadUrl: Type.Optional(Type.String()),
|
|
230
|
+
url: Type.Optional(Type.String()),
|
|
231
|
+
space: Type.Optional(Type.String()),
|
|
232
|
+
match: Type.Optional(Type.String()),
|
|
233
|
+
exclude: Type.Optional(Type.String()),
|
|
126
234
|
pollIntervalSec: Type.Optional(Type.Number())
|
|
127
235
|
}),
|
|
128
236
|
execute: async (_toolCallID, input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_create", input))
|
|
@@ -156,12 +264,23 @@ async function sourcefedExtension(pi) {
|
|
|
156
264
|
execute: async (_toolCallID, input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_start", input))
|
|
157
265
|
});
|
|
158
266
|
pi.registerCommand("sourcefed", {
|
|
159
|
-
description: "
|
|
267
|
+
description: "Show, stop, start, or delete Sourcefed monitors for the current Pi session",
|
|
160
268
|
handler: async (_args, ctx) => {
|
|
161
|
-
const
|
|
162
|
-
const
|
|
269
|
+
const monitors = await listMonitors(ctx);
|
|
270
|
+
const run = async (action, id) => {
|
|
271
|
+
const result = await call(ctx, `monitor_${action}`, { id });
|
|
272
|
+
if (result?.ok === false) throw new Error(result.error ?? `monitor ${action} failed`);
|
|
273
|
+
void refreshStatus();
|
|
274
|
+
return listMonitors(ctx);
|
|
275
|
+
};
|
|
163
276
|
await ctx.ui.custom(
|
|
164
|
-
(tui, theme,
|
|
277
|
+
(tui, theme, keybindings, done) => new MonitorManager(monitors, {
|
|
278
|
+
theme,
|
|
279
|
+
keys: keybindings,
|
|
280
|
+
run,
|
|
281
|
+
requestRender: () => tui.requestRender(),
|
|
282
|
+
close: () => done(null)
|
|
283
|
+
})
|
|
165
284
|
);
|
|
166
285
|
}
|
|
167
286
|
});
|
|
@@ -185,9 +304,12 @@ async function sourcefedExtension(pi) {
|
|
|
185
304
|
statusTimer = void 0;
|
|
186
305
|
}
|
|
187
306
|
}
|
|
188
|
-
async function
|
|
307
|
+
async function listMonitors(ctx) {
|
|
189
308
|
const result = await call(ctx, "monitor_list", {});
|
|
190
|
-
|
|
309
|
+
return Array.isArray(result?.monitors) ? result.monitors : [];
|
|
310
|
+
}
|
|
311
|
+
async function updateStatus(ctx) {
|
|
312
|
+
const monitors = await listMonitors(ctx);
|
|
191
313
|
const active = monitors.filter((monitor) => monitor.enabled);
|
|
192
314
|
if (active.length === 0) {
|
|
193
315
|
ctx.ui.setStatus("sourcefed", void 0);
|