@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
@@ -8,8 +8,8 @@
8
8
  />
9
9
  <meta name="viewport" content="width=device-width, initial-scale=1" />
10
10
  <title>agent-serve playground</title>
11
- <script type="module" crossorigin src="./assets/index-DEVTyeOu.js"></script>
12
- <link rel="stylesheet" crossorigin href="./assets/index-CiCmH6R-.css">
11
+ <script type="module" crossorigin src="./assets/index-BKMz70wx.js"></script>
12
+ <link rel="stylesheet" crossorigin href="./assets/index-BmMrulSc.css">
13
13
  </head>
14
14
  <body>
15
15
  <div id="root"></div>
package/dist/storage.d.ts CHANGED
@@ -9,9 +9,12 @@
9
9
  * The sink is a plain key-value store — put/get/delete/list, no schema —
10
10
  * plus a conditional-write group ({@link StorageConfig.cas}, the substrate
11
11
  * for framework coordination; optional for plain storage, required by
12
- * coordination features) and two optional dedicated tables
13
- * ({@link StorageConfig.evals} and {@link StorageConfig.abs}) for
14
- * eval-run and A/B history:
12
+ * coordination features). Implementing that small KV core is enough for
13
+ * FULL functionality: eval-run and A/B history are derived over the core
14
+ * when the optional dedicated tables ({@link StorageConfig.evals} and
15
+ * {@link StorageConfig.abs}) are not authored — those groups exist as
16
+ * backend-native optimizations (a real table, an analytics pipeline),
17
+ * not as required-or-lose-history hooks:
15
18
  *
16
19
  * ```ts
17
20
  * import { defineStorage } from "@anysphere/agent-serve/storage";
@@ -178,13 +181,20 @@ export interface StorageConfig {
178
181
  /** Timing knobs; see {@link StoragePolicy}. */
179
182
  policy?: StoragePolicy;
180
183
  /**
181
- * Dedicated eval-runs table. Omit it and playground eval history stays
182
- * in process memory (lost on restart).
184
+ * Dedicated eval-runs table a backend-native optimization, not a
185
+ * requirement. When omitted, `defineStorage` derives the table over the
186
+ * KV core (one key per run under `agentkit/v1/{agent}/eval-runs/`),
187
+ * which needs core `put`, `delete`, and `list`; only when the core
188
+ * lacks `delete` or `list` does playground eval history stay in process
189
+ * memory (lost on restart).
183
190
  */
184
191
  evals?: StorageEvalsTable;
185
192
  /**
186
- * Dedicated A/B table. Omit it and metric samples are not exported
187
- * (session event logs remain the assignment/fold source of truth).
193
+ * Dedicated A/B table a backend-native optimization, not a
194
+ * requirement. When omitted, `defineStorage` derives it over the KV
195
+ * core: `putSample` and `putSnapshot` need only core `put` (always
196
+ * present), `getSnapshot` additionally needs core `get`. Session event
197
+ * logs remain the assignment/fold source of truth either way.
188
198
  */
189
199
  abs?: StorageABTable;
190
200
  /**
@@ -217,7 +227,8 @@ export interface StorageConfig {
217
227
  /**
218
228
  * All entries under a key prefix, in ascending key order. Optional —
219
229
  * required for the **startup bulk restore** (sessions + event streams)
220
- * and playground eval history.
230
+ * and, together with `delete`, for the derived eval-runs table
231
+ * (playground eval history).
221
232
  */
222
233
  list?(prefix: string, ctx: StorageContext): StorageEntry[] | Promise<StorageEntry[]>;
223
234
  }
@@ -252,9 +263,14 @@ export declare const STORAGE_KEY_ROOT: "agentkit/v1";
252
263
  * | `agentkit/v1/{agent}/session-events/{sessionId}/{index}` | `SessionEvent[]` chunk (index = first event's index, zero-padded) |
253
264
  * | `agentkit/v1/{agent}/continuation/{channelId}/{token}` | `{ sessionId }` |
254
265
  * | `agentkit/v1/{agent}/kv/{key}` | Author JSON via {@link HostContext.kv} |
266
+ * | `agentkit/v1/{agent}/eval-runs/{runId}` | `EvalRunSnapshot` (derived `evals` table) |
267
+ * | `agentkit/v1/{agent}/ab-samples/{experiment}/{sessionId}/{at}` | `ABMetricSample` (derived `abs` table, append-only) |
268
+ * | `agentkit/v1/{agent}/ab-snapshot` | `ABSnapshot` (derived `abs` table, LWW) |
255
269
  *
256
- * Eval-run and A/B history do not flow through this KV scheme — they have
257
- * dedicated tables ({@link StorageConfig.evals} / {@link StorageConfig.abs}).
270
+ * The `eval-runs` / `ab-samples` / `ab-snapshot` families are minted only
271
+ * by the tables `defineStorage` derives over the KV core; a backend that
272
+ * authors dedicated {@link StorageConfig.evals} / {@link StorageConfig.abs}
273
+ * groups never sees them.
258
274
  */
259
275
  export declare const storageKeys: {
260
276
  readonly session: (agent: string, sessionId: string) => string;
@@ -268,6 +284,16 @@ export declare const storageKeys: {
268
284
  */
269
285
  readonly kv: (agent: string, key: string) => string;
270
286
  readonly kvPrefix: (agent: string) => string;
287
+ /** One playground eval-run snapshot (derived `evals` table). */
288
+ readonly evalRun: (agent: string, runId: string) => string;
289
+ readonly evalRunsPrefix: (agent: string) => string;
290
+ /**
291
+ * One A/B metric sample (derived `abs` table); the segments mirror the
292
+ * dedicated table's row identity (experiment + sessionId + at).
293
+ */
294
+ readonly abSample: (agent: string, experiment: string, sessionId: string, at: string) => string;
295
+ /** Latest aggregate A/B snapshot (derived `abs` table, LWW). */
296
+ readonly abSnapshot: (agent: string) => string;
271
297
  };
272
298
  /**
273
299
  * Max bytes a caller-controlled key segment may occupy after URI-encoding.
@@ -1 +1 @@
1
- {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"storage.d.ts","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoDG;AAGH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,2BAA2B,CAAC;AAE5D,OAAO,KAAK,EAAE,SAAS,EAAE,WAAW,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAM3E,wEAAwE;AACxE,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,SAAS,CAAC;CAClB;AAED,yCAAyC;AACzC,MAAM,WAAW,cAAc;IAC7B,uEAAuE;IACvE,SAAS,EAAE,MAAM,CAAC;IAClB,sEAAsE;IACtE,WAAW,EAAE,MAAM,CAAC;IACpB;;;;;;;OAOG;IACH,MAAM,EAAE,QAAQ,GAAG,UAAU,GAAG,SAAS,GAAG,cAAc,CAAC;CAC5D;AAED,MAAM,WAAW,aAAa;IAC5B;;;;;;OAMG;IACH,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB;;;;;;;;;OASG;IACH,OAAO,CAAC,EAAE,oBAAoB,GAAG,KAAK,CAAC;CACxC;AAED,mFAAmF;AACnF,MAAM,WAAW,oBAAoB;IACnC,wFAAwF;IACxF,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB;;;;;OAKG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED;;;;;GAKG;AACH,MAAM,WAAW,iBAAiB;IAChC,mEAAmE;IACnE,GAAG,CAAC,GAAG,EAAE,eAAe,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACrE,gEAAgE;IAChE,MAAM,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACjE,+EAA+E;IAC/E,IAAI,CAAC,GAAG,EAAE,cAAc,GAAG,eAAe,EAAE,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAAC;CAC3E;AAED;;;;;;GAMG;AACH,MAAM,WAAW,cAAc;IAC7B,gEAAgE;IAChE,SAAS,CAAC,MAAM,EAAE,cAAc,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC7E,4EAA4E;IAC5E,WAAW,CAAC,CAAC,QAAQ,EAAE,UAAU,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,6EAA6E;IAC7E,WAAW,CAAC,CACV,GAAG,EAAE,cAAc,GAClB,UAAU,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;CAC3E;AAED;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,WAAW,eAAe;IAC9B,iEAAiE;IACjE,cAAc,CACZ,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,GAAG,gBAAgB,GAAG,SAAS,CAAC;IACxE,4EAA4E;IAC5E,WAAW,CACT,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,EAChB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACtC;;;OAGG;IACH,YAAY,CACV,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,SAAS,EAChB,eAAe,EAAE,MAAM,EACvB,GAAG,EAAE,cAAc,GAClB,OAAO,CAAC,WAAW,CAAC,GAAG,WAAW,CAAC;IACtC,uDAAuD;IACvD,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,GAAG,MAAM,EAAE,CAAC;CAC7E;AAED,MAAM,WAAW,aAAa;IAC5B,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+CAA+C;IAC/C,MAAM,CAAC,EAAE,aAAa,CAAC;IACvB;;;;;;;OAOG;IACH,KAAK,CAAC,EAAE,iBAAiB,CAAC;IAC1B;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,cAAc,CAAC;IACrB;;;;;;OAMG;IACH,GAAG,CAAC,EAAE,eAAe,CAAC;IACtB;;;;;;OAMG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC9E,kEAAkE;IAClE,MAAM,CAAC,CAAC,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,cAAc,GAAG,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAChE;;;;;;;OAOG;IACH,GAAG,CAAC,CACF,GAAG,EAAE,MAAM,EACX,GAAG,EAAE,cAAc,GAClB,SAAS,GAAG,SAAS,GAAG,IAAI,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,GAAG,IAAI,CAAC,CAAC;IACxE;;;;;OAKG;IACH,IAAI,CAAC,CACH,MAAM,EAAE,MAAM,EACd,GAAG,EAAE,cAAc,GAClB,YAAY,EAAE,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;CAC7C;AAED,MAAM,MAAM,iBAAiB,GAAG,aAAa,GAAG;IAC9C,QAAQ,CAAC,YAAY,EAAE,SAAS,CAAC;CAClC,CAAC;AAEF;;;GAGG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,iBAAiB,CAyEtE;AA+ED;;;GAGG;AACH,eAAO,MAAM,gBAAgB,EAAG,aAAsB,CAAC;AAEvD;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,WAAW;aACtB,OAAO,UAAU,MAAM,aAAa,MAAM,KAAG,MAAM;aAEnD,aAAa,UAAU,MAAM,KAAG,MAAM;aAEtC,aAAa,UACJ,MAAM,aACF,MAAM,cACL,MAAM,KACjB,MAAM;aAET,mBAAmB,UAAU,MAAM,aAAa,MAAM,KAAG,MAAM;aAE/D,YAAY,UACH,MAAM,aACF,MAAM,mBACA,MAAM,KACtB,MAAM;IAET;;;OAGG;aACH,EAAE,UAAU,MAAM,OAAO,MAAM,KAAG,MAAM;aAExC,QAAQ,UAAU,MAAM,KAAG,MAAM;IACjC,gEAAgE;aAChE,OAAO,UAAU,MAAM,SAAS,MAAM,KAAG,MAAM;aAE/C,cAAc,UAAU,MAAM,KAAG,MAAM;IAEvC;;;OAGG;aACH,QAAQ,UACC,MAAM,cACD,MAAM,aACP,MAAM,MACb,MAAM,KACT,MAAM;IAET,gEAAgE;aAChE,UAAU,UAAU,MAAM,KAAG,MAAM;CAE3B,CAAC;AAEX;;;;;GAKG;AACH,eAAO,MAAM,qBAAqB,MAAM,CAAC;AAEzC;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAM9C;AAMD,eAAO,MAAM,oCAAoC,OAAQ,CAAC;AAC1D,eAAO,MAAM,kCAAkC,EAAE,MAA8B,CAAC;AAChF,eAAO,MAAM,uCAAuC,aAAgB,CAAC;AAErE,mDAAmD;AACnD,MAAM,WAAW,qBAAqB;IACpC,sEAAsE;IACtE,MAAM,EAAE,SAAS,GAAG;QAAE,UAAU,EAAE,MAAM,CAAA;KAAE,CAAC;IAC3C,OAAO,EACH,KAAK,GACL;QAAE,WAAW,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAA;KAAE,CAAC;CACtE;AAED,wEAAwE;AACxE,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,aAAa,GAAG,SAAS,GAChC,qBAAqB,CA8BvB"}
package/dist/storage.js CHANGED
@@ -9,9 +9,12 @@
9
9
  * The sink is a plain key-value store — put/get/delete/list, no schema —
10
10
  * plus a conditional-write group ({@link StorageConfig.cas}, the substrate
11
11
  * for framework coordination; optional for plain storage, required by
12
- * coordination features) and two optional dedicated tables
13
- * ({@link StorageConfig.evals} and {@link StorageConfig.abs}) for
14
- * eval-run and A/B history:
12
+ * coordination features). Implementing that small KV core is enough for
13
+ * FULL functionality: eval-run and A/B history are derived over the core
14
+ * when the optional dedicated tables ({@link StorageConfig.evals} and
15
+ * {@link StorageConfig.abs}) are not authored — those groups exist as
16
+ * backend-native optimizations (a real table, an analytics pipeline),
17
+ * not as required-or-lose-history hooks:
15
18
  *
16
19
  * ```ts
17
20
  * import { defineStorage } from "@anysphere/agent-serve/storage";
@@ -48,6 +51,15 @@
48
51
  * event log under `--state-root` remains the live source of truth; this
49
52
  * interface is the durable mirror.
50
53
  */
54
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
55
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
56
+ return new (P || (P = Promise))(function (resolve, reject) {
57
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
58
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
59
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
60
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
61
+ });
62
+ };
51
63
  import { createHash } from "node:crypto";
52
64
  import { brandDefinition } from "./internal/brand.js";
53
65
  /**
@@ -101,7 +113,56 @@ export function defineStorage(config) {
101
113
  }
102
114
  // Validate eagerly so a bad policy fails at discovery, not first flush.
103
115
  resolveStoragePolicy(config.policy);
104
- return brandDefinition("storage", config);
116
+ // A backend that implements only the KV core gets full functionality:
117
+ // the dedicated tables are backend-native optimizations, derived over
118
+ // the core when absent. Authored groups always win.
119
+ const derivedEvals = config.evals === undefined ? deriveEvalsTable(config) : undefined;
120
+ const derivedAbs = config.abs === undefined ? deriveAbsTable(config) : undefined;
121
+ return brandDefinition("storage", Object.assign(Object.assign(Object.assign({}, config), (derivedEvals === undefined ? {} : { evals: derivedEvals })), (derivedAbs === undefined ? {} : { abs: derivedAbs })));
122
+ }
123
+ /**
124
+ * Eval-runs table over the KV core: one key per run under
125
+ * {@link storageKeys.evalRun}, hydrate via prefix `list`, prune via
126
+ * `delete`. Requires core `put` + `delete` + `list`; without `delete` or
127
+ * `list` there is no derivation (pruning or hydration would silently not
128
+ * work) and eval history stays in process memory.
129
+ */
130
+ function deriveEvalsTable(config) {
131
+ if (config.delete === undefined || config.list === undefined) {
132
+ return undefined;
133
+ }
134
+ return {
135
+ put: (run, ctx) => config.put(storageKeys.evalRun(ctx.agentName, run.runId), run, ctx),
136
+ delete: (runId, ctx) => { var _a; return (_a = config.delete) === null || _a === void 0 ? void 0 : _a.call(config, storageKeys.evalRun(ctx.agentName, runId), ctx); },
137
+ list: (ctx) => __awaiter(this, void 0, void 0, function* () {
138
+ var _a;
139
+ var _b;
140
+ const entries = (_b = (yield (_a = config.list) === null || _a === void 0 ? void 0 : _a.call(config, storageKeys.evalRunsPrefix(ctx.agentName), ctx))) !== null && _b !== void 0 ? _b : [];
141
+ return entries.map((entry) => entry.value);
142
+ }),
143
+ };
144
+ }
145
+ /**
146
+ * A/B table over the KV core. Each sample lands as its own key (identity
147
+ * = experiment + sessionId + at, matching the dedicated table's row
148
+ * uniqueness): appending to one array value would need read-modify-write
149
+ * — lost updates under concurrent writers without CAS, and unbounded
150
+ * value growth — while a key per sample keeps `putSample` a blind put
151
+ * with real append-only semantics. The aggregate snapshot lives at one
152
+ * fixed key via plain `put` (last-write-wins is correct for "latest").
153
+ * Requires only core `put`; `getSnapshot` is included when core `get`
154
+ * exists.
155
+ */
156
+ function deriveAbsTable(config) {
157
+ const get = config.get;
158
+ return Object.assign({ putSample: (sample, ctx) => config.put(storageKeys.abSample(ctx.agentName, sample.experiment, sample.sessionId, sample.at), sample, ctx), putSnapshot: (snapshot, ctx) => config.put(storageKeys.abSnapshot(ctx.agentName), snapshot, ctx) }, (get === undefined
159
+ ? {}
160
+ : {
161
+ getSnapshot: (ctx) => __awaiter(this, void 0, void 0, function* () {
162
+ const value = yield get(storageKeys.abSnapshot(ctx.agentName), ctx);
163
+ return (value !== null && value !== void 0 ? value : undefined);
164
+ }),
165
+ }));
105
166
  }
106
167
  // ============================================================================
107
168
  // Key scheme
@@ -129,9 +190,14 @@ export const STORAGE_KEY_ROOT = "agentkit/v1";
129
190
  * | `agentkit/v1/{agent}/session-events/{sessionId}/{index}` | `SessionEvent[]` chunk (index = first event's index, zero-padded) |
130
191
  * | `agentkit/v1/{agent}/continuation/{channelId}/{token}` | `{ sessionId }` |
131
192
  * | `agentkit/v1/{agent}/kv/{key}` | Author JSON via {@link HostContext.kv} |
193
+ * | `agentkit/v1/{agent}/eval-runs/{runId}` | `EvalRunSnapshot` (derived `evals` table) |
194
+ * | `agentkit/v1/{agent}/ab-samples/{experiment}/{sessionId}/{at}` | `ABMetricSample` (derived `abs` table, append-only) |
195
+ * | `agentkit/v1/{agent}/ab-snapshot` | `ABSnapshot` (derived `abs` table, LWW) |
132
196
  *
133
- * Eval-run and A/B history do not flow through this KV scheme — they have
134
- * dedicated tables ({@link StorageConfig.evals} / {@link StorageConfig.abs}).
197
+ * The `eval-runs` / `ab-samples` / `ab-snapshot` families are minted only
198
+ * by the tables `defineStorage` derives over the KV core; a backend that
199
+ * authors dedicated {@link StorageConfig.evals} / {@link StorageConfig.abs}
200
+ * groups never sees them.
135
201
  */
136
202
  export const storageKeys = {
137
203
  session: (agent, sessionId) => `${STORAGE_KEY_ROOT}/${agent}/session/${sessionId}`,
@@ -145,6 +211,16 @@ export const storageKeys = {
145
211
  */
146
212
  kv: (agent, key) => `${STORAGE_KEY_ROOT}/${agent}/kv/${keySegment(key)}`,
147
213
  kvPrefix: (agent) => `${STORAGE_KEY_ROOT}/${agent}/kv/`,
214
+ /** One playground eval-run snapshot (derived `evals` table). */
215
+ evalRun: (agent, runId) => `${STORAGE_KEY_ROOT}/${agent}/eval-runs/${keySegment(runId)}`,
216
+ evalRunsPrefix: (agent) => `${STORAGE_KEY_ROOT}/${agent}/eval-runs/`,
217
+ /**
218
+ * One A/B metric sample (derived `abs` table); the segments mirror the
219
+ * dedicated table's row identity (experiment + sessionId + at).
220
+ */
221
+ abSample: (agent, experiment, sessionId, at) => `${STORAGE_KEY_ROOT}/${agent}/ab-samples/${keySegment(experiment)}/${keySegment(sessionId)}/${keySegment(at)}`,
222
+ /** Latest aggregate A/B snapshot (derived `abs` table, LWW). */
223
+ abSnapshot: (agent) => `${STORAGE_KEY_ROOT}/${agent}/ab-snapshot`,
148
224
  };
149
225
  /**
150
226
  * Max bytes a caller-controlled key segment may occupy after URI-encoding.
package/docs/ab.md CHANGED
@@ -255,9 +255,10 @@ too. This include-all behavior can still apply to `GET /v1/abs` in dev
255
255
  when bearer or custom auth keeps `GET /v1/sessions` owner-scoped.
256
256
 
257
257
  Session `events.ndjson` is the source of truth for assignment + fold.
258
- `GET /v1/abs` recomputes aggregates from those logs. For durable
259
- sample and snapshot export, declare an `abs` table in
260
- `agent/storage.ts` same idea as the eval-runs table. See
258
+ `GET /v1/abs` recomputes aggregates from those logs. Any
259
+ `agent/storage.ts` exports samples and snapshots durably: an authored
260
+ `abs` table when the backend has a native shape for it, or the table
261
+ derived over the KV core otherwise. See
261
262
  [Storage](./storage.md#eval-and-a-b-tables).
262
263
 
263
264
  ## Configure the playground fold window
@@ -262,7 +262,7 @@ Slack** connects the workspace with a one-time authorization, and
262
262
  **Create Slack app** creates and installs the app, then stores its
263
263
  tokens as deployment secrets automatically. Redeploy when prompted so
264
264
  the running agent picks them up. See
265
- [Provision from the dashboard](./guides/slack.md#provision-from-the-dashboard-hosted-deployments)
265
+ [Provision from the dashboard](./guides/slack.md#provision-from-the-dashboard)
266
266
  for the walkthrough, including workspace-admin approval.
267
267
 
268
268
  If you created the Slack app by hand instead, set its tokens as
package/docs/evals.md CHANGED
@@ -147,10 +147,12 @@ JUnit XML file for CI, `Artifacts` writes per-case files, and
147
147
  the XML for a custom destination). A file or case can add its own
148
148
  `reporters` on top of the config list.
149
149
 
150
- Playground batches live in process memory and disappear when `serve`
151
- exits. Navigating away and back still works while the process is up.
152
- To keep batches across restarts, declare an `evals` table in
153
- `agent/storage.ts`; see [Storage](./storage.md#eval-and-a-b-tables).
150
+ Playground batches survive restarts whenever `agent/storage.ts` exists
151
+ with an `evals` table or a KV core providing `delete` and `list` (the
152
+ table is derived over the core); see
153
+ [Storage](./storage.md#eval-and-a-b-tables). Without storage they live
154
+ in process memory and disappear when `serve` exits — navigating away
155
+ and back still works while the process is up.
154
156
 
155
157
  ## Drive and assert with `t`
156
158
 
@@ -360,9 +362,10 @@ agent-sdk serve --dir . --dev
360
362
 
361
363
  Playground runs target the live server instead of an ephemeral one.
362
364
  Their sessions appear in the session list. One eval batch can run at a
363
- time. By default those batches are **in-memory only** (capped by
364
- `maxPlaygroundRuns`); declare an `evals` table in `agent/storage.ts` if
365
- you need them after a serve restart see
365
+ time. Batches persist across restarts whenever `agent/storage.ts`
366
+ provides an `evals` table or a KV core with `delete` and `list` (the
367
+ table is derived over the core); without storage they are **in-memory
368
+ only** (capped by `maxPlaygroundRuns`) — see
366
369
  [Storage](./storage.md#eval-and-a-b-tables).
367
370
 
368
371
  The UI uses the playground eval routes (available without `--dev`):
@@ -101,9 +101,8 @@ For the watched-channel path, configure a dedicated Socket Mode app with:
101
101
  - have an App-Level Token with `connections:write`, and
102
102
  - be a member of the watched channel.
103
103
 
104
- Run `agent-sdk slack setup` for the guided app workflow. Generate the project
105
- manifest with `--channel-posts` when you create a new copy, then validate the
106
- configured channel prefix with `agent-sdk slack doctor`.
104
+ Run `agent-sdk slack create --dir examples/benny --channel-posts` for a
105
+ dedicated Socket Mode app, then `agent-sdk slack doctor`.
107
106
 
108
107
  Missing dedicated-app tokens leave that channel idle. They don't stop the
109
108
  account-linked channel.
@@ -139,14 +139,13 @@ Channel watching is Socket Mode only, so this example uses a dedicated
139
139
  app:
140
140
 
141
141
  ```bash
142
- agent-sdk slack init --dir examples/oncall --name "Oncall" --channel-posts
142
+ agent-sdk slack create --dir examples/oncall --name "Oncall" --channel-posts
143
143
  agent-sdk slack doctor --prefix ONCALL
144
144
  ```
145
145
 
146
- The generated manifest subscribes to `message.channels` and
147
- `message.groups` and includes `reactions:write` for the lock-in reaction.
148
- Install the app, export `ONCALL_SLACK_BOT_TOKEN` and
149
- `ONCALL_SLACK_APP_TOKEN`, and invite the bot to each watched channel.
146
+ `--channel-posts` prefills channel-watch events (`message.channels` /
147
+ `message.groups`). Invite the bot to each watched channel after the
148
+ wizard finishes.
150
149
 
151
150
  `ONCALL_ALERTS_CHANNELS` sets the watch list as comma-separated ids or
152
151
  `#names`. It defaults to `#alerts`.
@@ -92,7 +92,7 @@ export default slackChannel({
92
92
  });
93
93
  ```
94
94
 
95
- The Slack app manifest needs interactivity enabled. Cards show redacted,
95
+ Approval cards need interactivity on the Slack app. Cards show redacted,
96
96
  truncated arguments because of Block Kit size limits. Execution still
97
97
  uses the full validated input, so review sensitive tools in the
98
98
  playground when the arguments may exceed the card. Details in the
@@ -1,15 +1,15 @@
1
1
  ---
2
2
  title: "Slack"
3
- description: "Put the agent in Slack over Socket Mode: Add to Slack provisioning, manifests, tokens, doctor, engagement rules, access policy, and approval buttons."
3
+ description: "Put the agent in Slack: Cursor-hosted connection or a dedicated Socket Mode app via the dashboard wizard, plus doctor, engagement rules, access policy, and approval buttons."
4
4
  ---
5
5
 
6
6
  # Slack agents
7
7
 
8
- The Slack channel puts your agent in Slack over Socket Mode: no public
9
- Request URL, streaming replies in threads, tool "thinking" steps,
10
- suggested prompts, and opt-in approval buttons. Cursor's **Add to
11
- Slack** provisioning handles the setup in one CLI command or one
12
- dashboard click; the manual manifest flow remains as a fallback.
8
+ The Slack channel puts your agent in Slack. Two products: the Cursor-hosted
9
+ connection (`cursorAccount: true`), or a dedicated Socket Mode app created
10
+ in the dashboard wizard (`agent-sdk slack create`). Socket Mode has no
11
+ public Request URL. Replies stream in threads, with tool "thinking" steps,
12
+ suggested prompts, and opt-in approval buttons.
13
13
 
14
14
  The companion skill is
15
15
  [`skills/setup-slack/SKILL.md`](../../skills/setup-slack/SKILL.md).
@@ -99,17 +99,17 @@ export default slackChannel({
99
99
 
100
100
  ## Set it up
101
101
 
102
- Start with Cursor's **Add to Slack** provisioning: Cursor creates and
103
- installs a dedicated Slack app for the agent and delivers its tokens,
104
- so nobody visits [api.slack.com](https://api.slack.com/apps) or copies
105
- an `xoxb-…` / `xapp-…` pair by hand. Use the CLI for local development
106
- and the dashboard for hosted deployments. Fall back to the
107
- [manual manifest flow](#manual-setup-fallback) only when provisioning
108
- reports the feature is not enabled for your account.
102
+ For a dedicated Socket Mode bot, run `agent-sdk slack create`. The CLI
103
+ opens the signed-in Cursor dashboard wizard. Slack consent, bot name,
104
+ and admin-approval wait happen there. Tokens are stored as deployment
105
+ secrets and written to `.env.local`. They are never shown. Do not paste
106
+ a manifest at [api.slack.com](https://api.slack.com/apps). `slack init`
107
+ is removed.
109
108
 
110
- ### Provision with the CLI
109
+ Bots that already have tokens in `.env.local` keep working. Skip the
110
+ wizard unless you want a Cursor-managed app.
111
111
 
112
- One command runs the whole setup:
112
+ ### Provision with the CLI
113
113
 
114
114
  ```bash
115
115
  agent-sdk slack create --dir . # dev app (default)
@@ -118,97 +118,47 @@ agent-sdk slack create --dir . --prod # prod app
118
118
 
119
119
  `slack create` needs a signed-in host (`agent-sdk login` or
120
120
  `CURSOR_API_KEY`). It scaffolds `agent/channels/slack.ts` when the file
121
- is missing, connects your Slack workspace through a browser consent
122
- page when it isn't connected yet (a one-time authorization per user and
123
- workspace), creates and installs the agent's dedicated Socket Mode app,
121
+ is missing, opens the dashboard wizard, and waits. Finish **Add Slack
122
+ to this agent** in the browser as the same Cursor account. The CLI
124
123
  writes `<PREFIX>_SLACK_BOT_TOKEN` and `<PREFIX>_SLACK_APP_TOKEN` into
125
- `<dir>/.env.local`, and finishes with a `doctor` pass. Then serve and
126
- smoke it as described [below](#wire-the-env-and-verify); the tokens are
127
- already in place.
128
-
129
- If the workspace requires admin approval for new apps, `create` prints
130
- the Slack approval page for a workspace admin. Re-run
131
- `agent-sdk slack create` after the approval to finish the install and
132
- mint the tokens.
133
-
134
- Useful companions: `--slack-team T0123ABCD` picks a workspace when
135
- several are connected, `--icon <https-url-or-file>` sets the app icon,
136
- `agent-sdk slack destroy` deletes the provisioned app, and
137
- `agent-sdk slack icon <source>` updates the icon later. A re-run of
138
- `create` refuses to overwrite manifest edits made by hand in Slack;
139
- pass `--force` to overwrite them.
140
-
141
- ### Provision from the dashboard (hosted deployments)
142
-
143
- For a [Cursor-hosted deployment](../deployment.md#cursor-managed-hosting),
144
- provision from
145
- [cursor.com/dashboard](https://cursor.com/dashboard): open **Deployed
146
- Agents**, select the deployment, switch to the **Details** view, and
147
- expand the **Slack** row under **Integrations**.
148
-
149
- 1. Click **Add to Slack** and approve the authorization in the tab that
150
- opens. This is a one-time consent per user and workspace.
151
- 2. Pick the bot name (and the workspace, when several are connected)
152
- and click **Create Slack app**. Cursor creates and installs the app,
153
- then stores its tokens as deployment secrets; the values are never
154
- shown. The **Advanced** disclosure sets the env-var prefix, so the
155
- secret names match what your `slackChannel({ envPrefix })` reads.
156
- 3. If the workspace requires admin approval, the row shows **Waiting
157
- for admin approval** with an **Approve in Slack** button that opens
158
- Slack's pending-request page. After an admin approves, pick
159
- **Retry** from the row's menu.
160
- 4. Click **Redeploy** when the banner appears. The running agent keeps
161
- its old environment until the next deploy.
162
-
163
- The row's menu also covers later care: rename the app, set its icon,
164
- rotate its tokens, remove it from Slack, or disconnect the workspace.
165
-
166
- ### Manual setup (fallback)
167
-
168
- When Add to Slack is not enabled for your account, create the apps by
169
- hand. Generate the channel file, the app manifests, and the env
170
- template:
124
+ `<dir>/.env.local`, then runs `doctor`. Serve and smoke it as described
125
+ [below](#wire-the-env-and-verify).
171
126
 
172
- ```bash
173
- agent-sdk slack init --dir . --name "My Agent"
174
- ```
127
+ If Slack needs a workspace admin to approve the app, keep the CLI
128
+ running. Managed install does not file the request — open Slack's
129
+ **Request approval** page (the CLI prints the link; the same URL is
130
+ **Send a reminder** after you submit). After an admin approves, click
131
+ **Retry** in the wizard.
175
132
 
176
- This writes `agent/channels/slack.ts` (with an `envPrefix` derived from
177
- the directory name), importable app manifests at
178
- `.agent-serve/slack/manifest.{dev,prod}.json`, and
179
- `.agent-serve/slack/env.example`. Use `--no-prefix` for the shared
180
- `SLACK_*` variables on single-agent hosts, `--prefix CUSTOM` to
181
- override, and `--channel-posts` if you plan to watch channels.
133
+ Useful companions: `--name` / `--icon` / `--channel-posts` prefill the
134
+ wizard. `--slack-team T0123ABCD` picks a workspace when several are
135
+ connected. A second `slack create` for the same agent and env overwrites
136
+ that Slack app. It keeps the Slack app id and replaces the manifest and
137
+ tokens. `agent-sdk slack destroy` deletes the provisioned app.
138
+ `agent-sdk slack icon <source>` updates the icon later.
182
139
 
183
- #### Create the apps (human, Slack admin)
140
+ ### Provision from the dashboard
184
141
 
185
- This phase needs a human with permission to create Slack apps.
142
+ The same wizard is on [Deployed Agents](https://cursor.com/dashboard).
143
+ Open **Integrations** on an agent and click **Add Slack to this agent**,
144
+ or follow the URL `slack create` printed.
186
145
 
187
- 1. Open [api.slack.com/apps](https://api.slack.com/apps) **Create New
188
- App** **From a manifest**.
189
- 2. Paste `manifest.dev.json` and create the dev app.
190
- 3. Repeat with `manifest.prod.json`. Dev and prod are separate Slack
191
- apps with separate tokens.
146
+ A first-run agent that has no hosted engine yet shows **Not deployed
147
+ yet**. Local `agent-sdk serve` works from `.env.local`. The next
148
+ **Deploy** injects the stored secrets; there is no Slack-only Redeploy.
192
149
 
193
- #### Install and mint tokens (human)
150
+ If Slack needs admin approval, the wizard waits. Click **Request
151
+ approval** to file the request in Slack (that same page later sends a
152
+ reminder). After an admin approves, click **Retry**.
194
153
 
195
- For each app: **Install to Workspace** and copy the Bot User OAuth Token
196
- (`xoxb-…`), then under **Basic Information App-Level Tokens** create a
197
- token with scope `connections:write` and copy it (`xapp-…`).
154
+ The app row's menu covers later care: rename, set an icon, rotate
155
+ tokens, remove the app, or disconnect the workspace.
198
156
 
199
157
  ### Wire the env and verify
200
158
 
201
159
  `agent-sdk slack create` already wrote the tokens to `.env.local`, so
202
- after provisioning skip straight to `doctor`. After a manual setup,
203
- export the tokens in the shell that runs `serve`, using the names from
204
- `env.example`, or put them in the agent directory's `.env.local` —
205
- `serve`/`dev`/`slack doctor` load that file (real environment variables
206
- always win over it):
207
-
208
- ```bash
209
- export MY_AGENT_SLACK_BOT_TOKEN=xoxb-…
210
- export MY_AGENT_SLACK_APP_TOKEN=xapp-…
211
- ```
160
+ after provisioning skip straight to `doctor`. `serve` / `dev` /
161
+ `slack doctor` load that file (real environment variables always win).
212
162
 
213
163
  ```bash
214
164
  agent-sdk slack doctor --prefix MY_AGENT
@@ -252,15 +202,9 @@ export default slackChannel({
252
202
  ```
253
203
 
254
204
  Channel watching needs the `message.channels` / `message.groups` events
255
- on the Slack app (Socket Mode only not available with
256
- `cursorAccount: true`). Generate manifests with `slack init --channel-posts`,
257
- or add the events and re-import. The bot must also be a member of each
258
- watched channel. Posts that mention the bot stay on the `app_mention`
259
- path, bot-authored posts never dispatch by default, and deleting a post
260
- inside the debounce window cancels its dispatch. Watched posts reuse the
261
- thread-scoped principal, so a later @mention continues the same session.
262
- Set `engagement.mentions` or `engagement.directMessages` to `false` to
263
- turn those surfaces off.
205
+ on the Slack app (Socket Mode only; not available with
206
+ `cursorAccount: true`). Pass `--channel-posts` on `slack create`. The
207
+ bot must also be a member of each watched channel.
264
208
 
265
209
  Set `includeBotPosts: true` when the posts worth watching come from bots:
266
210
  alert feeds, webhook integrations, or other agents posting notes. The
@@ -289,9 +233,8 @@ export default slackChannel({
289
233
  });
290
234
  ```
291
235
 
292
- The Slack app manifest must have interactivity enabled. Regenerate with
293
- `buildSlackManifest({ interactivity: true })` (or edit and re-import) if
294
- your app predates it. Composing events by hand instead: spread
236
+ Approval cards need interactivity on the Slack app. Recreate with
237
+ `slack create` if clicks do nothing. Composing events by hand: spread
295
238
  `buildToolApprovalEvents({ credentials })` into `events` and set
296
239
  `interactivity: true` on the channel so Socket Mode routes the clicks.
297
240
 
@@ -331,15 +274,11 @@ Two habits matter most.
331
274
  The `slack` subcommands cover setup end to end.
332
275
 
333
276
  ```bash
334
- agent-sdk slack setup # guided checklist
335
- agent-sdk slack create --dir . # provision via Add to Slack (dev app)
277
+ agent-sdk slack setup # two-product chooser
278
+ agent-sdk slack create --dir . # dashboard wizard (dev app)
336
279
  agent-sdk slack create --dir . --prod # prod app
337
280
  agent-sdk slack destroy --dir . # delete the provisioned app
338
281
  agent-sdk slack icon ./icon.png --dir . # set the provisioned app's icon
339
- agent-sdk slack init --dir . --name "My Agent"
340
- agent-sdk slack init --dir . --no-prefix # shared SLACK_* vars
341
- agent-sdk slack init --dir . --channel-posts
342
- agent-sdk slack manifest --env both # regenerate manifests
343
282
  agent-sdk slack doctor --prefix MY_AGENT # token / connectivity checks
344
283
  ```
345
284