@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.
- package/AGENTS.md +3 -3
- package/README.md +7 -14
- package/dist/bin/agent-serve.js +22 -8
- package/dist/channels/slack/init.d.ts +2 -3
- package/dist/channels/slack/init.d.ts.map +1 -1
- package/dist/channels/slack/init.js +8 -43
- package/dist/channels/slack/manifest.d.ts +3 -3
- package/dist/channels/slack/manifest.js +3 -3
- package/dist/channels/slack/setup.d.ts +2 -11
- package/dist/channels/slack/setup.d.ts.map +1 -1
- package/dist/channels/slack/setup.js +26 -94
- package/dist/channels/slack/types.d.ts +3 -4
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +5 -5
- package/dist/docs/assets/{ab.md.hdxsvX5M.js → ab.md.DYjwREAP.js} +2 -2
- package/dist/docs/assets/{ab.md.hdxsvX5M.lean.js → ab.md.DYjwREAP.lean.js} +1 -1
- package/dist/docs/assets/{app.BC1P20xI.js → app.C51TX1Bw.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.D2DpXdZN.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.C_900xn2.js → VPLocalSearchBox.BB9HCJPq.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CT135Jhh.js → theme.Dp-0SZcu.js} +2 -2
- package/dist/docs/assets/{deployment.md.Cdp4rTE4.js → deployment.md.B8kW-h7P.js} +1 -1
- package/dist/docs/assets/{evals.md.qeoGgPw0.js → evals.md.CVe_O75-.js} +3 -3
- package/dist/docs/assets/{evals.md.qeoGgPw0.lean.js → evals.md.CVe_O75-.lean.js} +1 -1
- package/dist/docs/assets/{example-agents_benny.md.l7JTmm8X.js → example-agents_benny.md.B-LIDGja.js} +1 -1
- package/dist/docs/assets/{example-agents_oncall.md.ZE0n6ZFN.js → example-agents_oncall.md.CBmyuAKc.js} +2 -2
- package/dist/docs/assets/{guides_human-in-the-loop.md.BWvT7UqY.js → guides_human-in-the-loop.md.Cf8kIIqC.js} +2 -2
- package/dist/docs/assets/{guides_human-in-the-loop.md.BWvT7UqY.lean.js → guides_human-in-the-loop.md.Cf8kIIqC.lean.js} +1 -1
- package/dist/docs/assets/{guides_slack.md.zriQpU_9.js → guides_slack.md.D2nTRu9M.js} +7 -12
- package/dist/docs/assets/guides_slack.md.D2nTRu9M.lean.js +1 -0
- package/dist/docs/assets/{reference_cli.md.BDmjPPAm.js → reference_cli.md.CGKfz_Yj.js} +3 -7
- package/dist/docs/assets/{reference_cli.md.BDmjPPAm.lean.js → reference_cli.md.CGKfz_Yj.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.DGrw_wOu.js → reference_http-api.md.DMbdFGVQ.js} +1 -1
- package/dist/docs/assets/{storage.md.CJYd5YmN.js → storage.md.D8NQ389l.js} +3 -3
- package/dist/docs/assets/storage.md.D8NQ389l.lean.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.CkgwmVI0.js → troubleshooting.md.C6n3wCr6.js} +1 -1
- package/dist/docs/building-with-agents.html +3 -3
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +5 -5
- package/dist/docs/evals.html +6 -6
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +5 -5
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +3 -3
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +6 -6
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +5 -5
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/opentelemetry.html +3 -3
- package/dist/docs/guides/slack.html +11 -16
- package/dist/docs/guides/webhooks.html +3 -3
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +3 -3
- package/dist/docs/quickstart.html +3 -3
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/artifacts.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +6 -10
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +3 -3
- package/dist/docs/reference/http-api.html +5 -5
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +5 -5
- package/dist/docs/templates/triage.html +3 -3
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/internal/cli-ax.js +3 -3
- package/dist/internal/cli-cursor.d.ts +18 -0
- package/dist/internal/cli-cursor.d.ts.map +1 -1
- package/dist/internal/cli-cursor.js +25 -0
- package/dist/internal/cli-slack.d.ts +3 -4
- package/dist/internal/cli-slack.d.ts.map +1 -1
- package/dist/internal/cli-slack.js +126 -325
- package/dist/internal/convert-automation/convert-workflow.js +2 -2
- package/dist/internal/event-log.d.ts +17 -0
- package/dist/internal/event-log.d.ts.map +1 -1
- package/dist/internal/event-log.js +32 -2
- package/dist/internal/process-memory-telemetry.d.ts +90 -0
- package/dist/internal/process-memory-telemetry.d.ts.map +1 -0
- package/dist/internal/process-memory-telemetry.js +259 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +9 -10
- package/dist/internal/session-engine.d.ts +4 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +19 -5
- package/dist/internal/slack-provision-client.d.ts +41 -6
- package/dist/internal/slack-provision-client.d.ts.map +1 -1
- package/dist/internal/slack-provision-client.js +53 -7
- package/dist/playground/assets/{index-DEVTyeOu.js → index-BKMz70wx.js} +41 -41
- package/dist/playground/assets/index-BmMrulSc.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +36 -10
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +82 -6
- package/docs/ab.md +4 -3
- package/docs/deployment.md +1 -1
- package/docs/evals.md +10 -7
- package/docs/example-agents/benny.md +2 -3
- package/docs/example-agents/oncall.md +4 -5
- package/docs/guides/human-in-the-loop.md +1 -1
- package/docs/guides/slack.md +51 -112
- package/docs/reference/cli.md +14 -37
- package/docs/reference/http-api.md +4 -3
- package/docs/storage.md +38 -22
- package/docs/troubleshooting.md +2 -2
- package/package.json +1 -1
- package/skills/create-agent/SKILL.md +4 -5
- package/skills/setup-slack/SKILL.md +74 -132
- package/src/bin/agent-serve.ts +26 -9
- package/src/channels/slack/init.ts +10 -71
- package/src/channels/slack/manifest.ts +3 -3
- package/src/channels/slack/setup.ts +25 -103
- package/src/channels/slack/types.ts +3 -4
- package/src/internal/cli-ax.ts +3 -3
- package/src/internal/cli-cursor.ts +34 -0
- package/src/internal/cli-slack.ts +136 -394
- package/src/internal/convert-automation/convert-workflow.ts +2 -2
- package/src/internal/event-log.ts +45 -7
- package/src/internal/process-memory-telemetry.ts +373 -0
- package/src/internal/server.ts +13 -0
- package/src/internal/session-engine.ts +20 -1
- package/src/internal/slack-provision-client.ts +90 -9
- package/src/storage.ts +130 -11
- package/dist/docs/assets/chunks/@localSearchIndexroot.DV5SAHnQ.js +0 -1
- package/dist/docs/assets/guides_slack.md.zriQpU_9.lean.js +0 -1
- package/dist/docs/assets/storage.md.CJYd5YmN.lean.js +0 -1
- package/dist/playground/assets/index-CiCmH6R-.css +0 -1
- /package/dist/docs/assets/{deployment.md.Cdp4rTE4.lean.js → deployment.md.B8kW-h7P.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_benny.md.l7JTmm8X.lean.js → example-agents_benny.md.B-LIDGja.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_oncall.md.ZE0n6ZFN.lean.js → example-agents_oncall.md.CBmyuAKc.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.DGrw_wOu.lean.js → reference_http-api.md.DMbdFGVQ.lean.js} +0 -0
- /package/dist/docs/assets/{troubleshooting.md.CkgwmVI0.lean.js → troubleshooting.md.C6n3wCr6.lean.js} +0 -0
package/docs/reference/cli.md
CHANGED
|
@@ -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>]
|
|
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
|
|
783
|
+
`slack setup` prints the two-product chooser and doesn't change files.
|
|
788
784
|
|
|
789
|
-
`slack create`
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
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`
|
|
812
|
-
|
|
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.
|
|
212
|
-
`agent/storage.ts`
|
|
213
|
-
|
|
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 |
|
|
65
|
-
| `abs` | No |
|
|
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
|
|
75
|
-
Both are optional
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
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
|
package/docs/troubleshooting.md
CHANGED
|
@@ -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 |
|
|
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 |
|
|
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.
|
|
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
|
|
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
|
|
163
|
-
|
|
164
|
-
|
|
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
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
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
|
|
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
|
-
|
|
19
|
+
tokens, no Slack admin. Live in minutes.
|
|
22
20
|
- **Path B — Dedicated Slack app** (Socket Mode): the agent's own bot
|
|
23
|
-
user
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
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
|
-
|
|
30
|
-
|
|
31
|
-
|
|
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
|
|
40
|
-
| Prereq | Cursor Slack integration installed in the workspace and linked to the Cursor account |
|
|
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
|
|
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
|
|
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
|
|
67
|
-
|
|
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
|
|
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
|
|
84
|
-
|
|
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
|
|
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
|
|
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
|
|
157
|
-
agent-sdk slack create --dir
|
|
142
|
+
agent-sdk login
|
|
143
|
+
agent-sdk slack create --dir .
|
|
158
144
|
```
|
|
159
145
|
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
consent
|
|
163
|
-
|
|
164
|
-
`<
|
|
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
|
-
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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
|
|
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-
|
|
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
|
-
|
|
283
|
-
`message.channels` / `message.groups
|
|
284
|
-
|
|
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
|
|
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
|
|
307
|
-
|
|
308
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
336
|
-
|
|
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 . #
|
|
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
|
```
|