@pinet/slack-bridge 0.1.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 (179) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +570 -0
  3. package/dist/activity-log.d.ts +62 -0
  4. package/dist/activity-log.js +293 -0
  5. package/dist/agent-completion-runtime.d.ts +17 -0
  6. package/dist/agent-completion-runtime.js +26 -0
  7. package/dist/agent-event-runtime.d.ts +13 -0
  8. package/dist/agent-event-runtime.js +27 -0
  9. package/dist/agent-prompt-guidance.d.ts +22 -0
  10. package/dist/agent-prompt-guidance.js +46 -0
  11. package/dist/broker/adapters/slack.d.ts +74 -0
  12. package/dist/broker/adapters/slack.js +563 -0
  13. package/dist/broker/adapters/types.d.ts +1 -0
  14. package/dist/broker/adapters/types.js +1 -0
  15. package/dist/broker/agent-messaging.d.ts +1 -0
  16. package/dist/broker/agent-messaging.js +1 -0
  17. package/dist/broker/auth.d.ts +1 -0
  18. package/dist/broker/auth.js +1 -0
  19. package/dist/broker/client.d.ts +167 -0
  20. package/dist/broker/client.js +624 -0
  21. package/dist/broker/control-plane-dashboard.d.ts +98 -0
  22. package/dist/broker/control-plane-dashboard.js +213 -0
  23. package/dist/broker/ghost-reaper.d.ts +49 -0
  24. package/dist/broker/ghost-reaper.js +209 -0
  25. package/dist/broker/index.d.ts +36 -0
  26. package/dist/broker/index.js +90 -0
  27. package/dist/broker/leader.d.ts +1 -0
  28. package/dist/broker/leader.js +1 -0
  29. package/dist/broker/maintenance.d.ts +1 -0
  30. package/dist/broker/maintenance.js +1 -0
  31. package/dist/broker/message-send.d.ts +1 -0
  32. package/dist/broker/message-send.js +1 -0
  33. package/dist/broker/paths.d.ts +1 -0
  34. package/dist/broker/paths.js +1 -0
  35. package/dist/broker/raw-tcp-loopback.d.ts +1 -0
  36. package/dist/broker/raw-tcp-loopback.js +1 -0
  37. package/dist/broker/router.d.ts +1 -0
  38. package/dist/broker/router.js +1 -0
  39. package/dist/broker/schema.d.ts +9 -0
  40. package/dist/broker/schema.js +63 -0
  41. package/dist/broker/socket-server.d.ts +120 -0
  42. package/dist/broker/socket-server.js +1087 -0
  43. package/dist/broker/types.d.ts +1 -0
  44. package/dist/broker/types.js +1 -0
  45. package/dist/broker-delivery.d.ts +10 -0
  46. package/dist/broker-delivery.js +26 -0
  47. package/dist/broker-inbound-persistence.d.ts +11 -0
  48. package/dist/broker-inbound-persistence.js +22 -0
  49. package/dist/broker-prompt-loader.d.ts +34 -0
  50. package/dist/broker-prompt-loader.js +185 -0
  51. package/dist/broker-runtime-access.d.ts +14 -0
  52. package/dist/broker-runtime-access.js +20 -0
  53. package/dist/broker-runtime.d.ts +100 -0
  54. package/dist/broker-runtime.js +533 -0
  55. package/dist/broker-thread-owner-hints.d.ts +10 -0
  56. package/dist/broker-thread-owner-hints.js +14 -0
  57. package/dist/canvases.d.ts +80 -0
  58. package/dist/canvases.js +221 -0
  59. package/dist/command-registration-runtime.d.ts +9 -0
  60. package/dist/command-registration-runtime.js +9 -0
  61. package/dist/core-tool-guardrails.d.ts +24 -0
  62. package/dist/core-tool-guardrails.js +66 -0
  63. package/dist/deploy-manifest.d.ts +27 -0
  64. package/dist/deploy-manifest.js +197 -0
  65. package/dist/follower-delivery.d.ts +16 -0
  66. package/dist/follower-delivery.js +70 -0
  67. package/dist/follower-runtime.d.ts +61 -0
  68. package/dist/follower-runtime.js +350 -0
  69. package/dist/git-metadata.d.ts +35 -0
  70. package/dist/git-metadata.js +88 -0
  71. package/dist/guardrails.d.ts +69 -0
  72. package/dist/guardrails.js +283 -0
  73. package/dist/helpers.d.ts +550 -0
  74. package/dist/helpers.js +2711 -0
  75. package/dist/home-tab.d.ts +27 -0
  76. package/dist/home-tab.js +242 -0
  77. package/dist/imessage-tools.d.ts +33 -0
  78. package/dist/imessage-tools.js +96 -0
  79. package/dist/inbox-drain-runtime.d.ts +30 -0
  80. package/dist/inbox-drain-runtime.js +71 -0
  81. package/dist/index.d.ts +2 -0
  82. package/dist/index.js +1330 -0
  83. package/dist/persisted-runtime-state.d.ts +52 -0
  84. package/dist/persisted-runtime-state.js +98 -0
  85. package/dist/pinet-activity-formatting.d.ts +20 -0
  86. package/dist/pinet-activity-formatting.js +43 -0
  87. package/dist/pinet-agent-status.d.ts +36 -0
  88. package/dist/pinet-agent-status.js +48 -0
  89. package/dist/pinet-commands.d.ts +70 -0
  90. package/dist/pinet-commands.js +402 -0
  91. package/dist/pinet-confirmation-replies.d.ts +7 -0
  92. package/dist/pinet-confirmation-replies.js +30 -0
  93. package/dist/pinet-control-plane-dashboard.d.ts +34 -0
  94. package/dist/pinet-control-plane-dashboard.js +86 -0
  95. package/dist/pinet-home-tabs.d.ts +36 -0
  96. package/dist/pinet-home-tabs.js +101 -0
  97. package/dist/pinet-maintenance-delivery.d.ts +22 -0
  98. package/dist/pinet-maintenance-delivery.js +45 -0
  99. package/dist/pinet-mesh-ops.d.ts +97 -0
  100. package/dist/pinet-mesh-ops.js +266 -0
  101. package/dist/pinet-registration-gate.d.ts +14 -0
  102. package/dist/pinet-registration-gate.js +42 -0
  103. package/dist/pinet-remote-control-acks.d.ts +16 -0
  104. package/dist/pinet-remote-control-acks.js +46 -0
  105. package/dist/pinet-remote-control.d.ts +17 -0
  106. package/dist/pinet-remote-control.js +74 -0
  107. package/dist/pinet-runtime-composition.d.ts +27 -0
  108. package/dist/pinet-runtime-composition.js +20 -0
  109. package/dist/pinet-tools.d.ts +67 -0
  110. package/dist/pinet-tools.js +1211 -0
  111. package/dist/prompts/broker/default.md +41 -0
  112. package/dist/prompts/broker/tmux.md +49 -0
  113. package/dist/ralph-loop.d.ts +76 -0
  114. package/dist/ralph-loop.js +524 -0
  115. package/dist/reaction-triggers.d.ts +25 -0
  116. package/dist/reaction-triggers.js +171 -0
  117. package/dist/repo-tool-guardrails.d.ts +20 -0
  118. package/dist/repo-tool-guardrails.js +81 -0
  119. package/dist/runtime-agent-context.d.ts +93 -0
  120. package/dist/runtime-agent-context.js +302 -0
  121. package/dist/runtime-mode.d.ts +10 -0
  122. package/dist/runtime-mode.js +39 -0
  123. package/dist/scheduled-wakeups.d.ts +1 -0
  124. package/dist/scheduled-wakeups.js +1 -0
  125. package/dist/session-ui-runtime.d.ts +20 -0
  126. package/dist/session-ui-runtime.js +163 -0
  127. package/dist/single-player-runtime.d.ts +71 -0
  128. package/dist/single-player-runtime.js +436 -0
  129. package/dist/skins/cosmere.json +1571 -0
  130. package/dist/skins/foundation.json +1304 -0
  131. package/dist/slack-access.d.ts +186 -0
  132. package/dist/slack-access.js +462 -0
  133. package/dist/slack-api.d.ts +2 -0
  134. package/dist/slack-api.js +1 -0
  135. package/dist/slack-block-kit.d.ts +36 -0
  136. package/dist/slack-block-kit.js +242 -0
  137. package/dist/slack-export.d.ts +31 -0
  138. package/dist/slack-export.js +206 -0
  139. package/dist/slack-message-context.d.ts +15 -0
  140. package/dist/slack-message-context.js +207 -0
  141. package/dist/slack-modals.d.ts +13 -0
  142. package/dist/slack-modals.js +79 -0
  143. package/dist/slack-pinet-runtime-adapter.d.ts +16 -0
  144. package/dist/slack-pinet-runtime-adapter.js +72 -0
  145. package/dist/slack-presence.d.ts +36 -0
  146. package/dist/slack-presence.js +89 -0
  147. package/dist/slack-request-runtime.d.ts +8 -0
  148. package/dist/slack-request-runtime.js +19 -0
  149. package/dist/slack-runtime-access.d.ts +28 -0
  150. package/dist/slack-runtime-access.js +107 -0
  151. package/dist/slack-scope-diagnostics.d.ts +31 -0
  152. package/dist/slack-scope-diagnostics.js +235 -0
  153. package/dist/slack-socket-dedup.d.ts +7 -0
  154. package/dist/slack-socket-dedup.js +135 -0
  155. package/dist/slack-thread-status.d.ts +41 -0
  156. package/dist/slack-thread-status.js +156 -0
  157. package/dist/slack-tool-policy-runtime.d.ts +36 -0
  158. package/dist/slack-tool-policy-runtime.js +96 -0
  159. package/dist/slack-tools.d.ts +52 -0
  160. package/dist/slack-tools.js +2688 -0
  161. package/dist/slack-turn-guardrails.d.ts +19 -0
  162. package/dist/slack-turn-guardrails.js +36 -0
  163. package/dist/slack-upload.d.ts +49 -0
  164. package/dist/slack-upload.js +224 -0
  165. package/dist/task-assignments.d.ts +45 -0
  166. package/dist/task-assignments.js +527 -0
  167. package/dist/thread-confirmations.d.ts +22 -0
  168. package/dist/thread-confirmations.js +139 -0
  169. package/dist/tool-registration-runtime.d.ts +13 -0
  170. package/dist/tool-registration-runtime.js +13 -0
  171. package/dist/ttl-cache.d.ts +47 -0
  172. package/dist/ttl-cache.js +105 -0
  173. package/manifest.yaml +57 -0
  174. package/package.json +60 -0
  175. package/skills/pinet-skin-creator/SKILL.md +109 -0
  176. package/skills/pinet-skin-creator/references/descriptor-format.md +99 -0
  177. package/skills/pinet-skin-creator/references/safety-checklist.md +56 -0
  178. package/skills/pinet-skin-creator/templates/pinet-skin-descriptor.json +77 -0
  179. package/skills/slack-bridge/SKILL.md +360 -0
@@ -0,0 +1 @@
1
+ export * from "@pinet/broker-core/types";
@@ -0,0 +1 @@
1
+ export * from "@pinet/broker-core/types";
@@ -0,0 +1,10 @@
1
+ import type { InboxMessage } from "./helpers.js";
2
+ export interface BrokerDeliveryState {
3
+ pendingInboxIds: Set<number>;
4
+ }
5
+ export declare function createBrokerDeliveryState(): BrokerDeliveryState;
6
+ export declare function resetBrokerDeliveryState(state: BrokerDeliveryState): void;
7
+ export declare function isBrokerInboxIdTracked(state: BrokerDeliveryState, inboxId: number): boolean;
8
+ export declare function queueBrokerInboxIds(state: BrokerDeliveryState, inboxIds: Iterable<number>): void;
9
+ export declare function markBrokerInboxIdsHandled(state: BrokerDeliveryState, inboxIds: Iterable<number>): void;
10
+ export declare function getBrokerInboxIds(messages: InboxMessage[]): number[];
@@ -0,0 +1,26 @@
1
+ export function createBrokerDeliveryState() {
2
+ return {
3
+ pendingInboxIds: new Set(),
4
+ };
5
+ }
6
+ export function resetBrokerDeliveryState(state) {
7
+ state.pendingInboxIds.clear();
8
+ }
9
+ export function isBrokerInboxIdTracked(state, inboxId) {
10
+ return state.pendingInboxIds.has(inboxId);
11
+ }
12
+ export function queueBrokerInboxIds(state, inboxIds) {
13
+ for (const inboxId of inboxIds) {
14
+ state.pendingInboxIds.add(inboxId);
15
+ }
16
+ }
17
+ export function markBrokerInboxIdsHandled(state, inboxIds) {
18
+ for (const inboxId of inboxIds) {
19
+ state.pendingInboxIds.delete(inboxId);
20
+ }
21
+ }
22
+ export function getBrokerInboxIds(messages) {
23
+ return [
24
+ ...new Set(messages.flatMap((message) => (message.brokerInboxId ? [message.brokerInboxId] : []))),
25
+ ];
26
+ }
@@ -0,0 +1,11 @@
1
+ import type { BrokerMessage, DeliveredInboundMessageResult, InboundMessage } from "@pinet/broker-core/types";
2
+ export interface DeliveredInboundPersistenceStore {
3
+ queueDeliveredMessage(agentId: string, message: InboundMessage): DeliveredInboundMessageResult;
4
+ }
5
+ export interface PersistedInboundNotification {
6
+ result: DeliveredInboundMessageResult;
7
+ notificationText: string;
8
+ }
9
+ export declare function buildPinetReadPointer(threadId: string): string;
10
+ export declare function buildPersistedInboundNotificationText(message: BrokerMessage): string;
11
+ export declare function persistDeliveredInboundMessage(store: DeliveredInboundPersistenceStore, agentId: string, message: InboundMessage): PersistedInboundNotification;
@@ -0,0 +1,22 @@
1
+ export function buildPinetReadPointer(threadId) {
2
+ const trimmed = threadId.trim();
3
+ const parts = [
4
+ "pointer=pinet action=read",
5
+ trimmed ? `args.thread_id=${trimmed}` : null,
6
+ "args.unread_only=true",
7
+ ].filter((part) => Boolean(part));
8
+ return parts.join(" ");
9
+ }
10
+ export function buildPersistedInboundNotificationText(message) {
11
+ return [
12
+ `Durable ${message.source} mail stored as #${message.id}.`,
13
+ buildPinetReadPointer(message.threadId),
14
+ ].join(" ");
15
+ }
16
+ export function persistDeliveredInboundMessage(store, agentId, message) {
17
+ const result = store.queueDeliveredMessage(agentId, message);
18
+ return {
19
+ result,
20
+ notificationText: buildPersistedInboundNotificationText(result.message),
21
+ };
22
+ }
@@ -0,0 +1,34 @@
1
+ export declare const DEFAULT_BROKER_PROMPT_MAX_BYTES: number;
2
+ export type BrokerPromptSource = "configured" | "workspace" | "user" | "packaged";
3
+ export interface BrokerPromptWarning {
4
+ source: BrokerPromptSource;
5
+ reason: "unsafe_path" | "unreadable" | "too_large" | "invalid_utf8" | "empty";
6
+ message: string;
7
+ }
8
+ export interface BrokerPromptCandidate {
9
+ source: BrokerPromptSource;
10
+ path: string;
11
+ root: string;
12
+ required: boolean;
13
+ }
14
+ export interface BrokerPromptLoadOptions {
15
+ workspaceRoot?: string;
16
+ cwd?: string;
17
+ homeDir?: string;
18
+ defaultPromptPath?: string;
19
+ configuredPrompt?: string;
20
+ maxBytes?: number;
21
+ }
22
+ export interface BrokerPromptLoadResult {
23
+ source: BrokerPromptSource;
24
+ content: string;
25
+ warnings: BrokerPromptWarning[];
26
+ diagnostic: string;
27
+ }
28
+ export interface BrokerPromptTemplateValues {
29
+ agentEmoji: string;
30
+ agentName: string;
31
+ }
32
+ export declare function resolveBrokerPromptCandidates(options?: BrokerPromptLoadOptions): BrokerPromptCandidate[];
33
+ export declare function loadBrokerPrompt(options?: BrokerPromptLoadOptions): Promise<BrokerPromptLoadResult>;
34
+ export declare function renderBrokerPromptContent(content: string, values: BrokerPromptTemplateValues): string;
@@ -0,0 +1,185 @@
1
+ import { promises as fs } from "node:fs";
2
+ import path from "node:path";
3
+ import { fileURLToPath } from "node:url";
4
+ import { TextDecoder } from "node:util";
5
+ import { probeGitContext } from "./git-metadata.js";
6
+ export const DEFAULT_BROKER_PROMPT_MAX_BYTES = 64 * 1024;
7
+ const decoder = new TextDecoder("utf-8", { fatal: true });
8
+ const moduleDir = path.dirname(fileURLToPath(import.meta.url));
9
+ function isWithinRoot(candidate, root) {
10
+ return candidate === root || candidate.startsWith(`${root}${path.sep}`);
11
+ }
12
+ function describeSource(source) {
13
+ switch (source) {
14
+ case "configured":
15
+ return "configured prompt";
16
+ case "workspace":
17
+ return "workspace override";
18
+ case "user":
19
+ return "user-local override";
20
+ case "packaged":
21
+ return "packaged default";
22
+ }
23
+ }
24
+ function warning(source, reason, detail) {
25
+ return {
26
+ source,
27
+ reason,
28
+ message: `broker prompt: ${describeSource(source)} rejected (${detail}); continuing`,
29
+ };
30
+ }
31
+ function resolveConfiguredBrokerPromptCandidate(configuredPrompt, options) {
32
+ const prompt = configuredPrompt?.trim();
33
+ if (!prompt) {
34
+ return null;
35
+ }
36
+ const hasPathSyntax = prompt.startsWith(".") ||
37
+ prompt.startsWith("~") ||
38
+ path.isAbsolute(prompt) ||
39
+ prompt.includes("/") ||
40
+ prompt.includes(path.sep);
41
+ if (!hasPathSyntax) {
42
+ const presetFile = prompt.endsWith(".md") ? prompt : `${prompt}.md`;
43
+ const presetPath = path.resolve(moduleDir, "prompts", "broker", presetFile);
44
+ return {
45
+ source: "configured",
46
+ path: presetPath,
47
+ root: path.resolve(path.dirname(path.dirname(path.dirname(presetPath)))),
48
+ required: true,
49
+ };
50
+ }
51
+ const expandedPath = prompt.startsWith("~/")
52
+ ? path.join(options.homeDir, prompt.slice(2))
53
+ : prompt;
54
+ const resolvedPath = path.isAbsolute(expandedPath)
55
+ ? path.resolve(expandedPath)
56
+ : path.resolve(options.workspaceRoot, expandedPath);
57
+ return {
58
+ source: "configured",
59
+ path: resolvedPath,
60
+ root: path.isAbsolute(expandedPath) ? path.dirname(resolvedPath) : options.workspaceRoot,
61
+ required: true,
62
+ };
63
+ }
64
+ export function resolveBrokerPromptCandidates(options = {}) {
65
+ const workspaceRoot = path.resolve(options.workspaceRoot ?? options.cwd ?? process.cwd());
66
+ const homeDir = path.resolve(options.homeDir ?? process.env.HOME ?? "");
67
+ const userRoot = path.join(homeDir, ".pi", "agent", "slack-bridge");
68
+ const defaultPromptPath = path.resolve(options.defaultPromptPath ?? path.join(moduleDir, "prompts", "broker", "tmux.md"));
69
+ const defaultRoot = path.resolve(path.dirname(path.dirname(path.dirname(defaultPromptPath))));
70
+ const packagedCandidates = [
71
+ {
72
+ source: "packaged",
73
+ path: defaultPromptPath,
74
+ root: defaultRoot,
75
+ required: true,
76
+ },
77
+ ];
78
+ const configuredCandidate = resolveConfiguredBrokerPromptCandidate(options.configuredPrompt, {
79
+ workspaceRoot,
80
+ homeDir,
81
+ });
82
+ return [
83
+ ...(configuredCandidate ? [configuredCandidate] : []),
84
+ {
85
+ source: "workspace",
86
+ path: path.join(workspaceRoot, ".pi", "slack-bridge", "tmux.md"),
87
+ root: workspaceRoot,
88
+ required: false,
89
+ },
90
+ {
91
+ source: "user",
92
+ path: path.join(userRoot, "tmux.md"),
93
+ root: userRoot,
94
+ required: false,
95
+ },
96
+ ...packagedCandidates,
97
+ ];
98
+ }
99
+ async function readValidCandidate(candidate, maxBytes) {
100
+ let realRoot;
101
+ let realPath;
102
+ try {
103
+ realRoot = await fs.realpath(candidate.root);
104
+ realPath = await fs.realpath(candidate.path);
105
+ }
106
+ catch (error) {
107
+ if (!candidate.required && error.code === "ENOENT") {
108
+ return null;
109
+ }
110
+ return { warning: warning(candidate.source, "unreadable", "unreadable") };
111
+ }
112
+ if (!isWithinRoot(realPath, realRoot)) {
113
+ return { warning: warning(candidate.source, "unsafe_path", "path escapes allowed root") };
114
+ }
115
+ let stat;
116
+ try {
117
+ stat = await fs.stat(realPath);
118
+ }
119
+ catch {
120
+ return { warning: warning(candidate.source, "unreadable", "unreadable") };
121
+ }
122
+ if (!stat.isFile()) {
123
+ return { warning: warning(candidate.source, "unreadable", "not a regular file") };
124
+ }
125
+ if (stat.size > maxBytes) {
126
+ return { warning: warning(candidate.source, "too_large", `over ${maxBytes} bytes`) };
127
+ }
128
+ let data;
129
+ try {
130
+ data = await fs.readFile(realPath);
131
+ }
132
+ catch {
133
+ return { warning: warning(candidate.source, "unreadable", "unreadable") };
134
+ }
135
+ let content;
136
+ try {
137
+ content = decoder.decode(data);
138
+ }
139
+ catch {
140
+ return { warning: warning(candidate.source, "invalid_utf8", "invalid UTF-8") };
141
+ }
142
+ if (content.includes("\0")) {
143
+ return { warning: warning(candidate.source, "invalid_utf8", "binary-looking content") };
144
+ }
145
+ const trimmed = content.trim();
146
+ if (trimmed.length === 0) {
147
+ return { warning: warning(candidate.source, "empty", "empty file") };
148
+ }
149
+ return { content: trimmed };
150
+ }
151
+ async function resolveDefaultWorkspaceRoot(options) {
152
+ if (options.workspaceRoot) {
153
+ return path.resolve(options.workspaceRoot);
154
+ }
155
+ const cwd = path.resolve(options.cwd ?? process.cwd());
156
+ const gitContext = await probeGitContext(cwd);
157
+ return path.resolve(gitContext.repoRoot ?? cwd);
158
+ }
159
+ export async function loadBrokerPrompt(options = {}) {
160
+ const warnings = [];
161
+ const maxBytes = options.maxBytes ?? DEFAULT_BROKER_PROMPT_MAX_BYTES;
162
+ const workspaceRoot = await resolveDefaultWorkspaceRoot(options);
163
+ for (const candidate of resolveBrokerPromptCandidates({ ...options, workspaceRoot })) {
164
+ const result = await readValidCandidate(candidate, maxBytes);
165
+ if (result === null) {
166
+ continue;
167
+ }
168
+ if ("warning" in result) {
169
+ warnings.push(result.warning);
170
+ continue;
171
+ }
172
+ return {
173
+ source: candidate.source,
174
+ content: result.content,
175
+ warnings,
176
+ diagnostic: `broker prompt: ${describeSource(candidate.source)} loaded`,
177
+ };
178
+ }
179
+ throw new Error("No valid broker prompt candidates found; packaged default is missing or invalid.");
180
+ }
181
+ export function renderBrokerPromptContent(content, values) {
182
+ return content
183
+ .replaceAll("{{agentEmoji}}", values.agentEmoji)
184
+ .replaceAll("{{agentName}}", values.agentName);
185
+ }
@@ -0,0 +1,14 @@
1
+ import type { Broker } from "./broker/index.js";
2
+ import type { BrokerDB } from "./broker/schema.js";
3
+ export interface BrokerRuntimeAccessDeps {
4
+ getBroker: () => Broker | null;
5
+ getSelfId: () => string | null;
6
+ getHomeTabViewerIds: () => string[];
7
+ }
8
+ export interface BrokerRuntimeAccess {
9
+ getActiveBroker: () => Broker | null;
10
+ getActiveBrokerDb: () => BrokerDB | null;
11
+ getActiveBrokerSelfId: () => string | null;
12
+ getBrokerControlPlaneHomeTabViewerIds: () => string[];
13
+ }
14
+ export declare function createBrokerRuntimeAccess(deps: BrokerRuntimeAccessDeps): BrokerRuntimeAccess;
@@ -0,0 +1,20 @@
1
+ export function createBrokerRuntimeAccess(deps) {
2
+ function getActiveBroker() {
3
+ return deps.getBroker();
4
+ }
5
+ function getActiveBrokerDb() {
6
+ return getActiveBroker()?.db ?? null;
7
+ }
8
+ function getActiveBrokerSelfId() {
9
+ return deps.getSelfId();
10
+ }
11
+ function getBrokerControlPlaneHomeTabViewerIds() {
12
+ return deps.getHomeTabViewerIds();
13
+ }
14
+ return {
15
+ getActiveBroker,
16
+ getActiveBrokerDb,
17
+ getActiveBrokerSelfId,
18
+ getBrokerControlPlaneHomeTabViewerIds,
19
+ };
20
+ }
@@ -0,0 +1,100 @@
1
+ import type { ExtensionContext } from "@earendil-works/pi-coding-agent";
2
+ import { type InboxMessage, type PinetControlCommand, type PinetRemoteControlRequestResult, type PinetSkinStatusVocabulary, type SlackBridgeSettings } from "./helpers.js";
3
+ import { type Broker } from "./broker/index.js";
4
+ import { MessageRouter } from "./broker/router.js";
5
+ import { type BrokerMaintenanceResult } from "./broker/maintenance.js";
6
+ import { type BrokerDeliveryState } from "./broker-delivery.js";
7
+ import type { InboundMessage } from "./broker/types.js";
8
+ import { type ActivityLogEntry, type ActivityLogTone, type LoggedActivityLogEntry, type SlackActivityLogger } from "./activity-log.js";
9
+ import type { BrokerControlPlaneDashboardSnapshot } from "./broker/control-plane-dashboard.js";
10
+ import { type RalphSnoozeStatus } from "./ralph-loop.js";
11
+ import { type PinetRuntimeAdapterFactory } from "./pinet-runtime-composition.js";
12
+ export interface BrokerRuntimeConnectResult {
13
+ botUserId: string | null;
14
+ recoveredBrokerMessages: number;
15
+ recoveredTargetedBacklogCount: number;
16
+ releasedBrokerClaims: number;
17
+ }
18
+ export interface BrokerRuntimeDeps {
19
+ getSettings: () => SlackBridgeSettings;
20
+ getAllowedUsers: () => Set<string> | null;
21
+ getBrokerStableId: () => string;
22
+ setBrokerStableId: (stableId: string) => void;
23
+ getActiveSkinTheme: () => string | null;
24
+ setActiveSkinTheme: (theme: string) => void;
25
+ setAgentOwnerToken: (ownerToken: string) => void;
26
+ getAgentMetadata: (role: "broker" | "worker") => Promise<Record<string, unknown>>;
27
+ applyLocalAgentIdentity: (name: string, emoji: string, personality: string | null) => void;
28
+ buildSkinMetadata: (metadata: Record<string, unknown> | undefined, personality: string, statusVocabulary?: PinetSkinStatusVocabulary) => Record<string, unknown>;
29
+ getMeshRoleFromMetadata: (metadata: Record<string, unknown> | undefined, fallback?: "broker" | "worker") => "broker" | "worker";
30
+ handleInboundMessage: (input: {
31
+ message: InboundMessage;
32
+ broker: Broker;
33
+ router: MessageRouter;
34
+ selfId: string;
35
+ ctx: ExtensionContext;
36
+ }) => Promise<void> | void;
37
+ pushInboxMessages: (messages: InboxMessage[]) => void;
38
+ updateBadge: () => void;
39
+ maybeDrainInboxIfIdle: (ctx: ExtensionContext) => boolean;
40
+ requestRemoteControl: (command: PinetControlCommand, ctx: ExtensionContext) => PinetRemoteControlRequestResult;
41
+ deferControlAck: (command: PinetControlCommand, inboxId: number) => void;
42
+ runRemoteControl: (command: PinetControlCommand, ctx: ExtensionContext) => void;
43
+ formatError: (error: unknown) => string;
44
+ deliveryState: BrokerDeliveryState;
45
+ onMaintenanceResult: (ctx: ExtensionContext, input: {
46
+ result: BrokerMaintenanceResult;
47
+ previousSignature: string;
48
+ signature: string;
49
+ }) => void;
50
+ onMaintenanceError: (ctx: ExtensionContext, error: unknown) => void;
51
+ onScheduledWakeupError: (ctx: ExtensionContext, error: unknown) => void;
52
+ onAgentStatusChange: (ctx: ExtensionContext, changedAgentId: string, status: "working" | "idle") => void;
53
+ createActivityLogger: (onError: (error: unknown) => void) => SlackActivityLogger;
54
+ formatTrackedAgent: (agentId: string) => string;
55
+ summarizeTrackedAssignmentStatus: (status: "assigned" | "branch_pushed" | "pr_open" | "pr_merged" | "pr_closed", prNumber: number | null, branch: string | null) => {
56
+ summary: string;
57
+ tone: ActivityLogTone;
58
+ };
59
+ sendMaintenanceMessage: (targetAgentId: string, body: string) => void;
60
+ trySendFollowUp: (body: string, onDelivered: () => void) => void;
61
+ refreshHomeTabs: (ctx: ExtensionContext, snapshot: BrokerControlPlaneDashboardSnapshot, refreshedAt: string, userIds?: string[]) => Promise<void>;
62
+ buildControlPlaneDashboardSnapshot: (input: Record<string, unknown>) => BrokerControlPlaneDashboardSnapshot;
63
+ buildCurrentDashboardSnapshot: (openedAt?: string) => Promise<BrokerControlPlaneDashboardSnapshot | null>;
64
+ createAdapterBindings: readonly PinetRuntimeAdapterFactory[];
65
+ }
66
+ export declare function resolveConfiguredBrokerSkinTheme(settings: SlackBridgeSettings): string;
67
+ export interface BrokerRuntime {
68
+ connect: (ctx: ExtensionContext) => Promise<BrokerRuntimeConnectResult>;
69
+ disconnect: (options?: {
70
+ releaseIdentity?: boolean;
71
+ }) => Promise<void>;
72
+ claimThread: (threadTs: string, channelId: string, source?: string) => void;
73
+ runMaintenance: (ctx: ExtensionContext) => void;
74
+ markDelivered: (inboxIds: number[]) => void;
75
+ startObservability: (ctx: ExtensionContext) => void;
76
+ clearFollowUpPending: () => void;
77
+ logActivity: (entry: ActivityLogEntry) => void;
78
+ getRecentActivityEntries: (limit?: number) => ReadonlyArray<LoggedActivityLogEntry>;
79
+ getBroker: () => Broker | null;
80
+ getSelfId: () => string | null;
81
+ getLastMaintenance: () => BrokerMaintenanceResult | null;
82
+ getRalphSnoozeStatus: () => RalphSnoozeStatus;
83
+ snoozeRalphLoop: (input: {
84
+ durationMs: number;
85
+ reason?: string | null;
86
+ }) => RalphSnoozeStatus;
87
+ clearRalphSnooze: () => RalphSnoozeStatus;
88
+ heartbeatTimerActive: () => boolean;
89
+ maintenanceTimerActive: () => boolean;
90
+ isConnected: () => boolean;
91
+ getHomeTabViewerIds: () => string[];
92
+ getLastHomeTabSnapshot: () => BrokerControlPlaneDashboardSnapshot | null;
93
+ setLastHomeTabSnapshot: (snapshot: BrokerControlPlaneDashboardSnapshot | null) => void;
94
+ getLastHomeTabRefreshAt: () => string | null;
95
+ setLastHomeTabRefreshAt: (value: string | null) => void;
96
+ getLastHomeTabError: () => string | null;
97
+ setLastHomeTabError: (value: string | null) => void;
98
+ publishCurrentHomeTabSafely: (userId: string, ctx: ExtensionContext, openedAt?: string) => Promise<boolean>;
99
+ }
100
+ export declare function createBrokerRuntime(deps: BrokerRuntimeDeps): BrokerRuntime;