@cursor/july 0.1.48 → 0.1.51

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 (151) hide show
  1. package/AGENTS.md +3 -3
  2. package/README.md +7 -14
  3. package/dist/bin/agent-serve.js +22 -8
  4. package/dist/channels/slack/init.d.ts +2 -3
  5. package/dist/channels/slack/init.d.ts.map +1 -1
  6. package/dist/channels/slack/init.js +8 -43
  7. package/dist/channels/slack/manifest.d.ts +3 -3
  8. package/dist/channels/slack/manifest.js +3 -3
  9. package/dist/channels/slack/setup.d.ts +2 -11
  10. package/dist/channels/slack/setup.d.ts.map +1 -1
  11. package/dist/channels/slack/setup.js +26 -94
  12. package/dist/channels/slack/types.d.ts +3 -4
  13. package/dist/channels/slack/types.d.ts.map +1 -1
  14. package/dist/docs/404.html +2 -2
  15. package/dist/docs/ab.html +5 -5
  16. package/dist/docs/assets/{ab.md.hdxsvX5M.js → ab.md.DYjwREAP.js} +2 -2
  17. package/dist/docs/assets/{ab.md.hdxsvX5M.lean.js → ab.md.DYjwREAP.lean.js} +1 -1
  18. package/dist/docs/assets/{app.BC1P20xI.js → app.C51TX1Bw.js} +1 -1
  19. package/dist/docs/assets/chunks/@localSearchIndexroot.D2DpXdZN.js +1 -0
  20. package/dist/docs/assets/chunks/{VPLocalSearchBox.C_900xn2.js → VPLocalSearchBox.BB9HCJPq.js} +1 -1
  21. package/dist/docs/assets/chunks/{theme.CT135Jhh.js → theme.Dp-0SZcu.js} +2 -2
  22. package/dist/docs/assets/{deployment.md.Cdp4rTE4.js → deployment.md.B8kW-h7P.js} +1 -1
  23. package/dist/docs/assets/{evals.md.qeoGgPw0.js → evals.md.CVe_O75-.js} +3 -3
  24. package/dist/docs/assets/{evals.md.qeoGgPw0.lean.js → evals.md.CVe_O75-.lean.js} +1 -1
  25. package/dist/docs/assets/{example-agents_benny.md.l7JTmm8X.js → example-agents_benny.md.B-LIDGja.js} +1 -1
  26. package/dist/docs/assets/{example-agents_oncall.md.ZE0n6ZFN.js → example-agents_oncall.md.CBmyuAKc.js} +2 -2
  27. package/dist/docs/assets/{guides_human-in-the-loop.md.BWvT7UqY.js → guides_human-in-the-loop.md.Cf8kIIqC.js} +2 -2
  28. package/dist/docs/assets/{guides_human-in-the-loop.md.BWvT7UqY.lean.js → guides_human-in-the-loop.md.Cf8kIIqC.lean.js} +1 -1
  29. package/dist/docs/assets/{guides_slack.md.zriQpU_9.js → guides_slack.md.D2nTRu9M.js} +7 -12
  30. package/dist/docs/assets/guides_slack.md.D2nTRu9M.lean.js +1 -0
  31. package/dist/docs/assets/{reference_cli.md.BDmjPPAm.js → reference_cli.md.CGKfz_Yj.js} +3 -7
  32. package/dist/docs/assets/{reference_cli.md.BDmjPPAm.lean.js → reference_cli.md.CGKfz_Yj.lean.js} +1 -1
  33. package/dist/docs/assets/{reference_http-api.md.DGrw_wOu.js → reference_http-api.md.DMbdFGVQ.js} +1 -1
  34. package/dist/docs/assets/{storage.md.CJYd5YmN.js → storage.md.D8NQ389l.js} +3 -3
  35. package/dist/docs/assets/storage.md.D8NQ389l.lean.js +1 -0
  36. package/dist/docs/assets/{troubleshooting.md.CkgwmVI0.js → troubleshooting.md.C6n3wCr6.js} +1 -1
  37. package/dist/docs/building-with-agents.html +3 -3
  38. package/dist/docs/concepts.html +3 -3
  39. package/dist/docs/deployment.html +5 -5
  40. package/dist/docs/evals.html +6 -6
  41. package/dist/docs/example-agents/approval-buddy.html +3 -3
  42. package/dist/docs/example-agents/benny.html +5 -5
  43. package/dist/docs/example-agents/bugbot.html +3 -3
  44. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  45. package/dist/docs/example-agents/codeowners-review.html +3 -3
  46. package/dist/docs/example-agents/concierge.html +3 -3
  47. package/dist/docs/example-agents/fsd.html +3 -3
  48. package/dist/docs/example-agents/index.html +3 -3
  49. package/dist/docs/example-agents/knowledge-base.html +3 -3
  50. package/dist/docs/example-agents/oncall.html +6 -6
  51. package/dist/docs/example-agents/security-reviewer.html +3 -3
  52. package/dist/docs/example-agents/slack-agent.html +3 -3
  53. package/dist/docs/example-agents/weather-agent.html +3 -3
  54. package/dist/docs/guides/agent-to-agent.html +3 -3
  55. package/dist/docs/guides/cloud-runtime.html +3 -3
  56. package/dist/docs/guides/github.html +3 -3
  57. package/dist/docs/guides/human-in-the-loop.html +5 -5
  58. package/dist/docs/guides/mcp-oauth.html +3 -3
  59. package/dist/docs/guides/opentelemetry.html +3 -3
  60. package/dist/docs/guides/slack.html +11 -16
  61. package/dist/docs/guides/webhooks.html +3 -3
  62. package/dist/docs/hashmap.json +1 -1
  63. package/dist/docs/hillclimbing.html +3 -3
  64. package/dist/docs/index.html +3 -3
  65. package/dist/docs/quickstart.html +3 -3
  66. package/dist/docs/reference/agent-config.html +3 -3
  67. package/dist/docs/reference/artifacts.html +3 -3
  68. package/dist/docs/reference/channels.html +3 -3
  69. package/dist/docs/reference/cli.html +6 -10
  70. package/dist/docs/reference/connections.html +3 -3
  71. package/dist/docs/reference/hooks.html +3 -3
  72. package/dist/docs/reference/http-api.html +5 -5
  73. package/dist/docs/reference/instructions.html +3 -3
  74. package/dist/docs/reference/playground.html +3 -3
  75. package/dist/docs/reference/project-layout.html +3 -3
  76. package/dist/docs/reference/prompt.html +3 -3
  77. package/dist/docs/reference/schedules.html +3 -3
  78. package/dist/docs/reference/sessions.html +3 -3
  79. package/dist/docs/reference/skills.html +3 -3
  80. package/dist/docs/reference/subagents.html +3 -3
  81. package/dist/docs/reference/tools.html +3 -3
  82. package/dist/docs/scaffolding-agents.html +3 -3
  83. package/dist/docs/storage.html +5 -5
  84. package/dist/docs/templates/triage.html +3 -3
  85. package/dist/docs/troubleshooting.html +5 -5
  86. package/dist/internal/cli-ax.js +3 -3
  87. package/dist/internal/cli-cursor.d.ts +18 -0
  88. package/dist/internal/cli-cursor.d.ts.map +1 -1
  89. package/dist/internal/cli-cursor.js +25 -0
  90. package/dist/internal/cli-slack.d.ts +3 -4
  91. package/dist/internal/cli-slack.d.ts.map +1 -1
  92. package/dist/internal/cli-slack.js +126 -325
  93. package/dist/internal/convert-automation/convert-workflow.js +2 -2
  94. package/dist/internal/event-log.d.ts +17 -0
  95. package/dist/internal/event-log.d.ts.map +1 -1
  96. package/dist/internal/event-log.js +32 -2
  97. package/dist/internal/process-memory-telemetry.d.ts +90 -0
  98. package/dist/internal/process-memory-telemetry.d.ts.map +1 -0
  99. package/dist/internal/process-memory-telemetry.js +259 -0
  100. package/dist/internal/server.d.ts.map +1 -1
  101. package/dist/internal/server.js +9 -10
  102. package/dist/internal/session-engine.d.ts +4 -0
  103. package/dist/internal/session-engine.d.ts.map +1 -1
  104. package/dist/internal/session-engine.js +19 -5
  105. package/dist/internal/slack-provision-client.d.ts +41 -6
  106. package/dist/internal/slack-provision-client.d.ts.map +1 -1
  107. package/dist/internal/slack-provision-client.js +53 -7
  108. package/dist/playground/assets/{index-DEVTyeOu.js → index-BKMz70wx.js} +41 -41
  109. package/dist/playground/assets/index-BmMrulSc.css +1 -0
  110. package/dist/playground/index.html +2 -2
  111. package/dist/storage.d.ts +36 -10
  112. package/dist/storage.d.ts.map +1 -1
  113. package/dist/storage.js +82 -6
  114. package/docs/ab.md +4 -3
  115. package/docs/deployment.md +1 -1
  116. package/docs/evals.md +10 -7
  117. package/docs/example-agents/benny.md +2 -3
  118. package/docs/example-agents/oncall.md +4 -5
  119. package/docs/guides/human-in-the-loop.md +1 -1
  120. package/docs/guides/slack.md +51 -112
  121. package/docs/reference/cli.md +14 -37
  122. package/docs/reference/http-api.md +4 -3
  123. package/docs/storage.md +38 -22
  124. package/docs/troubleshooting.md +2 -2
  125. package/package.json +1 -1
  126. package/skills/create-agent/SKILL.md +4 -5
  127. package/skills/setup-slack/SKILL.md +74 -132
  128. package/src/bin/agent-serve.ts +26 -9
  129. package/src/channels/slack/init.ts +10 -71
  130. package/src/channels/slack/manifest.ts +3 -3
  131. package/src/channels/slack/setup.ts +25 -103
  132. package/src/channels/slack/types.ts +3 -4
  133. package/src/internal/cli-ax.ts +3 -3
  134. package/src/internal/cli-cursor.ts +34 -0
  135. package/src/internal/cli-slack.ts +136 -394
  136. package/src/internal/convert-automation/convert-workflow.ts +2 -2
  137. package/src/internal/event-log.ts +45 -7
  138. package/src/internal/process-memory-telemetry.ts +373 -0
  139. package/src/internal/server.ts +13 -0
  140. package/src/internal/session-engine.ts +20 -1
  141. package/src/internal/slack-provision-client.ts +90 -9
  142. package/src/storage.ts +130 -11
  143. package/dist/docs/assets/chunks/@localSearchIndexroot.DV5SAHnQ.js +0 -1
  144. package/dist/docs/assets/guides_slack.md.zriQpU_9.lean.js +0 -1
  145. package/dist/docs/assets/storage.md.CJYd5YmN.lean.js +0 -1
  146. package/dist/playground/assets/index-CiCmH6R-.css +0 -1
  147. /package/dist/docs/assets/{deployment.md.Cdp4rTE4.lean.js → deployment.md.B8kW-h7P.lean.js} +0 -0
  148. /package/dist/docs/assets/{example-agents_benny.md.l7JTmm8X.lean.js → example-agents_benny.md.B-LIDGja.lean.js} +0 -0
  149. /package/dist/docs/assets/{example-agents_oncall.md.ZE0n6ZFN.lean.js → example-agents_oncall.md.CBmyuAKc.lean.js} +0 -0
  150. /package/dist/docs/assets/{reference_http-api.md.DGrw_wOu.lean.js → reference_http-api.md.DMbdFGVQ.lean.js} +0 -0
  151. /package/dist/docs/assets/{troubleshooting.md.CkgwmVI0.lean.js → troubleshooting.md.C6n3wCr6.lean.js} +0 -0
@@ -771,35 +771,27 @@ setup.
771
771
  agent-sdk slack setup
772
772
  agent-sdk slack create [--dir <path>] [--name <name>] [--prod]
773
773
  [--slack-team <T…>] [--team <id>]
774
- [--icon <https-url-or-file>] [--force]
774
+ [--icon <https-url-or-file>]
775
775
  [--prefix <prefix> | --no-prefix] [--json]
776
776
  agent-sdk slack destroy [--dir <path>] [--prod] [--slack-team <T…>]
777
777
  [--team <id>] [--json]
778
778
  agent-sdk slack icon <https-url-or-file> [--dir <path>] [--prod]
779
779
  [--slack-team <T…>] [--team <id>] [--json]
780
- agent-sdk slack init [--dir <path>] [--name <name>]
781
- [--prefix <prefix> | --no-prefix] [--channel-posts]
782
- agent-sdk slack manifest [--dir <path>] [--name <name>]
783
- [--env dev|prod|both] [--channel-posts] [--print]
784
780
  agent-sdk slack doctor [--dir <path>] [--prefix <prefix> | --no-prefix] [--json]
785
781
  ```
786
782
 
787
- `slack setup` prints a guided checklist and doesn't change files.
783
+ `slack setup` prints the two-product chooser and doesn't change files.
788
784
 
789
- `slack create` provisions a dedicated Socket Mode app through Cursor's
790
- Add to Slack API instead of the manual manifest import. It requires a
791
- signed-in host (`agent-sdk login` or `CURSOR_API_KEY`) and the
792
- provisioning feature to be enabled for the account. The command
793
- scaffolds the channel file when missing, opens the browser consent flow
794
- when the workspace isn't connected to Cursor yet, creates and installs
795
- the app, writes the bot and app-level tokens into `<dir>/.env.local`,
796
- and ends with a `doctor` pass. `--prod` provisions the production app;
797
- the default is the development app. When the install needs a Slack
798
- workspace admin's approval, the command prints the approval page and
799
- exits non-zero; re-run it after the approval to finish and mint the
800
- tokens. A re-run rebuilds the manifest from the command's flags and
801
- refuses to overwrite edits made by hand in Slack unless you pass
802
- `--force`.
785
+ `slack create` opens the signed-in Cursor dashboard wizard. Finish Slack
786
+ consent and the bot name there. The CLI writes the token pair into
787
+ `<dir>/.env.local` and runs `doctor`. It requires a signed-in host
788
+ (`agent-sdk login` or `CURSOR_API_KEY`). `--prod` provisions the
789
+ production app; the default is the development app. `--name` / `--icon`
790
+ / `--channel-posts` prefill the wizard. A second create for the same
791
+ slug and env overwrites the live Slack app. If Slack needs a workspace
792
+ admin's approval, the wizard waits; keep the CLI running, open Slack's
793
+ **Request approval** page (the CLI prints the link), and click **Retry**
794
+ after the admin approves. Token values never print.
803
795
 
804
796
  `slack destroy` deletes the provisioned app for the selected
805
797
  environment. Tokens already written to `.env.local` stay in place and
@@ -808,23 +800,8 @@ stop working.
808
800
  `slack icon` sets the provisioned app's icon from an https image URL or
809
801
  a local png, jpg, or gif file of at most 512KB.
810
802
 
811
- `slack init` creates the channel file, development and production
812
- manifests, `env.example`, and setup status under the project. It refuses
813
- to overwrite a target file. If a collision occurs, it exits non-zero;
814
- files created earlier in the run remain. The token prefix defaults to
815
- the directory basename normalized to uppercase snake case. Explicit
816
- `--prefix` values use the same normalization when the Agent SDK builds token
817
- variable names. For example, `pr-approver` becomes
818
- `PR_APPROVER_SLACK_BOT_TOKEN`. `--no-prefix` uses shared
819
- `SLACK_BOT_TOKEN` and `SLACK_APP_TOKEN`. `--channel-posts` subscribes
820
- the manifests to channel-post events. The command always prints a JSON
821
- summary.
822
-
823
- `slack manifest` regenerates selected manifest files. `--env` defaults
824
- to `both`, and `--name` defaults to the directory name. `--print` writes
825
- the manifest JSON to stdout instead of changing files. With the default
826
- `--env both`, it prints development JSON, a `--- prod ---` separator,
827
- then production JSON.
803
+ `slack init` is removed. It exits non-zero and writes no files. Use
804
+ `slack create`.
828
805
 
829
806
  `slack doctor` checks both tokens, Socket Mode connectivity, and
830
807
  Slack's `auth.test`. It exits non-zero when any check fails.
@@ -208,9 +208,10 @@ Eval runs are asynchronous. Poll the run route for case progress and
208
208
  the final `completed` or `failed` status. Batch errors appear on the
209
209
  snapshot returned by the poll. Entries within `filterIds` and `tags`
210
210
  use OR semantics. When both fields are present, a case must match one
211
- entry from each field. Without a storage `evals` table in
212
- `agent/storage.ts` (see [Storage](../storage.md)), listed runs are
213
- process-memory only (capped by `maxPlaygroundRuns`).
211
+ entry from each field. Listed runs persist across restarts whenever
212
+ `agent/storage.ts` provides an `evals` table or a KV core with `delete`
213
+ and `list` (the table is derived — see [Storage](../storage.md));
214
+ otherwise they are process-memory only (capped by `maxPlaygroundRuns`).
214
215
 
215
216
  ## Dev-mode routes
216
217
 
package/docs/storage.md CHANGED
@@ -52,17 +52,22 @@ export default defineStorage({
52
52
 
53
53
  ## Which fields to provide
54
54
 
55
+ Implement the small KV core — `put`/`get`/`delete`/`list` plus the `cas`
56
+ group — and you get **full functionality**: eval-run and A/B history are
57
+ derived over the core automatically. The dedicated `evals` / `abs` groups
58
+ are backend-native optimizations, not required-or-lose-history hooks.
59
+
55
60
  | Field | Required | Role |
56
61
  | --- | --- | --- |
57
62
  | `put` | Yes | Write or update a value |
58
63
  | `cas` | For coordination | Conditional writes; see [Conditional writes](#conditional-writes-the-cas-group) |
59
- | `get` | For restore | Look up one key |
60
- | `list` | For restore | Return entries under a prefix, in key order |
61
- | `delete` | For cleanup | Remove a key |
64
+ | `get` | For restore | Look up one key (also: derived A/B snapshot backfill) |
65
+ | `list` | For restore | Return entries under a prefix, in key order (also: derived eval-runs hydrate) |
66
+ | `delete` | For cleanup | Remove a key (also: derived eval-runs pruning) |
62
67
  | `name` | No | Label surfaced on `GET /v1/info` diagnostics |
63
68
  | `policy` | No | Timing knobs; see [Policy](#policy) |
64
- | `evals` | No | Dedicated eval-runs table; see [Eval and A/B tables](#eval-and-a-b-tables) |
65
- | `abs` | No | Dedicated A/B metrics table; see [Eval and A/B tables](#eval-and-a-b-tables) |
69
+ | `evals` | No | Backend-native eval-runs table; derived over the core when omitted — see [Eval and A/B tables](#eval-and-a-b-tables) |
70
+ | `abs` | No | Backend-native A/B metrics table; derived over the core when omitted — see [Eval and A/B tables](#eval-and-a-b-tables) |
66
71
 
67
72
  A throwing `put` is logged and dropped. It never fails a turn. When
68
73
  resolving a missing continuation token, a throwing `get` fails the
@@ -71,23 +76,34 @@ follow-up so a store outage does not open a new session. Return
71
76
 
72
77
  ## Eval and A/B tables
73
78
 
74
- Two dedicated tables carry structured rows instead of opaque KV values.
75
- Both are optional and independent of `put` / `get` / `list`.
76
-
77
- `evals` keeps playground eval batches across restarts. Provide `put`,
78
- `delete`, and `list` over run snapshots keyed by `runId`. The Agent SDK
79
- upserts a snapshot as a batch starts, progresses, and finishes, prunes
80
- runs past the playground history window, and lists everything back at
81
- serve start. Without this table, eval history lives in process memory
82
- and a restart clears it. See [Evals](./evals.md#configure-eval-runs).
83
-
84
- `abs` exports live A/B metrics. Provide `putSample` to append one
85
- cumulative metric sample per enrolled experiment on each completed or
86
- failed turn. Optional `putSnapshot` and `getSnapshot` store and serve
87
- back the latest aggregate snapshot, so a replacement host with no local
88
- sessions can still serve the A/Bs surface. Without this table, samples
89
- only go where each experiment's `onSample` sends them; session event
90
- logs remain the assignment source of truth. See
79
+ Two dedicated table groups carry structured rows instead of opaque KV
80
+ values. Both are **optional optimizations**: when a group is not
81
+ authored, `defineStorage` derives it over the KV core, so a backend that
82
+ implements only the core loses nothing. Author a group only when the
83
+ backend has a better native shape (a real database table, an analytics
84
+ pipeline) the built-in `fileKv` and `cursorHostedStorage` both do.
85
+
86
+ `evals` keeps playground eval batches across restarts (`put`, `delete`,
87
+ `list` over run snapshots keyed by `runId`). The Agent SDK upserts a
88
+ snapshot as a batch starts, progresses, and finishes, prunes runs past
89
+ the playground history window, and lists everything back at serve start.
90
+ **Derived form**: one key per run under
91
+ `agentkit/v1/{agent}/eval-runs/{runId}` needs core `put` + `delete` +
92
+ `list`. Only a core missing `delete` or `list` leaves eval history in
93
+ process memory (cleared on restart). See
94
+ [Evals](./evals.md#configure-eval-runs).
95
+
96
+ `abs` exports live A/B metrics: `putSample` appends one cumulative
97
+ metric sample per enrolled experiment on each completed or failed turn;
98
+ optional `putSnapshot` / `getSnapshot` store and serve back the latest
99
+ aggregate so a replacement host with no local sessions can still serve
100
+ the A/Bs surface. **Derived form**: each sample lands as its own key
101
+ (`agentkit/v1/{agent}/ab-samples/{experiment}/{sessionId}/{at}` — a
102
+ blind append-only put, never a read-modify-write of one growing array)
103
+ and the snapshot lives at the fixed `agentkit/v1/{agent}/ab-snapshot`
104
+ key (last-write-wins is correct for "latest aggregate"). `putSample` and
105
+ `putSnapshot` need only core `put`; `getSnapshot` needs core `get`.
106
+ Session event logs remain the assignment source of truth either way. See
91
107
  [Live A/B metrics](./ab.md).
92
108
 
93
109
  ## Policy
@@ -60,9 +60,9 @@ Match your symptom below. Keep the commands as `agent-sdk`; see
60
60
  | What you see | What to do |
61
61
  | --- | --- |
62
62
  | Logs show `channel idle … missing credentials` | Expected when tokens are missing. Run `agent-sdk slack create --dir <agent>` to provision the app and write the tokens, or set `<PREFIX>_SLACK_BOT_TOKEN` and `<PREFIX>_SLACK_APP_TOKEN` per agent yourself, then run `agent-sdk slack doctor --prefix <PREFIX>`. |
63
- | `slack create` reports the app needs admin approval | The workspace requires admin approval for new apps. A Slack workspace admin approves it at the printed link (in the dashboard: **Approve in Slack**), then re-run `agent-sdk slack create` (or **Retry** in the dashboard). |
63
+ | `slack create` reports the app needs admin approval | Open Slack's **Request approval** page (the CLI prints the link; the same URL is **Send a reminder** after you submit). Managed install does not file the request. Keep the CLI running, then click **Retry** in the dashboard after an admin approves. |
64
64
  | The bot ignores ordinary channel posts | Default engagement is mentions and DMs only. Enable `engagement.channelPosts` with an allowlist, and subscribe the app to `message.channels` / `message.groups`. |
65
- | Approve / Deny buttons do nothing | Re-import a Slack app manifest with interactivity enabled. Channels that post approval cards need `toolApprovals: true` (and `interactivity: true` when you compose events by hand). |
65
+ | Approve / Deny buttons do nothing | Channels that post approval cards need `toolApprovals: true`. Recreate the app with `slack create` if interactivity is off. |
66
66
 
67
67
  ## What if host MCP OAuth fails?
68
68
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cursor/july",
3
- "version": "0.1.48",
3
+ "version": "0.1.51",
4
4
  "description": "(early alpha) Filesystem-first framework for defining Cursor agents as markdown and TypeScript and serving them over channels with the Cursor SDK.",
5
5
  "license": "SEE LICENSE IN LICENSE.md",
6
6
  "repository": {
@@ -97,7 +97,7 @@ Defaults that make first cuts good:
97
97
  `prompt\`…\`` / `prompt.lines\`…\`` from `@cursor/july` (dedents indented
98
98
  multi-line strings).
99
99
  - **Env prefix** for Slack tokens = upper-snake slug (`my-agent` →
100
- `MY_AGENT_SLACK_*`); `agent-sdk slack init` derives it for you.
100
+ `MY_AGENT_SLACK_*`); `agent-sdk slack create` derives it for you.
101
101
  Dedicated-app path only — the Cursor-hosted connection has no tokens.
102
102
  - **Host prep beats model wandering — for evidence, not judgment.** When the
103
103
  purpose has a deterministic setup step (fetch a PR, seed files), do it in
@@ -159,10 +159,9 @@ plan:
159
159
  short hand-written `agent/channels/slack.ts`
160
160
  (`slackChannel({ cursorAccount: true, agentName: "<Name>" })` — no
161
161
  tokens, no manifests); for a dedicated Socket Mode app do not hand-write
162
- the channel — `agent-sdk slack init --dir ./<slug> --name "<Name>"`
163
- generates `agent/channels/slack.ts` (with the env prefix) plus manifests
164
- and `env.example`; customize the generated file (e.g. `suggestedPrompts`)
165
- afterwards.
162
+ the channel — `agent-sdk slack create --dir ./<slug> --name "<Name>"`
163
+ opens the dashboard wizard (env prefix from the directory name);
164
+ customize `agent/channels/slack.ts` afterwards (e.g. `suggestedPrompts`).
166
165
  5. `evals/evals.config.ts` — `defineEvalConfig({ maxConcurrency: 20 })`
167
166
  (playground runs are memory-only unless you add `persistRuns`)
168
167
  (`maxConcurrency` is required; hard-capped at 200 due to model provider
@@ -1,34 +1,34 @@
1
1
  ---
2
2
  name: agentkit-setup-slack
3
3
  description: >-
4
- Put an Agent SDK agent in Slack. Covers the required connection decision
5
- (Cursor-hosted connection vs dedicated Socket Mode Slack app) with an
6
- AskQuestion gate, then both setup paths end to end cursorAccount
7
- sign-in + smoke, or manifests, tokens, doctor, smoke test, and opt-in
8
- Slack tool approvals (HITL). Read this skill when wiring Slack for an
9
- Agent SDK project.
4
+ Wire Slack to an Agent SDK agent. Gate Cursor-hosted vs a dedicated
5
+ Socket Mode app, then finish that path: cursorAccount sign-in + smoke,
6
+ or slack create via the dashboard wizard, doctor, and optional HITL.
7
+ Use when adding Slack to an agent.
10
8
  ---
11
9
 
12
10
  # Setup Slack for the Agent SDK
13
11
 
14
12
  Use this skill when a human asks to wire Slack to an Agent SDK agent.
15
13
 
16
- There are **two ways to connect**, and they differ mostly in setup cost:
14
+ There are **two ways to connect**:
17
15
 
18
16
  - **Path A — Cursor-hosted connection**
19
17
  (`slackChannel({ cursorAccount: true })`): rides the Cursor Slack
20
18
  integration already installed in the workspace. No Slack app, no
21
- manifests, no tokens, no Slack admin. Live in minutes.
19
+ tokens, no Slack admin. Live in minutes.
22
20
  - **Path B — Dedicated Slack app** (Socket Mode): the agent's own bot
23
- user, created from generated manifests with an `xoxb-…` + `xapp-…`
24
- token pair. Required for channel watching, approval buttons, or a
25
- distinct bot handle. When the workspace is enrolled in Cursor's
26
- **Add to Slack** (feature gate + a workspace-manager consent),
27
- `agent-sdk slack create` provisions all of it in one command.
21
+ user. `agent-sdk slack create` opens a signed-in Cursor dashboard
22
+ wizard; Slack consent and the bot name happen there. Tokens land in
23
+ `.env.local` and as deployment secrets. Required for channel watching,
24
+ approval buttons, or a distinct bot handle.
28
25
 
29
- **Do not generate manifests or ask for tokens until the decision below
30
- is made.** Defaulting into Path B buries the user in Slack admin work
31
- (two app creations, token minting, env wiring) they may not need.
26
+ Do not generate manifests or ask anyone to paste tokens. Defaulting into
27
+ Path B buries the user in Slack admin work they may not need.
28
+
29
+ Existing DIY bots that already have `<PREFIX>_SLACK_BOT_TOKEN` and
30
+ `_SLACK_APP_TOKEN` in `.env.local` keep working. Do not force them onto
31
+ the wizard.
32
32
 
33
33
  ## Step 0 — Choose the connection (required gate)
34
34
 
@@ -36,8 +36,8 @@ Walk the user through the tradeoffs before touching files:
36
36
 
37
37
  | | A: Cursor-hosted | B: Dedicated Slack app |
38
38
  | --- | --- | --- |
39
- | Setup | Zero Slack admin sign the host in (`agent-sdk login` / `CURSOR_API_KEY`) and serve | Enrolled in Cursor's Add to Slack: one `agent-sdk slack create` per env (app + install + tokens, signed-in host). Otherwise: a Slack admin creates **two** apps (dev + prod) from manifests, installs them, mints `xoxb-…` + `xapp-…` for each |
40
- | Prereq | Cursor Slack integration installed in the workspace and linked to the Cursor account | Permission to create Slack apps; token storage/rotation is on you |
39
+ | Setup | Zero Slack admin: sign the host in (`agent-sdk login` / `CURSOR_API_KEY`) and serve | One `agent-sdk slack create` per env. Finish in the dashboard wizard (Slack consent + bot name). Tokens are never shown. |
40
+ | Prereq | Cursor Slack integration installed in the workspace and linked to the Cursor account | Agent Serve access (`agent-sdk login`) and permission to approve a Slack app |
41
41
  | How users reach it | `@Cursor <AgentName> …`, DMs to @Cursor, replies in claimed threads | Its own bot user: @mention, DM, channel invites |
42
42
  | Identity | Posts as the Cursor app under the agent's name + icon | Own app name, avatar, and handle |
43
43
  | Channel watching (dispatch without a mention) | Not available | `engagement.channelPosts` allowlist |
@@ -45,7 +45,7 @@ Walk the user through the tradeoffs before touching files:
45
45
  | Reply delivery | Status while working, then one final post (no streaming edits) | Streaming replies with postMessage fallback |
46
46
  | Multi-agent hosts | Any number of agents, unique `agentName` each, no extra Slack apps | One Slack app + token pair **per agent** |
47
47
 
48
- Decision shortcuts skip the question when the request already decides:
48
+ Decision shortcuts; skip the question when the request already decides:
49
49
 
50
50
  - Needs channel watching, Approve/Deny buttons, `onBlockAction`, or its
51
51
  own bot user / handle → **Path B**. Say which requirement forced it.
@@ -56,19 +56,19 @@ Decision shortcuts — skip the question when the request already decides:
56
56
 
57
57
  ### Collect the decision with AskQuestion
58
58
 
59
- Otherwise ask one single-select question via the `AskQuestion` tool,
59
+ Otherwise ask. One single-select question via the `AskQuestion` tool,
60
60
  recommended option first so one click accepts it:
61
61
 
62
62
  - **Cursor-hosted Slack connection (recommended)** — zero Slack setup;
63
63
  sign in and mention `@Cursor <AgentName>`. No channel watching or
64
64
  approval buttons.
65
65
  - **Dedicated Slack app (Socket Mode)** — own bot user, channel
66
- watching, approval buttons; needs a Slack admin to create two apps
67
- and mint tokens.
66
+ watching, approval buttons. `agent-sdk slack create` opens the
67
+ dashboard wizard.
68
68
 
69
69
  If `AskQuestion` is unavailable in your environment, or the user does
70
70
  not answer, **default to Path A (Cursor-hosted)**: state the assumption
71
- in one line and proceed. It is the reversible choice a dedicated app
71
+ in one line and proceed. It is the reversible choice. A dedicated app
72
72
  can be added later as a *second* channel file without losing anything.
73
73
  Never mix both in one channel definition: `cursorAccount: true` rejects
74
74
  `credentials` / `envPrefix` at construction.
@@ -80,8 +80,8 @@ threaded reply. No Slack app, no tokens, no manifests.
80
80
 
81
81
  ### A1 — Author the channel (agent)
82
82
 
83
- Write `agent/channels/slack.ts` by hand do **not** run
84
- `agent-sdk slack init` (that scaffolds the Path B manifests + env):
83
+ Write `agent/channels/slack.ts` by hand. Do not run `slack create` for
84
+ this path:
85
85
 
86
86
  ```ts
87
87
  import { slackChannel } from "@cursor/july/channels/slack";
@@ -94,7 +94,7 @@ export default slackChannel({
94
94
  ```
95
95
 
96
96
  `agentName` defaults from the mount slug (PascalCase) and must be a
97
- single token string literals with spaces fail typecheck; runtime
97
+ single token. String literals with spaces fail typecheck; runtime
98
98
  values throw at construction/serve. Names must be unique on the host;
99
99
  an unmatched `@Cursor <name>` stays with Cursor's normal Slack agent.
100
100
  External senders (Slack Connect / guests / other workspaces) are
@@ -117,7 +117,7 @@ An unsigned host fails `serve` with a sign-in hint naming the channel.
117
117
  `@Cursor MyAgent <question>` (or DM @Cursor)
118
118
  2. Confirm a working status while the turn runs, then a threaded reply
119
119
  posted under the agent's name and icon
120
- 3. Reply in the thread without re-mentioning it stays with the agent
120
+ 3. Reply in the thread without re-mentioning; it stays with the agent
121
121
 
122
122
  ### Path A limits (enforced at construction)
123
123
 
@@ -135,109 +135,47 @@ cursor-account channel and add a Path B channel file beside it.
135
135
 
136
136
  ## Path B — Dedicated Slack app (Socket Mode)
137
137
 
138
- Goal:
139
-
140
- - Importable **dev** and **prod** Slack app manifests (Socket Mode on)
141
- - App-level Token (`xapp-…`, `connections:write`) + Bot token (`xoxb-…`)
142
- - No public Request URL (Socket Mode only)
143
- - Thread ↔ session via `continuationToken = channelId:threadTs`
144
- - One Slack app (token pair) **per agent** when serving multiple demos
145
-
146
- Update `.agent-serve/slack/setup-status.json` as you complete phases.
147
-
148
- ### Provisioned variant — `agent-sdk slack create` (primary when enrolled)
149
-
150
- When the Slack workspace is enrolled in Cursor's **Add to Slack**
151
- (the provisioning feature gate plus a workspace-manager consent), one
152
- command collapses Phases 0–3 — manifest import, app creation, install,
153
- and token minting:
138
+ Goal: one dedicated bot per agent, tokens in `.env.local`, local serve
139
+ without a cloud deploy. The dashboard wizard is the only first-run.
154
140
 
155
141
  ```bash
156
- agent-sdk slack create --dir <agent> # dev app (default)
157
- agent-sdk slack create --dir <agent> --prod # prod app
142
+ agent-sdk login
143
+ agent-sdk slack create --dir .
158
144
  ```
159
145
 
160
- `create` scaffolds `agent/channels/slack.ts` + the `.agent-serve/slack`
161
- files when missing (never overwriting existing ones), runs the browser
162
- consent flow when the workspace is not connected yet, provisions +
163
- installs the app, writes `<PREFIX>_SLACK_BOT_TOKEN` /
164
- `<PREFIX>_SLACK_APP_TOKEN` into `<dir>/.env.local` (replacing stale
165
- lines), and finishes with `doctor`. It needs a signed-in host
166
- (`agent-sdk login` / `CURSOR_API_KEY`). Pass `--slack-team <id>` when
167
- several workspaces are connected. If the install lands in
168
- `pending_admin_approval`, a Slack workspace admin must approve the
169
- printed link — then re-run `create` to finish and mint the tokens.
170
- `agent-sdk slack destroy` deletes the provisioned app (tokens left in
171
- `.env.local` simply stop working). Skip to Phase 4 when `create`
172
- succeeds — `dev`/`serve` load the agent's `.env.local` (real env wins).
173
- Note: re-running `create` rebuilds the app manifest from the command's
174
- flags, so any customization made outside the CLI resets to it.
175
-
176
- If the command reports the feature gate is not enabled (the workspace
177
- is not enrolled), fall back to the manual manifest-import flow below
178
- (Phases 0–3).
179
-
180
- ### Phase 0 — Generate (agent)
181
-
182
- ```bash
183
- pnpm exec tsx packages/agent-serve/src/bin/agent-serve.ts slack init \
184
- --dir <agent> --name "My Agent"
185
- ```
186
-
187
- Creates:
188
-
189
- - `agent/channels/slack.ts` with `envPrefix` from the directory name
190
- - `.agent-serve/slack/manifest.{dev,prod}.json`
191
- - `.agent-serve/slack/env.example` (`<PREFIX>_SLACK_BOT_TOKEN` / `_APP_TOKEN`)
192
-
193
- Use `--no-prefix` for the shared `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` globals
194
- (single-agent only). Use `--prefix CUSTOM` to override the default prefix.
195
-
196
- These files deliberately omit `settings.managed_app_settings` — Slack accepts
197
- that block only from a manager app's user token, so it belongs to the
198
- `slack create` path, not to a manifest a human pastes in.
199
-
200
- ### Phase 1 — Create apps (human)
146
+ That opens the signed-in Cursor dashboard. Sign in as the same Cursor
147
+ account that ran the command. Click **Add Slack to this agent**, approve
148
+ Slack's consent screen, pick the bot name, and continue. The CLI waits
149
+ and writes `<PREFIX>_SLACK_BOT_TOKEN` / `<PREFIX>_SLACK_APP_TOKEN` into
150
+ `<dir>/.env.local`, then runs `doctor`. Token values never print.
201
151
 
202
- 1. Open https://api.slack.com/apps **Create New App** **From a manifest**
203
- 2. Paste `manifest.dev.json` create the *dev* app
204
- 3. Repeat with `manifest.prod.json` for prod
152
+ `--prod` provisions the prod app (default is dev). `--name` / `--icon` /
153
+ `--channel-posts` prefill the wizard. `--prefix` / `--no-prefix` set the
154
+ env-var names.
205
155
 
206
- Stop and ask the human to complete this gate.
156
+ If Slack asks a workspace admin to approve the app, keep the CLI
157
+ running. Open Slack's **Request approval** page (the CLI prints the
158
+ link; the same URL is **Send a reminder** after you submit). Managed
159
+ install does not file the request. After an admin approves, click
160
+ **Retry** in the wizard.
207
161
 
208
- ### Phase 2 Install + tokens (human)
162
+ `create` scaffolds `agent/channels/slack.ts` when missing. Do not paste
163
+ a manifest at api.slack.com. `slack init` is removed.
209
164
 
210
- For each app:
165
+ Existing tokens in `.env.local` keep working. Skip the wizard for those
166
+ agents unless you want a Cursor-managed app.
211
167
 
212
- 1. **Install to Workspace** — copy Bot User OAuth Token (`xoxb-…`)
213
- 2. **Basic Information → App-Level Tokens** — Create Token with scope `connections:write` → copy (`xapp-…`)
214
-
215
- ### Phase 3 — Env (agent)
216
-
217
- Write into `.env.local` (dev app), using the keys from `env.example`:
218
-
219
- ```bash
220
- MY_AGENT_SLACK_BOT_TOKEN=xoxb-…
221
- MY_AGENT_SLACK_APP_TOKEN=xapp-…
222
- ```
168
+ Then:
223
169
 
224
170
  ```bash
225
171
  agent-sdk slack doctor --prefix MY_AGENT
226
- ```
227
-
228
- Stop when `app_token`, `connections_open`, `bot_token`, and `auth_test` are green.
229
-
230
- ### Phase 4 — Serve + smoke (agent + human)
231
-
232
- ```bash
233
172
  agent-sdk dev .
234
173
  ```
235
174
 
236
175
  Confirm log: `[agent-sdk/slack] Socket Mode connected`.
237
176
 
238
177
  When tokens are missing the channel logs
239
- `channel idle reason=missing credentials need=…` and `serve` continues — useful
240
- when mounting a folder of agents where only some have tokens.
178
+ `channel idle reason=missing credentials need=…` and `serve` continues.
241
179
 
242
180
  Human:
243
181
 
@@ -249,6 +187,15 @@ Human:
249
187
  - `session start …`
250
188
  - `reply delivered via postMessage|stream …`
251
189
 
190
+ The dashboard lists a first-run agent as **Not deployed yet**. Local
191
+ serve does not need a hosted engine. The next `agent-sdk deploy` (or
192
+ dashboard **Deploy**) injects the stored secrets.
193
+
194
+ A second `slack create` for the same agent and env overwrites that Slack
195
+ app. It keeps the Slack app id and replaces the manifest and tokens.
196
+ `agent-sdk slack destroy` deletes the provisioned app. Tokens left in
197
+ `.env.local` simply stop working.
198
+
252
199
  ## Features (defaults ON)
253
200
 
254
201
  - Chat streaming (`chat.startStream` / `appendStream` / `stopStream`) with postMessage fallback (Path B; Path A posts one final reply)
@@ -262,7 +209,7 @@ If a Slack API is unavailable (`method_not_found` / `missing_scope`), the pack f
262
209
 
263
210
  ## Engagement: mentions by default, channel watch opt-in (Path B only)
264
211
 
265
- The pack dispatches only on `app_mention` + DMs unless told otherwise
212
+ The pack dispatches only on `app_mention` + DMs unless told otherwise:
266
213
  summoned, never proactive. To watch channels (dispatch on new posts without
267
214
  a mention), opt in explicitly:
268
215
 
@@ -270,7 +217,7 @@ a mention), opt in explicitly:
270
217
  export default slackChannel({
271
218
  engagement: {
272
219
  channelPosts: {
273
- allow: ["#issues-glass"], // explicit allowlist; no wildcard exists
220
+ allow: ["#issues-cursor-desktop"], // explicit allowlist; no wildcard exists
274
221
  posts: "top-level", // default — thread replies never dispatch
275
222
  debounceMs: 15_000, // optional: edits settle, deletes cancel
276
223
  },
@@ -279,9 +226,9 @@ export default slackChannel({
279
226
  });
280
227
  ```
281
228
 
282
- Requirements: generate manifests with `slack init --channel-posts` (or add
283
- `message.channels` / `message.groups` events + re-import), and invite the
284
- bot to each watched channel. Posts mentioning the bot stay on the
229
+ Pass `--channel-posts` on `slack create` so the wizard-built app
230
+ subscribes to `message.channels` / `message.groups`. Invite the bot to
231
+ each watched channel. Posts mentioning the bot stay on the
285
232
  `app_mention` path; watch sessions reuse the thread-scoped principal with an
286
233
  `engagement: "channel_post"` attribute, so a later mention continues the
287
234
  thread. `engagement.mentions` / `engagement.directMessages` can be set to
@@ -290,7 +237,7 @@ thread. `engagement.mentions` / `engagement.directMessages` can be set to
290
237
  ## Tool approvals over Slack (opt-in HITL, Path B only)
291
238
 
292
239
  Tools with `needsApproval` park until a human approves or denies. To route
293
- that through Slack, set `toolApprovals: true` on `slackChannel` it posts
240
+ that through Slack, set `toolApprovals: true` on `slackChannel`. It posts
294
241
  Block Kit Approve/Deny cards and routes Socket Mode `interactive` clicks
295
242
  back to the parked call:
296
243
 
@@ -303,10 +250,9 @@ export default slackChannel({
303
250
 
304
251
  Requirements and caveats:
305
252
 
306
- - The Slack app manifest needs **interactivity** enabled
307
- (`buildSlackManifest({ interactivity: true })`; `toolApprovals: true`
308
- implies the Socket Mode routing, but the app must allow it). Re-import
309
- the manifest after changing this.
253
+ - The Slack app needs **interactivity** enabled. The wizard turns this
254
+ on when `toolApprovals` is in play; `buildSlackManifest({ interactivity: true })`
255
+ is the same switch for existing apps.
310
256
  - Composing by hand: spread `buildToolApprovalEvents({ credentials })` into
311
257
  `events` **and** set `interactivity: true` on the channel.
312
258
  - Cards show **redacted / truncated** args (Block Kit limits); execution
@@ -323,27 +269,23 @@ Requirements and caveats:
323
269
  ## Notes
324
270
 
325
271
  - Dev and prod are **separate Slack apps** (separate tokens) on Path B.
326
- Path A has no per-env app split the host's Cursor account decides
272
+ Path A has no per-env app split; the host's Cursor account decides
327
273
  where it relays.
328
- - Socket Mode / the Cursor relay are outbound only no Events HTTP /
274
+ - Socket Mode / the Cursor relay are outbound only. No Events HTTP /
329
275
  Request URL path on either connection.
330
- - Do not `await waitForCompletion()` inside Slack dispatch handlers the pack uses `waitUntil`.
276
+ - Do not `await waitForCompletion()` inside Slack dispatch handlers. The pack uses `waitUntil`.
331
277
  - Do not share one token pair across multiple agents in the same process.
332
278
 
333
279
  ## CLI reference
334
280
 
335
- `slack create` / `destroy` / `init` / `manifest` / `doctor` are Path B
336
- tooling; Path A needs only `login`.
281
+ Path B tooling is `create` / `destroy` / `icon` / `doctor`. Path A needs
282
+ only `login`. `slack setup` prints this chooser. `slack init` hard-errors.
337
283
 
338
284
  ```bash
339
285
  agent-sdk slack setup
340
- agent-sdk slack create --dir . # provision via Add to Slack (dev app)
286
+ agent-sdk slack create --dir . # dashboard wizard (dev app)
341
287
  agent-sdk slack create --dir . --prod # prod app
342
288
  agent-sdk slack create --dir . --slack-team T0123ABCD
343
289
  agent-sdk slack destroy --dir . [--prod] [--slack-team T0123ABCD]
344
- agent-sdk slack init --dir . --name "My Agent"
345
- agent-sdk slack init --dir . --no-prefix
346
- agent-sdk slack init --dir . --channel-posts # + message.channels/groups events
347
- agent-sdk slack manifest --env both
348
290
  agent-sdk slack doctor --prefix MY_AGENT
349
291
  ```