@cursor/july 0.1.7 → 0.1.8

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 (173) hide show
  1. package/dist/bin/agent-serve.js +31 -2
  2. package/dist/channels/slack/channel-watch.d.ts +6 -1
  3. package/dist/channels/slack/channel-watch.d.ts.map +1 -1
  4. package/dist/channels/slack/channel-watch.js +22 -1
  5. package/dist/channels/slack/cursor-account.d.ts +4 -0
  6. package/dist/channels/slack/cursor-account.d.ts.map +1 -1
  7. package/dist/channels/slack/cursor-account.js +12 -2
  8. package/dist/channels/slack/defaults.d.ts +10 -5
  9. package/dist/channels/slack/defaults.d.ts.map +1 -1
  10. package/dist/channels/slack/defaults.js +39 -17
  11. package/dist/channels/slack/dispatch.d.ts +18 -0
  12. package/dist/channels/slack/dispatch.d.ts.map +1 -1
  13. package/dist/channels/slack/dispatch.js +141 -38
  14. package/dist/channels/slack/inbound.d.ts +13 -3
  15. package/dist/channels/slack/inbound.d.ts.map +1 -1
  16. package/dist/channels/slack/inbound.js +17 -9
  17. package/dist/channels/slack/index.d.ts +4 -0
  18. package/dist/channels/slack/index.d.ts.map +1 -1
  19. package/dist/channels/slack/index.js +4 -0
  20. package/dist/channels/slack/live-delivery.d.ts.map +1 -1
  21. package/dist/channels/slack/live-delivery.js +1 -0
  22. package/dist/channels/slack/manifest.d.ts.map +1 -1
  23. package/dist/channels/slack/manifest.js +3 -0
  24. package/dist/channels/slack/nudge-carrier.d.ts +19 -0
  25. package/dist/channels/slack/nudge-carrier.d.ts.map +1 -0
  26. package/dist/channels/slack/nudge-carrier.js +166 -0
  27. package/dist/channels/slack/nudge-store.d.ts +61 -0
  28. package/dist/channels/slack/nudge-store.d.ts.map +1 -0
  29. package/dist/channels/slack/nudge-store.js +266 -0
  30. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  31. package/dist/channels/slack/slack-channel.js +74 -25
  32. package/dist/channels/slack/stop.d.ts +14 -0
  33. package/dist/channels/slack/stop.d.ts.map +1 -0
  34. package/dist/channels/slack/stop.js +22 -0
  35. package/dist/channels/slack/thread-context.d.ts +81 -0
  36. package/dist/channels/slack/thread-context.d.ts.map +1 -0
  37. package/dist/channels/slack/thread-context.js +470 -0
  38. package/dist/channels/slack/types.d.ts +27 -0
  39. package/dist/channels/slack/types.d.ts.map +1 -1
  40. package/dist/docs/404.html +2 -2
  41. package/dist/docs/ab.html +4 -4
  42. package/dist/docs/assets/{app.COTN7wgo.js → app.BP8mAVMW.js} +1 -1
  43. package/dist/docs/assets/chunks/@localSearchIndexroot.DevOabKJ.js +1 -0
  44. package/dist/docs/assets/chunks/{VPLocalSearchBox.BW3TBdT0.js → VPLocalSearchBox.1FXIZbz8.js} +1 -1
  45. package/dist/docs/assets/chunks/{theme.BEJW0vE7.js → theme.Dm1R02v9.js} +2 -2
  46. package/dist/docs/assets/example-agents_index.md.CwtWu5ix.js +2 -0
  47. package/dist/docs/assets/{example-agents_index.md.CRqJlnIf.lean.js → example-agents_index.md.CwtWu5ix.lean.js} +1 -1
  48. package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.js +10 -0
  49. package/dist/docs/assets/example-agents_oncall.md.BG_sUMly.lean.js +1 -0
  50. package/dist/docs/assets/{guides_slack.md.CCwqHvSV.js → guides_slack.md.FWale6Ip.js} +4 -3
  51. package/dist/docs/assets/{guides_slack.md.CCwqHvSV.lean.js → guides_slack.md.FWale6Ip.lean.js} +1 -1
  52. package/dist/docs/assets/{reference_sessions.md.DdjWabnN.js → reference_sessions.md.DLd6mvbv.js} +2 -2
  53. package/dist/docs/assets/{reference_sessions.md.DdjWabnN.lean.js → reference_sessions.md.DLd6mvbv.lean.js} +1 -1
  54. package/dist/docs/assets/{storage.md.CVnInNiN.js → storage.md.Cu3MwM2a.js} +3 -2
  55. package/dist/docs/assets/{storage.md.CVnInNiN.lean.js → storage.md.Cu3MwM2a.lean.js} +1 -1
  56. package/dist/docs/building-with-agents.html +4 -4
  57. package/dist/docs/concepts.html +4 -4
  58. package/dist/docs/deployment.html +4 -4
  59. package/dist/docs/evals.html +4 -4
  60. package/dist/docs/example-agents/approval-buddy.html +4 -4
  61. package/dist/docs/example-agents/benny.html +5 -5
  62. package/dist/docs/example-agents/bugbot.html +5 -5
  63. package/dist/docs/example-agents/codebase-wiki.html +4 -4
  64. package/dist/docs/example-agents/codeowners-review.html +4 -4
  65. package/dist/docs/example-agents/concierge.html +4 -4
  66. package/dist/docs/example-agents/fsd.html +4 -4
  67. package/dist/docs/example-agents/index.html +6 -6
  68. package/dist/docs/example-agents/knowledge-base.html +4 -4
  69. package/dist/docs/example-agents/oncall.html +34 -0
  70. package/dist/docs/example-agents/security-reviewer.html +4 -4
  71. package/dist/docs/example-agents/slack-agent.html +4 -4
  72. package/dist/docs/example-agents/weather-agent.html +4 -4
  73. package/dist/docs/guides/agent-to-agent.html +4 -4
  74. package/dist/docs/guides/cloud-runtime.html +4 -4
  75. package/dist/docs/guides/github.html +4 -4
  76. package/dist/docs/guides/human-in-the-loop.html +4 -4
  77. package/dist/docs/guides/slack.html +7 -6
  78. package/dist/docs/guides/webhooks.html +4 -4
  79. package/dist/docs/hashmap.json +1 -1
  80. package/dist/docs/hillclimbing.html +4 -4
  81. package/dist/docs/index.html +4 -4
  82. package/dist/docs/quickstart.html +4 -4
  83. package/dist/docs/reference/agent-config.html +4 -4
  84. package/dist/docs/reference/channels.html +4 -4
  85. package/dist/docs/reference/cli.html +4 -4
  86. package/dist/docs/reference/connections.html +4 -4
  87. package/dist/docs/reference/hooks.html +4 -4
  88. package/dist/docs/reference/http-api.html +4 -4
  89. package/dist/docs/reference/instructions.html +4 -4
  90. package/dist/docs/reference/playground.html +4 -4
  91. package/dist/docs/reference/project-layout.html +4 -4
  92. package/dist/docs/reference/schedules.html +4 -4
  93. package/dist/docs/reference/sessions.html +5 -5
  94. package/dist/docs/reference/skills.html +4 -4
  95. package/dist/docs/reference/subagents.html +4 -4
  96. package/dist/docs/reference/tools.html +4 -4
  97. package/dist/docs/scaffolding-agents.html +4 -4
  98. package/dist/docs/storage.html +7 -6
  99. package/dist/docs/troubleshooting.html +4 -4
  100. package/dist/internal/cli-mcp.d.ts +64 -0
  101. package/dist/internal/cli-mcp.d.ts.map +1 -0
  102. package/dist/internal/cli-mcp.js +570 -0
  103. package/dist/internal/distribution.d.ts.map +1 -1
  104. package/dist/internal/distribution.js +2 -0
  105. package/dist/internal/host-kv.d.ts +17 -0
  106. package/dist/internal/host-kv.d.ts.map +1 -0
  107. package/dist/internal/host-kv.js +77 -0
  108. package/dist/internal/server.d.ts.map +1 -1
  109. package/dist/internal/server.js +8 -0
  110. package/dist/internal/session-engine.d.ts +42 -7
  111. package/dist/internal/session-engine.d.ts.map +1 -1
  112. package/dist/internal/session-engine.js +247 -51
  113. package/dist/internal/storage-coordinator.d.ts +18 -1
  114. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  115. package/dist/internal/storage-coordinator.js +43 -0
  116. package/dist/playground/assets/index-7GJIUFQj.css +1 -0
  117. package/dist/playground/assets/index-Bpr4Th4M.js +319 -0
  118. package/dist/playground/index.html +2 -2
  119. package/dist/storage-backends/file-kv.d.ts +42 -0
  120. package/dist/storage-backends/file-kv.d.ts.map +1 -0
  121. package/dist/storage-backends/file-kv.js +190 -0
  122. package/dist/storage-backends/postgres-kv.d.ts +77 -0
  123. package/dist/storage-backends/postgres-kv.d.ts.map +1 -0
  124. package/dist/storage-backends/postgres-kv.js +180 -0
  125. package/dist/storage.d.ts +10 -1
  126. package/dist/storage.d.ts.map +1 -1
  127. package/dist/storage.js +10 -1
  128. package/dist/types.d.ts +79 -0
  129. package/dist/types.d.ts.map +1 -1
  130. package/docs/example-agents/index.md +14 -9
  131. package/docs/example-agents/oncall.md +216 -0
  132. package/docs/guides/slack.md +11 -2
  133. package/docs/reference/sessions.md +13 -4
  134. package/docs/storage.md +27 -0
  135. package/package.json +15 -1
  136. package/skills/framework-map/SKILL.md +6 -4
  137. package/src/bin/agent-serve.ts +32 -2
  138. package/src/channels/slack/channel-watch.ts +28 -1
  139. package/src/channels/slack/cursor-account.ts +20 -0
  140. package/src/channels/slack/defaults.ts +51 -20
  141. package/src/channels/slack/dispatch.ts +215 -40
  142. package/src/channels/slack/inbound.ts +30 -10
  143. package/src/channels/slack/index.ts +4 -0
  144. package/src/channels/slack/live-delivery.ts +1 -0
  145. package/src/channels/slack/manifest.ts +3 -0
  146. package/src/channels/slack/nudge-carrier.ts +182 -0
  147. package/src/channels/slack/nudge-store.ts +308 -0
  148. package/src/channels/slack/slack-channel.ts +106 -31
  149. package/src/channels/slack/stop.ts +25 -0
  150. package/src/channels/slack/thread-context.ts +572 -0
  151. package/src/channels/slack/types.ts +27 -0
  152. package/src/internal/cli-mcp.ts +708 -0
  153. package/src/internal/distribution.ts +2 -0
  154. package/src/internal/host-kv.ts +85 -0
  155. package/src/internal/server.ts +31 -0
  156. package/src/internal/session-engine.ts +351 -50
  157. package/src/internal/storage-coordinator.ts +41 -0
  158. package/src/storage-backends/file-kv.ts +221 -0
  159. package/src/storage-backends/postgres-kv.ts +248 -0
  160. package/src/storage.ts +11 -1
  161. package/src/types.ts +83 -0
  162. package/dist/channels/slack/post-update-delivery.d.ts +0 -85
  163. package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
  164. package/dist/docs/assets/chunks/@localSearchIndexroot.B7UcKvIn.js +0 -1
  165. package/dist/docs/assets/example-agents_index.md.CRqJlnIf.js +0 -2
  166. package/dist/internal/json-dir-store.d.ts +0 -32
  167. package/dist/internal/json-dir-store.d.ts.map +0 -1
  168. package/dist/internal/persistence-coordinator.d.ts +0 -127
  169. package/dist/internal/persistence-coordinator.d.ts.map +0 -1
  170. package/dist/persistence.d.ts +0 -184
  171. package/dist/persistence.d.ts.map +0 -1
  172. package/dist/playground/assets/index-72vCOBWO.js +0 -86
  173. package/dist/playground/assets/index-BjnMwYoR.css +0 -1
@@ -35,9 +35,8 @@ import {
35
35
  } from "./cursor-account.js";
36
36
  import {
37
37
  buildDefaultEvents,
38
- defaultOnAppMention,
39
- defaultOnChannelPost,
40
- defaultOnDirectMessage,
38
+ createDefaultOnChannelPost,
39
+ createDefaultOnInbound,
41
40
  } from "./defaults.js";
42
41
  import {
43
42
  dispatchInboundFromEventBody,
@@ -130,9 +129,12 @@ export function slackChannel<const Name extends string = string>(
130
129
  ? { botToken: accountTransport }
131
130
  : (options.credentials ?? credentialsFromEnv(options.envPrefix));
132
131
  const envKeys = slackEnvKeys(options.envPrefix);
133
- const onAppMention = options.onAppMention ?? defaultOnAppMention;
134
- const onDirectMessage = options.onDirectMessage ?? defaultOnDirectMessage;
135
- const onChannelPost = options.onChannelPost ?? defaultOnChannelPost;
132
+ const loadingMessages = options.loadingMessages;
133
+ const defaultInbound = createDefaultOnInbound(loadingMessages);
134
+ const onAppMention = options.onAppMention ?? defaultInbound;
135
+ const onDirectMessage = options.onDirectMessage ?? defaultInbound;
136
+ const onChannelPost =
137
+ options.onChannelPost ?? createDefaultOnChannelPost(loadingMessages);
136
138
  const engagement = options.engagement ?? {};
137
139
  const mentionsEnabled = engagement.mentions !== false;
138
140
  const directMessagesEnabled = engagement.directMessages !== false;
@@ -167,6 +169,7 @@ export function slackChannel<const Name extends string = string>(
167
169
  thinkingSteps: options.thinkingSteps,
168
170
  suggestedPrompts: options.suggestedPrompts,
169
171
  suggestedPromptsTitle: options.suggestedPromptsTitle,
172
+ loadingMessages,
170
173
  getLog,
171
174
  })
172
175
  );
@@ -183,6 +186,12 @@ export function slackChannel<const Name extends string = string>(
183
186
  send: SendMessageFn;
184
187
  waitUntil: (promise: Promise<unknown>) => void;
185
188
  host: HostContext;
189
+ hasContinuationSession?: (continuationToken: string) => Promise<boolean>;
190
+ isContinuationBusy?: (continuationToken: string) => Promise<boolean>;
191
+ getContinuationLastBotMessageTs?: (
192
+ continuationToken: string
193
+ ) => Promise<string | undefined>;
194
+ interruptContinuation?: (continuationToken: string) => Promise<boolean>;
186
195
  }): SlackInboundDispatchDeps {
187
196
  return {
188
197
  send: args.send,
@@ -195,6 +204,21 @@ export function slackChannel<const Name extends string = string>(
195
204
  log: getLog(),
196
205
  mentionsEnabled,
197
206
  directMessagesEnabled,
207
+ ...(args.hasContinuationSession === undefined
208
+ ? {}
209
+ : { hasContinuationSession: args.hasContinuationSession }),
210
+ ...(args.isContinuationBusy === undefined
211
+ ? {}
212
+ : { isContinuationBusy: args.isContinuationBusy }),
213
+ ...(args.getContinuationLastBotMessageTs === undefined
214
+ ? {}
215
+ : {
216
+ getContinuationLastBotMessageTs:
217
+ args.getContinuationLastBotMessageTs,
218
+ }),
219
+ ...(args.interruptContinuation === undefined
220
+ ? {}
221
+ : { interruptContinuation: args.interruptContinuation }),
198
222
  ...(channelWatch === undefined ? {} : { channelWatch }),
199
223
  };
200
224
  }
@@ -237,6 +261,7 @@ export function slackChannel<const Name extends string = string>(
237
261
 
238
262
  return send(input.message, {
239
263
  auth: input.auth,
264
+ admission: "coalesce",
240
265
  continuationToken: slackContinuationKey(channelId, threadTs),
241
266
  state: emptySlackChannelState({
242
267
  channelId,
@@ -271,12 +296,15 @@ export function slackChannel<const Name extends string = string>(
271
296
  if (channelPosts !== undefined) {
272
297
  const allowlist = new SlackChannelAllowlist(channelPosts.allow);
273
298
  let botUserId: string | undefined;
299
+ let botId: string | undefined;
274
300
  try {
275
301
  const { WebClient } = await import("@slack/web-api");
276
302
  const client = new WebClient(botToken);
277
303
  const identity = await client.auth.test();
278
304
  botUserId =
279
305
  typeof identity.user_id === "string" ? identity.user_id : undefined;
306
+ botId =
307
+ typeof identity.bot_id === "string" ? identity.bot_id : undefined;
280
308
  const names = allowlist.unresolvedNames();
281
309
  if (names.length > 0) {
282
310
  allowlist.applyResolvedNames(
@@ -288,31 +316,62 @@ export function slackChannel<const Name extends string = string>(
288
316
  error: error instanceof Error ? error.message : String(error),
289
317
  });
290
318
  }
291
- channelWatch = createChannelPostWatcher({
292
- options: channelPosts,
293
- allowlist,
294
- getBotUserId: () => botUserId,
295
- log: getLog(),
296
- dispatch: (message, eventId) => {
297
- args.waitUntil(
298
- dispatchInboundMessage({
299
- kind: "channel_post",
300
- message,
301
- handler: onChannelPost,
302
- send: args.send,
303
- credentials,
304
- host: args.host,
305
- log: getLog(),
306
- ...(eventId === undefined ? {} : { eventId }),
307
- })
308
- );
309
- },
310
- });
311
- getLog().info("channel watch enabled", {
312
- channels: channelPosts.allow.join(","),
313
- posts: channelPosts.posts ?? "top-level",
314
- debounce_ms: channelPosts.debounceMs ?? 0,
315
- });
319
+ if (
320
+ channelPosts.includeBotPosts === true &&
321
+ botUserId === undefined &&
322
+ botId === undefined
323
+ ) {
324
+ getLog().error("channel watch disabled", {
325
+ reason:
326
+ "includeBotPosts requires bot identity from auth.test (loop safety)",
327
+ });
328
+ } else {
329
+ channelWatch = createChannelPostWatcher({
330
+ options: channelPosts,
331
+ allowlist,
332
+ getBotUserId: () => botUserId,
333
+ getBotId: () => botId,
334
+ log: getLog(),
335
+ dispatch: (message, eventId) => {
336
+ args.waitUntil(
337
+ dispatchInboundMessage({
338
+ kind: "channel_post",
339
+ message,
340
+ handler: onChannelPost,
341
+ send: args.send,
342
+ credentials,
343
+ host: args.host,
344
+ log: getLog(),
345
+ ...(args.hasContinuationSession === undefined
346
+ ? {}
347
+ : {
348
+ hasContinuationSession: args.hasContinuationSession,
349
+ }),
350
+ ...(args.isContinuationBusy === undefined
351
+ ? {}
352
+ : { isContinuationBusy: args.isContinuationBusy }),
353
+ ...(args.getContinuationLastBotMessageTs === undefined
354
+ ? {}
355
+ : {
356
+ getContinuationLastBotMessageTs:
357
+ args.getContinuationLastBotMessageTs,
358
+ }),
359
+ ...(args.interruptContinuation === undefined
360
+ ? {}
361
+ : {
362
+ interruptContinuation: args.interruptContinuation,
363
+ }),
364
+ ...(eventId === undefined ? {} : { eventId }),
365
+ })
366
+ );
367
+ },
368
+ });
369
+ getLog().info("channel watch enabled", {
370
+ channels: channelPosts.allow.join(","),
371
+ posts: channelPosts.posts ?? "top-level",
372
+ debounce_ms: channelPosts.debounceMs ?? 0,
373
+ });
374
+ }
316
375
  }
317
376
 
318
377
  const socketOptions: SlackSocketModeOptions = {
@@ -325,6 +384,21 @@ export function slackChannel<const Name extends string = string>(
325
384
  send: args.send,
326
385
  waitUntil: args.waitUntil,
327
386
  host: args.host,
387
+ ...(args.hasContinuationSession === undefined
388
+ ? {}
389
+ : { hasContinuationSession: args.hasContinuationSession }),
390
+ ...(args.isContinuationBusy === undefined
391
+ ? {}
392
+ : { isContinuationBusy: args.isContinuationBusy }),
393
+ ...(args.getContinuationLastBotMessageTs === undefined
394
+ ? {}
395
+ : {
396
+ getContinuationLastBotMessageTs:
397
+ args.getContinuationLastBotMessageTs,
398
+ }),
399
+ ...(args.interruptContinuation === undefined
400
+ ? {}
401
+ : { interruptContinuation: args.interruptContinuation }),
328
402
  })
329
403
  );
330
404
  },
@@ -366,6 +440,7 @@ export function slackChannel<const Name extends string = string>(
366
440
  channelWatch = undefined;
367
441
  await socketHandle?.stop();
368
442
  socketHandle = null;
443
+ await options.onStop?.();
369
444
  },
370
445
  });
371
446
 
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Whole-message Slack "stop" directive (Benny parity).
3
+ *
4
+ * A message whose body is only `@bot stop` / `stop` cancels the active turn.
5
+ * The word "stop" embedded in a longer message is not a directive.
6
+ */
7
+
8
+ const MENTION_RE = /^<@[A-Z0-9]+>\s*/i;
9
+
10
+ /** Strip leading Slack user mentions and surrounding whitespace. */
11
+ export function stripLeadingSlackMentions(text: string): string {
12
+ let current = text.trim();
13
+ while (MENTION_RE.test(current)) {
14
+ current = current.replace(MENTION_RE, "").trim();
15
+ }
16
+ return current;
17
+ }
18
+
19
+ /**
20
+ * True when the message (after stripping @mentions) is exactly `stop`
21
+ * (case-insensitive).
22
+ */
23
+ export function isWholeMessageStop(text: string): boolean {
24
+ return stripLeadingSlackMentions(text).toLowerCase() === "stop";
25
+ }