@cursor/july 0.1.52 → 0.1.54

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 (112) hide show
  1. package/AGENTS.md +13 -0
  2. package/README.md +4 -2
  3. package/dist/bin/agent-serve.js +2 -0
  4. package/dist/channels/slack/init.d.ts +16 -3
  5. package/dist/channels/slack/init.d.ts.map +1 -1
  6. package/dist/channels/slack/init.js +92 -18
  7. package/dist/channels/slack/manifest.d.ts +13 -3
  8. package/dist/channels/slack/manifest.d.ts.map +1 -1
  9. package/dist/channels/slack/manifest.js +24 -3
  10. package/dist/channels/slack/setup.d.ts +26 -1
  11. package/dist/channels/slack/setup.d.ts.map +1 -1
  12. package/dist/channels/slack/setup.js +107 -25
  13. package/dist/docs/404.html +3 -3
  14. package/dist/docs/ab.html +6 -6
  15. package/dist/docs/assets/{app.Cbeq6FOy.js → app.DAKcDclS.js} +1 -1
  16. package/dist/docs/assets/chunks/@localSearchIndexroot.C4uxzYEU.js +1 -0
  17. package/dist/docs/assets/chunks/{VPLocalSearchBox.Bmb8QjCI.js → VPLocalSearchBox.BNIaCSfG.js} +2 -2
  18. package/dist/docs/assets/chunks/{theme.BLNMeCRL.js → theme.B47GzJjc.js} +2 -2
  19. package/dist/docs/assets/{guides_slack.md.D2nTRu9M.js → guides_slack.md.DP4H75WP.js} +8 -6
  20. package/dist/docs/assets/guides_slack.md.DP4H75WP.lean.js +1 -0
  21. package/dist/docs/assets/{reference_cli.md.CGKfz_Yj.js → reference_cli.md.-V6J7Cl8.js} +7 -3
  22. package/dist/docs/assets/{reference_cli.md.CGKfz_Yj.lean.js → reference_cli.md.-V6J7Cl8.lean.js} +1 -1
  23. package/dist/docs/assets/{style.CK3hwt6q.css → style.kTsvp4pE.css} +1 -1
  24. package/dist/docs/assets/{troubleshooting.md.C6n3wCr6.js → troubleshooting.md.CuVztCKs.js} +1 -1
  25. package/dist/docs/building-with-agents.html +6 -6
  26. package/dist/docs/concepts.html +6 -6
  27. package/dist/docs/deployment.html +6 -6
  28. package/dist/docs/evals.html +6 -6
  29. package/dist/docs/example-agents/approval-buddy.html +6 -6
  30. package/dist/docs/example-agents/benny.html +6 -6
  31. package/dist/docs/example-agents/bugbot.html +6 -6
  32. package/dist/docs/example-agents/codebase-wiki.html +6 -6
  33. package/dist/docs/example-agents/codeowners-review.html +6 -6
  34. package/dist/docs/example-agents/concierge.html +6 -6
  35. package/dist/docs/example-agents/fsd.html +6 -6
  36. package/dist/docs/example-agents/index.html +6 -6
  37. package/dist/docs/example-agents/knowledge-base.html +6 -6
  38. package/dist/docs/example-agents/oncall.html +6 -6
  39. package/dist/docs/example-agents/security-reviewer.html +6 -6
  40. package/dist/docs/example-agents/slack-agent.html +6 -6
  41. package/dist/docs/example-agents/weather-agent.html +6 -6
  42. package/dist/docs/guides/agent-to-agent.html +6 -6
  43. package/dist/docs/guides/cloud-runtime.html +6 -6
  44. package/dist/docs/guides/github.html +6 -6
  45. package/dist/docs/guides/human-in-the-loop.html +6 -6
  46. package/dist/docs/guides/mcp-oauth.html +6 -6
  47. package/dist/docs/guides/opentelemetry.html +6 -6
  48. package/dist/docs/guides/slack.html +14 -12
  49. package/dist/docs/guides/webhooks.html +6 -6
  50. package/dist/docs/hashmap.json +1 -1
  51. package/dist/docs/hillclimbing.html +6 -6
  52. package/dist/docs/index.html +6 -6
  53. package/dist/docs/quickstart.html +6 -6
  54. package/dist/docs/reference/agent-config.html +6 -6
  55. package/dist/docs/reference/artifacts.html +6 -6
  56. package/dist/docs/reference/channels.html +6 -6
  57. package/dist/docs/reference/cli.html +13 -9
  58. package/dist/docs/reference/connections.html +6 -6
  59. package/dist/docs/reference/hooks.html +6 -6
  60. package/dist/docs/reference/http-api.html +6 -6
  61. package/dist/docs/reference/instructions.html +6 -6
  62. package/dist/docs/reference/playground.html +5 -5
  63. package/dist/docs/reference/project-layout.html +6 -6
  64. package/dist/docs/reference/prompt.html +6 -6
  65. package/dist/docs/reference/schedules.html +6 -6
  66. package/dist/docs/reference/sessions.html +6 -6
  67. package/dist/docs/reference/skills.html +6 -6
  68. package/dist/docs/reference/subagents.html +6 -6
  69. package/dist/docs/reference/tools.html +6 -6
  70. package/dist/docs/scaffolding-agents.html +5 -5
  71. package/dist/docs/storage.html +6 -6
  72. package/dist/docs/templates/triage.html +6 -6
  73. package/dist/docs/troubleshooting.html +6 -6
  74. package/dist/internal/cli-deploy.d.ts.map +1 -1
  75. package/dist/internal/cli-deploy.js +8 -18
  76. package/dist/internal/cli-slack-manual.d.ts +20 -0
  77. package/dist/internal/cli-slack-manual.d.ts.map +1 -0
  78. package/dist/internal/cli-slack-manual.js +106 -0
  79. package/dist/internal/cli-slack.d.ts +5 -2
  80. package/dist/internal/cli-slack.d.ts.map +1 -1
  81. package/dist/internal/cli-slack.js +18 -69
  82. package/dist/internal/deploy-client.d.ts +7 -10
  83. package/dist/internal/deploy-client.d.ts.map +1 -1
  84. package/dist/internal/deploy-client.js +1 -3
  85. package/dist/internal/deploy-source.d.ts +1 -1
  86. package/dist/internal/deploy-source.js +1 -1
  87. package/dist/internal/process-memory-telemetry.d.ts +3 -4
  88. package/dist/internal/process-memory-telemetry.d.ts.map +1 -1
  89. package/dist/internal/process-memory-telemetry.js +4 -17
  90. package/dist/playground/assets/{index-BKMz70wx.js → index-BHAPd9KT.js} +31 -31
  91. package/dist/playground/assets/index-DpKH0HcT.css +1 -0
  92. package/dist/playground/index.html +2 -2
  93. package/docs/guides/slack.md +52 -7
  94. package/docs/reference/cli.md +29 -6
  95. package/docs/troubleshooting.md +1 -1
  96. package/package.json +1 -1
  97. package/skills/create-agent/SKILL.md +1 -0
  98. package/skills/setup-slack/SKILL.md +99 -7
  99. package/src/bin/agent-serve.ts +2 -0
  100. package/src/channels/slack/init.ts +130 -20
  101. package/src/channels/slack/manifest.ts +36 -3
  102. package/src/channels/slack/setup.ts +124 -23
  103. package/src/internal/cli-deploy.ts +8 -22
  104. package/src/internal/cli-slack-manual.ts +127 -0
  105. package/src/internal/cli-slack.ts +18 -70
  106. package/src/internal/deploy-client.ts +8 -13
  107. package/src/internal/deploy-source.ts +1 -1
  108. package/src/internal/process-memory-telemetry.ts +5 -24
  109. package/dist/docs/assets/chunks/@localSearchIndexroot.TzAgoWLl.js +0 -1
  110. package/dist/docs/assets/guides_slack.md.D2nTRu9M.lean.js +0 -1
  111. package/dist/playground/assets/index-BmMrulSc.css +0 -1
  112. /package/dist/docs/assets/{troubleshooting.md.C6n3wCr6.lean.js → troubleshooting.md.CuVztCKs.lean.js} +0 -0
package/AGENTS.md CHANGED
@@ -16,6 +16,16 @@ HTTP/2 client corrupts local harness
16
16
  tool-result streams (`NGHTTP2_FRAME_SIZE_ERROR`), which makes every
17
17
  built-in read/grep fail and sends models into retry loops.
18
18
 
19
+ ## Bump `@cursor/july` with every source change
20
+
21
+ Any PR that changes this package's **source** (`src/`, `playground/`,
22
+ CLI, shipped `skills/` / `templates/` — runtime behavior that goes out
23
+ in `@cursor/july`) **must bump** `version` in `package.json` in the
24
+ **same PR**. On 0.x, bump the patch (`0.1.N` → `0.1.N+1`). Do not
25
+ publish from the PR; merging the bump is what lets the `july-release`
26
+ pipeline cut. Docs-only, tests-only, and edits to this file do not
27
+ need a bump.
28
+
19
29
  ## Skills
20
30
 
21
31
  Before scaffolding, wiring channels, writing evals, or deploying, **read the
@@ -203,6 +213,7 @@ distinct bot handle:
203
213
  agent-serve slack setup
204
214
  agent-serve slack create --dir ./my-agent --channel-posts
205
215
  # envPrefix from the directory name (MY_AGENT_SLACK_*)
216
+ # Manual path: agent-serve slack init --manual --dir ./my-agent
206
217
  agent-serve slack doctor --prefix MY_AGENT
207
218
  agent-serve dev ./my-agent
208
219
  ```
@@ -305,6 +316,8 @@ Fixtures still work for offline replay: `POST` a saved payload with an
305
316
 
306
317
  ## Do not
307
318
 
319
+ - Land source changes without bumping `version` in `package.json` in the
320
+ same PR (see **Bump `@cursor/july` with every source change** above).
308
321
  - Proactively add or update documentation (`docs/`, READMEs, this file) as
309
322
  part of a code change. Docs are written intentionally, on explicit request
310
323
  only — never as a side effect of a feature or fix. If a change makes docs
package/README.md CHANGED
@@ -952,14 +952,16 @@ agent-to-agent only (no Slack channel).
952
952
 
953
953
  For Socket Mode apps (channel watch / approvals), run
954
954
  `agent-serve slack create`. It opens the dashboard wizard, creates and
955
- installs the app, and writes the token pair to `.env.local`. Do not paste
956
- a manifest at api.slack.com.
955
+ installs the app, and writes the token pair to `.env.local`. To own the
956
+ Slack app yourself, run `agent-serve slack init --manual` and paste the
957
+ manifests at api.slack.com.
957
958
 
958
959
  CLI (`agent-serve slack …`; guided setup in `skills/setup-slack/SKILL.md`):
959
960
 
960
961
  ```bash
961
962
  agent-serve slack create --dir ./my-agent # dashboard wizard (dev app)
962
963
  agent-serve slack create --dir ./my-agent --prod # prod app
964
+ agent-serve slack init --manual --dir ./my-agent # manifests for api.slack.com
963
965
  agent-serve slack setup
964
966
  agent-serve slack doctor --prefix MY_AGENT
965
967
  ```
@@ -496,6 +496,7 @@ function main(argv) {
496
496
  "slack-team": { type: "string" },
497
497
  icon: { type: "string" },
498
498
  force: { type: "boolean", default: false },
499
+ manual: { type: "boolean", default: false },
499
500
  repo: { type: "string", multiple: true },
500
501
  org: { type: "string" },
501
502
  "cursor-events": { type: "boolean", default: false },
@@ -555,6 +556,7 @@ function main(argv) {
555
556
  apiKey: values["api-key"],
556
557
  icon: values.icon,
557
558
  force: values.force,
559
+ manual: values.manual,
558
560
  iconSource: positionals[0] === "icon" ? positionals[1] : undefined,
559
561
  });
560
562
  }
@@ -1,20 +1,27 @@
1
1
  /**
2
2
  * Scaffold a Slack channel into an agent-serve project.
3
+ *
4
+ * `initSlackChannel` is the create-safe writer: `agent/channels/slack.ts`
5
+ * only. DIY manifests for paste at api.slack.com live in
6
+ * {@link initSlackManual} so `slack create` cannot reach them.
3
7
  */
4
8
  export interface InitSlackOptions {
5
9
  dir: string;
6
10
  /** Display name for the Slack app. Defaults to directory basename. */
7
11
  name?: string;
8
- description?: string;
9
12
  /**
10
13
  * Env prefix for tokens (`MY_AGENT` → `MY_AGENT_SLACK_BOT_TOKEN`). Defaults to
11
14
  * the directory basename so multi-agent serve can mount several Slack bots.
12
15
  * Pass `""` to use the shared `SLACK_BOT_TOKEN` / `SLACK_APP_TOKEN` globals.
13
16
  */
14
17
  envPrefix?: string;
18
+ }
19
+ export interface InitSlackManualOptions extends InitSlackOptions {
20
+ description?: string;
15
21
  /**
16
- * Subscribe the generated app to `message.channels` + `message.groups`
17
- * for the opt-in channel watch (`engagement.channelPosts`).
22
+ * Subscribe the generated manifests to `message.channels` +
23
+ * `message.groups` for the opt-in channel watch
24
+ * (`engagement.channelPosts` on `slackChannel`).
18
25
  */
19
26
  channelPosts?: boolean;
20
27
  }
@@ -27,5 +34,11 @@ export interface InitSlackResult {
27
34
  app: string;
28
35
  };
29
36
  }
37
+ /** Create-safe: write `agent/channels/slack.ts` only. */
30
38
  export declare function initSlackChannel(options: InitSlackOptions): Promise<InitSlackResult>;
39
+ /**
40
+ * `slack init --manual`: channel file plus DIY manifests
41
+ * (`managedByCursor: false`), env.example, and setup-status.json.
42
+ */
43
+ export declare function initSlackManual(options: InitSlackManualOptions): Promise<InitSlackResult>;
31
44
  //# sourceMappingURL=init.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/init.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB;;;OAGG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAED,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAuC1B"}
1
+ {"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/init.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAYH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,EAAE,MAAM,CAAC;IACZ,sEAAsE;IACtE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd;;;;OAIG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,MAAM,WAAW,sBAAuB,SAAQ,gBAAgB;IAC9D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB;;;;OAIG;IACH,YAAY,CAAC,EAAE,OAAO,CAAC;CACxB;AAED,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,EAAE,CAAC;IAChB,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC;AAoED,yDAAyD;AACzD,wBAAsB,gBAAgB,CACpC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,eAAe,CAAC,CAa1B;AAED;;;GAGG;AACH,wBAAsB,eAAe,CACnC,OAAO,EAAE,sBAAsB,GAC9B,OAAO,CAAC,eAAe,CAAC,CAgD1B"}
@@ -1,5 +1,9 @@
1
1
  /**
2
2
  * Scaffold a Slack channel into an agent-serve project.
3
+ *
4
+ * `initSlackChannel` is the create-safe writer: `agent/channels/slack.ts`
5
+ * only. DIY manifests for paste at api.slack.com live in
6
+ * {@link initSlackManual} so `slack create` cannot reach them.
3
7
  */
4
8
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
5
9
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -14,28 +18,46 @@ import { mkdir, writeFile } from "node:fs/promises";
14
18
  import { basename, join, resolve } from "node:path";
15
19
  import { PACKAGE_NAME } from "../../internal/distribution.js";
16
20
  import { envPrefixFromName, slackEnvKeys } from "./credentials.js";
17
- export function initSlackChannel(options) {
21
+ import { buildSlackManifestPair, slackManifestFileEntries, } from "./manifest.js";
22
+ import { initialSlackSetupStatus } from "./setup.js";
23
+ function resolveSlackInitTarget(options) {
24
+ var _a, _b;
25
+ const rootDir = resolve(options.dir);
26
+ const envPrefix = options.envPrefix === ""
27
+ ? undefined
28
+ : ((_a = options.envPrefix) !== null && _a !== void 0 ? _a : envPrefixFromName(basename(rootDir)));
29
+ return {
30
+ rootDir,
31
+ name: (_b = options.name) !== null && _b !== void 0 ? _b : basename(rootDir),
32
+ envPrefix,
33
+ envKeys: slackEnvKeys(envPrefix),
34
+ };
35
+ }
36
+ function writeExclusive(rootDir, rel, contents) {
18
37
  return __awaiter(this, void 0, void 0, function* () {
19
- var _a;
20
- const rootDir = resolve(options.dir);
21
- const envPrefix = options.envPrefix === ""
22
- ? undefined
23
- : ((_a = options.envPrefix) !== null && _a !== void 0 ? _a : envPrefixFromName(basename(rootDir)));
24
- const envKeys = slackEnvKeys(envPrefix);
25
- const written = [];
26
- const abs = join(rootDir, "agent/channels/slack.ts");
38
+ const abs = join(rootDir, rel);
27
39
  yield mkdir(join(abs, ".."), { recursive: true });
28
- const envPrefixLine = envPrefix === undefined
29
- ? ""
30
- : ` envPrefix: ${JSON.stringify(envPrefix)},\n`;
31
- yield writeFile(abs, `import { slackChannel } from "${PACKAGE_NAME}/channels/slack";
40
+ yield writeFile(abs, contents, { flag: "wx" });
41
+ });
42
+ }
43
+ function slackChannelSource(target, kind) {
44
+ const envPrefixLine = target.envPrefix === undefined
45
+ ? ""
46
+ : ` envPrefix: ${JSON.stringify(target.envPrefix)},\n`;
47
+ const tokenLines = kind === "manual"
48
+ ? ` * Tokens: ${target.envKeys.bot} + ${target.envKeys.app}\n * (see .agent-serve/slack/env.example).`
49
+ : ` * Tokens: ${target.envKeys.bot} + ${target.envKeys.app}`;
50
+ const setupLine = kind === "manual"
51
+ ? " * Full setup: agent-serve slack setup"
52
+ : " * Full setup: agent-serve slack create --dir .";
53
+ return `import { slackChannel } from "${PACKAGE_NAME}/channels/slack";
32
54
 
33
55
  /**
34
56
  * Slack channel (Socket Mode).
35
57
  *
36
- * Tokens: ${envKeys.bot} + ${envKeys.app}
58
+ ${tokenLines}
37
59
  *
38
- * Full setup: agent-serve slack create --dir .
60
+ ${setupLine}
39
61
  */
40
62
  export default slackChannel({
41
63
  ${envPrefixLine} // Streaming and thinking steps default to true.
@@ -44,8 +66,60 @@ ${envPrefixLine} // Streaming and thinking steps default to true.
44
66
  { title: "Status", message: "What are you working on?" },
45
67
  ],
46
68
  });
47
- `, { flag: "wx" });
48
- written.push("agent/channels/slack.ts");
49
- return { rootDir, files: written, envPrefix, envKeys };
69
+ `;
70
+ }
71
+ /** Create-safe: write `agent/channels/slack.ts` only. */
72
+ export function initSlackChannel(options) {
73
+ return __awaiter(this, void 0, void 0, function* () {
74
+ const target = resolveSlackInitTarget(options);
75
+ yield writeExclusive(target.rootDir, "agent/channels/slack.ts", slackChannelSource(target, "create"));
76
+ return {
77
+ rootDir: target.rootDir,
78
+ files: ["agent/channels/slack.ts"],
79
+ envPrefix: target.envPrefix,
80
+ envKeys: target.envKeys,
81
+ };
82
+ });
83
+ }
84
+ /**
85
+ * `slack init --manual`: channel file plus DIY manifests
86
+ * (`managedByCursor: false`), env.example, and setup-status.json.
87
+ */
88
+ export function initSlackManual(options) {
89
+ return __awaiter(this, void 0, void 0, function* () {
90
+ const target = resolveSlackInitTarget(options);
91
+ const files = [];
92
+ const write = (rel, contents) => __awaiter(this, void 0, void 0, function* () {
93
+ yield writeExclusive(target.rootDir, rel, contents);
94
+ files.push(rel);
95
+ });
96
+ yield write("agent/channels/slack.ts", slackChannelSource(target, "manual"));
97
+ const pair = buildSlackManifestPair({
98
+ name: target.name,
99
+ managedByCursor: false,
100
+ description: options.description,
101
+ channelPosts: options.channelPosts,
102
+ });
103
+ for (const file of slackManifestFileEntries(pair)) {
104
+ yield write(`.agent-serve/slack/${file.name}`, file.contents);
105
+ }
106
+ yield write(".agent-serve/slack/env.example", `# Copy to .env.local (or export in your shell). Use the *dev* Slack app
107
+ # for local development; use the Prod app tokens in deployment secrets.
108
+ #
109
+ # Multi-agent serve needs a distinct Slack app (and token pair) per agent.
110
+
111
+ ${target.envKeys.bot}=xoxb-...
112
+ ${target.envKeys.app}=xapp-...
113
+ `);
114
+ yield write(".agent-serve/slack/setup-status.json", `${JSON.stringify(initialSlackSetupStatus({
115
+ envPrefix: target.envPrefix,
116
+ envKeys: target.envKeys,
117
+ }), null, 2)}\n`);
118
+ return {
119
+ rootDir: target.rootDir,
120
+ files,
121
+ envPrefix: target.envPrefix,
122
+ envKeys: target.envKeys,
123
+ };
50
124
  });
51
125
  }
@@ -9,9 +9,10 @@
9
9
  */
10
10
  import type { SlackManifestOptions } from "./types.js";
11
11
  /**
12
- * Where Slack points users who open a Cursor-provisioned app's settings
13
- * page. Manifest builders know neither the team slug nor the deployment
14
- * id, so this is the dashboard tab root rather than a per-agent deep link.
12
+ * Dashboard tab root: Slack's app-settings banner, and the only OAuth
13
+ * redirect URI we register. AAA request-approval (`oauth_authorize_url`)
14
+ * 400s with redirect_uri mismatch unless a URI is registered. This is
15
+ * not an install callback. `apps.managedInstall` still installs.
15
16
  */
16
17
  export declare const SLACK_EXTERNAL_APP_MANAGEMENT_URL = "https://cursor.com/dashboard/deployed-agents";
17
18
  export interface SlackAppManifest {
@@ -41,6 +42,7 @@ export interface SlackAppManifest {
41
42
  scopes: {
42
43
  bot: string[];
43
44
  };
45
+ redirect_urls?: string[];
44
46
  };
45
47
  settings: {
46
48
  event_subscriptions: {
@@ -67,4 +69,12 @@ export declare function buildSlackManifestPair(options: Omit<SlackManifestOption
67
69
  dev: SlackAppManifest;
68
70
  prod: SlackAppManifest;
69
71
  };
72
+ /** Relative names under `.agent-serve/slack/`. */
73
+ export declare function slackManifestFileEntries(pair: {
74
+ dev: SlackAppManifest;
75
+ prod: SlackAppManifest;
76
+ }, env?: "dev" | "prod" | "both"): ReadonlyArray<{
77
+ name: "manifest.dev.json" | "manifest.prod.json";
78
+ contents: string;
79
+ }>;
70
80
  //# sourceMappingURL=manifest.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;GAIG;AACH,eAAO,MAAM,iCAAiC,iDACE,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE;YACR,YAAY,EAAE,MAAM,CAAC;YACrB,aAAa,EAAE,OAAO,CAAC;SACxB,CAAC;QACF,cAAc,CAAC,EAAE;YACf,qBAAqB,EAAE,MAAM,CAAC;YAC9B,iBAAiB,EAAE,KAAK,CAAC;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC9D,CAAC;QACF,QAAQ,CAAC,EAAE;YACT,gBAAgB,EAAE,OAAO,CAAC;YAC1B,oBAAoB,EAAE,OAAO,CAAC;YAC9B,8BAA8B,EAAE,OAAO,CAAC;SACzC,CAAC;KACH,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE;YACN,GAAG,EAAE,MAAM,EAAE,CAAC;SACf,CAAC;KACH,CAAC;IACF,QAAQ,EAAE;QACR,mBAAmB,EAAE;YACnB,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;QACF,aAAa,EAAE;YACb,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;QACF,kBAAkB,EAAE,OAAO,CAAC;QAC5B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,sBAAsB,EAAE,OAAO,CAAC;QAChC,cAAc,EAAE,OAAO,CAAC;QACxB,oBAAoB,CAAC,EAAE;YACrB,8BAA8B,EAAE,OAAO,CAAC;YACxC,2BAA2B,EAAE,MAAM,CAAC;SACrC,CAAC;KACH,CAAC;CACH;AAwDD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,GAC5B,gBAAgB,CA+ElB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,GACzC;IACD,GAAG,EAAE,gBAAgB,CAAC;IACtB,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAKA"}
1
+ {"version":3,"file":"manifest.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/manifest.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,YAAY,CAAC;AAEvD;;;;;GAKG;AACH,eAAO,MAAM,iCAAiC,iDACE,CAAC;AAEjD,MAAM,WAAW,gBAAgB;IAC/B,mBAAmB,EAAE;QACnB,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,CAAC,EAAE,MAAM,CAAC;KACtB,CAAC;IACF,QAAQ,EAAE;QACR,QAAQ,EAAE;YACR,YAAY,EAAE,MAAM,CAAC;YACrB,aAAa,EAAE,OAAO,CAAC;SACxB,CAAC;QACF,cAAc,CAAC,EAAE;YACf,qBAAqB,EAAE,MAAM,CAAC;YAC9B,iBAAiB,EAAE,KAAK,CAAC;gBAAE,KAAK,EAAE,MAAM,CAAC;gBAAC,OAAO,EAAE,MAAM,CAAA;aAAE,CAAC,CAAC;SAC9D,CAAC;QACF,QAAQ,CAAC,EAAE;YACT,gBAAgB,EAAE,OAAO,CAAC;YAC1B,oBAAoB,EAAE,OAAO,CAAC;YAC9B,8BAA8B,EAAE,OAAO,CAAC;SACzC,CAAC;KACH,CAAC;IACF,YAAY,EAAE;QACZ,MAAM,EAAE;YACN,GAAG,EAAE,MAAM,EAAE,CAAC;SACf,CAAC;QACF,aAAa,CAAC,EAAE,MAAM,EAAE,CAAC;KAC1B,CAAC;IACF,QAAQ,EAAE;QACR,mBAAmB,EAAE;YACnB,UAAU,EAAE,MAAM,EAAE,CAAC;SACtB,CAAC;QACF,aAAa,EAAE;YACb,UAAU,EAAE,OAAO,CAAC;SACrB,CAAC;QACF,kBAAkB,EAAE,OAAO,CAAC;QAC5B,mBAAmB,EAAE,OAAO,CAAC;QAC7B,sBAAsB,EAAE,OAAO,CAAC;QAChC,cAAc,EAAE,OAAO,CAAC;QACxB,oBAAoB,CAAC,EAAE;YACrB,8BAA8B,EAAE,OAAO,CAAC;YACxC,2BAA2B,EAAE,MAAM,CAAC;SACrC,CAAC;KACH,CAAC;CACH;AAwDD;;GAEG;AACH,wBAAgB,kBAAkB,CAChC,OAAO,EAAE,oBAAoB,GAC5B,gBAAgB,CAmFlB;AAED,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,IAAI,CAAC,oBAAoB,EAAE,KAAK,CAAC,GACzC;IACD,GAAG,EAAE,gBAAgB,CAAC;IACtB,IAAI,EAAE,gBAAgB,CAAC;CACxB,CAKA;AAED,kDAAkD;AAClD,wBAAgB,wBAAwB,CACtC,IAAI,EAAE;IAAE,GAAG,EAAE,gBAAgB,CAAC;IAAC,IAAI,EAAE,gBAAgB,CAAA;CAAE,EACvD,GAAG,GAAE,KAAK,GAAG,MAAM,GAAG,MAAe,GACpC,aAAa,CAAC;IACf,IAAI,EAAE,mBAAmB,GAAG,oBAAoB,CAAC;IACjD,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAkBD"}
@@ -8,9 +8,10 @@
8
8
  * backend cannot import this published package); keep the twins in lockstep.
9
9
  */
10
10
  /**
11
- * Where Slack points users who open a Cursor-provisioned app's settings
12
- * page. Manifest builders know neither the team slug nor the deployment
13
- * id, so this is the dashboard tab root rather than a per-agent deep link.
11
+ * Dashboard tab root: Slack's app-settings banner, and the only OAuth
12
+ * redirect URI we register. AAA request-approval (`oauth_authorize_url`)
13
+ * 400s with redirect_uri mismatch unless a URI is registered. This is
14
+ * not an install callback. `apps.managedInstall` still installs.
14
15
  */
15
16
  export const SLACK_EXTERNAL_APP_MANAGEMENT_URL = "https://cursor.com/dashboard/deployed-agents";
16
17
  const BOT_SCOPES = [
@@ -108,6 +109,9 @@ export function buildSlackManifest(options) {
108
109
  scopes: {
109
110
  bot: botScopes,
110
111
  },
112
+ redirect_urls: options.managedByCursor === false
113
+ ? undefined
114
+ : [SLACK_EXTERNAL_APP_MANAGEMENT_URL],
111
115
  },
112
116
  settings: Object.assign({ event_subscriptions: {
113
117
  bot_events: botEvents,
@@ -134,3 +138,20 @@ export function buildSlackManifestPair(options) {
134
138
  prod: buildSlackManifest(Object.assign(Object.assign({}, options), { env: "prod" })),
135
139
  };
136
140
  }
141
+ /** Relative names under `.agent-serve/slack/`. */
142
+ export function slackManifestFileEntries(pair, env = "both") {
143
+ const files = [];
144
+ if (env === "dev" || env === "both") {
145
+ files.push({
146
+ name: "manifest.dev.json",
147
+ contents: `${JSON.stringify(pair.dev, null, 2)}\n`,
148
+ });
149
+ }
150
+ if (env === "prod" || env === "both") {
151
+ files.push({
152
+ name: "manifest.prod.json",
153
+ contents: `${JSON.stringify(pair.prod, null, 2)}\n`,
154
+ });
155
+ }
156
+ return files;
157
+ }
@@ -2,7 +2,32 @@
2
2
  * Slack setup guide printed by `agent-serve slack setup`.
3
3
  *
4
4
  * Two products: Cursor-hosted (`cursorAccount`) vs a dedicated Socket
5
- * Mode app via `slack create` (dashboard wizard).
5
+ * Mode app via `slack create` (dashboard wizard). `slack init --manual`
6
+ * is the unmanaged paste-at-api.slack.com path. {@link SLACK_SETUP_PHASES}
7
+ * is that checklist; its ids key `.agent-serve/slack/setup-status.json`.
6
8
  */
9
+ export interface SlackSetupPhase {
10
+ id: string;
11
+ actor: "agent" | "human";
12
+ title: string;
13
+ steps: string[];
14
+ }
15
+ export declare const SLACK_SETUP_PHASES: SlackSetupPhase[];
16
+ /** Seed `.agent-serve/slack/setup-status.json` after `slack init --manual`. */
17
+ export declare function initialSlackSetupStatus(options: {
18
+ envPrefix: string | undefined;
19
+ envKeys: {
20
+ bot: string;
21
+ app: string;
22
+ };
23
+ }): {
24
+ updatedAt: string;
25
+ envPrefix: string | null;
26
+ envKeys: {
27
+ bot: string;
28
+ app: string;
29
+ };
30
+ phases: Record<string, boolean>;
31
+ };
7
32
  export declare function formatSlackSetupGuide(): string;
8
33
  //# sourceMappingURL=setup.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/setup.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,wBAAgB,qBAAqB,IAAI,MAAM,CAyB9C"}
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/channels/slack/setup.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,WAAW,eAAe;IAC9B,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IACzB,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,EAAE,CAAC;CACjB;AAED,eAAO,MAAM,kBAAkB,EAAE,eAAe,EA4D/C,CAAC;AAEF,+EAA+E;AAC/E,wBAAgB,uBAAuB,CAAC,OAAO,EAAE;IAC/C,SAAS,EAAE,MAAM,GAAG,SAAS,CAAC;IAC9B,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;CACvC,GAAG;IACF,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,OAAO,EAAE;QAAE,GAAG,EAAE,MAAM,CAAC;QAAC,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACtC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;CACjC,CAUA;AAED,wBAAgB,qBAAqB,IAAI,MAAM,CAkC9C"}
@@ -2,31 +2,113 @@
2
2
  * Slack setup guide printed by `agent-serve slack setup`.
3
3
  *
4
4
  * Two products: Cursor-hosted (`cursorAccount`) vs a dedicated Socket
5
- * Mode app via `slack create` (dashboard wizard).
5
+ * Mode app via `slack create` (dashboard wizard). `slack init --manual`
6
+ * is the unmanaged paste-at-api.slack.com path. {@link SLACK_SETUP_PHASES}
7
+ * is that checklist; its ids key `.agent-serve/slack/setup-status.json`.
6
8
  */
9
+ export const SLACK_SETUP_PHASES = [
10
+ {
11
+ id: "generate",
12
+ actor: "agent",
13
+ title: "Generate channel + manifests",
14
+ steps: [
15
+ "agent-serve slack init --manual --dir . --name My Agent",
16
+ "Manifests default to Socket Mode (no public Request URL).",
17
+ ],
18
+ },
19
+ {
20
+ id: "createApps",
21
+ actor: "human",
22
+ title: "Create two Slack apps from manifests",
23
+ steps: [
24
+ "Open https://api.slack.com/apps -> Create New App from a manifest",
25
+ "Paste .agent-serve/slack/manifest.dev.json -> create the *dev* app",
26
+ "Repeat with manifest.prod.json for the *prod* app",
27
+ ],
28
+ },
29
+ {
30
+ id: "install",
31
+ actor: "human",
32
+ title: "Install + mint App-Level Token",
33
+ steps: [
34
+ "Install to Workspace; copy Bot User OAuth Token (xoxb-...)",
35
+ "App-Level Tokens: create token with connections:write; copy xapp-...",
36
+ ],
37
+ },
38
+ {
39
+ id: "env",
40
+ actor: "agent",
41
+ title: "Wire environment",
42
+ steps: [
43
+ "Write per-agent tokens into .env.local (see .agent-serve/slack/env.example)",
44
+ "Multi-agent: <PREFIX>_SLACK_BOT_TOKEN + <PREFIX>_SLACK_APP_TOKEN",
45
+ "Single agent: SLACK_BOT_TOKEN + SLACK_APP_TOKEN (--no-prefix)",
46
+ "agent-serve slack doctor --prefix <PREFIX>",
47
+ ],
48
+ },
49
+ {
50
+ id: "serve",
51
+ actor: "agent",
52
+ title: "Serve",
53
+ steps: [
54
+ "agent-serve serve --dir . --dev",
55
+ "Confirm log: [agent-sdk/slack] Socket Mode connected",
56
+ ],
57
+ },
58
+ {
59
+ id: "smoke",
60
+ actor: "human",
61
+ title: "Smoke test",
62
+ steps: [
63
+ "Invite the bot to a channel",
64
+ "@mention it or DM it",
65
+ "Confirm logs: inbound → session start → reply delivered",
66
+ "Confirm streaming reply and rotating status",
67
+ ],
68
+ },
69
+ ];
70
+ /** Seed `.agent-serve/slack/setup-status.json` after `slack init --manual`. */
71
+ export function initialSlackSetupStatus(options) {
72
+ var _a;
73
+ var _b;
74
+ const completed = (_a = SLACK_SETUP_PHASES[0]) === null || _a === void 0 ? void 0 : _a.id;
75
+ return {
76
+ updatedAt: new Date().toISOString(),
77
+ envPrefix: (_b = options.envPrefix) !== null && _b !== void 0 ? _b : null,
78
+ envKeys: options.envKeys,
79
+ phases: Object.fromEntries(SLACK_SETUP_PHASES.map((phase) => [phase.id, phase.id === completed])),
80
+ };
81
+ }
7
82
  export function formatSlackSetupGuide() {
8
- return `agent-serve Slack setup
9
-
10
- Two products. Pick one.
11
-
12
- A) Cursor-hosted (recommended default, zero Slack admin):
13
- slackChannel({ cursorAccount: true, agentName: "MyAgent" })
14
- Sign in (agent-serve login / CURSOR_API_KEY), serve, then mention
15
- "@Cursor MyAgent ..." in the linked workspace. No app, no tokens.
16
-
17
- B) Dedicated Slack app (Socket Mode):
18
- agent-serve slack create --dir .
19
- Opens the signed-in Cursor dashboard wizard. Finish Slack consent
20
- and the bot name there. The CLI writes tokens into .env.local.
21
- Use this when you need your own bot user, channel watching
22
- (engagement.channelPosts), or approval buttons.
23
-
24
- Do not paste a manifest at api.slack.com. \`slack init\` is removed.
25
-
26
- Then:
27
- - agent-serve serve --dir . --dev
28
- - Invite the bot (Path B) or mention @Cursor <name> (Path A)
29
-
30
- Skill: packages/agent-serve/skills/setup-slack/SKILL.md
31
- `;
83
+ const lines = [
84
+ "agent-serve — Slack setup",
85
+ "",
86
+ "Two products. Pick one.",
87
+ "",
88
+ " A) Cursor-hosted (recommended default, zero Slack admin):",
89
+ ' slackChannel({ cursorAccount: true, agentName: "MyAgent" })',
90
+ " Sign in (agent-serve login / CURSOR_API_KEY), serve, then mention",
91
+ ' "@Cursor MyAgent ..." in the linked workspace. No app, no tokens.',
92
+ " B) Dedicated Slack app (Socket Mode) via the dashboard wizard:",
93
+ " agent-serve slack create --dir .",
94
+ " Finish Slack consent and the bot name there. The CLI writes",
95
+ " tokens into .env.local. Use this when you need your own bot",
96
+ " user, channel watching, or approval buttons.",
97
+ "",
98
+ "Manual Slack app: `slack init --manual`. Phases below.",
99
+ "Goal: importable dev + prod Slack apps over Socket Mode (no public URL).",
100
+ "App-Level Token (xapp-...) + Bot Token (xoxb-...) required.",
101
+ "",
102
+ ];
103
+ for (const [index, phase] of SLACK_SETUP_PHASES.entries()) {
104
+ lines.push(`## Phase ${index} — ${phase.title} (${phase.actor})`);
105
+ for (const step of phase.steps) {
106
+ lines.push(` - ${step}`);
107
+ }
108
+ lines.push("");
109
+ }
110
+ lines.push("Status file: .agent-serve/slack/setup-status.json");
111
+ lines.push("Skill (Cursor): packages/agent-serve/skills/setup-slack/SKILL.md");
112
+ lines.push("");
113
+ return lines.join("\n");
32
114
  }
@@ -6,17 +6,17 @@
6
6
  <title>404 | Agent SDK</title>
7
7
  <meta name="description" content="Not Found">
8
8
  <meta name="generator" content="VitePress v1.6.4">
9
- <link rel="preload stylesheet" href="/docs/assets/style.CK3hwt6q.css" as="style">
9
+ <link rel="preload stylesheet" href="/docs/assets/style.kTsvp4pE.css" as="style">
10
10
  <link rel="preload stylesheet" href="/docs/vp-icons.css" as="style">
11
11
 
12
- <script type="module" src="/docs/assets/app.Cbeq6FOy.js"></script>
12
+ <script type="module" src="/docs/assets/app.DAKcDclS.js"></script>
13
13
  <link rel="preload" href="/docs/assets/inter-roman-latin.Di8DUHzh.woff2" as="font" type="font/woff2" crossorigin="">
14
14
  <script id="check-dark-mode">(()=>{const e=localStorage.getItem("vitepress-theme-appearance")||"auto",a=window.matchMedia("(prefers-color-scheme: dark)").matches;(!e||e==="auto"?a:e==="dark")&&document.documentElement.classList.add("dark")})();</script>
15
15
  <script id="check-mac-os">document.documentElement.classList.toggle("mac",/Mac|iPhone|iPod|iPad/i.test(navigator.platform));</script>
16
16
  </head>
17
17
  <body>
18
18
  <div id="app"></div>
19
- <script>window.__VP_HASH_MAP__=JSON.parse("{\"ab.md\":\"DYjwREAP\",\"building-with-agents.md\":\"PeZaZA1P\",\"concepts.md\":\"CqOsxbMU\",\"deployment.md\":\"B8kW-h7P\",\"evals.md\":\"CVe_O75-\",\"example-agents_approval-buddy.md\":\"CIiZ9coo\",\"example-agents_benny.md\":\"B-LIDGja\",\"example-agents_bugbot.md\":\"Dp5JqHSQ\",\"example-agents_codebase-wiki.md\":\"D-lteFf0\",\"example-agents_codeowners-review.md\":\"BU2ZXLf-\",\"example-agents_concierge.md\":\"DA2al_NK\",\"example-agents_fsd.md\":\"DPz9ezO4\",\"example-agents_index.md\":\"xmJ87d_3\",\"example-agents_knowledge-base.md\":\"IneynQSR\",\"example-agents_oncall.md\":\"CBmyuAKc\",\"example-agents_security-reviewer.md\":\"Dkf1gyo6\",\"example-agents_slack-agent.md\":\"06jQXTAI\",\"example-agents_weather-agent.md\":\"DC3lINjo\",\"guides_agent-to-agent.md\":\"Bmbxy-FA\",\"guides_cloud-runtime.md\":\"V5igN4Sq\",\"guides_github.md\":\"B8QKtIpw\",\"guides_human-in-the-loop.md\":\"Cf8kIIqC\",\"guides_mcp-oauth.md\":\"C7G7IykG\",\"guides_opentelemetry.md\":\"Csn7ZI25\",\"guides_slack.md\":\"D2nTRu9M\",\"guides_webhooks.md\":\"DB-r_er9\",\"hillclimbing.md\":\"yXqdlv2R\",\"index.md\":\"COeoSkcF\",\"quickstart.md\":\"DZxBu44y\",\"reference_agent-config.md\":\"DHkkvcEZ\",\"reference_artifacts.md\":\"BGG4bZo-\",\"reference_channels.md\":\"MN8iDy8V\",\"reference_cli.md\":\"CGKfz_Yj\",\"reference_connections.md\":\"CSQiNzre\",\"reference_hooks.md\":\"DJE5DXcT\",\"reference_http-api.md\":\"DMbdFGVQ\",\"reference_instructions.md\":\"CgoV-YEb\",\"reference_playground.md\":\"CPZhfYaO\",\"reference_project-layout.md\":\"D3MdHM2z\",\"reference_prompt.md\":\"BaiweQxE\",\"reference_schedules.md\":\"gmfYzf_I\",\"reference_sessions.md\":\"DBVFi2Sx\",\"reference_skills.md\":\"B_jHN7JL\",\"reference_subagents.md\":\"DSrGLIuB\",\"reference_tools.md\":\"kJfJAP2m\",\"scaffolding-agents.md\":\"mkc3B_ZW\",\"storage.md\":\"D8NQ389l\",\"templates_triage.md\":\"CConZt1z\",\"troubleshooting.md\":\"C6n3wCr6\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Agent SDK\",\"description\":\"Filesystem-first framework for building and serving Cursor agents.\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Guides\",\"link\":\"/guides/webhooks\"},{\"text\":\"Examples\",\"link\":\"/example-agents/\"},{\"text\":\"Reference\",\"link\":\"/reference/project-layout\"}],\"search\":{\"provider\":\"local\"},\"outline\":{\"level\":[2,3]},\"sidebar\":[{\"text\":\"Getting started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/\"},{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Scaffold an agent with Cursor\",\"link\":\"/scaffolding-agents\"},{\"text\":\"Concepts\",\"link\":\"/concepts\"}]},{\"text\":\"Templates\",\"items\":[{\"text\":\"Triage agent\",\"link\":\"/templates/triage\"}]},{\"text\":\"Improving agents\",\"items\":[{\"text\":\"Building agents with agents\",\"link\":\"/building-with-agents\"},{\"text\":\"Evals\",\"link\":\"/evals\"},{\"text\":\"Live A/B metrics\",\"link\":\"/ab\"},{\"text\":\"Storage\",\"link\":\"/storage\"},{\"text\":\"Hillclimbing\",\"link\":\"/hillclimbing\"}]},{\"text\":\"Guides\",\"items\":[{\"text\":\"Webhooks & custom channels\",\"link\":\"/guides/webhooks\"},{\"text\":\"GitHub\",\"link\":\"/guides/github\"},{\"text\":\"Slack\",\"link\":\"/guides/slack\"},{\"text\":\"Human-in-the-loop approvals\",\"link\":\"/guides/human-in-the-loop\"},{\"text\":\"Agent-to-agent\",\"link\":\"/guides/agent-to-agent\"},{\"text\":\"Host MCP OAuth\",\"link\":\"/guides/mcp-oauth\"},{\"text\":\"Cloud runtime\",\"link\":\"/guides/cloud-runtime\"},{\"text\":\"OpenTelemetry\",\"link\":\"/guides/opentelemetry\"}]},{\"text\":\"Example agents\",\"items\":[{\"text\":\"Choose an example\",\"link\":\"/example-agents/\"},{\"text\":\"Weather agent\",\"link\":\"/example-agents/weather-agent\"},{\"text\":\"Slack agent\",\"link\":\"/example-agents/slack-agent\"},{\"text\":\"Concierge\",\"link\":\"/example-agents/concierge\"},{\"text\":\"Playbook router\",\"link\":\"/example-agents/benny\"},{\"text\":\"Alert investigator\",\"link\":\"/example-agents/oncall\"},{\"text\":\"PR evidence reviewer\",\"link\":\"/example-agents/bugbot\"},{\"text\":\"Approval Buddy\",\"link\":\"/example-agents/approval-buddy\"},{\"text\":\"Security Reviewer\",\"link\":\"/example-agents/security-reviewer\"},{\"text\":\"Remote PR coordinator\",\"link\":\"/example-agents/fsd\"},{\"text\":\"Knowledge base\",\"link\":\"/example-agents/knowledge-base\"},{\"text\":\"Codebase wiki\",\"link\":\"/example-agents/codebase-wiki\"},{\"text\":\"Codeowners review\",\"link\":\"/example-agents/codeowners-review\"}]},{\"text\":\"Operating\",\"items\":[{\"text\":\"Deployment\",\"link\":\"/deployment\"},{\"text\":\"Fix common problems\",\"link\":\"/troubleshooting\"}]},{\"text\":\"Reference\",\"collapsed\":false,\"items\":[{\"text\":\"Project layout\",\"link\":\"/reference/project-layout\"},{\"text\":\"Agent config\",\"link\":\"/reference/agent-config\"},{\"text\":\"Instructions\",\"link\":\"/reference/instructions\"},{\"text\":\"Tools\",\"link\":\"/reference/tools\"},{\"text\":\"prompt\",\"link\":\"/reference/prompt\"},{\"text\":\"Skills\",\"link\":\"/reference/skills\"},{\"text\":\"MCP Connections\",\"link\":\"/reference/connections\"},{\"text\":\"Subagents\",\"link\":\"/reference/subagents\"},{\"text\":\"Channels\",\"link\":\"/reference/channels\"},{\"text\":\"Schedules & reminders\",\"link\":\"/reference/schedules\"},{\"text\":\"Hooks\",\"link\":\"/reference/hooks\"},{\"text\":\"Artifacts\",\"link\":\"/reference/artifacts\"},{\"text\":\"Sessions & streaming\",\"link\":\"/reference/sessions\"},{\"text\":\"Playground\",\"link\":\"/reference/playground\"},{\"text\":\"CLI\",\"link\":\"/reference/cli\"},{\"text\":\"HTTP API\",\"link\":\"/reference/http-api\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
19
+ <script>window.__VP_HASH_MAP__=JSON.parse("{\"ab.md\":\"DYjwREAP\",\"building-with-agents.md\":\"PeZaZA1P\",\"concepts.md\":\"CqOsxbMU\",\"deployment.md\":\"B8kW-h7P\",\"evals.md\":\"CVe_O75-\",\"example-agents_approval-buddy.md\":\"CIiZ9coo\",\"example-agents_benny.md\":\"B-LIDGja\",\"example-agents_bugbot.md\":\"Dp5JqHSQ\",\"example-agents_codebase-wiki.md\":\"D-lteFf0\",\"example-agents_codeowners-review.md\":\"BU2ZXLf-\",\"example-agents_concierge.md\":\"DA2al_NK\",\"example-agents_fsd.md\":\"DPz9ezO4\",\"example-agents_index.md\":\"xmJ87d_3\",\"example-agents_knowledge-base.md\":\"IneynQSR\",\"example-agents_oncall.md\":\"CBmyuAKc\",\"example-agents_security-reviewer.md\":\"Dkf1gyo6\",\"example-agents_slack-agent.md\":\"06jQXTAI\",\"example-agents_weather-agent.md\":\"DC3lINjo\",\"guides_agent-to-agent.md\":\"Bmbxy-FA\",\"guides_cloud-runtime.md\":\"V5igN4Sq\",\"guides_github.md\":\"B8QKtIpw\",\"guides_human-in-the-loop.md\":\"Cf8kIIqC\",\"guides_mcp-oauth.md\":\"C7G7IykG\",\"guides_opentelemetry.md\":\"Csn7ZI25\",\"guides_slack.md\":\"DP4H75WP\",\"guides_webhooks.md\":\"DB-r_er9\",\"hillclimbing.md\":\"yXqdlv2R\",\"index.md\":\"COeoSkcF\",\"quickstart.md\":\"DZxBu44y\",\"reference_agent-config.md\":\"DHkkvcEZ\",\"reference_artifacts.md\":\"BGG4bZo-\",\"reference_channels.md\":\"MN8iDy8V\",\"reference_cli.md\":\"-V6J7Cl8\",\"reference_connections.md\":\"CSQiNzre\",\"reference_hooks.md\":\"DJE5DXcT\",\"reference_http-api.md\":\"DMbdFGVQ\",\"reference_instructions.md\":\"CgoV-YEb\",\"reference_playground.md\":\"CPZhfYaO\",\"reference_project-layout.md\":\"D3MdHM2z\",\"reference_prompt.md\":\"BaiweQxE\",\"reference_schedules.md\":\"gmfYzf_I\",\"reference_sessions.md\":\"DBVFi2Sx\",\"reference_skills.md\":\"B_jHN7JL\",\"reference_subagents.md\":\"DSrGLIuB\",\"reference_tools.md\":\"kJfJAP2m\",\"scaffolding-agents.md\":\"mkc3B_ZW\",\"storage.md\":\"D8NQ389l\",\"templates_triage.md\":\"CConZt1z\",\"troubleshooting.md\":\"CuVztCKs\"}");window.__VP_SITE_DATA__=JSON.parse("{\"lang\":\"en-US\",\"dir\":\"ltr\",\"title\":\"Agent SDK\",\"description\":\"Filesystem-first framework for building and serving Cursor agents.\",\"base\":\"/docs/\",\"head\":[],\"router\":{\"prefetchLinks\":true},\"appearance\":true,\"themeConfig\":{\"nav\":[{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Guides\",\"link\":\"/guides/webhooks\"},{\"text\":\"Examples\",\"link\":\"/example-agents/\"},{\"text\":\"Reference\",\"link\":\"/reference/project-layout\"}],\"search\":{\"provider\":\"local\"},\"outline\":{\"level\":[2,3]},\"sidebar\":[{\"text\":\"Getting started\",\"items\":[{\"text\":\"Overview\",\"link\":\"/\"},{\"text\":\"Quickstart\",\"link\":\"/quickstart\"},{\"text\":\"Scaffold an agent with Cursor\",\"link\":\"/scaffolding-agents\"},{\"text\":\"Concepts\",\"link\":\"/concepts\"}]},{\"text\":\"Templates\",\"items\":[{\"text\":\"Triage agent\",\"link\":\"/templates/triage\"}]},{\"text\":\"Improving agents\",\"items\":[{\"text\":\"Building agents with agents\",\"link\":\"/building-with-agents\"},{\"text\":\"Evals\",\"link\":\"/evals\"},{\"text\":\"Live A/B metrics\",\"link\":\"/ab\"},{\"text\":\"Storage\",\"link\":\"/storage\"},{\"text\":\"Hillclimbing\",\"link\":\"/hillclimbing\"}]},{\"text\":\"Guides\",\"items\":[{\"text\":\"Webhooks & custom channels\",\"link\":\"/guides/webhooks\"},{\"text\":\"GitHub\",\"link\":\"/guides/github\"},{\"text\":\"Slack\",\"link\":\"/guides/slack\"},{\"text\":\"Human-in-the-loop approvals\",\"link\":\"/guides/human-in-the-loop\"},{\"text\":\"Agent-to-agent\",\"link\":\"/guides/agent-to-agent\"},{\"text\":\"Host MCP OAuth\",\"link\":\"/guides/mcp-oauth\"},{\"text\":\"Cloud runtime\",\"link\":\"/guides/cloud-runtime\"},{\"text\":\"OpenTelemetry\",\"link\":\"/guides/opentelemetry\"}]},{\"text\":\"Example agents\",\"items\":[{\"text\":\"Choose an example\",\"link\":\"/example-agents/\"},{\"text\":\"Weather agent\",\"link\":\"/example-agents/weather-agent\"},{\"text\":\"Slack agent\",\"link\":\"/example-agents/slack-agent\"},{\"text\":\"Concierge\",\"link\":\"/example-agents/concierge\"},{\"text\":\"Playbook router\",\"link\":\"/example-agents/benny\"},{\"text\":\"Alert investigator\",\"link\":\"/example-agents/oncall\"},{\"text\":\"PR evidence reviewer\",\"link\":\"/example-agents/bugbot\"},{\"text\":\"Approval Buddy\",\"link\":\"/example-agents/approval-buddy\"},{\"text\":\"Security Reviewer\",\"link\":\"/example-agents/security-reviewer\"},{\"text\":\"Remote PR coordinator\",\"link\":\"/example-agents/fsd\"},{\"text\":\"Knowledge base\",\"link\":\"/example-agents/knowledge-base\"},{\"text\":\"Codebase wiki\",\"link\":\"/example-agents/codebase-wiki\"},{\"text\":\"Codeowners review\",\"link\":\"/example-agents/codeowners-review\"}]},{\"text\":\"Operating\",\"items\":[{\"text\":\"Deployment\",\"link\":\"/deployment\"},{\"text\":\"Fix common problems\",\"link\":\"/troubleshooting\"}]},{\"text\":\"Reference\",\"collapsed\":false,\"items\":[{\"text\":\"Project layout\",\"link\":\"/reference/project-layout\"},{\"text\":\"Agent config\",\"link\":\"/reference/agent-config\"},{\"text\":\"Instructions\",\"link\":\"/reference/instructions\"},{\"text\":\"Tools\",\"link\":\"/reference/tools\"},{\"text\":\"prompt\",\"link\":\"/reference/prompt\"},{\"text\":\"Skills\",\"link\":\"/reference/skills\"},{\"text\":\"MCP Connections\",\"link\":\"/reference/connections\"},{\"text\":\"Subagents\",\"link\":\"/reference/subagents\"},{\"text\":\"Channels\",\"link\":\"/reference/channels\"},{\"text\":\"Schedules & reminders\",\"link\":\"/reference/schedules\"},{\"text\":\"Hooks\",\"link\":\"/reference/hooks\"},{\"text\":\"Artifacts\",\"link\":\"/reference/artifacts\"},{\"text\":\"Sessions & streaming\",\"link\":\"/reference/sessions\"},{\"text\":\"Playground\",\"link\":\"/reference/playground\"},{\"text\":\"CLI\",\"link\":\"/reference/cli\"},{\"text\":\"HTTP API\",\"link\":\"/reference/http-api\"}]}]},\"locales\":{},\"scrollOffset\":134,\"cleanUrls\":false}");</script>
20
20
 
21
21
  </body>
22
22
  </html>