@cursor/july 0.1.1 → 0.1.2

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 (199) hide show
  1. package/AGENTS.md +24 -2
  2. package/README.md +25 -15
  3. package/dist/bin/agent-serve.js +101 -12
  4. package/dist/channels/github/api.d.ts.map +1 -1
  5. package/dist/channels/github/api.js +31 -14
  6. package/dist/channels/github/cursor-account.d.ts +43 -0
  7. package/dist/channels/github/cursor-account.d.ts.map +1 -0
  8. package/dist/channels/github/cursor-account.js +95 -0
  9. package/dist/channels/github/github-channel.d.ts.map +1 -1
  10. package/dist/channels/github/github-channel.js +46 -9
  11. package/dist/channels/github/index.d.ts +2 -2
  12. package/dist/channels/github/index.js +2 -2
  13. package/dist/channels/github/types.d.ts +17 -0
  14. package/dist/channels/github/types.d.ts.map +1 -1
  15. package/dist/channels/slack/slack-channel.d.ts +8 -2
  16. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  17. package/dist/channels/slack/slack-channel.js +8 -0
  18. package/dist/channels/slack/types.d.ts +24 -3
  19. package/dist/channels/slack/types.d.ts.map +1 -1
  20. package/dist/channels/slack/types.js +15 -1
  21. package/dist/docs/404.html +2 -2
  22. package/dist/docs/ab.html +8 -8
  23. package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
  24. package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
  25. package/dist/docs/assets/{app.DqfFEmJd.js → app.Oje4vhlk.js} +1 -1
  26. package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +1 -0
  27. package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.H5XZ2zCB.js} +1 -1
  28. package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.CTR_TuaE.js} +2 -2
  29. package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
  30. package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
  31. package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
  32. package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
  33. package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
  34. package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
  35. package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
  36. package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
  37. package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
  38. package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
  39. package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
  40. package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
  41. package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
  42. package/dist/docs/assets/quickstart.md.CfU8_uTC.js +192 -0
  43. package/dist/docs/assets/quickstart.md.CfU8_uTC.lean.js +1 -0
  44. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
  45. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
  46. package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
  47. package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
  48. package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
  49. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
  50. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
  51. package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
  52. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
  53. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
  54. package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
  55. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
  56. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
  57. package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
  58. package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
  59. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
  60. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
  61. package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
  62. package/dist/docs/assets/storage.md.CVnInNiN.lean.js +1 -0
  63. package/dist/docs/building-with-agents.html +4 -4
  64. package/dist/docs/concepts.html +4 -4
  65. package/dist/docs/deployment.html +7 -7
  66. package/dist/docs/evals.html +7 -7
  67. package/dist/docs/guides/agent-to-agent.html +6 -6
  68. package/dist/docs/guides/cloud-runtime.html +5 -5
  69. package/dist/docs/guides/github.html +14 -7
  70. package/dist/docs/guides/human-in-the-loop.html +6 -6
  71. package/dist/docs/guides/slack.html +8 -8
  72. package/dist/docs/guides/webhooks.html +6 -6
  73. package/dist/docs/hashmap.json +1 -1
  74. package/dist/docs/hillclimbing.html +5 -5
  75. package/dist/docs/index.html +7 -7
  76. package/dist/docs/quickstart.html +180 -23
  77. package/dist/docs/reference/agent-config.html +7 -7
  78. package/dist/docs/reference/channels.html +8 -8
  79. package/dist/docs/reference/cli.html +4 -4
  80. package/dist/docs/reference/connections.html +5 -5
  81. package/dist/docs/reference/hooks.html +5 -5
  82. package/dist/docs/reference/http-api.html +6 -6
  83. package/dist/docs/reference/instructions.html +13 -11
  84. package/dist/docs/reference/playground.html +4 -4
  85. package/dist/docs/reference/project-layout.html +4 -4
  86. package/dist/docs/reference/schedules.html +7 -7
  87. package/dist/docs/reference/sessions.html +4 -4
  88. package/dist/docs/reference/skills.html +6 -6
  89. package/dist/docs/reference/subagents.html +6 -6
  90. package/dist/docs/reference/tools.html +7 -7
  91. package/dist/docs/scaffolding-agents.html +5 -5
  92. package/dist/docs/storage.html +41 -0
  93. package/dist/docs/troubleshooting.html +4 -4
  94. package/dist/index.d.ts +2 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +1 -0
  97. package/dist/internal/cli-deploy.d.ts +52 -0
  98. package/dist/internal/cli-deploy.d.ts.map +1 -0
  99. package/dist/internal/cli-deploy.js +731 -0
  100. package/dist/internal/cursor/backend-client.d.ts +10 -1
  101. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  102. package/dist/internal/cursor/backend-client.js +79 -1
  103. package/dist/internal/cursor/github-credentials.d.ts +44 -0
  104. package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
  105. package/dist/internal/cursor/github-credentials.js +195 -0
  106. package/dist/internal/deploy-client.d.ts +176 -0
  107. package/dist/internal/deploy-client.d.ts.map +1 -0
  108. package/dist/internal/deploy-client.js +375 -0
  109. package/dist/internal/discovery.d.ts.map +1 -1
  110. package/dist/internal/discovery.js +73 -5
  111. package/dist/internal/distribution.d.ts.map +1 -1
  112. package/dist/internal/distribution.js +1 -0
  113. package/dist/internal/eval-run-store.d.ts +22 -3
  114. package/dist/internal/eval-run-store.d.ts.map +1 -1
  115. package/dist/internal/eval-run-store.js +37 -19
  116. package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
  117. package/dist/internal/handleAgentServeTrigger.js +10 -12
  118. package/dist/internal/host-platforms.d.ts +7 -2
  119. package/dist/internal/host-platforms.d.ts.map +1 -1
  120. package/dist/internal/host-platforms.js +15 -10
  121. package/dist/internal/hosting.d.ts +37 -0
  122. package/dist/internal/hosting.d.ts.map +1 -0
  123. package/dist/internal/hosting.js +67 -0
  124. package/dist/internal/reminder-runner.d.ts +7 -0
  125. package/dist/internal/reminder-runner.d.ts.map +1 -1
  126. package/dist/internal/reminder-runner.js +50 -6
  127. package/dist/internal/reminder-store.d.ts +2 -0
  128. package/dist/internal/reminder-store.d.ts.map +1 -1
  129. package/dist/internal/reminder-store.js +18 -0
  130. package/dist/internal/server.d.ts.map +1 -1
  131. package/dist/internal/server.js +173 -42
  132. package/dist/internal/session-engine.d.ts +49 -0
  133. package/dist/internal/session-engine.d.ts.map +1 -1
  134. package/dist/internal/session-engine.js +246 -17
  135. package/dist/internal/storage-coordinator.d.ts +139 -0
  136. package/dist/internal/storage-coordinator.d.ts.map +1 -0
  137. package/dist/internal/storage-coordinator.js +499 -0
  138. package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
  139. package/dist/playground/assets/index-B1Qc9h2u.css +1 -0
  140. package/dist/playground/assets/{index-FlWjhg3x.js → index-CpDYCj8W.js} +42 -42
  141. package/dist/playground/index.html +2 -2
  142. package/dist/storage.d.ts +204 -0
  143. package/dist/storage.d.ts.map +1 -0
  144. package/dist/storage.js +153 -0
  145. package/dist/types.d.ts +44 -3
  146. package/dist/types.d.ts.map +1 -1
  147. package/docs/README.md +3 -2
  148. package/docs/guides/github.md +43 -8
  149. package/docs/guides/slack.md +1 -1
  150. package/docs/quickstart.md +329 -51
  151. package/docs/reference/instructions.md +8 -6
  152. package/docs/scaffolding-agents.md +1 -1
  153. package/docs/storage.md +98 -0
  154. package/package.json +8 -1
  155. package/skills/github/SKILL.md +9 -1
  156. package/src/bin/agent-serve.ts +139 -0
  157. package/src/channels/github/api.ts +42 -23
  158. package/src/channels/github/cursor-account.ts +165 -0
  159. package/src/channels/github/github-channel.ts +66 -6
  160. package/src/channels/github/index.ts +2 -2
  161. package/src/channels/github/types.ts +19 -0
  162. package/src/channels/slack/slack-channel.ts +17 -3
  163. package/src/channels/slack/types.ts +44 -3
  164. package/src/index.ts +13 -0
  165. package/src/internal/cli-deploy.ts +940 -0
  166. package/src/internal/cursor/backend-client.ts +103 -1
  167. package/src/internal/cursor/github-credentials.ts +248 -0
  168. package/src/internal/deploy-client.ts +591 -0
  169. package/src/internal/discovery.ts +88 -1
  170. package/src/internal/distribution.ts +1 -0
  171. package/src/internal/eval-run-store.ts +48 -19
  172. package/src/internal/handleAgentServeTrigger.ts +10 -12
  173. package/src/internal/host-platforms.ts +28 -11
  174. package/src/internal/hosting.ts +77 -0
  175. package/src/internal/reminder-runner.ts +50 -6
  176. package/src/internal/reminder-store.ts +21 -0
  177. package/src/internal/server.ts +213 -27
  178. package/src/internal/session-engine.ts +285 -7
  179. package/src/internal/storage-coordinator.ts +615 -0
  180. package/src/storage.ts +325 -0
  181. package/src/types.ts +40 -2
  182. package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
  183. package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
  184. package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
  185. package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
  186. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
  187. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
  188. package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
  189. package/dist/playground/assets/index-1K-hG-7p.css +0 -1
  190. /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
  191. /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
  192. /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
  193. /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
  194. /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
  195. /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
  196. /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
  197. /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
  198. /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
  199. /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
@@ -23,6 +23,13 @@ import {
23
23
  type GitHubBindingConfig,
24
24
  type GitHubBindingState,
25
25
  } from "./binding.js";
26
+ import {
27
+ createCursorAccountGithubTokenResolver,
28
+ createPendingCursorGithubCredentials,
29
+ type PendingCursorGithubCredentials,
30
+ parseCursorGithubRepoScope,
31
+ registerGithubCursorAccountRuntime,
32
+ } from "./cursor-account.js";
26
33
  import { buildDefaultGitHubEvents } from "./defaults.js";
27
34
  import { deriveGitHubWebhookEvents, GITHUB_CHANNEL_KIND } from "./events.js";
28
35
  import {
@@ -581,9 +588,36 @@ export function getGitHubChannelOptions(
581
588
  export function githubChannel(
582
589
  options: GitHubChannelOptions = {}
583
590
  ): ChannelDefinition<GitHubChannelState> {
591
+ const usesCursorAccount =
592
+ options.cursorAccount === true || typeof options.cursorAccount === "object";
593
+ // Normalized scope lives on the private runtime — never rewrite authored
594
+ // `cursorAccount` on the options object the author passed in.
595
+ const cursorScope =
596
+ typeof options.cursorAccount === "object"
597
+ ? parseCursorGithubRepoScope(
598
+ options.cursorAccount.repos,
599
+ options.cursorAccount.permissions
600
+ )
601
+ : undefined;
602
+
603
+ let cursorCredentials: PendingCursorGithubCredentials | undefined;
604
+ let credentials = options.credentials;
605
+ if (usesCursorAccount) {
606
+ if (hasDedicatedGitHubApiCredentials(options)) {
607
+ throw new Error(
608
+ "githubChannel({ cursorAccount: true }) cannot be combined with token or GitHub App credentials."
609
+ );
610
+ }
611
+ const pending = createPendingCursorGithubCredentials();
612
+ cursorCredentials = pending;
613
+ credentials = {
614
+ ...options.credentials,
615
+ token: createCursorAccountGithubTokenResolver(() => pending.getToken()),
616
+ };
617
+ }
618
+
584
619
  const routePath = options.path ?? "/";
585
- const webhookSecret =
586
- options.credentials?.webhookSecret ?? envWebhookSecret();
620
+ const webhookSecret = credentials?.webhookSecret ?? envWebhookSecret();
587
621
  // With a secret the HMAC is the request auth (allowAll). Without one, prod
588
622
  // stays loopback-strict; dev admits unsigned deliveries from a loopback peer
589
623
  // only (loopbackGitHubDev) — not the LAN. Admits `gh webhook forward`
@@ -607,8 +641,12 @@ export function githubChannel(
607
641
  ),
608
642
  ]);
609
643
 
644
+ const channelOptions: GitHubChannelOptions = {
645
+ ...options,
646
+ credentials,
647
+ };
610
648
  const events: ChannelEventHandlers<GitHubChannelState> = {
611
- ...buildDefaultGitHubEvents({ ...options }),
649
+ ...buildDefaultGitHubEvents({ ...channelOptions }),
612
650
  ...options.events,
613
651
  };
614
652
 
@@ -618,7 +656,7 @@ export function githubChannel(
618
656
  events,
619
657
  meta: {
620
658
  kind: GITHUB_CHANNEL_KIND,
621
- githubWebhookEvents: deriveGitHubWebhookEvents(options),
659
+ githubWebhookEvents: deriveGitHubWebhookEvents(channelOptions),
622
660
  },
623
661
  onStart: options.onStart,
624
662
  onStop: options.onStop,
@@ -630,14 +668,36 @@ export function githubChannel(
630
668
  bodySchema: z.unknown(),
631
669
  description: "GitHub webhook ingress",
632
670
  handler: async (request, args) =>
633
- handleGitHubWebhookRequest({ options, request, args }),
671
+ handleGitHubWebhookRequest({
672
+ options: channelOptions,
673
+ request,
674
+ args,
675
+ }),
634
676
  }),
635
677
  ],
636
678
  });
637
- githubChannelOptionsByDefinition.set(definition, options);
679
+ githubChannelOptionsByDefinition.set(definition, channelOptions);
680
+ if (cursorCredentials !== undefined) {
681
+ registerGithubCursorAccountRuntime(definition, {
682
+ options,
683
+ credentials: cursorCredentials,
684
+ scope: cursorScope,
685
+ });
686
+ }
638
687
  return definition;
639
688
  }
640
689
 
690
+ function hasDedicatedGitHubApiCredentials(
691
+ options: GitHubChannelOptions
692
+ ): boolean {
693
+ return (
694
+ options.credentials?.token !== undefined ||
695
+ options.credentials?.installationToken !== undefined ||
696
+ options.credentials?.appId !== undefined ||
697
+ options.credentials?.privateKey !== undefined
698
+ );
699
+ }
700
+
641
701
  async function handlePullRequest(input: {
642
702
  options: GitHubChannelOptions;
643
703
  bindingConfig: GitHubBindingConfig;
@@ -6,8 +6,8 @@
6
6
  *
7
7
  * export default githubChannel({
8
8
  * botName: "my-agent",
9
- * // API auth: App installation (preferred) GITHUB_TOKEN / GH_TOKEN → `gh auth`
10
- * credentials: { webhookSecret: () => process.env.GITHUB_WEBHOOK_SECRET },
9
+ * // Reuses `agentkit login` for events, ctx.github, ctx.host.github, and gh.
10
+ * cursorAccount: { repos: ["owner/repo"] },
11
11
  * onComment: (ctx, comment) => ({ auth: defaultGitHubAuth(ctx) }),
12
12
  * onPullRequest: (ctx, pr) =>
13
13
  * pr.action === "opened" ? { auth: defaultGitHubAuth(ctx) } : null,
@@ -421,6 +421,25 @@ export interface GitHubChannelOptions {
421
421
  * API calls prefer App installation tokens, then local PAT / `gh auth`.
422
422
  */
423
423
  credentials?: GitHubChannelCredentials;
424
+ /**
425
+ * Use the signed-in Cursor account's GitHub connection for inbound events
426
+ * and outbound API calls. `true` takes repository scope from
427
+ * `serve --cursor-events --repo`; `{ repos }` makes the channel self-contained.
428
+ * `permissions` chooses the minted token tier (`"pr-write"` default).
429
+ * Cannot be combined with explicit token or GitHub App credentials.
430
+ */
431
+ cursorAccount?:
432
+ | boolean
433
+ | {
434
+ repos: readonly string[];
435
+ /**
436
+ * Token capability tier:
437
+ * - `"read"` — PR/issue/status read
438
+ * - `"pr-write"` (default) — comments / PR+issue write, no `contents:write`
439
+ * - `"contents-write"` — also push code (host-held; prefer only when needed)
440
+ */
441
+ permissions?: "read" | "pr-write" | "contents-write";
442
+ };
424
443
  /** Optional GitHub API transport overrides (`apiBaseUrl`, `fetch`). */
425
444
  api?: GitHubApiOptions;
426
445
  /**
@@ -54,13 +54,24 @@ import {
54
54
  startSlackSocketMode,
55
55
  } from "./socket-mode.js";
56
56
  import { buildToolApprovalEvents } from "./tool-approval-events.js";
57
- import type { SlackChannelOptions, SlackChannelState } from "./types.js";
57
+ import {
58
+ assertSlackCursorAgentName,
59
+ type SlackChannelOptions,
60
+ type SlackChannelState,
61
+ type SlackCursorAgentName,
62
+ } from "./types.js";
58
63
 
59
64
  /**
60
65
  * Create a Slack channel. Author as `agent/channels/slack.ts` default export.
66
+ *
67
+ * When `cursorAccount` is on, `agentName` must be a single token (no
68
+ * whitespace) — string literals with spaces fail at the type level;
69
+ * runtime values are still checked by {@link assertSlackCursorAgentName}.
61
70
  */
62
- export function slackChannel(
63
- options: SlackChannelOptions = {}
71
+ export function slackChannel<const Name extends string = string>(
72
+ options: Omit<SlackChannelOptions, "agentName"> & {
73
+ agentName?: SlackCursorAgentName<Name>;
74
+ } = {}
64
75
  ): ChannelDefinition<SlackChannelState> {
65
76
  const cursorAccount = options.cursorAccount === true;
66
77
  if (cursorAccount) {
@@ -71,6 +82,9 @@ export function slackChannel(
71
82
  "slackChannel({ cursorAccount: true }) uses the Cursor account's Slack connection — do not also set credentials/envPrefix. Author a second slack channel file for a dedicated Slack app."
72
83
  );
73
84
  }
85
+ if (options.agentName !== undefined) {
86
+ assertSlackCursorAgentName(options.agentName);
87
+ }
74
88
  // Channel watching is Socket Mode only — cursorAccount agents must be
75
89
  // explicitly addressed (@mention, DM, or claimed-thread reply).
76
90
  if (options.engagement?.channelPosts !== undefined) {
@@ -210,6 +210,46 @@ export interface SlackEngagementOptions {
210
210
  channelPosts?: SlackChannelPostsOptions;
211
211
  }
212
212
 
213
+ /**
214
+ * Whitespace forbidden in {@link SlackChannelOptions.agentName}. The Cursor
215
+ * Slack router matches on leading words; multi-word names collide with Named
216
+ * Agent shortened-prefix matching (`Approval …` stealing `ApprovalBuddy`).
217
+ */
218
+ type SlackAgentNameWhitespace = " " | "\t" | "\n" | "\r" | "\f" | "\v";
219
+
220
+ /**
221
+ * Single-token Cursor Slack handle for `cursorAccount` routing
222
+ * (`@Cursor <name> …`). String literals that contain whitespace become
223
+ * `never` (type error at the call site); plain `string` stays `string` and
224
+ * is still rejected at runtime by {@link assertSlackCursorAgentName}.
225
+ */
226
+ export type SlackCursorAgentName<S extends string = string> = string extends S
227
+ ? string
228
+ : S extends `${string}${SlackAgentNameWhitespace}${string}`
229
+ ? never
230
+ : S;
231
+
232
+ const SLACK_CURSOR_AGENT_NAME_WHITESPACE = /\s/;
233
+
234
+ /**
235
+ * Runtime guard for {@link SlackChannelOptions.agentName}. Call from
236
+ * `slackChannel({ cursorAccount: true })` construction and serve-time
237
+ * name resolution so derived defaults cannot sneak spaces in.
238
+ */
239
+ export function assertSlackCursorAgentName(name: string): void {
240
+ const trimmed = name.trim();
241
+ if (trimmed.length === 0) {
242
+ throw new Error(
243
+ 'slackChannel({ cursorAccount: true }) agentName must be a non-empty single token (no whitespace), e.g. "ApprovalBuddy".'
244
+ );
245
+ }
246
+ if (SLACK_CURSOR_AGENT_NAME_WHITESPACE.test(trimmed)) {
247
+ throw new Error(
248
+ `slackChannel({ cursorAccount: true }) agentName must be a single token with no whitespace (got ${JSON.stringify(name)}). Use PascalCase like "ApprovalBuddy" — multi-word names break @Cursor routing.`
249
+ );
250
+ }
251
+ }
252
+
213
253
  export interface SlackChannelOptions {
214
254
  credentials?: SlackCredentials;
215
255
  /**
@@ -242,12 +282,13 @@ export interface SlackChannelOptions {
242
282
  */
243
283
  cursorAccount?: boolean;
244
284
  /**
245
- * Display name registered with the Cursor backend when
285
+ * Single-token display name registered with the Cursor backend when
246
286
  * {@link cursorAccount} is on: `@Cursor <agentName> …` routes here, and
247
- * replies post under this username. Defaults to a name derived from the
287
+ * replies post under this username. **No whitespace** prefer PascalCase
288
+ * (`ApprovalBuddy`). Defaults to a PascalCase name derived from the
248
289
  * agent's mount slug (or project name).
249
290
  */
250
- agentName?: string;
291
+ agentName?: SlackCursorAgentName;
251
292
  /** Avatar for posts when {@link cursorAccount} is on. */
252
293
  agentIcon?: { url?: string; emoji?: string };
253
294
  /**
package/src/index.ts CHANGED
@@ -104,6 +104,19 @@ export type {
104
104
  } from "./reminders.js";
105
105
  export { defineSchedule } from "./schedules.js";
106
106
  export { defineSkill } from "./skills.js";
107
+ export type {
108
+ StorageConfig,
109
+ StorageContext,
110
+ StorageDefinition,
111
+ StorageEntry,
112
+ StoragePolicy,
113
+ StorageRestorePolicy,
114
+ } from "./storage.js";
115
+ export {
116
+ defineStorage,
117
+ STORAGE_KEY_ROOT,
118
+ storageKeys,
119
+ } from "./storage.js";
107
120
  export { defineTool } from "./tools.js";
108
121
  export type * from "./types.js";
109
122
  export {