lastlight 0.3.0 → 0.5.1

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 (87) hide show
  1. package/README.md +17 -6
  2. package/deploy/entrypoint.sh +21 -6
  3. package/deploy/sandbox-entrypoint.sh +1 -1
  4. package/dist/admin/routes.d.ts +5 -0
  5. package/dist/admin/routes.js +9 -0
  6. package/dist/admin/routes.js.map +1 -1
  7. package/dist/cli-server.d.ts +3 -1
  8. package/dist/cli-server.js +20 -2
  9. package/dist/cli-server.js.map +1 -1
  10. package/dist/cli.js +23 -2
  11. package/dist/cli.js.map +1 -1
  12. package/dist/config.d.ts +12 -1
  13. package/dist/config.js +26 -6
  14. package/dist/config.js.map +1 -1
  15. package/dist/connectors/messaging/base.js +22 -9
  16. package/dist/connectors/messaging/base.js.map +1 -1
  17. package/dist/connectors/slack/connector.d.ts +62 -9
  18. package/dist/connectors/slack/connector.js +216 -63
  19. package/dist/connectors/slack/connector.js.map +1 -1
  20. package/dist/connectors/slack/connector.test.d.ts +1 -0
  21. package/dist/connectors/slack/connector.test.js +135 -0
  22. package/dist/connectors/slack/connector.test.js.map +1 -0
  23. package/dist/connectors/types.d.ts +7 -0
  24. package/dist/engine/agent-executor.d.ts +32 -10
  25. package/dist/engine/agent-executor.js +239 -1
  26. package/dist/engine/agent-executor.js.map +1 -1
  27. package/dist/engine/agent-executor.seam.test.d.ts +1 -0
  28. package/dist/engine/agent-executor.seam.test.js +57 -0
  29. package/dist/engine/agent-executor.seam.test.js.map +1 -0
  30. package/dist/engine/dispatcher.d.ts +13 -0
  31. package/dist/engine/dispatcher.js +26 -7
  32. package/dist/engine/dispatcher.js.map +1 -1
  33. package/dist/engine/dispatcher.test.js.map +1 -1
  34. package/dist/engine/message-batcher.d.ts +32 -0
  35. package/dist/engine/message-batcher.js +109 -0
  36. package/dist/engine/message-batcher.js.map +1 -0
  37. package/dist/engine/message-batcher.test.d.ts +1 -0
  38. package/dist/engine/message-batcher.test.js +109 -0
  39. package/dist/engine/message-batcher.test.js.map +1 -0
  40. package/dist/engine/profiles.d.ts +9 -0
  41. package/dist/engine/profiles.js.map +1 -1
  42. package/dist/evals-api.d.ts +24 -0
  43. package/dist/evals-api.js +22 -0
  44. package/dist/evals-api.js.map +1 -0
  45. package/dist/fork-cli.d.ts +30 -0
  46. package/dist/fork-cli.js +240 -0
  47. package/dist/fork-cli.js.map +1 -0
  48. package/dist/fork-cli.test.d.ts +1 -0
  49. package/dist/fork-cli.test.js +109 -0
  50. package/dist/fork-cli.test.js.map +1 -0
  51. package/dist/index.js +43 -4
  52. package/dist/index.js.map +1 -1
  53. package/dist/overlay-assets.d.ts +20 -0
  54. package/dist/overlay-assets.js +114 -0
  55. package/dist/overlay-assets.js.map +1 -0
  56. package/dist/overlay-assets.test.d.ts +1 -0
  57. package/dist/overlay-assets.test.js +75 -0
  58. package/dist/overlay-assets.test.js.map +1 -0
  59. package/dist/sandbox/command-exec.integration.test.d.ts +1 -0
  60. package/dist/sandbox/command-exec.integration.test.js +183 -0
  61. package/dist/sandbox/command-exec.integration.test.js.map +1 -0
  62. package/dist/sandbox/docker.d.ts +32 -0
  63. package/dist/sandbox/docker.js +109 -4
  64. package/dist/sandbox/docker.js.map +1 -1
  65. package/dist/setup.js +9 -44
  66. package/dist/setup.js.map +1 -1
  67. package/dist/workflows/loader.test.js +83 -0
  68. package/dist/workflows/loader.test.js.map +1 -1
  69. package/dist/workflows/phase-executor.d.ts +28 -3
  70. package/dist/workflows/phase-executor.js +170 -45
  71. package/dist/workflows/phase-executor.js.map +1 -1
  72. package/dist/workflows/phase-executor.test.js +64 -1
  73. package/dist/workflows/phase-executor.test.js.map +1 -1
  74. package/dist/workflows/runner.test.js +32 -27
  75. package/dist/workflows/runner.test.js.map +1 -1
  76. package/dist/workflows/schema.d.ts +20 -0
  77. package/dist/workflows/schema.js +72 -2
  78. package/dist/workflows/schema.js.map +1 -1
  79. package/package.json +12 -2
  80. package/sandbox.Dockerfile +7 -0
  81. package/skills/browser-qa/scripts/agent-browser.mjs +15 -0
  82. package/skills/demo/SKILL.md +45 -19
  83. package/skills/demo/scripts/compose-demo.sh +77 -39
  84. package/workflows/examples/bash-smoke.yaml +41 -0
  85. package/workflows/prompts/demo.md +27 -5
  86. package/workflows/qa-test.yaml +1 -1
  87. package/workflows/verify.yaml +1 -1
@@ -1,4 +1,6 @@
1
1
  import { App } from "@slack/bolt";
2
+ import { WebClient } from "@slack/web-api";
3
+ import { createHmac, timingSafeEqual } from "crypto";
2
4
  import { MessagingConnector } from "../messaging/base.js";
3
5
  import { markdownToSlackMrkdwn } from "./mrkdwn.js";
4
6
  /** Rotating status messages shown while the agent is thinking */
@@ -15,38 +17,77 @@ const THINKING_MESSAGES = [
15
17
  "Almost there...",
16
18
  ];
17
19
  /**
18
- * Slack connector using Socket Mode (WebSocket, no public URL needed).
20
+ * Slack connector. Two receive modes:
21
+ *
22
+ * - **webhook** (default/prod): the HTTP Events API. Slack POSTs to
23
+ * `/webhooks/slack`; we verify the signing-secret signature, answer the
24
+ * one-time url_verification handshake, dedup retries by `event_id`, and ack
25
+ * within Slack's 3s window while processing async. Slack retries failed
26
+ * deliveries, so this is at-least-once — it does not silently drop messages
27
+ * the way Socket Mode does.
28
+ * - **socket** (dev fallback): Socket Mode over a WebSocket, no public URL
29
+ * needed. At-most-once; kept only for local development.
30
+ *
31
+ * Sending is identical in both modes via a `WebClient`.
19
32
  *
20
33
  * Behaviors:
21
- * - DMs: responds to every message
22
- * - Channels: only responds when @mentioned, replies in threads
23
- * - Supports multi-turn conversations via SessionManager
34
+ * - DMs: responds to every message (subscribe `message.im` in webhook mode)
35
+ * - Channels: only responds when @mentioned (subscribe `app_mention`)
24
36
  */
25
37
  export class SlackConnector extends MessagingConnector {
26
38
  name = "slack";
27
- app;
39
+ /** Web API client for sending — used in both modes. */
40
+ web;
41
+ /** Bolt app — constructed only in socket mode, purely as the receiver. */
42
+ bolt = null;
28
43
  slackConfig;
29
44
  userCache = new Map(); // userId → username
45
+ /** Bounded set of processed Events API delivery ids, to drop Slack retries. */
46
+ seenEventIds = new Set();
47
+ seenEventOrder = [];
30
48
  constructor(config, sessionManager) {
31
49
  super(config, sessionManager);
32
50
  this.slackConfig = config;
33
- this.app = new App({
34
- token: config.botToken,
35
- appToken: config.appToken,
36
- socketMode: true,
37
- });
38
- this.setupListeners();
51
+ this.web = new WebClient(config.botToken);
52
+ if (config.mode === "socket") {
53
+ if (!config.appToken)
54
+ throw new Error("[slack] socket mode requires appToken");
55
+ this.bolt = new App({
56
+ token: config.botToken,
57
+ appToken: config.appToken,
58
+ socketMode: true,
59
+ });
60
+ this.setupSocketListeners();
61
+ }
62
+ else {
63
+ if (!config.honoApp) {
64
+ throw new Error("[slack] webhook mode requires an HTTP server to mount /webhooks/slack on " +
65
+ "(none available — is the GitHub webhook connector configured?). " +
66
+ "Set SLACK_MODE=socket for a standalone Slack deployment.");
67
+ }
68
+ if (!config.signingSecret)
69
+ throw new Error("[slack] webhook mode requires signingSecret");
70
+ this.mountWebhookRoute(config.honoApp);
71
+ }
39
72
  }
40
73
  async start() {
41
- await this.app.start();
42
- console.log(`[slack] Connected via Socket Mode`);
74
+ if (this.bolt) {
75
+ await this.bolt.start();
76
+ console.log(`[slack] Connected via Socket Mode`);
77
+ }
78
+ else {
79
+ console.log(`[slack] Listening via HTTP Events API at /webhooks/slack`);
80
+ }
43
81
  }
44
82
  async stop() {
45
- await this.app.stop();
46
- console.log(`[slack] Disconnected`);
83
+ if (this.bolt) {
84
+ await this.bolt.stop();
85
+ console.log(`[slack] Disconnected`);
86
+ }
87
+ // Webhook mode shares the GitHub connector's HTTP server; nothing to stop.
47
88
  }
48
89
  async sendMessage(channelId, threadId, text) {
49
- const result = await this.app.client.chat.postMessage({
90
+ const result = await this.web.chat.postMessage({
50
91
  channel: channelId,
51
92
  text: markdownToSlackMrkdwn(text),
52
93
  thread_ts: threadId || undefined,
@@ -62,7 +103,7 @@ export class SlackConnector extends MessagingConnector {
62
103
  * at the end for an actual ping.
63
104
  */
64
105
  async updateMessage(channelId, ts, text) {
65
- await this.app.client.chat.update({
106
+ await this.web.chat.update({
66
107
  channel: channelId,
67
108
  ts,
68
109
  text: markdownToSlackMrkdwn(text),
@@ -70,7 +111,7 @@ export class SlackConnector extends MessagingConnector {
70
111
  }
71
112
  async addReaction(channelId, messageId, emoji) {
72
113
  try {
73
- await this.app.client.reactions.add({
114
+ await this.web.reactions.add({
74
115
  channel: channelId,
75
116
  timestamp: messageId,
76
117
  name: emoji,
@@ -85,7 +126,7 @@ export class SlackConnector extends MessagingConnector {
85
126
  // thread_ts MUST be the thread root — passing the new reply's ts in an
86
127
  // existing thread silently errors and the indicator never shows.
87
128
  try {
88
- await this.app.client.assistant.threads.setStatus({
129
+ await this.web.assistant.threads.setStatus({
89
130
  channel_id: channelId,
90
131
  thread_ts: threadRootId,
91
132
  status: "Thinking...",
@@ -101,7 +142,7 @@ export class SlackConnector extends MessagingConnector {
101
142
  /** Clear the thinking status after processing completes */
102
143
  async clearTyping(channelId, threadId) {
103
144
  try {
104
- await this.app.client.assistant.threads.setStatus({
145
+ await this.web.assistant.threads.setStatus({
105
146
  channel_id: channelId,
106
147
  thread_ts: threadId,
107
148
  status: "",
@@ -122,51 +163,137 @@ export class SlackConnector extends MessagingConnector {
122
163
  await this.sendMessage(this.slackConfig.deliveryChannel, null, chunk);
123
164
  }
124
165
  }
125
- setupListeners() {
166
+ // ── Webhook (HTTP Events API) receiver ─────────────────────────────────
167
+ /**
168
+ * Mount `POST /webhooks/slack` on the shared Hono app. Verifies the request
169
+ * signature, handles the url_verification handshake, dedups retries, and
170
+ * acks fast while processing the event asynchronously.
171
+ */
172
+ mountWebhookRoute(app) {
173
+ app.post("/webhooks/slack", async (c) => {
174
+ const body = await c.req.text();
175
+ const timestamp = c.req.header("x-slack-request-timestamp") || "";
176
+ const signature = c.req.header("x-slack-signature") || "";
177
+ if (!verifySlackSignature(body, timestamp, signature, this.slackConfig.signingSecret)) {
178
+ return c.json({ error: "Invalid signature" }, 401);
179
+ }
180
+ let payload;
181
+ try {
182
+ payload = JSON.parse(body);
183
+ }
184
+ catch {
185
+ return c.json({ error: "Invalid JSON" }, 400);
186
+ }
187
+ // One-time handshake when (re)configuring the Request URL in the Slack app.
188
+ if (payload.type === "url_verification") {
189
+ return c.json({ challenge: payload.challenge });
190
+ }
191
+ if (payload.type === "event_callback") {
192
+ const eventId = typeof payload.event_id === "string" ? payload.event_id : undefined;
193
+ // Slack retries on any non-200 / >3s; dedup so a retry of an event we
194
+ // already accepted is a no-op rather than a double-processed message.
195
+ if (eventId && this.markSeen(eventId)) {
196
+ return c.body(null, 200);
197
+ }
198
+ const event = payload.event;
199
+ // Ack immediately, process async — never hold the response past 3s or
200
+ // Slack will retry (and we'd handle it twice if it slipped past dedup).
201
+ setImmediate(() => {
202
+ this.dispatchSlackEvent(event).catch((err) => console.error("[slack] event handler error:", err));
203
+ });
204
+ }
205
+ return c.body(null, 200);
206
+ });
207
+ }
208
+ /** Route a raw Events API `event` object to the right handler. */
209
+ async dispatchSlackEvent(event) {
210
+ if (!event || typeof event !== "object")
211
+ return;
212
+ if (event.type === "message") {
213
+ await this.onMessageEvent(event);
214
+ }
215
+ else if (event.type === "app_mention") {
216
+ await this.onAppMention(event);
217
+ }
218
+ }
219
+ /**
220
+ * Record an Events API delivery id as seen. Returns true if it was already
221
+ * seen (a Slack retry). Bounded to the most recent ~1000 ids.
222
+ */
223
+ markSeen(eventId) {
224
+ if (this.seenEventIds.has(eventId))
225
+ return true;
226
+ this.seenEventIds.add(eventId);
227
+ this.seenEventOrder.push(eventId);
228
+ if (this.seenEventOrder.length > 1000) {
229
+ const evicted = this.seenEventOrder.shift();
230
+ if (evicted)
231
+ this.seenEventIds.delete(evicted);
232
+ }
233
+ return false;
234
+ }
235
+ // ── Socket Mode receiver (dev fallback) ────────────────────────────────
236
+ setupSocketListeners() {
126
237
  // Handle all message events (DMs, channels, groups)
127
- this.app.message(async ({ message }) => {
128
- // Filter out non-standard message subtypes (edits, deletes, joins, etc.)
129
- const msg = message;
130
- if (msg.subtype)
131
- return;
132
- if (!msg.user || !msg.text)
133
- return;
134
- // Ignore bot messages
135
- if (msg.bot_id)
136
- return;
137
- const username = await this.resolveUsername(msg.user);
138
- const isDM = msg.channel_type === "im";
139
- const isMention = this.config.botIdentifier
140
- ? msg.text.includes(`<@${this.config.botIdentifier}>`)
141
- : false;
142
- await this.handleIncomingMessage({
143
- platformUserId: msg.user,
144
- platformUsername: username,
145
- channelId: msg.channel,
146
- threadId: msg.thread_ts || null,
147
- messageId: msg.ts,
148
- text: msg.text,
149
- isDM,
150
- isMention,
151
- raw: msg,
152
- });
238
+ this.bolt.message(async ({ message }) => {
239
+ await this.onMessageEvent(message);
153
240
  });
154
241
  // Handle explicit @mentions (app_mention event)
155
- this.app.event("app_mention", async ({ event }) => {
156
- if (!event.user || !event.text)
157
- return;
158
- const username = await this.resolveUsername(event.user);
159
- await this.handleIncomingMessage({
160
- platformUserId: event.user,
161
- platformUsername: username,
162
- channelId: event.channel,
163
- threadId: event.thread_ts || null,
164
- messageId: event.ts,
165
- text: event.text,
166
- isDM: false,
167
- isMention: true,
168
- raw: event,
169
- });
242
+ this.bolt.event("app_mention", async ({ event }) => {
243
+ await this.onAppMention(event);
244
+ });
245
+ }
246
+ // ── Shared event handling (both modes feed these) ──────────────────────
247
+ /** A raw Slack `message` event (DM or channel). */
248
+ async onMessageEvent(msg) {
249
+ // Log EVERY inbound message before any filtering. When a DM looks like it
250
+ // "dropped" messages, this line tells us whether Slack delivered the event
251
+ // at all and, if so, why we ignored it (a subtype like message_changed, a
252
+ // bot_id, or empty text) — versus Slack never sending it.
253
+ console.log(`[slack] inbound msg ch=${msg.channel ?? "-"} ts=${msg.ts ?? "-"} ` +
254
+ `thread_ts=${msg.thread_ts ?? "-"} subtype=${msg.subtype ?? "-"} ` +
255
+ `bot_id=${msg.bot_id ?? "-"} channel_type=${msg.channel_type ?? "-"} ` +
256
+ `user=${msg.user ?? "-"} hasText=${msg.text ? "y" : "n"}`);
257
+ // Filter out non-standard message subtypes (edits, deletes, joins, etc.)
258
+ if (msg.subtype)
259
+ return;
260
+ if (!msg.user || !msg.text)
261
+ return;
262
+ // Ignore bot messages
263
+ if (msg.bot_id)
264
+ return;
265
+ const username = await this.resolveUsername(msg.user);
266
+ const isDM = msg.channel_type === "im";
267
+ const isMention = this.config.botIdentifier
268
+ ? msg.text.includes(`<@${this.config.botIdentifier}>`)
269
+ : false;
270
+ await this.handleIncomingMessage({
271
+ platformUserId: msg.user,
272
+ platformUsername: username,
273
+ channelId: msg.channel,
274
+ threadId: msg.thread_ts || null,
275
+ messageId: msg.ts,
276
+ text: msg.text,
277
+ isDM,
278
+ isMention,
279
+ raw: msg,
280
+ });
281
+ }
282
+ /** A raw Slack `app_mention` event (always a channel mention). */
283
+ async onAppMention(event) {
284
+ if (!event.user || !event.text)
285
+ return;
286
+ const username = await this.resolveUsername(event.user);
287
+ await this.handleIncomingMessage({
288
+ platformUserId: event.user,
289
+ platformUsername: username,
290
+ channelId: event.channel,
291
+ threadId: event.thread_ts || null,
292
+ messageId: event.ts,
293
+ text: event.text,
294
+ isDM: false,
295
+ isMention: true,
296
+ raw: event,
170
297
  });
171
298
  }
172
299
  /** Resolve a Slack user ID to a username (cached) */
@@ -175,7 +302,7 @@ export class SlackConnector extends MessagingConnector {
175
302
  if (cached)
176
303
  return cached;
177
304
  try {
178
- const result = await this.app.client.users.info({ user: userId });
305
+ const result = await this.web.users.info({ user: userId });
179
306
  const username = result.user?.name || result.user?.real_name || userId;
180
307
  this.userCache.set(userId, username);
181
308
  return username;
@@ -185,4 +312,30 @@ export class SlackConnector extends MessagingConnector {
185
312
  }
186
313
  }
187
314
  }
315
+ /**
316
+ * Verify a Slack Events API request signature.
317
+ *
318
+ * Slack signs `v0:{timestamp}:{rawBody}` with the app's signing secret and
319
+ * sends it as `x-slack-signature: v0=…`. We recompute and compare in constant
320
+ * time, and reject requests whose timestamp is more than 5 minutes off (replay
321
+ * protection). `now` is injectable for tests. Exported for unit testing.
322
+ */
323
+ export function verifySlackSignature(body, timestamp, signature, signingSecret, now = Date.now()) {
324
+ if (!timestamp || !signature || !signingSecret)
325
+ return false;
326
+ const ts = Number.parseInt(timestamp, 10);
327
+ if (!Number.isFinite(ts))
328
+ return false;
329
+ if (Math.abs(now / 1000 - ts) > 300)
330
+ return false; // 5-minute replay window
331
+ const expected = "v0=" + createHmac("sha256", signingSecret)
332
+ .update(`v0:${timestamp}:${body}`)
333
+ .digest("hex");
334
+ try {
335
+ return timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
336
+ }
337
+ catch {
338
+ return false;
339
+ }
340
+ }
188
341
  //# sourceMappingURL=connector.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"connector.js","sourceRoot":"","sources":["../../../src/connectors/slack/connector.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"connector.js","sourceRoot":"","sources":["../../../src/connectors/slack/connector.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,135 @@
1
+ import { describe, it, expect, beforeEach, afterEach } from "vitest";
2
+ import { createHmac } from "crypto";
3
+ import { Hono } from "hono";
4
+ import Database from "better-sqlite3";
5
+ import { SlackConnector, verifySlackSignature } from "./connector.js";
6
+ import { SessionManager } from "../messaging/session-manager.js";
7
+ function sign(secret, ts, body) {
8
+ return "v0=" + createHmac("sha256", secret).update(`v0:${ts}:${body}`).digest("hex");
9
+ }
10
+ describe("verifySlackSignature", () => {
11
+ const secret = "shhh-signing-secret";
12
+ const body = JSON.stringify({ type: "event_callback", event: { type: "message" } });
13
+ const now = 1_700_000_000_000; // fixed clock (ms)
14
+ const ts = String(Math.floor(now / 1000));
15
+ it("accepts a correctly signed, fresh request", () => {
16
+ expect(verifySlackSignature(body, ts, sign(secret, ts, body), secret, now)).toBe(true);
17
+ });
18
+ it("rejects a signature made with the wrong secret", () => {
19
+ expect(verifySlackSignature(body, ts, sign("other-secret", ts, body), secret, now)).toBe(false);
20
+ });
21
+ it("rejects a tampered body", () => {
22
+ expect(verifySlackSignature(body + "x", ts, sign(secret, ts, body), secret, now)).toBe(false);
23
+ });
24
+ it("rejects a stale timestamp (replay protection)", () => {
25
+ const stale = String(Math.floor(now / 1000) - 600); // 10 minutes old
26
+ expect(verifySlackSignature(body, stale, sign(secret, stale, body), secret, now)).toBe(false);
27
+ });
28
+ it("rejects missing signature or timestamp", () => {
29
+ expect(verifySlackSignature(body, "", "", secret, now)).toBe(false);
30
+ expect(verifySlackSignature(body, ts, "", secret, now)).toBe(false);
31
+ });
32
+ });
33
+ describe("SlackConnector webhook receiver", () => {
34
+ const secret = "shhh-signing-secret";
35
+ let app;
36
+ let conn;
37
+ let db;
38
+ let events;
39
+ function headers(body) {
40
+ const ts = String(Math.floor(Date.now() / 1000));
41
+ return {
42
+ "content-type": "application/json",
43
+ "x-slack-request-timestamp": ts,
44
+ "x-slack-signature": sign(secret, ts, body),
45
+ };
46
+ }
47
+ const post = (body, hdrs) => app.request("/webhooks/slack", { method: "POST", headers: hdrs ?? headers(body), body });
48
+ beforeEach(() => {
49
+ app = new Hono();
50
+ db = new Database(":memory:");
51
+ const sm = new SessionManager(db);
52
+ conn = new SlackConnector({
53
+ botToken: "xoxb-test",
54
+ mode: "webhook",
55
+ signingSecret: secret,
56
+ honoApp: app,
57
+ allowedUsers: [],
58
+ botIdentifier: "",
59
+ }, sm);
60
+ // Stub the Web API client so nothing hits the network during processing.
61
+ conn.web = {
62
+ users: { info: async () => ({ user: { name: "alice" } }) },
63
+ assistant: { threads: { setStatus: async () => { } } },
64
+ reactions: { add: async () => { } },
65
+ chat: { postMessage: async () => ({ ts: "x" }), update: async () => { } },
66
+ };
67
+ events = [];
68
+ conn.on("event", (e) => events.push(e));
69
+ });
70
+ afterEach(() => db.close());
71
+ it("answers the url_verification handshake", async () => {
72
+ const body = JSON.stringify({ type: "url_verification", challenge: "abc123" });
73
+ const res = await post(body);
74
+ expect(res.status).toBe(200);
75
+ expect(await res.json()).toEqual({ challenge: "abc123" });
76
+ });
77
+ it("rejects a request with a bad signature", async () => {
78
+ const body = JSON.stringify({ type: "url_verification", challenge: "x" });
79
+ const res = await post(body, {
80
+ "content-type": "application/json",
81
+ "x-slack-request-timestamp": String(Math.floor(Date.now() / 1000)),
82
+ "x-slack-signature": "v0=deadbeef",
83
+ });
84
+ expect(res.status).toBe(401);
85
+ });
86
+ it("acks and emits an EventEnvelope for a DM message event", async () => {
87
+ const body = JSON.stringify({
88
+ type: "event_callback",
89
+ event_id: "Ev1",
90
+ event: { type: "message", channel: "D1", channel_type: "im", user: "U1", ts: "1.1", text: "hello" },
91
+ });
92
+ const res = await post(body);
93
+ expect(res.status).toBe(200);
94
+ // Processing is async (setImmediate) — let it run.
95
+ await new Promise((r) => setImmediate(r));
96
+ await new Promise((r) => setImmediate(r));
97
+ expect(events).toHaveLength(1);
98
+ expect(events[0].source).toBe("slack");
99
+ expect(events[0].body).toBe("hello");
100
+ });
101
+ it("dedupes Slack retries by event_id", async () => {
102
+ const body = JSON.stringify({
103
+ type: "event_callback",
104
+ event_id: "Ev-dup",
105
+ event: { type: "message", channel: "D1", channel_type: "im", user: "U1", ts: "2.2", text: "once" },
106
+ });
107
+ expect((await post(body)).status).toBe(200);
108
+ await new Promise((r) => setImmediate(r));
109
+ await new Promise((r) => setImmediate(r));
110
+ expect(events).toHaveLength(1);
111
+ // Same event_id again (a Slack retry) → acked but NOT reprocessed.
112
+ expect((await post(body)).status).toBe(200);
113
+ await new Promise((r) => setImmediate(r));
114
+ await new Promise((r) => setImmediate(r));
115
+ expect(events).toHaveLength(1);
116
+ });
117
+ it("ignores message subtypes and bot messages", async () => {
118
+ const edited = JSON.stringify({
119
+ type: "event_callback",
120
+ event_id: "Ev2",
121
+ event: { type: "message", subtype: "message_changed", channel: "D1", channel_type: "im", user: "U1", ts: "3.3", text: "edit" },
122
+ });
123
+ const bot = JSON.stringify({
124
+ type: "event_callback",
125
+ event_id: "Ev3",
126
+ event: { type: "message", channel: "D1", channel_type: "im", bot_id: "B1", ts: "4.4", text: "from a bot" },
127
+ });
128
+ await post(edited);
129
+ await post(bot);
130
+ await new Promise((r) => setImmediate(r));
131
+ await new Promise((r) => setImmediate(r));
132
+ expect(events).toHaveLength(0);
133
+ });
134
+ });
135
+ //# sourceMappingURL=connector.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connector.test.js","sourceRoot":"","sources":["../../../src/connectors/slack/connector.test.ts"],"names":[],"mappings":"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"}
@@ -33,6 +33,13 @@ export interface EventEnvelope {
33
33
  raw: unknown;
34
34
  /** Reply on the same platform/thread */
35
35
  reply: (msg: string) => Promise<void>;
36
+ /**
37
+ * Re-assert a "thinking" indicator for this thread, if the platform has one.
38
+ * Called at the start of each turn so a batched burst that drains as multiple
39
+ * turns shows the indicator for every turn — the per-arrival show is cleared
40
+ * by the first turn's reply. No-op for sources without an indicator (CLI).
41
+ */
42
+ typing?: () => Promise<void>;
36
43
  /** Timestamp of the event */
37
44
  timestamp: Date;
38
45
  }
@@ -34,16 +34,6 @@ export declare function stageSkillBundle(workspaceRoot: string, phaseKey: string
34
34
  * sibling. No-op when `repoDir` isn't a git checkout (e.g. the workspace root).
35
35
  */
36
36
  export declare function excludeFromGit(repoDir: string, entry: string): void;
37
- /**
38
- * Execute one workflow-phase agent task via agentic-pi.
39
- *
40
- * Sandbox backend (decided per call):
41
- * 1. gondolin — agentic-pi's QEMU micro-VM. cwd is the host worktree,
42
- * mounted at /workspace inside the VM.
43
- * 2. docker — the legacy container path (`src/sandbox/docker.ts`). The
44
- * entrypoint inside the container execs `agentic-pi run --sandbox none`.
45
- * 3. none — agentic-pi in-process with cwd = the host worktree.
46
- */
47
37
  export declare function executeAgent(prompt: string, config: ExecutorConfig, opts?: {
48
38
  taskId?: string;
49
39
  /**
@@ -54,6 +44,37 @@ export declare function executeAgent(prompt: string, config: ExecutorConfig, opt
54
44
  onSessionId?: (sessionId: string) => void;
55
45
  githubAccess?: GitSandboxAccess;
56
46
  }): Promise<ExecutionResult>;
47
+ /** What a command phase runs. */
48
+ export type CommandSpec = {
49
+ kind: "bash";
50
+ command: string;
51
+ } | {
52
+ kind: "script";
53
+ script: string;
54
+ runtime: "js" | "ts" | "python";
55
+ name: string;
56
+ };
57
+ /**
58
+ * Execute a deterministic command/script. Mirrors {@link executeDocker} /
59
+ * {@link executeInProcess} for sandbox setup but runs `runCommand` (docker) or
60
+ * `spawnSync` (gondolin/none) instead of an agent, and writes a session jsonl
61
+ * so the output is visible in the dashboard + CLI.
62
+ */
63
+ export declare function executeCommand(spec: CommandSpec, config: ExecutorConfig, opts?: {
64
+ taskId?: string;
65
+ githubAccess?: GitSandboxAccess;
66
+ /** Per-step timeout in seconds. */
67
+ timeoutSeconds?: number;
68
+ /** Extra env forwarded into the command (e.g. upstream phase outputs). */
69
+ sandboxEnv?: Record<string, string>;
70
+ onSessionId?: (sessionId: string) => void;
71
+ /**
72
+ * Mirror the command output to a session jsonl (visible in the dashboard +
73
+ * CLI). Default true. Set false for internal checks like `until_bash` that
74
+ * shouldn't create a user-facing session log.
75
+ */
76
+ writeSession?: boolean;
77
+ }): Promise<ExecutionResult>;
57
78
  /**
58
79
  * Build a RunResult-shaped tally from the JSONL event stream emitted by
59
80
  * `agentic-pi run` inside the docker sandbox. Mirrors what agentic-pi's
@@ -75,6 +96,7 @@ export declare class RunResultAccumulator {
75
96
  private finalText;
76
97
  private agentEnded;
77
98
  private toolErrors;
99
+ private maxStepsReached;
78
100
  private lastToolError?;
79
101
  private lastAssistantHadToolCall;
80
102
  private fatalError?;