@fdcn/sourcefed 0.2.8 → 0.3.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.
Files changed (30) hide show
  1. package/README.md +2 -2
  2. package/dist/{chunk-DK3LZ5RU.js → chunk-QPDTUNFA.js} +45 -19
  3. package/dist/cli.js +72 -38
  4. package/dist/daemon.js +45 -19
  5. package/dist/data/core/SKILL.md +4 -2
  6. package/dist/data/core/references/commands.md +2 -2
  7. package/dist/data/sourcefed/SKILL.md +4 -4
  8. package/dist/mcp.js +2 -2
  9. package/dist/opencode.js +139 -12545
  10. package/dist/pi.js +2 -2
  11. package/dist/tui-compiled.mjs +144 -126
  12. package/dist.dts/adapters/opencode/bridge.d.ts +4 -5
  13. package/dist.dts/adapters/opencode/index.d.ts +4 -3
  14. package/dist.dts/adapters/opencode/tools/monitor_create.d.ts +52 -2
  15. package/dist.dts/adapters/opencode/tools/monitor_list.d.ts +13 -2
  16. package/dist.dts/adapters/opencode/tools/monitor_start.d.ts +19 -2
  17. package/dist.dts/adapters/opencode/tools/monitor_status.d.ts +19 -2
  18. package/dist.dts/adapters/opencode/tools/monitor_stop.d.ts +19 -2
  19. package/dist.dts/adapters/opencode/tui/plugin.d.ts +2 -2
  20. package/dist.dts/adapters/opencode/tui/sidebar.d.ts +8 -3
  21. package/dist.dts/adapters/opencode/tui.d.ts +3 -2
  22. package/dist.dts/index.d.ts +1 -1
  23. package/dist.dts/packages/daemon/src/daemon.d.ts +2 -0
  24. package/dist.dts/packages/sourcefed/src/server.d.ts +2 -6
  25. package/dist.dts/providers/slack/src/monitor.d.ts +1 -1
  26. package/dist.dts/providers/slack/src/poll/utils/parse-slack-read-result.d.ts +1 -1
  27. package/dist.dts/providers/slack/src/poll/utils/slack-api.d.ts +4 -0
  28. package/dist.dts/providers/slack/src/schema.d.ts +1 -1
  29. package/dist.dts/providers/slack/src/types/source-record.d.ts +1 -1
  30. package/package.json +2 -2
package/dist/pi.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  daemonCommand,
4
4
  daemonEnvironment,
5
5
  spawnLocalDaemon
6
- } from "./chunk-DK3LZ5RU.js";
6
+ } from "./chunk-QPDTUNFA.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 Sourcefed monitor for the current Pi session.",
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"] }),
@@ -21,10 +21,20 @@ import { setProp as _$setProp } from "opentui:runtime-module:%40opentui%2Fsolid"
21
21
  import { createElement as _$createElement } from "opentui:runtime-module:%40opentui%2Fsolid";
22
22
  import { Show, createMemo, createSignal, onCleanup } from "opentui:runtime-module:solid-js";
23
23
  import { connectDaemonClient, defaultDaemonUrl } from "@fdcn/sourcefed/daemon";
24
+ function tone(theme) {
25
+ return {
26
+ text: theme.text.default,
27
+ textMuted: theme.text.subdued,
28
+ accent: theme.text.action.primary.default,
29
+ success: theme.text.feedback.success.default,
30
+ error: theme.text.feedback.error.default,
31
+ warning: theme.text.feedback.warning.default
32
+ };
33
+ }
24
34
  var REFRESH_MS = 3e3;
25
35
  function Sidebar(props) {
26
36
  const [monitors, setMonitors] = createSignal([]);
27
- const theme = createMemo(() => props.api.theme.current);
37
+ const palette = createMemo(() => tone(props.ctx.theme));
28
38
  const active = createMemo(() => monitors().filter((monitor) => monitor.enabled));
29
39
  const refresh = async () => {
30
40
  let client;
@@ -65,13 +75,13 @@ function Sidebar(props) {
65
75
  _$insert(_el$5, () => active().length, _el$7);
66
76
  _$insert(_el$, _$createComponent(MonitorRows, {
67
77
  monitors: active,
68
- get theme() {
69
- return theme();
78
+ get tone() {
79
+ return palette();
70
80
  },
71
81
  compact: true
72
82
  }), null);
73
83
  _$effect((_p$) => {
74
- var _v$ = theme().accent, _v$2 = theme().textMuted;
84
+ var _v$ = palette().accent, _v$2 = palette().textMuted;
75
85
  _v$ !== _p$.e && (_p$.e = _$setProp(_el$3, "fg", _v$, _p$.e));
76
86
  _v$2 !== _p$.t && (_p$.t = _$setProp(_el$5, "fg", _v$2, _p$.t));
77
87
  return _p$;
@@ -96,21 +106,22 @@ function MonitorRows(props) {
96
106
  return (() => {
97
107
  var _el$1 = _$createElement("text");
98
108
  _$insertNode(_el$1, _$createTextNode(`No active monitors`));
99
- _$effect((_$p) => _$setProp(_el$1, "fg", props.theme.textMuted, _$p));
109
+ _$effect((_$p) => _$setProp(_el$1, "fg", props.tone.textMuted, _$p));
100
110
  return _el$1;
101
111
  })();
102
112
  },
103
113
  get children() {
104
114
  return visible().map((monitor) => (() => {
105
- var _el$11 = _$createElement("box"), _el$12 = _$createElement("text"), _el$13 = _$createElement("text");
115
+ var _el$11 = _$createElement("box"), _el$12 = _$createElement("text"), _el$13 = _$createElement("text"), _el$14 = _$createTextNode(` `);
106
116
  _$insertNode(_el$11, _el$12);
107
117
  _$insertNode(_el$11, _el$13);
108
118
  _$setProp(_el$11, "flexDirection", "row");
109
119
  _$setProp(_el$11, "width", "100%");
110
120
  _$insert(_el$12, () => monitor.icon);
111
- _$insert(_el$13, () => monitor.detail);
121
+ _$insertNode(_el$13, _el$14);
122
+ _$insert(_el$13, () => monitor.name, null);
112
123
  _$effect((_p$) => {
113
- var _v$3 = monitorTone(monitor, props.theme), _v$4 = props.theme.textMuted;
124
+ var _v$3 = monitorTone(monitor, props.tone), _v$4 = props.tone.textMuted;
114
125
  _v$3 !== _p$.e && (_p$.e = _$setProp(_el$12, "fg", _v$3, _p$.e));
115
126
  _v$4 !== _p$.t && (_p$.t = _$setProp(_el$13, "fg", _v$4, _p$.t));
116
127
  return _p$;
@@ -129,127 +140,134 @@ function MonitorRows(props) {
129
140
  get children() {
130
141
  var _el$9 = _$createElement("text");
131
142
  _$insertNode(_el$9, _$createTextNode(`Open Sourcefed for more`));
132
- _$effect((_$p) => _$setProp(_el$9, "fg", props.theme.textMuted, _$p));
143
+ _$effect((_$p) => _$setProp(_el$9, "fg", props.tone.textMuted, _$p));
133
144
  return _el$9;
134
145
  }
135
146
  }), null);
136
147
  return _el$8;
137
148
  })();
138
149
  }
139
- function monitorTone(monitor, theme) {
140
- if (!monitor.enabled) return theme.textMuted;
141
- return theme.success;
150
+ function monitorTone(monitor, tone2) {
151
+ if (!monitor.enabled) return tone2.textMuted;
152
+ return tone2.success;
142
153
  }
143
154
 
144
155
  // .tui-build/tui/plugin.mjs
145
- var sourcefedTui = async (api) => {
146
- api.slots.register({
147
- order: 190,
148
- slots: {
149
- sidebar_content: (_context, value) => _$createComponent2(Sidebar, {
150
- api,
151
- get sessionID() {
152
- return value.session_id;
153
- }
154
- })
155
- }
156
- });
156
+ var sourcefedTui = (ctx) => {
157
157
  let client;
158
- const getSessionID = () => {
159
- const currentRoute = api.route.current;
160
- return "params" in currentRoute && typeof currentRoute.params?.sessionID === "string" ? currentRoute.params.sessionID : void 0;
161
- };
162
158
  const getClient = async () => {
163
- if (client) return client;
164
- client = await connectDaemonClient2({
165
- name: "sourcefed-opencode-tui",
166
- url: process.env.SOURCEFED_DAEMON_URL ?? defaultDaemonUrl2()
167
- });
159
+ if (!client) {
160
+ client = await connectDaemonClient2({
161
+ name: "sourcefed-opencode-tui",
162
+ url: process.env.SOURCEFED_DAEMON_URL ?? defaultDaemonUrl2()
163
+ });
164
+ }
168
165
  return client;
169
166
  };
170
- const unregister = api.command?.register(() => [{
171
- value: "sourcefed",
172
- title: "Sourcefed monitors",
173
- description: "Show monitors for the current OpenCode session",
174
- slash: {
175
- name: "sourcefed"
176
- },
177
- onSelect: async (dialog) => {
178
- const sessionID = getSessionID();
179
- if (!sessionID) {
180
- api.ui.toast({
181
- variant: "warning",
182
- message: "No active OpenCode session"
183
- });
184
- return;
185
- }
186
- try {
187
- const daemon = await getClient();
188
- if (!daemon) throw new Error("no daemon client");
189
- const result = await daemon.request("monitor.list", {
190
- target: {
191
- kind: "opencode-session",
192
- id: sessionID
193
- }
194
- });
195
- const monitors = result?.monitors ?? [];
196
- api.ui.dialog.replace(() => _$createComponent2(MonitorDialog, {
197
- api,
198
- monitors
199
- }));
200
- api.ui.dialog.setSize("large");
201
- } catch (error) {
202
- api.ui.toast({
203
- variant: "error",
204
- message: `Sourcefed daemon unavailable: ${error instanceof Error ? error.message : String(error)}`
205
- });
206
- }
207
- }
208
- }, {
209
- value: "sourcefed-logs",
210
- title: "Sourcefed logs",
211
- description: "Show recent Sourcefed notifications for the current OpenCode session",
212
- slash: {
213
- name: "sourcefed-logs"
214
- },
215
- onSelect: async (dialog) => {
216
- const sessionID = getSessionID();
217
- if (!sessionID) {
218
- api.ui.toast({
219
- variant: "warning",
220
- message: "No active OpenCode session"
221
- });
222
- return;
167
+ const currentSessionID = () => {
168
+ const route = ctx.ui.router.current();
169
+ return route.type === "session" ? route.sessionID : void 0;
170
+ };
171
+ const disposeSlot = ctx.ui.slot({
172
+ append: "sidebar.content",
173
+ render: ({
174
+ sessionID
175
+ }) => _$createComponent2(Sidebar, {
176
+ ctx,
177
+ sessionID
178
+ })
179
+ });
180
+ ctx.keymap.layer(() => ({
181
+ mode: "global",
182
+ commands: [{
183
+ id: "sourcefed",
184
+ title: "Sourcefed monitors",
185
+ description: "Show monitors for the current OpenCode session",
186
+ slash: {
187
+ name: "sourcefed"
188
+ },
189
+ run: async () => {
190
+ const id2 = currentSessionID();
191
+ if (!id2) {
192
+ ctx.ui.toast.show({
193
+ variant: "warning",
194
+ message: "No active OpenCode session"
195
+ });
196
+ return;
197
+ }
198
+ try {
199
+ const daemon = await getClient();
200
+ const result = await daemon.request("monitor.list", {
201
+ target: {
202
+ kind: "opencode-session",
203
+ id: id2
204
+ }
205
+ });
206
+ const monitors = result?.monitors ?? [];
207
+ ctx.ui.dialog.set({
208
+ size: "large"
209
+ });
210
+ ctx.ui.dialog.show(() => _$createComponent2(MonitorDialog, {
211
+ ctx,
212
+ monitors
213
+ }));
214
+ } catch (error) {
215
+ ctx.ui.toast.show({
216
+ variant: "error",
217
+ message: `Sourcefed daemon unavailable: ${error instanceof Error ? error.message : String(error)}`
218
+ });
219
+ }
223
220
  }
224
- try {
225
- const daemon = await getClient();
226
- if (!daemon) throw new Error("no daemon client");
227
- const result = await daemon.request("monitor.logs", {
228
- target: {
229
- kind: "opencode-session",
230
- id: sessionID
231
- }
232
- });
233
- const logs = result?.logs ?? [];
234
- api.ui.dialog.replace(() => _$createComponent2(LogsDialog, {
235
- api,
236
- logs
237
- }));
238
- api.ui.dialog.setSize("large");
239
- } catch (error) {
240
- api.ui.toast({
241
- variant: "error",
242
- message: `Sourcefed daemon unavailable: ${error instanceof Error ? error.message : String(error)}`
243
- });
221
+ }, {
222
+ id: "sourcefed-logs",
223
+ title: "Sourcefed logs",
224
+ description: "Show recent Sourcefed notifications for the current OpenCode session",
225
+ slash: {
226
+ name: "sourcefed-logs"
227
+ },
228
+ run: async () => {
229
+ const id2 = currentSessionID();
230
+ if (!id2) {
231
+ ctx.ui.toast.show({
232
+ variant: "warning",
233
+ message: "No active OpenCode session"
234
+ });
235
+ return;
236
+ }
237
+ try {
238
+ const daemon = await getClient();
239
+ const result = await daemon.request("monitor.logs", {
240
+ target: {
241
+ kind: "opencode-session",
242
+ id: id2
243
+ }
244
+ });
245
+ const logs = result?.logs ?? [];
246
+ ctx.ui.dialog.set({
247
+ size: "large"
248
+ });
249
+ ctx.ui.dialog.show(() => _$createComponent2(LogsDialog, {
250
+ ctx,
251
+ logs
252
+ }));
253
+ } catch (error) {
254
+ ctx.ui.toast.show({
255
+ variant: "error",
256
+ message: `Sourcefed daemon unavailable: ${error instanceof Error ? error.message : String(error)}`
257
+ });
258
+ }
244
259
  }
245
- }
246
- }]);
247
- void unregister;
260
+ }]
261
+ }));
262
+ return () => {
263
+ disposeSlot();
264
+ void client?.close();
265
+ };
248
266
  };
249
267
  function MonitorDialog(props) {
250
- const theme = createMemo2(() => props.api.theme.current);
268
+ const palette = createMemo2(() => tone(props.ctx.theme));
251
269
  const active = props.monitors.filter((monitor) => monitor.enabled);
252
- const maxListRows = Math.max(6, Math.floor(props.api.renderer.height * 0.45));
270
+ const maxListRows = Math.max(6, Math.floor(props.ctx.renderer.height * 0.45));
253
271
  return (() => {
254
272
  var _el$ = _$createElement2("box"), _el$2 = _$createElement2("box"), _el$3 = _$createElement2("text"), _el$4 = _$createTextNode2(`Sourcefed monitors (`), _el$5 = _$createTextNode2(`)`), _el$6 = _$createElement2("box"), _el$7 = _$createElement2("text");
255
273
  _$insertNode2(_el$, _el$2);
@@ -283,8 +301,8 @@ function MonitorDialog(props) {
283
301
  _$setProp2(_el$10, "width", "100%");
284
302
  _$insert2(_el$10, () => active.map((monitor) => _$createComponent2(MonitorCard, {
285
303
  monitor,
286
- get theme() {
287
- return theme();
304
+ get tone() {
305
+ return palette();
288
306
  }
289
307
  })));
290
308
  return _el$1;
@@ -293,12 +311,12 @@ function MonitorDialog(props) {
293
311
  get children() {
294
312
  var _el$9 = _$createElement2("text");
295
313
  _$insertNode2(_el$9, _$createTextNode2(`No active monitors`));
296
- _$effect2((_$p) => _$setProp2(_el$9, "fg", theme().textMuted, _$p));
314
+ _$effect2((_$p) => _$setProp2(_el$9, "fg", palette().textMuted, _$p));
297
315
  return _el$9;
298
316
  }
299
317
  }), null);
300
318
  _$effect2((_p$) => {
301
- var _v$ = theme().text, _v$2 = theme().textMuted;
319
+ var _v$ = palette().text, _v$2 = palette().textMuted;
302
320
  _v$ !== _p$.e && (_p$.e = _$setProp2(_el$3, "fg", _v$, _p$.e));
303
321
  _v$2 !== _p$.t && (_p$.t = _$setProp2(_el$7, "fg", _v$2, _p$.t));
304
322
  return _p$;
@@ -311,8 +329,8 @@ function MonitorDialog(props) {
311
329
  }
312
330
  function MonitorCard(props) {
313
331
  const monitor = props.monitor;
314
- const theme = props.theme;
315
- const status = monitor.unresponsive ? theme.error : monitor.enabled ? theme.success : theme.textMuted;
332
+ const palette = props.tone;
333
+ const status = monitor.unresponsive ? palette.error : monitor.enabled ? palette.success : palette.textMuted;
316
334
  const statusLabel = !monitor.enabled ? "stopped" : monitor.unresponsive ? "recovering connection" : "healthy";
317
335
  const rows = [["Delivery", monitor.delivery], ["Poll interval", `${monitor.pollIntervalSec}s`], ["Created", formatTime(monitor.createdAt)], ["Updated", formatTime(monitor.updatedAt)], ["Last poll", formatTime(monitor.lastPolledAt)], ["Webhook heartbeat", formatTime(monitor.webhookHeartbeatAt)]];
318
336
  return (() => {
@@ -358,7 +376,7 @@ function MonitorCard(props) {
358
376
  _$setProp2(_el$24, "truncate", true);
359
377
  _$insert2(_el$24, value);
360
378
  _$effect2((_p$) => {
361
- var _v$3 = theme.textMuted, _v$4 = theme.text;
379
+ var _v$3 = palette.textMuted, _v$4 = palette.text;
362
380
  _v$3 !== _p$.e && (_p$.e = _$setProp2(_el$22, "fg", _v$3, _p$.e));
363
381
  _v$4 !== _p$.t && (_p$.t = _$setProp2(_el$24, "fg", _v$4, _p$.t));
364
382
  return _p$;
@@ -368,7 +386,7 @@ function MonitorCard(props) {
368
386
  });
369
387
  return _el$21;
370
388
  })()), null);
371
- _$effect2((_$p) => _$setProp2(_el$15, "fg", theme.text, _$p));
389
+ _$effect2((_$p) => _$setProp2(_el$15, "fg", palette.text, _$p));
372
390
  return _el$11;
373
391
  })();
374
392
  }
@@ -379,8 +397,8 @@ function formatTime(value) {
379
397
  return date.toLocaleString();
380
398
  }
381
399
  function LogsDialog(props) {
382
- const theme = createMemo2(() => props.api.theme.current);
383
- const maxListRows = Math.max(6, Math.floor(props.api.renderer.height * 0.45));
400
+ const palette = createMemo2(() => tone(props.ctx.theme));
401
+ const maxListRows = Math.max(6, Math.floor(props.ctx.renderer.height * 0.45));
384
402
  return (() => {
385
403
  var _el$25 = _$createElement2("box"), _el$26 = _$createElement2("box"), _el$27 = _$createElement2("text"), _el$28 = _$createTextNode2(`Sourcefed notifications (`), _el$29 = _$createTextNode2(`)`), _el$30 = _$createElement2("box"), _el$31 = _$createElement2("text");
386
404
  _$insertNode2(_el$25, _el$26);
@@ -408,7 +426,7 @@ function LogsDialog(props) {
408
426
  return (() => {
409
427
  var _el$35 = _$createElement2("text");
410
428
  _$insertNode2(_el$35, _$createTextNode2(`No notifications sent yet`));
411
- _$effect2((_$p) => _$setProp2(_el$35, "fg", theme().textMuted, _$p));
429
+ _$effect2((_$p) => _$setProp2(_el$35, "fg", palette().textMuted, _$p));
412
430
  return _el$35;
413
431
  })();
414
432
  },
@@ -453,12 +471,12 @@ function LogsDialog(props) {
453
471
  var _el$45 = _$createElement2("text"), _el$46 = _$createTextNode2(` `);
454
472
  _$insertNode2(_el$45, _el$46);
455
473
  _$insert2(_el$45, () => entry.body, null);
456
- _$effect2((_$p) => _$setProp2(_el$45, "fg", theme().textMuted, _$p));
474
+ _$effect2((_$p) => _$setProp2(_el$45, "fg", palette().textMuted, _$p));
457
475
  return _el$45;
458
476
  }
459
477
  }), null);
460
478
  _$effect2((_p$) => {
461
- var _v$7 = entry.actionable ? theme().warning : theme().textMuted, _v$8 = theme().text, _v$9 = theme().text;
479
+ var _v$7 = entry.actionable ? palette().warning : palette().textMuted, _v$8 = palette().text, _v$9 = palette().text;
462
480
  _v$7 !== _p$.e && (_p$.e = _$setProp2(_el$39, "fg", _v$7, _p$.e));
463
481
  _v$8 !== _p$.t && (_p$.t = _$setProp2(_el$40, "fg", _v$8, _p$.t));
464
482
  _v$9 !== _p$.a && (_p$.a = _$setProp2(_el$42, "fg", _v$9, _p$.a));
@@ -474,7 +492,7 @@ function LogsDialog(props) {
474
492
  }
475
493
  }), null);
476
494
  _$effect2((_p$) => {
477
- var _v$5 = theme().text, _v$6 = theme().textMuted;
495
+ var _v$5 = palette().text, _v$6 = palette().textMuted;
478
496
  _v$5 !== _p$.e && (_p$.e = _$setProp2(_el$27, "fg", _v$5, _p$.e));
479
497
  _v$6 !== _p$.t && (_p$.t = _$setProp2(_el$31, "fg", _v$6, _p$.t));
480
498
  return _p$;
@@ -488,7 +506,7 @@ function LogsDialog(props) {
488
506
 
489
507
  // .tui-build/tui/index.mjs
490
508
  var id = "sourcefed-tui";
491
- var index_default = { id, tui: sourcefedTui };
509
+ var index_default = { id, setup: sourcefedTui };
492
510
  export {
493
511
  index_default as default,
494
512
  id
@@ -1,19 +1,18 @@
1
- import type { createOpencodeClient } from "@opencode-ai/sdk";
2
- type OpenCodeClient = ReturnType<typeof createOpencodeClient>;
1
+ import type { Plugin } from "@opencode/plugin";
2
+ type SessionDomain = Plugin.Context["session"];
3
3
  export declare class OpenCodeBridge {
4
- private readonly opencode;
4
+ private readonly session;
5
5
  private daemon?;
6
6
  private readonly listeners;
7
7
  private lastAttemptAt;
8
8
  private lastError;
9
- constructor(opencode: OpenCodeClient);
9
+ constructor(session: SessionDomain);
10
10
  start(): Promise<void>;
11
11
  ensureTarget(sessionID: string): Promise<void>;
12
12
  callTool(name: string, arguments_: Record<string, unknown>, sessionID: string): Promise<unknown>;
13
13
  close(): Promise<void>;
14
14
  private ensureDaemon;
15
15
  private routeEvents;
16
- private currentModel;
17
16
  private target;
18
17
  }
19
18
  export declare function setOpenCodeBridge(bridge: OpenCodeBridge): void;
@@ -1,3 +1,4 @@
1
- import type { Plugin } from "@opencode-ai/plugin";
2
- export declare const Sourcefed: Plugin;
3
- export default Sourcefed;
1
+ import { Plugin } from "@opencode/plugin";
2
+ export declare function setupSourcefed(ctx: Plugin.Context): Promise<Plugin.Cleanup>;
3
+ declare const _default: Plugin.Plugin;
4
+ export default _default;
@@ -1,3 +1,53 @@
1
- import { type ToolDefinition } from "@opencode-ai/plugin";
2
- declare const definition: ToolDefinition;
1
+ import type { ToolContext } from "@opencode/plugin/promise/tool";
2
+ declare const definition: {
3
+ name: string;
4
+ description: string;
5
+ input: {
6
+ type: string;
7
+ properties: {
8
+ name: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ sourceType: {
13
+ type: string;
14
+ enum: string[];
15
+ description: string;
16
+ };
17
+ issueKey: {
18
+ type: string;
19
+ description: string;
20
+ };
21
+ repo: {
22
+ type: string;
23
+ description: string;
24
+ };
25
+ prNumber: {
26
+ type: string;
27
+ description: string;
28
+ };
29
+ channelId: {
30
+ type: string;
31
+ description: string;
32
+ };
33
+ threadTs: {
34
+ type: string;
35
+ description: string;
36
+ };
37
+ threadUrl: {
38
+ type: string;
39
+ description: string;
40
+ };
41
+ pollIntervalSec: {
42
+ type: string;
43
+ description: string;
44
+ };
45
+ };
46
+ required: string[];
47
+ additionalProperties: boolean;
48
+ };
49
+ execute(input: unknown, context: ToolContext): Promise<{
50
+ content: string;
51
+ }>;
52
+ };
3
53
  export default definition;
@@ -1,3 +1,14 @@
1
- import { type ToolDefinition } from "@opencode-ai/plugin";
2
- declare const definition: ToolDefinition;
1
+ import type { ToolContext } from "@opencode/plugin/promise/tool";
2
+ declare const definition: {
3
+ name: string;
4
+ description: string;
5
+ input: {
6
+ type: string;
7
+ properties: {};
8
+ additionalProperties: boolean;
9
+ };
10
+ execute(_input: unknown, context: ToolContext): Promise<{
11
+ content: string;
12
+ }>;
13
+ };
3
14
  export default definition;
@@ -1,3 +1,20 @@
1
- import { type ToolDefinition } from "@opencode-ai/plugin";
2
- declare const definition: ToolDefinition;
1
+ import type { ToolContext } from "@opencode/plugin/promise/tool";
2
+ declare const definition: {
3
+ name: string;
4
+ description: string;
5
+ input: {
6
+ type: string;
7
+ properties: {
8
+ id: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ };
13
+ required: string[];
14
+ additionalProperties: boolean;
15
+ };
16
+ execute(input: unknown, context: ToolContext): Promise<{
17
+ content: string;
18
+ }>;
19
+ };
3
20
  export default definition;
@@ -1,3 +1,20 @@
1
- import { type ToolDefinition } from "@opencode-ai/plugin";
2
- declare const definition: ToolDefinition;
1
+ import type { ToolContext } from "@opencode/plugin/promise/tool";
2
+ declare const definition: {
3
+ name: string;
4
+ description: string;
5
+ input: {
6
+ type: string;
7
+ properties: {
8
+ id: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ };
13
+ required: string[];
14
+ additionalProperties: boolean;
15
+ };
16
+ execute(input: unknown, context: ToolContext): Promise<{
17
+ content: string;
18
+ }>;
19
+ };
3
20
  export default definition;
@@ -1,3 +1,20 @@
1
- import { type ToolDefinition } from "@opencode-ai/plugin";
2
- declare const definition: ToolDefinition;
1
+ import type { ToolContext } from "@opencode/plugin/promise/tool";
2
+ declare const definition: {
3
+ name: string;
4
+ description: string;
5
+ input: {
6
+ type: string;
7
+ properties: {
8
+ id: {
9
+ type: string;
10
+ description: string;
11
+ };
12
+ };
13
+ required: string[];
14
+ additionalProperties: boolean;
15
+ };
16
+ execute(input: unknown, context: ToolContext): Promise<{
17
+ content: string;
18
+ }>;
19
+ };
3
20
  export default definition;
@@ -1,3 +1,3 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
- import type { TuiPlugin } from "@opencode-ai/plugin/tui";
3
- export declare const sourcefedTui: TuiPlugin;
2
+ import type { Plugin } from "@opencode/plugin/tui";
3
+ export declare const sourcefedTui: (ctx: Plugin.Context) => (() => void);
@@ -1,13 +1,18 @@
1
1
  /** @jsxImportSource @opentui/solid */
2
2
  import { type MonitorView } from "@fdcn/sourcefed/daemon";
3
- import type { TuiPluginApi, TuiThemeCurrent } from "@opencode-ai/plugin/tui";
3
+ import type { Plugin } from "@opencode/plugin/tui";
4
+ type ThemeTokens = Plugin.Context["theme"];
5
+ type Color = ThemeTokens["text"]["default"];
6
+ export type Tone = Record<"text" | "textMuted" | "accent" | "success" | "error" | "warning", Color>;
7
+ export declare function tone(theme: ThemeTokens): Tone;
4
8
  export type SidebarProps = {
5
- api: TuiPluginApi;
9
+ ctx: Plugin.Context;
6
10
  sessionID: string;
7
11
  };
8
12
  export declare function Sidebar(props: SidebarProps): import("solid-js").JSX.Element;
9
13
  export declare function MonitorRows(props: {
10
14
  monitors: () => MonitorView[];
11
- theme: TuiThemeCurrent;
15
+ tone: Tone;
12
16
  compact?: boolean;
13
17
  }): import("solid-js").JSX.Element;
18
+ export {};
@@ -1,7 +1,8 @@
1
- import type { TuiPlugin } from "@opencode-ai/plugin/tui";
1
+ import type { Plugin } from "@opencode/plugin/tui";
2
+ type Setup = Plugin.Definition["setup"];
2
3
  export declare const id = "sourcefed-tui";
3
4
  declare const _default: {
4
5
  id: string;
5
- tui: TuiPlugin;
6
+ setup: (ctx: Parameters<Setup>[0]) => Promise<void | Plugin.Cleanup>;
6
7
  };
7
8
  export default _default;
@@ -1 +1 @@
1
- export { default, Sourcefed } from "./adapters/opencode/index.js";
1
+ export { default, setupSourcefed } from "./adapters/opencode/index.js";
@@ -31,6 +31,8 @@ export declare class SourcefedDaemon {
31
31
  private appendLog;
32
32
  private emit;
33
33
  private deliver;
34
+ private dropQueued;
35
+ private purgeMonitorEvents;
34
36
  }
35
37
  export declare function monitorView(monitor: MonitorRecord): MonitorView;
36
38
  export declare function logEntryView(queued: QueuedMonitorEvent): LogEntryView;