@cursor/july 0.1.91 → 0.1.92

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 (132) hide show
  1. package/AGENTS.md +4 -0
  2. package/dist/docs/404.html +3 -1
  3. package/dist/docs/ab.html +4 -2
  4. package/dist/docs/ab.md +338 -0
  5. package/dist/docs/building-with-agents.html +4 -2
  6. package/dist/docs/building-with-agents.md +124 -0
  7. package/dist/docs/concepts.html +4 -2
  8. package/dist/docs/concepts.md +174 -0
  9. package/dist/docs/deployment.html +4 -2
  10. package/dist/docs/deployment.md +464 -0
  11. package/dist/docs/evals.html +4 -2
  12. package/dist/docs/evals.md +481 -0
  13. package/dist/docs/example-agents/approval-buddy.html +4 -2
  14. package/dist/docs/example-agents/approval-buddy.md +266 -0
  15. package/dist/docs/example-agents/benny.html +4 -2
  16. package/dist/docs/example-agents/benny.md +182 -0
  17. package/dist/docs/example-agents/bugbot.html +4 -2
  18. package/dist/docs/example-agents/bugbot.md +229 -0
  19. package/dist/docs/example-agents/codebase-wiki.html +4 -2
  20. package/dist/docs/example-agents/codebase-wiki.md +170 -0
  21. package/dist/docs/example-agents/codeowners-review.html +4 -2
  22. package/dist/docs/example-agents/codeowners-review.md +192 -0
  23. package/dist/docs/example-agents/concierge.html +4 -2
  24. package/dist/docs/example-agents/concierge.md +201 -0
  25. package/dist/docs/example-agents/fsd.html +4 -2
  26. package/dist/docs/example-agents/fsd.md +329 -0
  27. package/dist/docs/example-agents/index.html +4 -2
  28. package/dist/docs/example-agents/index.md +102 -0
  29. package/dist/docs/example-agents/knowledge-base.html +4 -2
  30. package/dist/docs/example-agents/knowledge-base.md +168 -0
  31. package/dist/docs/example-agents/oncall.html +4 -2
  32. package/dist/docs/example-agents/oncall.md +212 -0
  33. package/dist/docs/example-agents/security-reviewer.html +4 -2
  34. package/dist/docs/example-agents/security-reviewer.md +265 -0
  35. package/dist/docs/example-agents/slack-agent.html +4 -2
  36. package/dist/docs/example-agents/slack-agent.md +142 -0
  37. package/dist/docs/example-agents/weather-agent.html +4 -2
  38. package/dist/docs/example-agents/weather-agent.md +296 -0
  39. package/dist/docs/guides/agent-to-agent.html +4 -2
  40. package/dist/docs/guides/agent-to-agent.md +113 -0
  41. package/dist/docs/guides/cloud-runtime.html +4 -2
  42. package/dist/docs/guides/cloud-runtime.md +131 -0
  43. package/dist/docs/guides/convert-automation.html +4 -2
  44. package/dist/docs/guides/convert-automation.md +171 -0
  45. package/dist/docs/guides/github.html +4 -2
  46. package/dist/docs/guides/github.md +287 -0
  47. package/dist/docs/guides/human-in-the-loop.html +4 -2
  48. package/dist/docs/guides/human-in-the-loop.md +126 -0
  49. package/dist/docs/guides/mcp-oauth.html +4 -2
  50. package/dist/docs/guides/mcp-oauth.md +159 -0
  51. package/dist/docs/guides/opentelemetry.html +4 -2
  52. package/dist/docs/guides/opentelemetry.md +209 -0
  53. package/dist/docs/guides/slack.html +4 -2
  54. package/dist/docs/guides/slack.md +337 -0
  55. package/dist/docs/guides/webhooks.html +4 -2
  56. package/dist/docs/guides/webhooks.md +463 -0
  57. package/dist/docs/hillclimbing.html +4 -2
  58. package/dist/docs/hillclimbing.md +88 -0
  59. package/dist/docs/index.html +4 -2
  60. package/dist/docs/index.md +179 -0
  61. package/dist/docs/llms-full.txt +11518 -0
  62. package/dist/docs/llms.txt +75 -0
  63. package/dist/docs/quickstart.html +4 -2
  64. package/dist/docs/quickstart.md +364 -0
  65. package/dist/docs/reference/agent-config.html +4 -2
  66. package/dist/docs/reference/agent-config.md +256 -0
  67. package/dist/docs/reference/artifacts.html +4 -2
  68. package/dist/docs/reference/artifacts.md +112 -0
  69. package/dist/docs/reference/channels.html +4 -2
  70. package/dist/docs/reference/channels.md +255 -0
  71. package/dist/docs/reference/cli.html +4 -2
  72. package/dist/docs/reference/cli.md +957 -0
  73. package/dist/docs/reference/connections.html +4 -2
  74. package/dist/docs/reference/connections.md +268 -0
  75. package/dist/docs/reference/hooks.html +4 -2
  76. package/dist/docs/reference/hooks.md +102 -0
  77. package/dist/docs/reference/http-api.html +4 -2
  78. package/dist/docs/reference/http-api.md +267 -0
  79. package/dist/docs/reference/instructions.html +4 -2
  80. package/dist/docs/reference/instructions.md +74 -0
  81. package/dist/docs/reference/playground.html +4 -2
  82. package/dist/docs/reference/playground.md +62 -0
  83. package/dist/docs/reference/project-layout.html +4 -2
  84. package/dist/docs/reference/project-layout.md +107 -0
  85. package/dist/docs/reference/prompt.html +4 -2
  86. package/dist/docs/reference/prompt.md +42 -0
  87. package/dist/docs/reference/schedules.html +4 -2
  88. package/dist/docs/reference/schedules.md +215 -0
  89. package/dist/docs/reference/sessions.html +4 -2
  90. package/dist/docs/reference/sessions.md +170 -0
  91. package/dist/docs/reference/skills.html +4 -2
  92. package/dist/docs/reference/skills.md +83 -0
  93. package/dist/docs/reference/subagents.html +4 -2
  94. package/dist/docs/reference/subagents.md +71 -0
  95. package/dist/docs/reference/tools.html +4 -2
  96. package/dist/docs/reference/tools.md +298 -0
  97. package/dist/docs/scaffolding-agents.html +4 -2
  98. package/dist/docs/scaffolding-agents.md +130 -0
  99. package/dist/docs/storage.html +4 -2
  100. package/dist/docs/storage.md +219 -0
  101. package/dist/docs/templates/agentic-owners.html +4 -2
  102. package/dist/docs/templates/agentic-owners.md +92 -0
  103. package/dist/docs/templates/demo.html +4 -2
  104. package/dist/docs/templates/demo.md +79 -0
  105. package/dist/docs/templates/pr-autofixer.html +4 -2
  106. package/dist/docs/templates/pr-autofixer.md +131 -0
  107. package/dist/docs/templates/security-reviewer.html +4 -2
  108. package/dist/docs/templates/security-reviewer.md +84 -0
  109. package/dist/docs/templates/triage.html +4 -2
  110. package/dist/docs/templates/triage.md +98 -0
  111. package/dist/docs/troubleshooting.html +4 -2
  112. package/dist/docs/troubleshooting.md +111 -0
  113. package/dist/internal/init-scaffold.d.ts.map +1 -1
  114. package/dist/internal/init-scaffold.js +1 -0
  115. package/dist/internal/playground/static.d.ts.map +1 -1
  116. package/dist/internal/playground/static.js +2 -0
  117. package/dist/internal/session-engine.d.ts.map +1 -1
  118. package/dist/internal/session-engine.js +3 -1
  119. package/package.json +2 -2
  120. package/skills/ab/SKILL.md +3 -0
  121. package/skills/create-agent/SKILL.md +3 -0
  122. package/skills/debug/SKILL.md +3 -0
  123. package/skills/evals/SKILL.md +3 -0
  124. package/skills/framework-map/SKILL.md +3 -0
  125. package/skills/github/SKILL.md +3 -0
  126. package/skills/hillclimb/SKILL.md +3 -0
  127. package/skills/mcp-auth/SKILL.md +3 -0
  128. package/skills/otel/SKILL.md +3 -0
  129. package/skills/setup-slack/SKILL.md +3 -0
  130. package/src/internal/init-scaffold.ts +1 -0
  131. package/src/internal/playground/static.ts +2 -0
  132. package/src/internal/session-engine.ts +4 -6
@@ -0,0 +1,329 @@
1
+ # Hand PR triage to managed remote agents
2
+
3
+ The remote PR coordinator keeps chat and routing on the local serve host,
4
+ then hands each pull request to a managed remote agent with a real checkout.
5
+ The same remote conversation resumes when a user drives the PR again, GitHub
6
+ reports a change, or a merge-conflict reminder fires.
7
+
8
+ This example is Cursor-internal. For your own repos, scaffold
9
+ [PR autofixer](/docs/templates/pr-autofixer.md) instead.
10
+
11
+ The workflow backend enrolls each remote run with a workflow MCP. Its tools
12
+ and the host's findings routes read and write the same external findings
13
+ service.
14
+
15
+ Use this example when repository work is too heavy or concurrent for local
16
+ worktrees, but the host should still own intake, session identity, policy, and
17
+ bookkeeping.
18
+
19
+ [Browse the current coordinator source.](https://github.com/cursor/cursor/tree/main/packages/agent-serve/examples/fsd/)
20
+
21
+ ## Resume one remote agent across every PR wake
22
+
23
+ The coordinator uses a hybrid runtime:
24
+
25
+ - Ordinary playground and Slack chat run locally.
26
+ - The `drive_pr` server tool creates a remote session for one PR.
27
+ - The remote worker gets the repository and PR reference.
28
+ - An `agent.bound` hook records the remote run id and enrolls the run into a
29
+ workflow MCP.
30
+ - Webhooks and reminders resume the same remote agent through durable
31
+ PR-to-agent affinity.
32
+
33
+ No other example moves one logical conversation across local chat, remote
34
+ execution, event wakes, and timed follow-ups.
35
+
36
+ ## Follow a chat request
37
+
38
+ 1. A user asks local chat or Slack to drive a PR.
39
+ 2. The root model calls `drive_pr` with the PR, mode, and optional hint.
40
+ 3. The tool calls `ctx.send("drive", ...)` with a per-session `cloud` block
41
+ to attach the PR.
42
+ 4. The Agent SDK creates or resumes the `drive` session keyed by
43
+ `pr:owner/repo#N`.
44
+ 5. The remote runtime provisions the agent and emits `agent.bound`.
45
+ 6. The enrollment hook writes PR affinity and calls the workflow backend to
46
+ attach run-scoped MCP tools.
47
+ 7. `drive_pr` waits for remote binding, then returns the agent id and URL.
48
+ If binding exceeds its wait window, those fields can be `null` while work
49
+ continues.
50
+ 8. The remote agent reads the host-prepared PR brief, checks unresolved state,
51
+ and records findings through the workflow MCP.
52
+ 9. The host forwards a validated fallback output block when MCP wasn't
53
+ available for the turn.
54
+
55
+ The local chat agent doesn't have the target checkout, `gh`, `git`, or the
56
+ workflow MCP. Its job is coordination.
57
+
58
+ A request for a merged or closed PR finishes before provisioning. That result
59
+ has `status: "finished"` and no remote session.
60
+
61
+ ## Map the framework features
62
+
63
+ | Capability | Source | Role |
64
+ | --- | --- | --- |
65
+ | Hybrid config | [`agent/agent.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/agent.ts) | Keep chat local, set remote-runtime defaults, disable automatic PR creation, and isolate local harness workspaces. |
66
+ | Root instructions | [`agent/instructions.md`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/instructions.md) | Separate local coordination from remote triage and define suggest/apply policy. |
67
+ | Drive tool | [`agent/tools/drive_pr.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/tools/drive_pr.ts) | Hand a chat request to the `drive` channel and wait for remote binding. |
68
+ | Drive channel | [`agent/channels/drive.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/channels/drive.ts) | Start remote work and expose findings read/write routes. |
69
+ | GitHub channel | [`agent/channels/github.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/channels/github.ts) | Buffer PR, comment, review, check, and status wakes. |
70
+ | Slack channel | [`agent/channels/slack.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/channels/slack.ts) | Route Slack requests to the local coordinator. |
71
+ | Hooks | [`agent/hooks/enroll-fsd.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/hooks/enroll-fsd.ts), [`agent/hooks/record-outputs.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/hooks/record-outputs.ts) | Bind remote identity, enroll MCP, and forward fallback findings. |
72
+ | Affinity and buffering | [`agent/lib/pr-affinity.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/lib/pr-affinity.ts), [`agent/lib/webhook-buffer.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/lib/webhook-buffer.ts) | Persist PR identity, sticky mode, and pending wakes. |
73
+ | Reminders | [`agent/lib/merge-conflict-watch.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/lib/merge-conflict-watch.ts) | Recheck merge conflicts every 30 minutes. |
74
+ | Workflow client | [`agent/lib/fsd-platform.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/lib/fsd-platform.ts) | Enroll external runs and read or record findings. |
75
+ | Storage | [`agent/storage.ts`](https://github.com/cursor/cursor/blob/main/packages/agent-serve/examples/fsd/agent/storage.ts) | Persist sessions and events with `cursorHostedStorage`. |
76
+
77
+ The coordinator has no authored skill, subagent, MCP connection, static
78
+ schedule, A/B experiment, eval, or tool approval.
79
+
80
+ The workflow MCP is dynamic. Backend enrollment attaches it to the remote run,
81
+ so there is no file under `agent/mcp-connections/`.
82
+
83
+ ## Understand local and remote workspaces
84
+
85
+ The root config sets `runtime: "local"` because `drive_pr` is a server tool.
86
+ It also supplies remote-runtime defaults through the `cloud` configuration:
87
+
88
+ ```ts
89
+ local: {
90
+ cwd: join(homedir(), ".cache", "agent-serve", "fsd"),
91
+ },
92
+ cloud: {
93
+ env: { type: "cloud" },
94
+ autoCreatePR: false,
95
+ },
96
+ ```
97
+
98
+ The local cwd sits outside the monorepo, so inherited repository instructions
99
+ don't affect coordinator chat.
100
+
101
+ Remote sessions get a repository attachment with the target PR. The worker starts
102
+ from the PR base and creates an automation side branch from the PR head only when
103
+ code context or a fix is needed. The serve host never checks out target code.
104
+
105
+ ## Prepare access
106
+
107
+ You need:
108
+
109
+ - Node 22.13 or newer.
110
+ - An agent-runtime user credential.
111
+ - Access to a managed remote runtime.
112
+ - Access to the target GitHub PR.
113
+ - Access to the workflow backend and findings store.
114
+
115
+ Keep the affinity and webhook-buffer files on durable storage for a
116
+ long-lived host.
117
+
118
+ ## Validate without starting remote work
119
+
120
+ ```bash
121
+ agent-sdk validate --dir examples/fsd
122
+ agent-sdk info --dir examples/fsd --json
123
+ agent-sdk github events --dir examples/fsd --json
124
+ ```
125
+
126
+ These commands inspect discovery and declared GitHub events. They don't
127
+ provision a remote agent.
128
+
129
+ ## Choose suggest or apply
130
+
131
+ Every PR has a sticky mode:
132
+
133
+ | Mode | Required remote behavior |
134
+ | --- | --- |
135
+ | `suggest` | May create verified commits on the VM's local side branch. Instructions require no pushes, comments, PR edits, or workflow actions. Records exact fixes and actions as findings for the owner. |
136
+ | `apply` | Pushes verified fixes to the existing PR head and may update metadata, reply to threads, mark a draft ready, rebase, or rerun CI. |
137
+
138
+ The remote instructions forbid merging, enabling auto-merge, force-pushing,
139
+ and opening a new PR in both modes. `autoCreatePR: false` also disables the
140
+ SDK's automatic PR creation. The other restrictions are prompt policy, not a
141
+ deterministic host gate. `suggest` is the default.
142
+
143
+ The selected mode is stored beside PR affinity. Webhooks and reminders reuse
144
+ it. Re-driving a PR can change the host-side mode. Backend enrollment records
145
+ the mode at first enrollment, so each later host prompt repeats the current
146
+ authoritative mode.
147
+
148
+ > [!CAUTION]
149
+ > `apply` writes to the user's PR branch and triggers CI. Use `suggest` for
150
+ > development. Both modes provision a billed remote agent and can write
151
+ > structured findings to the findings service. `drive_pr` has no approval gate,
152
+ > and suggest/apply restrictions depend on the remote agent following its
153
+ > instructions.
154
+
155
+ ## Start a suggest-mode drive
156
+
157
+ Run the host:
158
+
159
+ ```bash
160
+ agent-sdk dev examples/fsd
161
+ ```
162
+
163
+ From chat:
164
+
165
+ > Drive https://github.com/owner/repo/pull/123 in suggest mode.
166
+
167
+ Or call the coordinator tool:
168
+
169
+ ```bash
170
+ agent-sdk call drive_pr \
171
+ --dir examples/fsd \
172
+ --input '{"pr":"https://github.com/owner/repo/pull/123","mode":"suggest"}'
173
+ ```
174
+
175
+ For an open PR, the tool waits up to 60 seconds for remote binding and returns:
176
+
177
+ - the normalized PR label,
178
+ - session and continuation ids,
179
+ - the remote-agent id and URL when binding completes in that window,
180
+ - `status: "started"`, and
181
+ - the merge-conflict reminder id.
182
+
183
+ It doesn't wait for findings. A slow binding can return `null` identifiers.
184
+ Open the returned agent URL when present to follow the remote run.
185
+
186
+ ## Use the HTTP drive surface
187
+
188
+ The custom channel starts the same orchestration:
189
+
190
+ ```bash
191
+ curl -s -X POST \
192
+ http://127.0.0.1:3000/fsd/v1/channels/drive/ \
193
+ -H 'content-type: application/json' \
194
+ -d '{"pr":"owner/repo#123","mode":"suggest"}'
195
+ ```
196
+
197
+ This route returns as soon as the channel session exists. The remote-agent id
198
+ can still be `null` at that point. Triage continues in the background.
199
+
200
+ Read findings later:
201
+
202
+ ```bash
203
+ curl -s \
204
+ 'http://127.0.0.1:3000/fsd/v1/channels/drive/findings?pr=owner/repo%23123'
205
+ ```
206
+
207
+ The external findings service is the source of truth. The local host doesn't keep a second
208
+ findings database.
209
+
210
+ The channel also exposes `POST /findings` as a testing surface. It validates
211
+ outputs, then writes them to the findings service for a PR already bound by this
212
+ host. The route has no approval gate. Keep it under the default loopback auth
213
+ or another trusted boundary.
214
+
215
+ ## Keep one remote agent per PR
216
+
217
+ Within the `drive` channel, the stable continuation token
218
+ `pr:owner/repo#N` resumes the same session. GitHub sessions are scoped to
219
+ another channel, so a continuation token alone can't bridge them.
220
+
221
+ The enrollment hook closes that gap:
222
+
223
+ 1. Read the PR from the continuation token or host-authored session title.
224
+ 2. Record PR to `sdkAgentId` affinity after `agent.bound`.
225
+ 3. Seed later sessions with the same remote id.
226
+ 4. Retry workflow MCP enrollment after a completed turn when the first RPC
227
+ failed.
228
+
229
+ This lets Slack, HTTP drive, GitHub, and reminders talk to one remote
230
+ conversation without sharing one channel session.
231
+
232
+ ## Buffer GitHub wakes
233
+
234
+ The GitHub channel handles pull requests, comments, reviews, check suites,
235
+ check runs, and selected status events. It doesn't send payload details to the
236
+ model. It asks the remote agent to refresh live source of truth.
237
+
238
+ The buffer:
239
+
240
+ - groups events by PR,
241
+ - waits three seconds for a burst to settle,
242
+ - re-buffers while CI settles,
243
+ - skips a flush when the PR session is busy,
244
+ - tries to write its snapshot before acknowledging a wake, and
245
+ - restores pending entries when the channel starts.
246
+
247
+ Closing a PR discards its pending entry and cancels its reminders.
248
+
249
+ Snapshot persistence is best-effort. Write failures are swallowed silently,
250
+ so a delivery can still be acknowledged without a durable snapshot.
251
+
252
+ This is the high-volume counterpart to a direct `{ auth }` GitHub wake. See
253
+ [GitHub](/docs/guides/github.md#handle-high-event-volume) for the reusable
254
+ pattern.
255
+
256
+ ## Add merge-conflict checks
257
+
258
+ Starting a drive arms one recurring reminder per PR. Every 30 minutes the host
259
+ checks mergeability:
260
+
261
+ - closed or merged stops the reminder,
262
+ - clean skips delivery,
263
+ - conflicting sends a follow-up to the owning session, and
264
+ - a busy session skips the wake.
265
+
266
+ This uses runtime reminders, not a static `agent/schedules/` file. The host
267
+ creates, lists, replaces, and cancels reminders through `host.reminders`.
268
+ Development mode doesn't fire reminder timers automatically. Dispatch one
269
+ through the dev reminder endpoint for a manual proof, or use non-dev `serve`
270
+ to run the 30-minute cadence.
271
+
272
+ The reminder's `run` handler lives in memory. After a host restart, the Agent SDK
273
+ disarms it with `handler_lost_on_restart`; a later drive or webhook path can
274
+ arm a fresh handler. Persisted reminder metadata alone doesn't keep the check
275
+ running.
276
+
277
+ ## Record findings with MCP or a fallback
278
+
279
+ After enrollment, the remote agent receives workflow tools for:
280
+
281
+ - recording and updating outputs,
282
+ - listing current outputs,
283
+ - reading PR metadata,
284
+ - reading CI state, and
285
+ - reading review comments.
286
+
287
+ The main output is a structured workflow suggestion or code-change reference.
288
+ The remote prompt requires findings as soon as each action becomes clear.
289
+
290
+ If enrollment races or MCP is unavailable, the agent writes one fenced
291
+ fallback JSON block. The host validates allowed kinds, actions, statuses, and
292
+ the 140-character finding body before forwarding it to the same findings
293
+ service. The output hook catches fallback blocks from webhook and reminder
294
+ turns.
295
+
296
+ ## Verify the host logic
297
+
298
+ The coordinator has no filesystem evals. Its unit tests cover mode parsing, drive
299
+ orchestration, affinity, webhook durability, CI settlement, output parsing,
300
+ reminders, and Slack configuration:
301
+
302
+ ```bash
303
+ pnpm exec vitest run examples/fsd/agent/lib
304
+ ```
305
+
306
+ Use those tests for host policy. Use a dedicated test PR and suggest mode for
307
+ the end-to-end remote path.
308
+
309
+ ## Build another hybrid coordinator
310
+
311
+ Use this architecture when each work item needs a real checkout:
312
+
313
+ 1. Keep conversational intake local.
314
+ 2. Open a remote session only after the request identifies a work item.
315
+ 3. Give the work item a stable continuation key.
316
+ 4. Persist its remote-agent id for cross-channel resume.
317
+ 5. Coalesce noisy events before spending another turn.
318
+ 6. Put the current mode and permissions in every host prompt.
319
+ 7. Record outputs incrementally in a durable sink.
320
+ 8. Add reminders for state requiring periodic rechecks.
321
+
322
+ ## Where to go next
323
+
324
+ - [Cloud runtime](/docs/guides/cloud-runtime.md)
325
+ - [GitHub](/docs/guides/github.md)
326
+ - [Webhooks and custom channels](/docs/guides/webhooks.md)
327
+ - [Schedules and reminders](/docs/reference/schedules.md)
328
+ - [Sessions and streaming](/docs/reference/sessions.md)
329
+ - [Deployment](/docs/deployment.md)