@fdcn/sourcefed 0.2.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 (220) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +51 -0
  3. package/dist/chunk-B7T6IZYS.js +5155 -0
  4. package/dist/chunk-MLKGABMK.js +9 -0
  5. package/dist/chunk-NGJ6F5ST.js +766 -0
  6. package/dist/cli.js +30491 -0
  7. package/dist/core-storage.js +13 -0
  8. package/dist/core.js +643 -0
  9. package/dist/daemon.js +5190 -0
  10. package/dist/data/core/SKILL.md +71 -0
  11. package/dist/data/core/references/commands.md +75 -0
  12. package/dist/data/sourcefed/SKILL.md +31 -0
  13. package/dist/guidance.md +71 -0
  14. package/dist/mcp.js +4800 -0
  15. package/dist/opencode.js +12646 -0
  16. package/dist/pi.js +249 -0
  17. package/dist/tui-compiled.mjs +4096 -0
  18. package/dist.dts/adapters/opencode/bridge.d.ts +20 -0
  19. package/dist.dts/adapters/opencode/index.d.ts +3 -0
  20. package/dist.dts/adapters/opencode/tool-result.d.ts +1 -0
  21. package/dist.dts/adapters/opencode/tools/monitor_create.d.ts +3 -0
  22. package/dist.dts/adapters/opencode/tools/monitor_list.d.ts +3 -0
  23. package/dist.dts/adapters/opencode/tools/monitor_start.d.ts +3 -0
  24. package/dist.dts/adapters/opencode/tools/monitor_status.d.ts +3 -0
  25. package/dist.dts/adapters/opencode/tools/monitor_stop.d.ts +3 -0
  26. package/dist.dts/adapters/opencode/tui/plugin.d.ts +3 -0
  27. package/dist.dts/adapters/opencode/tui/sidebar.d.ts +13 -0
  28. package/dist.dts/adapters/opencode/tui.d.ts +7 -0
  29. package/dist.dts/adapters/pi/src/dialog.d.ts +12 -0
  30. package/dist.dts/adapters/pi/src/index.d.ts +2 -0
  31. package/dist.dts/index.d.ts +1 -0
  32. package/dist.dts/packages/cli/src/index.d.ts +2 -0
  33. package/dist.dts/packages/cli/src/skills/command.d.ts +1 -0
  34. package/dist.dts/packages/cli/src/skills/discovery.d.ts +7 -0
  35. package/dist.dts/packages/cli/src/skills/frontmatter.d.ts +5 -0
  36. package/dist.dts/packages/cli/src/skills/index.d.ts +1 -0
  37. package/dist.dts/packages/core/src/events.d.ts +24 -0
  38. package/dist.dts/packages/core/src/events.test.d.ts +1 -0
  39. package/dist.dts/packages/core/src/index.d.ts +9 -0
  40. package/dist.dts/packages/core/src/monitors/index.d.ts +6 -0
  41. package/dist.dts/packages/core/src/monitors/monitor.d.ts +26 -0
  42. package/dist.dts/packages/core/src/monitors/poll/index.d.ts +1 -0
  43. package/dist.dts/packages/core/src/monitors/poll/monitor.d.ts +12 -0
  44. package/dist.dts/packages/core/src/monitors/poll/types/index.d.ts +2 -0
  45. package/dist.dts/packages/core/src/monitors/poll/types/poll-monitor-options.d.ts +6 -0
  46. package/dist.dts/packages/core/src/monitors/poll/types/poll-runner.d.ts +3 -0
  47. package/dist.dts/packages/core/src/monitors/poll/types/routed-event-cursor.d.ts +2 -0
  48. package/dist.dts/packages/core/src/monitors/poll/utils/event-delivery-id.d.ts +2 -0
  49. package/dist.dts/packages/core/src/monitors/poll/utils/tick.d.ts +2 -0
  50. package/dist.dts/packages/core/src/monitors/schema.d.ts +37 -0
  51. package/dist.dts/packages/core/src/monitors/service.d.ts +35 -0
  52. package/dist.dts/packages/core/src/monitors/service.test.d.ts +1 -0
  53. package/dist.dts/packages/core/src/monitors/transport.test.d.ts +1 -0
  54. package/dist.dts/packages/core/src/monitors/types/index.d.ts +2 -0
  55. package/dist.dts/packages/core/src/monitors/types/monitor-record.d.ts +3 -0
  56. package/dist.dts/packages/core/src/monitors/types/monitor-registry.d.ts +3 -0
  57. package/dist.dts/packages/core/src/monitors/utils/monitor-identity.d.ts +5 -0
  58. package/dist.dts/packages/core/src/monitors/utils/monitor-identity.test.d.ts +1 -0
  59. package/dist.dts/packages/core/src/monitors/webhook/index.d.ts +1 -0
  60. package/dist.dts/packages/core/src/monitors/webhook/monitor.d.ts +24 -0
  61. package/dist.dts/packages/core/src/monitors/webhook/types/index.d.ts +3 -0
  62. package/dist.dts/packages/core/src/monitors/webhook/types/pending-webhook-event.d.ts +19 -0
  63. package/dist.dts/packages/core/src/monitors/webhook/types/webhook-monitor-options.d.ts +13 -0
  64. package/dist.dts/packages/core/src/monitors/webhook/utils/constants.d.ts +2 -0
  65. package/dist.dts/packages/core/src/monitors/webhook/utils/deliver-webhook.d.ts +3 -0
  66. package/dist.dts/packages/core/src/monitors/webhook/utils/handle-webhook.d.ts +2 -0
  67. package/dist.dts/packages/core/src/monitors/webhook/utils/handle-webhook.test.d.ts +1 -0
  68. package/dist.dts/packages/core/src/monitors/webhook/utils/heartbeat-webhooks.d.ts +3 -0
  69. package/dist.dts/packages/core/src/runtime.d.ts +23 -0
  70. package/dist.dts/packages/core/src/runtime.test.d.ts +1 -0
  71. package/dist.dts/packages/core/src/sources/index.d.ts +1 -0
  72. package/dist.dts/packages/core/src/sources/schema.d.ts +4 -0
  73. package/dist.dts/packages/core/src/sources/types/index.d.ts +3 -0
  74. package/dist.dts/packages/core/src/sources/types/monitor-source.d.ts +3 -0
  75. package/dist.dts/packages/core/src/sources/types/source-input.d.ts +4 -0
  76. package/dist.dts/packages/core/src/sources/types/source-registry.d.ts +2 -0
  77. package/dist.dts/packages/core/src/storage/in-memory-monitor-store.d.ts +8 -0
  78. package/dist.dts/packages/core/src/storage/index.d.ts +2 -0
  79. package/dist.dts/packages/core/src/storage/json.d.ts +30 -0
  80. package/dist.dts/packages/core/src/storage/json.test.d.ts +1 -0
  81. package/dist.dts/packages/core/src/types/delivery.d.ts +1 -0
  82. package/dist.dts/packages/core/src/types/event-sink.d.ts +12 -0
  83. package/dist.dts/packages/core/src/types/index.d.ts +11 -0
  84. package/dist.dts/packages/core/src/types/monitor-context.d.ts +10 -0
  85. package/dist.dts/packages/core/src/types/monitor-create-input.d.ts +8 -0
  86. package/dist.dts/packages/core/src/types/monitor-event-queue.d.ts +18 -0
  87. package/dist.dts/packages/core/src/types/monitor-event.d.ts +10 -0
  88. package/dist.dts/packages/core/src/types/monitor-options.d.ts +7 -0
  89. package/dist.dts/packages/core/src/types/monitor-store.d.ts +6 -0
  90. package/dist.dts/packages/core/src/types/monitor-target.d.ts +4 -0
  91. package/dist.dts/packages/core/src/types/source-event.d.ts +9 -0
  92. package/dist.dts/packages/core/src/types/source-poll-result.d.ts +6 -0
  93. package/dist.dts/packages/core/src/utils/event-to-text.d.ts +2 -0
  94. package/dist.dts/packages/core/src/utils/to-monitor-event.d.ts +3 -0
  95. package/dist.dts/packages/daemon/src/client.d.ts +2 -0
  96. package/dist.dts/packages/daemon/src/client.test.d.ts +1 -0
  97. package/dist.dts/packages/daemon/src/daemon.d.ts +36 -0
  98. package/dist.dts/packages/daemon/src/daemon.test.d.ts +1 -0
  99. package/dist.dts/packages/daemon/src/dispatch.d.ts +2 -0
  100. package/dist.dts/packages/daemon/src/http.d.ts +5 -0
  101. package/dist.dts/packages/daemon/src/index.d.ts +8 -0
  102. package/dist.dts/packages/daemon/src/registry.d.ts +14 -0
  103. package/dist.dts/packages/daemon/src/types/client.d.ts +21 -0
  104. package/dist.dts/packages/daemon/src/types/daemon.d.ts +58 -0
  105. package/dist.dts/packages/daemon/src/types/index.d.ts +3 -0
  106. package/dist.dts/packages/daemon/src/types/protocol.d.ts +21 -0
  107. package/dist.dts/packages/daemon/src/utils/env.d.ts +1 -0
  108. package/dist.dts/packages/daemon/src/utils/http-server.d.ts +10 -0
  109. package/dist.dts/packages/daemon/src/utils/index.d.ts +6 -0
  110. package/dist.dts/packages/daemon/src/utils/request-router.d.ts +11 -0
  111. package/dist.dts/packages/daemon/src/utils/sink.d.ts +13 -0
  112. package/dist.dts/packages/daemon/src/utils/spawn.d.ts +19 -0
  113. package/dist.dts/packages/daemon/src/utils/target.d.ts +4 -0
  114. package/dist.dts/packages/mcp/src/index.d.ts +2 -0
  115. package/dist.dts/packages/mcp/src/server.d.ts +14 -0
  116. package/dist.dts/packages/mcp/src/server.test.d.ts +1 -0
  117. package/dist.dts/packages/mcp/src/uris.d.ts +3 -0
  118. package/dist.dts/packages/sourcefed/src/server.d.ts +7 -0
  119. package/dist.dts/providers/github/src/api/client.d.ts +3 -0
  120. package/dist.dts/providers/github/src/api/comments.d.ts +1 -0
  121. package/dist.dts/providers/github/src/api/github-api.test.d.ts +1 -0
  122. package/dist.dts/providers/github/src/api/index.d.ts +4 -0
  123. package/dist.dts/providers/github/src/api/logs.d.ts +5 -0
  124. package/dist.dts/providers/github/src/api/pr.d.ts +8 -0
  125. package/dist.dts/providers/github/src/github.test.d.ts +1 -0
  126. package/dist.dts/providers/github/src/index.d.ts +2 -0
  127. package/dist.dts/providers/github/src/monitor.d.ts +15 -0
  128. package/dist.dts/providers/github/src/poll/index.d.ts +2 -0
  129. package/dist.dts/providers/github/src/poll/monitor.d.ts +3 -0
  130. package/dist.dts/providers/github/src/poll/utils/append-comments.d.ts +2 -0
  131. package/dist.dts/providers/github/src/poll/utils/append-github-ci-event.d.ts +2 -0
  132. package/dist.dts/providers/github/src/poll/utils/append-github-conflict-event.d.ts +2 -0
  133. package/dist.dts/providers/github/src/poll/utils/append-github-reviews.d.ts +2 -0
  134. package/dist.dts/providers/github/src/poll/utils/append-github-state-event.d.ts +2 -0
  135. package/dist.dts/providers/github/src/poll/utils/ci-failure-detail.d.ts +1 -0
  136. package/dist.dts/providers/github/src/poll/utils/clean-ci-log.d.ts +1 -0
  137. package/dist.dts/providers/github/src/poll/utils/confirm-still-failing.d.ts +1 -0
  138. package/dist.dts/providers/github/src/poll/utils/empty-cursor.d.ts +2 -0
  139. package/dist.dts/providers/github/src/poll/utils/failure-run-ids.d.ts +1 -0
  140. package/dist.dts/providers/github/src/poll/utils/failure-run-log.d.ts +1 -0
  141. package/dist.dts/providers/github/src/poll/utils/format-failed-check.d.ts +1 -0
  142. package/dist.dts/providers/github/src/poll/utils/index.d.ts +1 -0
  143. package/dist.dts/providers/github/src/poll/utils/poll-github.d.ts +6 -0
  144. package/dist.dts/providers/github/src/poll/utils/poll-helpers.test.d.ts +1 -0
  145. package/dist.dts/providers/github/src/schema.d.ts +17 -0
  146. package/dist.dts/providers/github/src/types/cursor.d.ts +11 -0
  147. package/dist.dts/providers/github/src/types/event.d.ts +11 -0
  148. package/dist.dts/providers/github/src/types/index.d.ts +3 -0
  149. package/dist.dts/providers/github/src/types/source-record.d.ts +5 -0
  150. package/dist.dts/providers/github/src/webhook/index.d.ts +3 -0
  151. package/dist.dts/providers/github/src/webhook/monitor.d.ts +3 -0
  152. package/dist.dts/providers/github/src/webhook/types/context.d.ts +7 -0
  153. package/dist.dts/providers/github/src/webhook/types/event-handler.d.ts +3 -0
  154. package/dist.dts/providers/github/src/webhook/types/event-shape.d.ts +7 -0
  155. package/dist.dts/providers/github/src/webhook/types/index.d.ts +1 -0
  156. package/dist.dts/providers/github/src/webhook/utils/fallback-github-event.d.ts +3 -0
  157. package/dist.dts/providers/github/src/webhook/utils/github-event-handlers.d.ts +2 -0
  158. package/dist.dts/providers/github/src/webhook/utils/index.d.ts +2 -0
  159. package/dist.dts/providers/github/src/webhook/utils/parse-check-run.d.ts +3 -0
  160. package/dist.dts/providers/github/src/webhook/utils/parse-check-suite.d.ts +3 -0
  161. package/dist.dts/providers/github/src/webhook/utils/parse-github-comment.d.ts +3 -0
  162. package/dist.dts/providers/github/src/webhook/utils/parse-github-webhook.d.ts +2 -0
  163. package/dist.dts/providers/github/src/webhook/utils/parse-pull-request-review.d.ts +3 -0
  164. package/dist.dts/providers/github/src/webhook/utils/parse-pull-request.d.ts +3 -0
  165. package/dist.dts/providers/github/src/webhook/utils/pull-request-number.d.ts +1 -0
  166. package/dist.dts/providers/github/src/webhook/utils/update-github-cursor.d.ts +3 -0
  167. package/dist.dts/providers/github/src/webhook/utils/verify-github-webhook.d.ts +1 -0
  168. package/dist.dts/providers/github/src/webhook/utils/verify-hmac.d.ts +1 -0
  169. package/dist.dts/providers/jira/src/index.d.ts +2 -0
  170. package/dist.dts/providers/jira/src/monitor.d.ts +14 -0
  171. package/dist.dts/providers/jira/src/poll/index.d.ts +2 -0
  172. package/dist.dts/providers/jira/src/poll/monitor.d.ts +3 -0
  173. package/dist.dts/providers/jira/src/poll/utils/adf-text.d.ts +1 -0
  174. package/dist.dts/providers/jira/src/poll/utils/append-jira-changelog.d.ts +2 -0
  175. package/dist.dts/providers/jira/src/poll/utils/append-jira-comments.d.ts +2 -0
  176. package/dist.dts/providers/jira/src/poll/utils/append-jira-description.d.ts +2 -0
  177. package/dist.dts/providers/jira/src/poll/utils/empty-cursor.d.ts +2 -0
  178. package/dist.dts/providers/jira/src/poll/utils/format-jira-changelog-item.d.ts +1 -0
  179. package/dist.dts/providers/jira/src/poll/utils/index.d.ts +1 -0
  180. package/dist.dts/providers/jira/src/poll/utils/is-terminal-status.d.ts +1 -0
  181. package/dist.dts/providers/jira/src/poll/utils/jira-auth.d.ts +1 -0
  182. package/dist.dts/providers/jira/src/poll/utils/jira-change-value.d.ts +1 -0
  183. package/dist.dts/providers/jira/src/poll/utils/jira-changelog-event.d.ts +2 -0
  184. package/dist.dts/providers/jira/src/poll/utils/jira-fetch.d.ts +1 -0
  185. package/dist.dts/providers/jira/src/poll/utils/meaningful-changelog-items.d.ts +1 -0
  186. package/dist.dts/providers/jira/src/poll/utils/poll-helpers.test.d.ts +1 -0
  187. package/dist.dts/providers/jira/src/poll/utils/poll-jira.d.ts +6 -0
  188. package/dist.dts/providers/jira/src/schema.d.ts +10 -0
  189. package/dist.dts/providers/jira/src/types/cursor.d.ts +5 -0
  190. package/dist.dts/providers/jira/src/types/event.d.ts +11 -0
  191. package/dist.dts/providers/jira/src/types/index.d.ts +3 -0
  192. package/dist.dts/providers/jira/src/types/source-record.d.ts +4 -0
  193. package/dist.dts/providers/slack/src/index.d.ts +2 -0
  194. package/dist.dts/providers/slack/src/monitor.d.ts +15 -0
  195. package/dist.dts/providers/slack/src/poll/index.d.ts +2 -0
  196. package/dist.dts/providers/slack/src/poll/monitor.d.ts +3 -0
  197. package/dist.dts/providers/slack/src/poll/utils/index.d.ts +2 -0
  198. package/dist.dts/providers/slack/src/poll/utils/parse-slack-read-result.d.ts +5 -0
  199. package/dist.dts/providers/slack/src/poll/utils/poll-slack.d.ts +6 -0
  200. package/dist.dts/providers/slack/src/poll/utils/slack-api.d.ts +4 -0
  201. package/dist.dts/providers/slack/src/schema.d.ts +11 -0
  202. package/dist.dts/providers/slack/src/slack.test.d.ts +1 -0
  203. package/dist.dts/providers/slack/src/types/cursor.d.ts +5 -0
  204. package/dist.dts/providers/slack/src/types/event.d.ts +8 -0
  205. package/dist.dts/providers/slack/src/types/index.d.ts +4 -0
  206. package/dist.dts/providers/slack/src/types/message.d.ts +6 -0
  207. package/dist.dts/providers/slack/src/types/read-result.d.ts +10 -0
  208. package/dist.dts/providers/slack/src/types/source-record.d.ts +5 -0
  209. package/dist.dts/providers/slack/src/utils/index.d.ts +2 -0
  210. package/dist.dts/providers/slack/src/utils/message-at.d.ts +1 -0
  211. package/dist.dts/providers/slack/src/utils/message-timestamp.d.ts +1 -0
  212. package/dist.dts/providers/slack/src/webhook/index.d.ts +2 -0
  213. package/dist.dts/providers/slack/src/webhook/monitor.d.ts +3 -0
  214. package/dist.dts/providers/slack/src/webhook/utils/index.d.ts +3 -0
  215. package/dist.dts/providers/slack/src/webhook/utils/parse-slack-webhook.d.ts +2 -0
  216. package/dist.dts/providers/slack/src/webhook/utils/slack-signature.d.ts +1 -0
  217. package/dist.dts/providers/slack/src/webhook/utils/update-slack-cursor.d.ts +3 -0
  218. package/dist.dts/providers/slack/src/webhook/utils/valid-slack-signature.d.ts +1 -0
  219. package/dist.dts/tui.d.ts +1 -0
  220. package/package.json +68 -0
package/dist/pi.js ADDED
@@ -0,0 +1,249 @@
1
+ import {
2
+ connectDaemonClient,
3
+ daemonCommand,
4
+ daemonEnvironment,
5
+ spawnLocalDaemon
6
+ } from "./chunk-B7T6IZYS.js";
7
+ import "./chunk-MLKGABMK.js";
8
+
9
+ // adapters/pi/src/index.ts
10
+ import { fileURLToPath } from "node:url";
11
+ import { Type } from "typebox";
12
+
13
+ // adapters/pi/src/dialog.ts
14
+ import { Container, Spacer, Text, truncateToWidth } from "@earendil-works/pi-tui";
15
+ import { DynamicBorder } from "@earendil-works/pi-coding-agent";
16
+ function showSourcefedDialog(_tui, theme, done, title, lines) {
17
+ const container = new Container();
18
+ container.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
19
+ container.addChild(new Text(theme.fg("accent", theme.bold(title)), 1, 0));
20
+ container.addChild(new Spacer(1));
21
+ for (const line of lines) {
22
+ container.addChild(new Text(line.text, 1, 0));
23
+ }
24
+ container.addChild(new Spacer(1));
25
+ container.addChild(new Text(theme.fg("dim", "esc to close"), 1, 0));
26
+ container.addChild(new DynamicBorder((s) => theme.fg("accent", s)));
27
+ return {
28
+ render: (width) => {
29
+ const rendered = container.render(width);
30
+ return rendered.map((line) => truncateToWidth(line, width));
31
+ },
32
+ invalidate: () => container.invalidate(),
33
+ handleInput: (data) => {
34
+ if (data === "\x1B" || data === "\r") done(null);
35
+ }
36
+ };
37
+ }
38
+ function monitorLines(monitors, theme) {
39
+ const active = monitors.filter((monitor) => monitor.enabled);
40
+ if (active.length === 0) return [{ text: theme.fg("dim", "No active monitors") }];
41
+ return active.map((monitor) => {
42
+ const status = monitor.unresponsive ? theme.fg("error", "\u25CF") : theme.fg("success", "\u25CF");
43
+ const describe = theme.fg("text", monitor.describe);
44
+ const detail = monitor.detail ? theme.fg("muted", monitor.detail) : "";
45
+ return { text: `${status} ${monitor.icon} ${describe}${detail}` };
46
+ });
47
+ }
48
+ function logLines(logs, theme) {
49
+ if (logs.length === 0) return [{ text: theme.fg("dim", "No notifications sent yet") }];
50
+ return logs.flatMap((entry) => {
51
+ const time = new Date(entry.at).toLocaleString();
52
+ const marker = entry.actionable ? theme.fg("warning", "\u25B6") : theme.fg("dim", "\xB7");
53
+ const summary = theme.fg("text", entry.summary);
54
+ const lines = [{ text: `${marker} ${entry.icon} ${theme.fg("muted", time)} ${summary}` }];
55
+ if (entry.body) lines.push({ text: theme.fg("muted", ` ${entry.body}`) });
56
+ return lines;
57
+ });
58
+ }
59
+
60
+ // adapters/pi/src/index.ts
61
+ var STATUS_REFRESH_MS = 3e3;
62
+ var SOURCE_ICONS = {
63
+ jira: "\u{F0303}",
64
+ github: "\u{F02A4}",
65
+ slack: "\u{F04B1}"
66
+ };
67
+ async function sourcefedExtension(pi) {
68
+ const listeners = /* @__PURE__ */ new Map();
69
+ let client;
70
+ let lastAttemptAt = 0;
71
+ let lastError;
72
+ let statusTimer;
73
+ let statusCtx;
74
+ pi.on("session_start", async (_event, ctx) => {
75
+ statusCtx = ctx;
76
+ await ensureTarget(ctx);
77
+ void refreshStatus();
78
+ statusTimer = setInterval(() => void refreshStatus(), STATUS_REFRESH_MS);
79
+ });
80
+ pi.on("session_shutdown", async () => {
81
+ if (statusTimer) clearInterval(statusTimer);
82
+ statusTimer = void 0;
83
+ statusCtx = void 0;
84
+ for (const listener of listeners.values()) await listener.close();
85
+ listeners.clear();
86
+ await client?.close();
87
+ client = void 0;
88
+ });
89
+ pi.registerTool({
90
+ name: "sourcefed_monitor_create",
91
+ label: "Sourcefed monitor create",
92
+ description: "Create or reuse a Sourcefed monitor for the current Pi session.",
93
+ parameters: Type.Object({
94
+ name: Type.String(),
95
+ sourceType: Type.Unsafe({ type: "string", enum: ["jira", "github", "slack"] }),
96
+ issueKey: Type.Optional(Type.String()),
97
+ repo: Type.Optional(Type.String()),
98
+ prNumber: Type.Optional(Type.Number()),
99
+ channelId: Type.Optional(Type.String()),
100
+ threadTs: Type.Optional(Type.String()),
101
+ threadUrl: Type.Optional(Type.String()),
102
+ pollIntervalSec: Type.Optional(Type.Number())
103
+ }),
104
+ execute: async (_toolCallID, input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_create", input))
105
+ });
106
+ pi.registerTool({
107
+ name: "sourcefed_monitor_list",
108
+ label: "Sourcefed monitor list",
109
+ description: "List Sourcefed monitors for the current Pi session.",
110
+ parameters: Type.Object({}),
111
+ execute: async (_toolCallID, _input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_list", {}))
112
+ });
113
+ pi.registerTool({
114
+ name: "sourcefed_monitor_status",
115
+ label: "Sourcefed monitor status",
116
+ description: "Read one Sourcefed monitor for the current Pi session.",
117
+ parameters: Type.Object({ id: Type.String() }),
118
+ execute: async (_toolCallID, input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_status", input))
119
+ });
120
+ pi.registerTool({
121
+ name: "sourcefed_monitor_stop",
122
+ label: "Sourcefed monitor stop",
123
+ description: "Stop one Sourcefed monitor for the current Pi session.",
124
+ parameters: Type.Object({ id: Type.String() }),
125
+ execute: async (_toolCallID, input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_stop", input))
126
+ });
127
+ pi.registerTool({
128
+ name: "sourcefed_monitor_start",
129
+ label: "Sourcefed monitor start",
130
+ description: "Start (re-enable) a stopped Sourcefed monitor for the current Pi session.",
131
+ parameters: Type.Object({ id: Type.String() }),
132
+ execute: async (_toolCallID, input, _signal, _onUpdate, ctx) => toolResult(await call(ctx, "monitor_start", input))
133
+ });
134
+ pi.registerCommand("sourcefed", {
135
+ description: "List Sourcefed monitors for the current Pi session",
136
+ handler: async (_args, ctx) => {
137
+ const result = await call(ctx, "monitor_list", {});
138
+ const monitors = Array.isArray(result?.monitors) ? result.monitors : [];
139
+ await ctx.ui.custom(
140
+ (tui, theme, _keybindings, done) => showSourcefedDialog(tui, theme, done, `Sourcefed monitors (${monitors.length})`, monitorLines(monitors, theme))
141
+ );
142
+ }
143
+ });
144
+ pi.registerCommand("sourcefed logs", {
145
+ description: "Show recent Sourcefed notifications for the current Pi session",
146
+ handler: async (_args, ctx) => {
147
+ const result = await call(ctx, "monitor_logs", {});
148
+ const logs = Array.isArray(result?.logs) ? result.logs : [];
149
+ await ctx.ui.custom(
150
+ (tui, theme, _keybindings, done) => showSourcefedDialog(tui, theme, done, `Sourcefed notifications (${logs.length})`, logLines(logs, theme))
151
+ );
152
+ }
153
+ });
154
+ async function refreshStatus() {
155
+ const ctx = statusCtx;
156
+ if (!ctx) return;
157
+ const result = await call(ctx, "monitor_list", {});
158
+ const monitors = Array.isArray(result?.monitors) ? result.monitors : [];
159
+ const active = monitors.filter((monitor) => monitor.enabled);
160
+ if (active.length === 0) {
161
+ ctx.ui.setStatus("sourcefed", void 0);
162
+ return;
163
+ }
164
+ const bySource = /* @__PURE__ */ new Map();
165
+ for (const monitor of active) {
166
+ const type = String(monitor.source && typeof monitor.source === "object" && "type" in monitor.source ? monitor.source.type : "");
167
+ const entry = bySource.get(type) ?? { count: 0, unresponsive: false };
168
+ entry.count += 1;
169
+ if (monitor.unresponsive) entry.unresponsive = true;
170
+ bySource.set(type, entry);
171
+ }
172
+ const parts = [...bySource.entries()].map(([type, entry]) => {
173
+ const icon = SOURCE_ICONS[type] ?? "?";
174
+ const colored = entry.unresponsive ? ctx.ui.theme.fg("error", icon) : ctx.ui.theme.fg("success", icon);
175
+ return `${colored}${entry.count}`;
176
+ });
177
+ ctx.ui.setStatus("sourcefed", parts.join(" "));
178
+ }
179
+ async function call(ctx, name, args) {
180
+ const target = await ensureTarget(ctx);
181
+ if (!client) return { ok: false, error: `sourcefed daemon unavailable: ${lastError ?? "not started"}` };
182
+ return client.request(name.replace(/_/g, "."), { ...args, target });
183
+ }
184
+ async function ensureTarget(ctx) {
185
+ await ensureClient();
186
+ const target = { kind: "pi-session", id: ctx.sessionManager.getSessionId() };
187
+ if (client && !listeners.has(target.id)) {
188
+ const listener = await client.subscribe(target, async (events) => {
189
+ await routeEvents(pi, events, target, client);
190
+ });
191
+ listeners.set(target.id, listener);
192
+ }
193
+ return target;
194
+ }
195
+ async function ensureClient() {
196
+ if (client) return;
197
+ if (Date.now() - lastAttemptAt < 15e3) return;
198
+ lastAttemptAt = Date.now();
199
+ try {
200
+ const url = process.env.SOURCEFED_DAEMON_URL;
201
+ if (url) {
202
+ client = await connectDaemonClient({ name: "sourcefed-pi", url });
203
+ } else {
204
+ const local = daemonCommand(cliEntry());
205
+ const spawned = await spawnLocalDaemon({
206
+ command: local.command,
207
+ args: local.args,
208
+ env: daemonEnvironment()
209
+ });
210
+ client = await connectDaemonClient({ name: "sourcefed-pi", url: spawned.url });
211
+ }
212
+ } catch (error) {
213
+ lastError = error instanceof Error ? error.message : String(error);
214
+ console.error(`[sourcefed] daemon unavailable: ${lastError}`);
215
+ }
216
+ }
217
+ }
218
+ async function routeEvents(pi, events, target, daemon) {
219
+ const delivered = [];
220
+ for (const queued of events) {
221
+ await pi.sendMessage({
222
+ customType: "sourcefed-monitor",
223
+ content: `[sourcefed monitor] ${queued.event.summary}${queued.event.body ? `
224
+
225
+ ${queued.event.body}` : ""}`,
226
+ display: true,
227
+ details: { actionable: queued.event.actionable, eventID: queued.id }
228
+ }, { triggerTurn: queued.event.actionable, deliverAs: "steer" });
229
+ delivered.push(queued);
230
+ }
231
+ if (delivered.length > 0) {
232
+ await daemon.request("monitor.ack", {
233
+ target,
234
+ eventIDs: delivered.map((queued) => queued.id)
235
+ });
236
+ }
237
+ }
238
+ function cliEntry() {
239
+ return fileURLToPath(import.meta.resolve("@sourcefed/cli"));
240
+ }
241
+ function toolResult(result) {
242
+ return {
243
+ content: [{ type: "text", text: JSON.stringify(result) }],
244
+ details: {}
245
+ };
246
+ }
247
+ export {
248
+ sourcefedExtension as default
249
+ };