@cursor/july 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +24 -2
- package/README.md +25 -15
- package/dist/bin/agent-serve.js +101 -12
- package/dist/channels/github/api.d.ts.map +1 -1
- package/dist/channels/github/api.js +31 -14
- package/dist/channels/github/cursor-account.d.ts +43 -0
- package/dist/channels/github/cursor-account.d.ts.map +1 -0
- package/dist/channels/github/cursor-account.js +95 -0
- package/dist/channels/github/github-channel.d.ts.map +1 -1
- package/dist/channels/github/github-channel.js +46 -9
- package/dist/channels/github/index.d.ts +2 -2
- package/dist/channels/github/index.js +2 -2
- package/dist/channels/github/types.d.ts +17 -0
- package/dist/channels/github/types.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.d.ts +8 -2
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +8 -0
- package/dist/channels/slack/types.d.ts +24 -3
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/channels/slack/types.js +15 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +8 -8
- package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
- package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
- package/dist/docs/assets/{app.DqfFEmJd.js → app.Oje4vhlk.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.H5XZ2zCB.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.CTR_TuaE.js} +2 -2
- package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
- package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
- package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
- package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
- package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
- package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
- package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
- package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
- package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
- package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
- package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
- package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
- package/dist/docs/assets/quickstart.md.CfU8_uTC.js +192 -0
- package/dist/docs/assets/quickstart.md.CfU8_uTC.lean.js +1 -0
- package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
- package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
- package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
- package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
- package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
- package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
- package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
- package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
- package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
- package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
- package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
- package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
- package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
- package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
- package/dist/docs/assets/storage.md.CVnInNiN.lean.js +1 -0
- package/dist/docs/building-with-agents.html +4 -4
- package/dist/docs/concepts.html +4 -4
- package/dist/docs/deployment.html +7 -7
- package/dist/docs/evals.html +7 -7
- package/dist/docs/guides/agent-to-agent.html +6 -6
- package/dist/docs/guides/cloud-runtime.html +5 -5
- package/dist/docs/guides/github.html +14 -7
- package/dist/docs/guides/human-in-the-loop.html +6 -6
- package/dist/docs/guides/slack.html +8 -8
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +5 -5
- package/dist/docs/index.html +7 -7
- package/dist/docs/quickstart.html +180 -23
- package/dist/docs/reference/agent-config.html +7 -7
- package/dist/docs/reference/channels.html +8 -8
- package/dist/docs/reference/cli.html +4 -4
- package/dist/docs/reference/connections.html +5 -5
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/instructions.html +13 -11
- package/dist/docs/reference/playground.html +4 -4
- package/dist/docs/reference/project-layout.html +4 -4
- package/dist/docs/reference/schedules.html +7 -7
- package/dist/docs/reference/sessions.html +4 -4
- package/dist/docs/reference/skills.html +6 -6
- package/dist/docs/reference/subagents.html +6 -6
- package/dist/docs/reference/tools.html +7 -7
- package/dist/docs/scaffolding-agents.html +5 -5
- package/dist/docs/storage.html +41 -0
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/index.d.ts +2 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/internal/cli-deploy.d.ts +52 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -0
- package/dist/internal/cli-deploy.js +731 -0
- package/dist/internal/cursor/backend-client.d.ts +10 -1
- package/dist/internal/cursor/backend-client.d.ts.map +1 -1
- package/dist/internal/cursor/backend-client.js +79 -1
- package/dist/internal/cursor/github-credentials.d.ts +44 -0
- package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
- package/dist/internal/cursor/github-credentials.js +195 -0
- package/dist/internal/deploy-client.d.ts +176 -0
- package/dist/internal/deploy-client.d.ts.map +1 -0
- package/dist/internal/deploy-client.js +375 -0
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +73 -5
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +1 -0
- package/dist/internal/eval-run-store.d.ts +22 -3
- package/dist/internal/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +37 -19
- package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
- package/dist/internal/handleAgentServeTrigger.js +10 -12
- package/dist/internal/host-platforms.d.ts +7 -2
- package/dist/internal/host-platforms.d.ts.map +1 -1
- package/dist/internal/host-platforms.js +15 -10
- package/dist/internal/hosting.d.ts +37 -0
- package/dist/internal/hosting.d.ts.map +1 -0
- package/dist/internal/hosting.js +67 -0
- package/dist/internal/reminder-runner.d.ts +7 -0
- package/dist/internal/reminder-runner.d.ts.map +1 -1
- package/dist/internal/reminder-runner.js +50 -6
- package/dist/internal/reminder-store.d.ts +2 -0
- package/dist/internal/reminder-store.d.ts.map +1 -1
- package/dist/internal/reminder-store.js +18 -0
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +173 -42
- package/dist/internal/session-engine.d.ts +49 -0
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +246 -17
- package/dist/internal/storage-coordinator.d.ts +139 -0
- package/dist/internal/storage-coordinator.d.ts.map +1 -0
- package/dist/internal/storage-coordinator.js +499 -0
- package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
- package/dist/playground/assets/index-B1Qc9h2u.css +1 -0
- package/dist/playground/assets/{index-FlWjhg3x.js → index-CpDYCj8W.js} +42 -42
- package/dist/playground/index.html +2 -2
- package/dist/storage.d.ts +204 -0
- package/dist/storage.d.ts.map +1 -0
- package/dist/storage.js +153 -0
- package/dist/types.d.ts +44 -3
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +3 -2
- package/docs/guides/github.md +43 -8
- package/docs/guides/slack.md +1 -1
- package/docs/quickstart.md +329 -51
- package/docs/reference/instructions.md +8 -6
- package/docs/scaffolding-agents.md +1 -1
- package/docs/storage.md +98 -0
- package/package.json +8 -1
- package/skills/github/SKILL.md +9 -1
- package/src/bin/agent-serve.ts +139 -0
- package/src/channels/github/api.ts +42 -23
- package/src/channels/github/cursor-account.ts +165 -0
- package/src/channels/github/github-channel.ts +66 -6
- package/src/channels/github/index.ts +2 -2
- package/src/channels/github/types.ts +19 -0
- package/src/channels/slack/slack-channel.ts +17 -3
- package/src/channels/slack/types.ts +44 -3
- package/src/index.ts +13 -0
- package/src/internal/cli-deploy.ts +940 -0
- package/src/internal/cursor/backend-client.ts +103 -1
- package/src/internal/cursor/github-credentials.ts +248 -0
- package/src/internal/deploy-client.ts +591 -0
- package/src/internal/discovery.ts +88 -1
- package/src/internal/distribution.ts +1 -0
- package/src/internal/eval-run-store.ts +48 -19
- package/src/internal/handleAgentServeTrigger.ts +10 -12
- package/src/internal/host-platforms.ts +28 -11
- package/src/internal/hosting.ts +77 -0
- package/src/internal/reminder-runner.ts +50 -6
- package/src/internal/reminder-store.ts +21 -0
- package/src/internal/server.ts +213 -27
- package/src/internal/session-engine.ts +285 -7
- package/src/internal/storage-coordinator.ts +615 -0
- package/src/storage.ts +325 -0
- package/src/types.ts +40 -2
- package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
- package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
- package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
- package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
- package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
- package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
- package/dist/playground/assets/index-1K-hG-7p.css +0 -1
- /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
- /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
- /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
- /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
- /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
- /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
- /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
- /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js}
RENAMED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import{_ as e,c as
|
|
1
|
+
import{_ as e,c as i,o as a,ag as t}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies.","frontmatter":{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies."},"headers":[],"relativePath":"reference/channels.md","filePath":"reference/channels.md"}'),n={name:"reference/channels.md"};function h(l,s,o,d,r,p){return a(),i("div",null,[...s[0]||(s[0]=[t(`<h1 id="channels" tabindex="-1">Channels <a class="header-anchor" href="#channels" aria-label="Permalink to "Channels""></a></h1><p>A channel is the surface an agent lives on. The built-in HTTP session channel is always mounted. Custom channels declare their own routes under <code>/v1/channels/<id></code>. The Slack and GitHub packs are prebuilt channels with platform transports. This page is the authoring reference; for the walkthrough, see the <a href="./../guides/webhooks.html">Webhooks guide</a>.</p><h2 id="the-built-in-http-channel" tabindex="-1">The built-in HTTP channel <a class="header-anchor" href="#the-built-in-http-channel" aria-label="Permalink to "The built-in HTTP channel""></a></h2><p>It's always mounted, under <code>/<slug></code> in the default multi-agent layout: session create, follow-up, stream, stop, the sessions list, approvals, deterministic tool calls, health, and info. For the route-by-route contract, see the <a href="./http-api.html">HTTP API reference</a>.</p><p>Author <code>agent/channels/http.ts</code> only to override its defaults:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> {</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> bearerAuth,</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> httpChannel,</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> localDevStrict,</span></span>
|
|
5
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">} </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
6
6
|
<span class="line"></span>
|
|
7
7
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> httpChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
8
8
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> auth: [</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">localDevStrict</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(), </span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">bearerAuth</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(process.env.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">AGENT_TOKEN</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ??</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> ""</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">)],</span></span>
|
|
9
9
|
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> onMessage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">message</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, { </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">auth</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span></span>
|
|
10
10
|
<span class="line"><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> \`[caller \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">auth</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">?.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">principalId</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> ??</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "anonymous"}] \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">message</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
11
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="define-a-custom-channel" tabindex="-1">Define a custom channel <a class="header-anchor" href="#define-a-custom-channel" aria-label="Permalink to "Define a custom channel""></a></h2><p>Author <code>agent/channels/<id>.ts</code>. The filename is the channel id and the route prefix:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineChannel, POST } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
11
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="define-a-custom-channel" tabindex="-1">Define a custom channel <a class="header-anchor" href="#define-a-custom-channel" aria-label="Permalink to "Define a custom channel""></a></h2><p>Author <code>agent/channels/<id>.ts</code>. The filename is the channel id and the route prefix:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineChannel, POST } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/channels"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
12
12
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { z } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "zod"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
13
13
|
<span class="line"></span>
|
|
14
14
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineChannel</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -50,4 +50,4 @@ import{_ as e,c as a,o as i,ag as t}from"./chunks/framework.CAZyNGu9.js";const c
|
|
|
50
50
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
51
51
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
52
52
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // auth: [...], state: {...}, onStart(...), onStop(...)</span></span>
|
|
53
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This example assumes <code>agent/tools/inspect_pr.ts</code> exists. The handler calls it before the model turn, so every review starts with validated PR data. It also derives a stable conversation key from the PR URL and writes the tool result to <code>pr.json</code>. Instructions can ask the model to inspect a PR, but host code guarantees it.</p><h2 id="route-verbs-and-schemas" tabindex="-1">Route verbs and schemas <a class="header-anchor" href="#route-verbs-and-schemas" aria-label="Permalink to "Route verbs and schemas""></a></h2><p><code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, and <code>DELETE</code> helpers build routes. Their schemas are Zod, enforced at compile time:</p><table tabindex="0"><thead><tr><th>Verb</th><th>Required schema</th></tr></thead><tbody><tr><td><code>GET</code></td><td><code>querySchema</code></td></tr><tr><td><code>POST</code> / <code>PUT</code> / <code>PATCH</code></td><td><code>bodySchema</code> (optional <code>querySchema</code>)</td></tr><tr><td><code>DELETE</code></td><td>both optional</td></tr></tbody></table><p>Plain JSON Schema objects won't type-check; use <code>z.object({})</code> or <code>z.unknown()</code> for intentionally open surfaces. The host validates before the handler runs. Handlers receive typed <code>args.body</code> and <code>args.query</code>, and empty POST bodies are coerced to <code>{}</code> first. Declared schemas are projected on <code>GET /v1/info</code>, which powers the playground's <strong>Try</strong> buttons and composer <strong>slash commands</strong>.</p><h2 id="handler-arguments" tabindex="-1">Handler arguments <a class="header-anchor" href="#handler-arguments" aria-label="Permalink to "Handler arguments""></a></h2><p>Handlers receive the Fetch <code>Request</code> and an args object:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>send(message, options?)</code></td><td>Run a model turn on this channel; returns the session handle. Options: <code>continuationToken</code> (the conversation key), <code>workspaceFiles</code>, <code>workspaceDir</code>, <code>cloud</code> (attach cloud repos for this session), <code>auth</code> (defaults to the request principal), <code>sdkAgentId</code> (resume a specific SDK agent).</td></tr><tr><td><code>getSession(sessionId)</code></td><td>Look up an existing session on this channel</td></tr><tr><td><code>receive(channelDefinition, input)</code></td><td>Hand off to another channel (schedules use this)</td></tr><tr><td><code>callTool(name, input, options?)</code></td><td>Deterministic server-tool call (<a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>)</td></tr><tr><td><code>body</code>, <code>query</code>, <code>params</code></td><td>Validated payloads and <code>:param</code> path segments</td></tr><tr><td><code>auth</code></td><td>The <code>AuthContext</code> resolved by this route's auth chain</td></tr><tr><td><code>requestIp</code></td><td>The TCP peer address</td></tr><tr><td><code>host</code></td><td>Shared services: <code>host.mcp</code>, <code>host.github</code>, <code>host.slack</code>, <code>host.reminders</code></td></tr><tr><td><code>waitUntil(promise)</code></td><td>Background work that outlives the response</td></tr><tr><td><code>sessionUrls(request, sessionId)</code></td><td>Absolute playground + trace URLs for a session on this mount</td></tr></tbody></table><h2 id="events" tabindex="-1">Events <a class="header-anchor" href="#events" aria-label="Permalink to "Events""></a></h2><p>The <code>events</code> map subscribes the channel to stream events for the sessions it owns. Keys are event types from the <a href="./sessions.html#the-event-vocabulary">event vocabulary</a>, or <code>"*"</code>. Handlers receive <code>(event, channel, ctx)</code>, where <code>channel.state</code> is the per-session adapter state and <code>ctx</code> exposes session info and host services. This is where a channel delivers replies back to its surface.</p><h2 id="state-and-lifecycle" tabindex="-1">State and lifecycle <a class="header-anchor" href="#state-and-lifecycle" aria-label="Permalink to "State and lifecycle""></a></h2><p><code>state</code> declares the starting per-session adapter state (JSON), persisted on the session record. Routes and event handlers read and mutate it through <code>channel.state</code>. <code>onStart(args)</code> runs when the channel mounts. It receives <code>send</code>, <code>receive</code>, <code>callTool</code>, <code>host</code>, and friends; the Slack pack opens its Socket Mode connection here. <code>onStop()</code> runs when the server drains.</p><h2 id="auth-policies" tabindex="-1">Auth policies <a class="header-anchor" href="#auth-policies" aria-label="Permalink to "Auth policies""></a></h2><p>Every route runs an auth-policy chain: the channel's <code>auth</code> array, or <code>[localDevStrict()]</code> when unset. A policy is a function <code>(request, info) => AuthContext | null</code> (async allowed); the first non-null wins, and a request no policy admits gets <code>401</code>.</p><table tabindex="0"><thead><tr><th>Policy</th><th>Admits</th></tr></thead><tbody><tr><td><code>localDevStrict()</code></td><td>Direct loopback callers with no proxy-forwarding headers (<code>X-Forwarded-For</code>, <code>X-Real-IP</code>, <code>Forwarded</code>, and <code>X-Forwarded-Host</code> are all rejected, so tunnels and same-host reverse proxies don't silently re-expose the route), plus a loopback <code>Host</code> header, which rejects DNS-rebinding callers that reach 127.0.0.1 with a remote hostname.</td></tr><tr><td><code>localDev()</code></td><td>Like <code>localDevStrict()</code> but without the <code>Host</code> check. An explicit, weaker opt-in.</td></tr><tr><td><code>loopbackOnly()</code></td><td>A loopback TCP peer, ignoring forwarding headers; for dev relays that legitimately carry them, like <code>gh webhook forward</code>.</td></tr><tr><td><code>bearerAuth(token)</code></td><td><code>Authorization: Bearer <token></code>, compared in constant time. Also accepts a verifier function mapping a presented token to an <code>AuthContext</code>.</td></tr><tr><td><code>allowAll()</code></td><td>Everyone, as an <code>anonymous</code> principal. Only for surfaces protected upstream (an HMAC-verified webhook) or intentionally public.</td></tr></tbody></table><p>The resolved <code>AuthContext</code> (<code>{ authenticator, principalId, principalType, attributes? }</code>) becomes the request principal. Sessions bind to the principal that created them, and follow-up, stream, and list routes enforce ownership (<code>403</code> otherwise).</p><p>Server flags interact with authored auth: <code>--bearer-token</code> swaps the default <code>localDevStrict()</code> for <code>bearerAuth(...)</code> on channels that don't author their own chain, and <code>--allow-anonymous</code> swaps it for <code>allowAll()</code>. Authored <code>auth</code> arrays always win over both. A channel that declares <code>[localDevStrict()]</code> stays loopback-only even on an <code>--allow-anonymous</code> host.</p><h2 id="first-class-channels" tabindex="-1">First class channels <a class="header-anchor" href="#first-class-channels" aria-label="Permalink to "First class channels""></a></h2><p><strong>Slack</strong> (<code>@
|
|
53
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This example assumes <code>agent/tools/inspect_pr.ts</code> exists. The handler calls it before the model turn, so every review starts with validated PR data. It also derives a stable conversation key from the PR URL and writes the tool result to <code>pr.json</code>. Instructions can ask the model to inspect a PR, but host code guarantees it.</p><h2 id="route-verbs-and-schemas" tabindex="-1">Route verbs and schemas <a class="header-anchor" href="#route-verbs-and-schemas" aria-label="Permalink to "Route verbs and schemas""></a></h2><p><code>GET</code>, <code>POST</code>, <code>PUT</code>, <code>PATCH</code>, and <code>DELETE</code> helpers build routes. Their schemas are Zod, enforced at compile time:</p><table tabindex="0"><thead><tr><th>Verb</th><th>Required schema</th></tr></thead><tbody><tr><td><code>GET</code></td><td><code>querySchema</code></td></tr><tr><td><code>POST</code> / <code>PUT</code> / <code>PATCH</code></td><td><code>bodySchema</code> (optional <code>querySchema</code>)</td></tr><tr><td><code>DELETE</code></td><td>both optional</td></tr></tbody></table><p>Plain JSON Schema objects won't type-check; use <code>z.object({})</code> or <code>z.unknown()</code> for intentionally open surfaces. The host validates before the handler runs. Handlers receive typed <code>args.body</code> and <code>args.query</code>, and empty POST bodies are coerced to <code>{}</code> first. Declared schemas are projected on <code>GET /v1/info</code>, which powers the playground's <strong>Try</strong> buttons and composer <strong>slash commands</strong>.</p><h2 id="handler-arguments" tabindex="-1">Handler arguments <a class="header-anchor" href="#handler-arguments" aria-label="Permalink to "Handler arguments""></a></h2><p>Handlers receive the Fetch <code>Request</code> and an args object:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>send(message, options?)</code></td><td>Run a model turn on this channel; returns the session handle. Options: <code>continuationToken</code> (the conversation key), <code>workspaceFiles</code>, <code>workspaceDir</code>, <code>cloud</code> (attach cloud repos for this session), <code>auth</code> (defaults to the request principal), <code>sdkAgentId</code> (resume a specific SDK agent).</td></tr><tr><td><code>getSession(sessionId)</code></td><td>Look up an existing session on this channel</td></tr><tr><td><code>receive(channelDefinition, input)</code></td><td>Hand off to another channel (schedules use this)</td></tr><tr><td><code>callTool(name, input, options?)</code></td><td>Deterministic server-tool call (<a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>)</td></tr><tr><td><code>body</code>, <code>query</code>, <code>params</code></td><td>Validated payloads and <code>:param</code> path segments</td></tr><tr><td><code>auth</code></td><td>The <code>AuthContext</code> resolved by this route's auth chain</td></tr><tr><td><code>requestIp</code></td><td>The TCP peer address</td></tr><tr><td><code>host</code></td><td>Shared services: <code>host.mcp</code>, <code>host.github</code>, <code>host.slack</code>, <code>host.reminders</code></td></tr><tr><td><code>waitUntil(promise)</code></td><td>Background work that outlives the response</td></tr><tr><td><code>sessionUrls(request, sessionId)</code></td><td>Absolute playground + trace URLs for a session on this mount</td></tr></tbody></table><h2 id="events" tabindex="-1">Events <a class="header-anchor" href="#events" aria-label="Permalink to "Events""></a></h2><p>The <code>events</code> map subscribes the channel to stream events for the sessions it owns. Keys are event types from the <a href="./sessions.html#the-event-vocabulary">event vocabulary</a>, or <code>"*"</code>. Handlers receive <code>(event, channel, ctx)</code>, where <code>channel.state</code> is the per-session adapter state and <code>ctx</code> exposes session info and host services. This is where a channel delivers replies back to its surface.</p><h2 id="state-and-lifecycle" tabindex="-1">State and lifecycle <a class="header-anchor" href="#state-and-lifecycle" aria-label="Permalink to "State and lifecycle""></a></h2><p><code>state</code> declares the starting per-session adapter state (JSON), persisted on the session record. Routes and event handlers read and mutate it through <code>channel.state</code>. <code>onStart(args)</code> runs when the channel mounts. It receives <code>send</code>, <code>receive</code>, <code>callTool</code>, <code>host</code>, and friends; the Slack pack opens its Socket Mode connection here. <code>onStop()</code> runs when the server drains.</p><h2 id="auth-policies" tabindex="-1">Auth policies <a class="header-anchor" href="#auth-policies" aria-label="Permalink to "Auth policies""></a></h2><p>Every route runs an auth-policy chain: the channel's <code>auth</code> array, or <code>[localDevStrict()]</code> when unset. A policy is a function <code>(request, info) => AuthContext | null</code> (async allowed); the first non-null wins, and a request no policy admits gets <code>401</code>.</p><table tabindex="0"><thead><tr><th>Policy</th><th>Admits</th></tr></thead><tbody><tr><td><code>localDevStrict()</code></td><td>Direct loopback callers with no proxy-forwarding headers (<code>X-Forwarded-For</code>, <code>X-Real-IP</code>, <code>Forwarded</code>, and <code>X-Forwarded-Host</code> are all rejected, so tunnels and same-host reverse proxies don't silently re-expose the route), plus a loopback <code>Host</code> header, which rejects DNS-rebinding callers that reach 127.0.0.1 with a remote hostname.</td></tr><tr><td><code>localDev()</code></td><td>Like <code>localDevStrict()</code> but without the <code>Host</code> check. An explicit, weaker opt-in.</td></tr><tr><td><code>loopbackOnly()</code></td><td>A loopback TCP peer, ignoring forwarding headers; for dev relays that legitimately carry them, like <code>gh webhook forward</code>.</td></tr><tr><td><code>bearerAuth(token)</code></td><td><code>Authorization: Bearer <token></code>, compared in constant time. Also accepts a verifier function mapping a presented token to an <code>AuthContext</code>.</td></tr><tr><td><code>allowAll()</code></td><td>Everyone, as an <code>anonymous</code> principal. Only for surfaces protected upstream (an HMAC-verified webhook) or intentionally public.</td></tr></tbody></table><p>The resolved <code>AuthContext</code> (<code>{ authenticator, principalId, principalType, attributes? }</code>) becomes the request principal. Sessions bind to the principal that created them, and follow-up, stream, and list routes enforce ownership (<code>403</code> otherwise).</p><p>Server flags interact with authored auth: <code>--bearer-token</code> swaps the default <code>localDevStrict()</code> for <code>bearerAuth(...)</code> on channels that don't author their own chain, and <code>--allow-anonymous</code> swaps it for <code>allowAll()</code>. Authored <code>auth</code> arrays always win over both. A channel that declares <code>[localDevStrict()]</code> stays loopback-only even on an <code>--allow-anonymous</code> host.</p><h2 id="first-class-channels" tabindex="-1">First class channels <a class="header-anchor" href="#first-class-channels" aria-label="Permalink to "First class channels""></a></h2><p><strong>Slack</strong> (<code>@cursor/july/channels/slack</code>): Socket Mode transport, streaming replies, engagement rules, approval cards. Author <code>agent/channels/slack.ts</code> with <code>slackChannel()</code>. Guide: <a href="./../guides/slack.html">Slack</a>.</p><p><strong>GitHub</strong> (<code>@cursor/july/channels/github</code>): webhook dispatch with signature verification, per-event hooks returning <code>{ auth }</code> (a model turn), <code>{ task }</code> (host work), or <code>null</code>, and CLI tooling for replay and live forwarding. Author <code>agent/channels/github.ts</code> with <code>githubChannel()</code>. Guide: <a href="./../guides/github.html">GitHub</a>.</p><p>For other platforms like Discord or Teams, use the authored <code>defineChannel</code> webhook form.</p><h2 id="continuation-semantics" tabindex="-1">Continuation semantics <a class="header-anchor" href="#continuation-semantics" aria-label="Permalink to "Continuation semantics""></a></h2><p>Channels own their continuation-token format. The built-in HTTP channel mints opaque rotating tokens, Slack uses <code>channelId:threadTs</code>, and PR automations use keys like <code>pr:owner/repo#N</code>. Same token, same durable session; one active continuation per session; the HTTP channel returns <code>409</code> for stale tokens. For the full session model, see <a href="./sessions.html">Sessions</a>.</p><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><p>Continue with these pages:</p><ul><li><a href="./../guides/webhooks.html">Webhooks guide</a>: the same API, walked through</li><li><a href="./http-api.html">HTTP API</a>: the built-in routes precisely</li><li><a href="./sessions.html">Sessions and streaming</a>: the events channels subscribe to</li></ul>`,35)])])}const E=e(n,[["render",h]]);export{c as __pageData,E as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as
|
|
1
|
+
import{_ as e,c as i,o as a,ag as t}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies.","frontmatter":{"title":"Channels","description":"The authoring reference for defineChannel, the built-in HTTP channel, route schemas, handler args, and the auth policies."},"headers":[],"relativePath":"reference/channels.md","filePath":"reference/channels.md"}'),n={name:"reference/channels.md"};function h(l,s,o,d,r,p){return a(),i("div",null,[...s[0]||(s[0]=[t("",35)])])}const E=e(n,[["render",h]]);export{c as __pageData,E as default};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as i,c as e,o as a,ag as n}from"./chunks/framework.CAZyNGu9.js";const d=JSON.parse(`{"title":"MCP Connections","description":"Pull in tools from MCP servers: remote, stdio, the signed-in Cursor account's connectors, and peer agents.","frontmatter":{"title":"MCP Connections","description":"Pull in tools from MCP servers: remote, stdio, the signed-in Cursor account's connectors, and peer agents."},"headers":[],"relativePath":"reference/connections.md","filePath":"reference/connections.md"}`),t={name:"reference/connections.md"};function h(l,s,o,p,r,c){return a(),e("div",null,[...s[0]||(s[0]=[n(`<h1 id="mcp-connections" tabindex="-1">MCP Connections <a class="header-anchor" href="#mcp-connections" aria-label="Permalink to "MCP Connections""></a></h1><p>An MCP connection gives the agent tools from an MCP server. One file per server under <code>agent/mcp-connections/</code>, and the filename becomes the server name the model sees. An MCP connection default-exports <code>defineConnection</code> from <code>@
|
|
1
|
+
import{_ as i,c as e,o as a,ag as n}from"./chunks/framework.CAZyNGu9.js";const d=JSON.parse(`{"title":"MCP Connections","description":"Pull in tools from MCP servers: remote, stdio, the signed-in Cursor account's connectors, and peer agents.","frontmatter":{"title":"MCP Connections","description":"Pull in tools from MCP servers: remote, stdio, the signed-in Cursor account's connectors, and peer agents."},"headers":[],"relativePath":"reference/connections.md","filePath":"reference/connections.md"}`),t={name:"reference/connections.md"};function h(l,s,o,p,r,c){return a(),e("div",null,[...s[0]||(s[0]=[n(`<h1 id="mcp-connections" tabindex="-1">MCP Connections <a class="header-anchor" href="#mcp-connections" aria-label="Permalink to "MCP Connections""></a></h1><p>An MCP connection gives the agent tools from an MCP server. One file per server under <code>agent/mcp-connections/</code>, and the filename becomes the server name the model sees. An MCP connection default-exports <code>defineConnection</code> from <code>@cursor/july/connections</code>, and the transport comes in four shapes: remote HTTP, local stdio, the signed-in Cursor account's connectors, and peer agents on the same host.</p><h2 id="remote-mcp-server" tabindex="-1">Remote MCP server <a class="header-anchor" href="#remote-mcp-server" aria-label="Permalink to "Remote MCP server""></a></h2><p>Point an MCP connection at a remote server with a URL.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineConnection } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/connections"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
2
2
|
<span class="line"></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineConnection</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> url: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"https://mcp.linear.app/mcp"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as s,c as t,o as a,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),n={name:"reference/hooks.md"};function o(r,e,h,
|
|
1
|
+
import{_ as s,c as t,o as a,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),n={name:"reference/hooks.md"};function o(r,e,d,h,l,c){return a(),t("div",null,[...e[0]||(e[0]=[i(`<h1 id="hooks" tabindex="-1">Hooks <a class="header-anchor" href="#hooks" aria-label="Permalink to "Hooks""></a></h1><p>A hook is an observe-only subscriber to the session event stream. Hooks run after each event is recorded and fanned out (file persistence flushes in the background). That makes them the home for audit logging, metrics, mirroring transcripts into your own store, and maintaining derived state. Handler errors are logged and never fatal. A hook can't modify events or block a turn.</p><p>Author <code>agent/hooks/<name>.ts</code> with <code>defineHook</code> from <code>@cursor/july/hooks</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineHook } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/hooks"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
2
2
|
<span class="line"></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineHook</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> events: {</span></span>
|
package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js}
RENAMED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as s,c as t,o as a,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),n={name:"reference/hooks.md"};function o(r,e,h,
|
|
1
|
+
import{_ as s,c as t,o as a,ag as i}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state.","frontmatter":{"title":"Hooks","description":"Observe-only subscribers to the session event stream: audit logs, metrics, transcript mirrors, derived state."},"headers":[],"relativePath":"reference/hooks.md","filePath":"reference/hooks.md"}'),n={name:"reference/hooks.md"};function o(r,e,d,h,l,c){return a(),t("div",null,[...e[0]||(e[0]=[i("",16)])])}const u=s(n,[["render",o]]);export{k as __pageData,u as default};
|
package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js}
RENAMED
|
@@ -8,4 +8,4 @@ import{_ as t,c as s,o as a,ag as o}from"./chunks/framework.CAZyNGu9.js";const u
|
|
|
8
8
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -H</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> 'content-type: application/json'</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> \\</span></span>
|
|
9
9
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;"> -d</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> '{"input":{"prUrl":"https://github.com/acme/checkout/pull/42"}}'</span></span>
|
|
10
10
|
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># {"ok":true,"toolName":"inspect_pr","callId":"tool_inspect_pr_…",</span></span>
|
|
11
|
-
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># "isError":false,"result":{…},"durationMs":12}</span></span></code></pre></div><p>It runs an authored server tool in-process: schema-validated, no model turn. An optional <code>"sessionId"</code> in the body runs it inside an existing session and records it on that session's stream (<code>409 session_busy</code> while a turn runs). Agent-execution tools are rejected with <code>400</code>, and unknown tools with <code>404</code> and the list of available names. For the semantics, see <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>.</p><h2 id="discovery-and-meta" tabindex="-1">Discovery and meta <a class="header-anchor" href="#discovery-and-meta" aria-label="Permalink to "Discovery and meta""></a></h2><p>Five read-only routes describe the running agent.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/info</code></td><td>The manifest snapshot: model, tools, skills, MCP connections, subagents, channels and routes (with schemas), schedules, hooks, A/B experiments, diagnostics; the same shape as <code>agentkit info --json</code></td></tr><tr><td><code>GET /v1/health</code></td><td>Per-agent liveness, no auth</td></tr><tr><td><code>GET /v1/meta</code></td><td>SPA bootstrap: agent name, dev flag, base path (no auth)</td></tr><tr><td><code>GET /v1/logs?after=N</code></td><td>Recent server log lines from the ring buffer, with a polling cursor</td></tr><tr><td><code>GET /v1/abs</code></td><td><a href="./../ab.html">Live A/B metrics</a>: per-session assignments and aggregate arm totals folded from durable event streams (<code>config</code> reports <code>maxPlaygroundSessions</code> / <code>durableSamples</code> / <code>durableSnapshots</code> from <code>agent/ab.config.ts</code>)</td></tr></tbody></table><h2 id="custom-channel-routes" tabindex="-1">Custom channel routes <a class="header-anchor" href="#custom-channel-routes" aria-label="Permalink to "Custom channel routes""></a></h2><p>Authored routes mount under <code>/v1/channels/<id></code> with the methods, paths, and Zod schemas the channel declared (a <code>POST /<slug>/v1/channels/drive</code> route, say). Bodies are validated before handlers run (<code>400</code> on schema violations), and each channel's auth chain applies. The GitHub channel verifies <code>X-Hub-Signature-256</code> when a secret is configured. See <a href="./channels.html">Channels</a>.</p><h2 id="mcp-endpoint" tabindex="-1">MCP endpoint <a class="header-anchor" href="#mcp-endpoint" aria-label="Permalink to "MCP endpoint""></a></h2><p><code>/v1/mcp</code> serves the Model Context Protocol over streamable HTTP (stateless; POST carries the protocol, and GET/DELETE return spec-compliant 405s). The tools are <code>ask</code> (delegate a message, bounded waits), <code>check</code> (poll a running session), and <code>call_tool</code> (deterministic server-tool passthrough, present when the agent has server tools). The route runs the same auth chain as the session API. See <a href="./../guides/agent-to-agent.html">Agent-to-agent</a>.</p><h2 id="playground-eval-routes" tabindex="-1">Playground eval routes <a class="header-anchor" href="#playground-eval-routes" aria-label="Permalink to "Playground eval routes""></a></h2><p>Always registered (including
|
|
11
|
+
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"># "isError":false,"result":{…},"durationMs":12}</span></span></code></pre></div><p>It runs an authored server tool in-process: schema-validated, no model turn. An optional <code>"sessionId"</code> in the body runs it inside an existing session and records it on that session's stream (<code>409 session_busy</code> while a turn runs). Agent-execution tools are rejected with <code>400</code>, and unknown tools with <code>404</code> and the list of available names. For the semantics, see <a href="./tools.html#call-a-tool-without-a-model-turn">Tools</a>.</p><h2 id="discovery-and-meta" tabindex="-1">Discovery and meta <a class="header-anchor" href="#discovery-and-meta" aria-label="Permalink to "Discovery and meta""></a></h2><p>Five read-only routes describe the running agent.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/info</code></td><td>The manifest snapshot: model, tools, skills, MCP connections, subagents, channels and routes (with schemas), schedules, hooks, A/B experiments, diagnostics; the same shape as <code>agentkit info --json</code></td></tr><tr><td><code>GET /v1/health</code></td><td>Per-agent liveness, no auth</td></tr><tr><td><code>GET /v1/meta</code></td><td>SPA bootstrap: agent name, dev flag, base path (no auth)</td></tr><tr><td><code>GET /v1/logs?after=N</code></td><td>Recent server log lines from the ring buffer, with a polling cursor</td></tr><tr><td><code>GET /v1/abs</code></td><td><a href="./../ab.html">Live A/B metrics</a>: per-session assignments and aggregate arm totals folded from durable event streams (<code>config</code> reports <code>maxPlaygroundSessions</code> / <code>durableSamples</code> / <code>durableSnapshots</code> from <code>agent/ab.config.ts</code>)</td></tr></tbody></table><h2 id="custom-channel-routes" tabindex="-1">Custom channel routes <a class="header-anchor" href="#custom-channel-routes" aria-label="Permalink to "Custom channel routes""></a></h2><p>Authored routes mount under <code>/v1/channels/<id></code> with the methods, paths, and Zod schemas the channel declared (a <code>POST /<slug>/v1/channels/drive</code> route, say). Bodies are validated before handlers run (<code>400</code> on schema violations), and each channel's auth chain applies. The GitHub channel verifies <code>X-Hub-Signature-256</code> when a secret is configured. See <a href="./channels.html">Channels</a>.</p><h2 id="mcp-endpoint" tabindex="-1">MCP endpoint <a class="header-anchor" href="#mcp-endpoint" aria-label="Permalink to "MCP endpoint""></a></h2><p><code>/v1/mcp</code> serves the Model Context Protocol over streamable HTTP (stateless; POST carries the protocol, and GET/DELETE return spec-compliant 405s). The tools are <code>ask</code> (delegate a message, bounded waits), <code>check</code> (poll a running session), and <code>call_tool</code> (deterministic server-tool passthrough, present when the agent has server tools). The route runs the same auth chain as the session API. See <a href="./../guides/agent-to-agent.html">Agent-to-agent</a>.</p><h2 id="playground-eval-routes" tabindex="-1">Playground eval routes <a class="header-anchor" href="#playground-eval-routes" aria-label="Permalink to "Playground eval routes""></a></h2><p>Always registered (including production / non-<code>--dev</code> serves). The playground Evals tab uses these:</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>GET /v1/dev/evals</code></td><td>List discovered eval datapoints and project config as <code>{ evals, config }</code> (<code>config</code> includes <code>maxPlaygroundRuns</code>, <code>durableRuns</code>)</td></tr><tr><td><code>GET /v1/dev/evals/runs</code></td><td>List recent run snapshots (newest first) as <code>{ runs, activeRunId? }</code> for playground rehydrate</td></tr><tr><td><code>POST /v1/dev/evals/runs</code></td><td>Start an eval run (<code>{filterIds?, tags?}</code>); <code>202</code> with a snapshot, <code>404</code> when nothing matches, <code>409</code> when one is running</td></tr><tr><td><code>GET /v1/dev/evals/runs/:runId</code></td><td>Poll a run's progress</td></tr></tbody></table><p>Eval runs are asynchronous. Poll the run route for case progress and the final <code>completed</code> or <code>failed</code> status. Batch errors appear on the snapshot returned by the poll. Entries within <code>filterIds</code> and <code>tags</code> use OR semantics. When both fields are present, a case must match one entry from each field. Without <code>persistRuns</code> in <code>evals.config.ts</code>, listed runs are process-memory only (capped by <code>maxPlaygroundRuns</code>).</p><h2 id="dev-mode-routes" tabindex="-1">Dev-mode routes <a class="header-anchor" href="#dev-mode-routes" aria-label="Permalink to "Dev-mode routes""></a></h2><p>These routes exist only under <code>serve --dev</code>.</p><table tabindex="0"><thead><tr><th>Route</th><th>What it does</th></tr></thead><tbody><tr><td><code>POST /v1/dev/schedules/:scheduleId</code></td><td>Dispatch a schedule by hand, exactly once, through the production path. Returns <code>{scheduleId, sessionIds}</code></td></tr><tr><td><code>GET /v1/dev/reminders</code></td><td>List reminders</td></tr><tr><td><code>POST /v1/dev/reminders/:reminderId</code></td><td>Fire a reminder by hand</td></tr></tbody></table><p>Schedules and reminders never fire automatically in dev mode. These routes are the only way they run, which keeps iteration deterministic.</p><h2 id="playground-assets" tabindex="-1">Playground assets <a class="header-anchor" href="#playground-assets" aria-label="Permalink to "Playground assets""></a></h2><p><code>GET /playground</code> and <code>GET /playground/assets/:file</code> serve the static SPA bundle (omitted with <code>--no-playground</code>). The playground calls the JSON API above and has no privileged surface.</p><h2 id="status-codes" tabindex="-1">Status codes <a class="header-anchor" href="#status-codes" aria-label="Permalink to "Status codes""></a></h2><p>Error responses use a small, consistent set of status codes.</p><table tabindex="0"><thead><tr><th>Code</th><th>Meaning here</th></tr></thead><tbody><tr><td><code>400</code></td><td>Schema-invalid body or query, agent-execution tool called on the host, malformed request</td></tr><tr><td><code>401</code></td><td>No auth policy admitted the request</td></tr><tr><td><code>403</code></td><td>Authenticated, but not the session owner</td></tr><tr><td><code>404</code></td><td>Unknown session, tool, schedule, reminder, or eval run; no eval datapoints match a run request</td></tr><tr><td><code>405</code></td><td>Wrong method (GET on the MCP endpoint, say)</td></tr><tr><td><code>409</code></td><td>Stale continuation token, busy session (<code>session_busy</code>), a non-followable task session, or an eval run already in progress</td></tr><tr><td><code>202</code></td><td>Accepted for background work (GitHub <code>{ task }</code> hooks, eval runs)</td></tr></tbody></table><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><p>Continue with these pages:</p><ul><li><a href="./sessions.html">Sessions and streaming</a>: the handles and events these routes traffic in</li><li><a href="./channels.html">Channels</a>: authoring your own routes</li><li><a href="./../deployment.html">Deployment</a>: auth on real hosts</li></ul>`,53)])])}const k=t(n,[["render",i]]);export{u as __pageData,k as default};
|
|
@@ -1,12 +1,14 @@
|
|
|
1
|
-
import{_ as e,c as t,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,h,
|
|
2
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineInstructions } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
1
|
+
import{_ as e,c as t,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,l,h,p,c){return i(),t("div",null,[...s[0]||(s[0]=[a(`<h1 id="instructions" tabindex="-1">Instructions <a class="header-anchor" href="#instructions" aria-label="Permalink to "Instructions""></a></h1><p><code>agent/instructions.md</code> is the always-on system prompt. It's the one piece of prose the model sees on every turn. It's required on the root agent; subagents may inline <code>instructions</code> in their <code>agent.ts</code> instead.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to "Authoring forms""></a></h2><p>Three forms cover every case.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>agent/instructions.md</code></td><td>Plain Markdown for most agents.</td></tr><tr><td><code>agent/instructions.ts</code></td><td>Generated prompts. Default-export <code>defineInstructions({ markdown })</code> or a plain string.</td></tr><tr><td><code>agent/instructions/</code> directory</td><td>A long prompt split across files, composed in filename order.</td></tr></tbody></table><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/instructions.ts</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineInstructions } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
3
3
|
<span class="line"></span>
|
|
4
4
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineInstructions</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
5
5
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> markdown: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">\`You are the on-call assistant for \${</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">process</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">env</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">TEAM_NAME</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">}.\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
6
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="how-instructions-reach-the-model" tabindex="-1">How instructions reach the model <a class="header-anchor" href="#how-instructions-reach-the-model" aria-label="Permalink to "How instructions reach the model""></a></h2><p>On the local runtime, instructions land in the session workspace as <code>AGENTS.md</code>, and the harness loads them natively. On the cloud runtime, they're prepended to the first prompt, because the cloud VM doesn't share the local session workspace.</p><p>The local workspace is a real Cursor project directory, so the harness may also load ambient <code>AGENTS.md</code> and <code>.cursor</code> config from ancestor directories. <a href="./agent-config.html#local-cwd">Agent config → Local cwd</a> covers controlling that.</p><h2 id="best-practices" tabindex="-1">Best Practices <a class="header-anchor" href="#best-practices" aria-label="Permalink to "Best Practices""></a></h2><p>Keep them a few lines: identity, when to use which tool, output shape. The <a href="./../quickstart.html">quickstart
|
|
6
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="how-instructions-reach-the-model" tabindex="-1">How instructions reach the model <a class="header-anchor" href="#how-instructions-reach-the-model" aria-label="Permalink to "How instructions reach the model""></a></h2><p>On the local runtime, instructions land in the session workspace as <code>AGENTS.md</code>, and the harness loads them natively. On the cloud runtime, they're prepended to the first prompt, because the cloud VM doesn't share the local session workspace.</p><p>The local workspace is a real Cursor project directory, so the harness may also load ambient <code>AGENTS.md</code> and <code>.cursor</code> config from ancestor directories. <a href="./agent-config.html#local-cwd">Agent config → Local cwd</a> covers controlling that.</p><h2 id="best-practices" tabindex="-1">Best Practices <a class="header-anchor" href="#best-practices" aria-label="Permalink to "Best Practices""></a></h2><p>Keep them a few lines: identity, when to use which tool, output shape. The <a href="./../quickstart.html">quickstart PR approver</a> is the pattern:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;"># PR approver</span></span>
|
|
7
7
|
<span class="line"></span>
|
|
8
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">You
|
|
8
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">You review GitHub pull requests. Be specific and brief.</span></span>
|
|
9
9
|
<span class="line"></span>
|
|
10
|
-
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"
|
|
11
|
-
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"
|
|
12
|
-
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;"
|
|
10
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">1.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Call </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\`inspect_pr\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> first. Never judge a change you haven't fetched.</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">2.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Match your review to the complexity it reports.</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">3.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Never approve a draft.</span></span>
|
|
13
|
+
<span class="line"></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">End with one sentence: the verdict and why.</span></span></code></pre></div><ul><li>Name the tools and the decision rule ("use X before answering about Y"), not general encouragement.</li><li>State the output contract: length, format, fences. That contract is what your <a href="./../evals.html">evals</a> gate.</li><li>Move procedures to <a href="./skills.html">skills</a>. A multi-step workflow the model only sometimes needs belongs in <code>agent/skills/</code>, where it loads on demand and keeps the always-on prompt small.</li></ul><p>Instructions are the third lever in the <a href="./../hillclimbing.html">hillclimbing loop</a>, after host preparation and evidence shape. If a fixture keeps failing, look there before rewriting prose.</p><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><p>Continue with these pages:</p><ul><li><a href="./skills.html">Skills</a>: procedures the model loads only when relevant</li><li><a href="./agent-config.html">Agent config</a>: the file next to this one</li><li><a href="./../hillclimbing.html">Hillclimbing</a>: iterating on instructions with evidence</li></ul>`,17)])])}const u=e(n,[["render",o]]);export{k as __pageData,u as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as t,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,h,
|
|
1
|
+
import{_ as e,c as t,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const k=JSON.parse('{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up.","frontmatter":{"title":"Instructions","description":"The always-on system prompt: authoring forms, how it reaches the model on each runtime, and what makes instructions hold up."},"headers":[],"relativePath":"reference/instructions.md","filePath":"reference/instructions.md"}'),n={name:"reference/instructions.md"};function o(r,s,l,h,p,c){return i(),t("div",null,[...s[0]||(s[0]=[a("",17)])])}const u=e(n,[["render",o]]);export{k as __pageData,u as default};
|
package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js}
RENAMED
|
@@ -2,7 +2,7 @@ import{_ as i,c as a,o as n,ag as e}from"./chunks/framework.CAZyNGu9.js";const E
|
|
|
2
2
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">cron: "0 9 * * 1-5"</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
|
|
4
4
|
<span class="line"></span>
|
|
5
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Pull open incidents and post a summary to the metrics endpoint.</span></span></code></pre></div><p>Each firing starts a task-mode session: the body is the prompt, the session runs to <code>session.completed</code> or <code>session.failed</code>, and it isn't followable.</p><h3 id="schedules-as-handlers" tabindex="-1">Schedules as handlers <a class="header-anchor" href="#schedules-as-handlers" aria-label="Permalink to "Schedules as handlers""></a></h3><p><code>defineSchedule</code> with a <code>run</code> handler gives you full control, most usefully to hand the work into a channel so its delivery events fire:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineSchedule } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
5
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">Pull open incidents and post a summary to the metrics endpoint.</span></span></code></pre></div><p>Each firing starts a task-mode session: the body is the prompt, the session runs to <code>session.completed</code> or <code>session.failed</code>, and it isn't followable.</p><h3 id="schedules-as-handlers" tabindex="-1">Schedules as handlers <a class="header-anchor" href="#schedules-as-handlers" aria-label="Permalink to "Schedules as handlers""></a></h3><p><code>defineSchedule</code> with a <code>run</code> handler gives you full control, most usefully to hand the work into a channel so its delivery events fire:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineSchedule } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/schedules"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
6
6
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> webhook </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "../channels/webhook.js"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
7
7
|
<span class="line"></span>
|
|
8
8
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineSchedule</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -40,7 +40,7 @@ import{_ as i,c as a,o as n,ag as e}from"./chunks/framework.CAZyNGu9.js";const E
|
|
|
40
40
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> });</span></span>
|
|
41
41
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { action: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"delivered"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> };</span></span>
|
|
42
42
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
43
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This reminder wakes the conversation three times, then stops itself.</p><p>The same API is <code>host.reminders</code> on channel handlers, tools, and schedule runs. An agent can even be given a tool that creates its own reminders.</p><p>For example, create <code>agent/tools/remind_me.ts</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
43
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>This reminder wakes the conversation three times, then stops itself.</p><p>The same API is <code>host.reminders</code> on channel handlers, tools, and schedule runs. An agent can even be given a tool that creates its own reminders.</p><p>For example, create <code>agent/tools/remind_me.ts</code>:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/tools"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
44
44
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { z } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "zod"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
45
45
|
<span class="line"></span>
|
|
46
46
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js}
RENAMED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import{_ as e,c as i,o as t,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),
|
|
1
|
+
import{_ as e,c as i,o as t,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),l={name:"reference/skills.md"};function n(h,s,o,r,d,p){return t(),i("div",null,[...s[0]||(s[0]=[a(`<h1 id="skills" tabindex="-1">Skills <a class="header-anchor" href="#skills" aria-label="Permalink to "Skills""></a></h1><p>A skill is an on-demand procedure following the <code>SKILL.md</code> convention: the harness advertises each skill by its description, and the model loads the full content only when the task calls for it. Skills are how you give an agent a multi-step workflow without carrying it in the always-on <a href="./instructions.html">instructions</a>.</p><h2 id="authoring-forms" tabindex="-1">Authoring forms <a class="header-anchor" href="#authoring-forms" aria-label="Permalink to "Authoring forms""></a></h2><p>Three forms cover every case.</p><table tabindex="0"><thead><tr><th>Form</th><th>Reach for it when</th></tr></thead><tbody><tr><td><code>agent/skills/<name>.md</code></td><td>Flat markdown. Optional <code>description</code> frontmatter; the first body line is the fallback.</td></tr><tr><td><code>agent/skills/<name>/SKILL.md</code> plus siblings</td><td>A packaged directory with reference files (<code>references/…</code>). Requires <code>description</code> frontmatter.</td></tr><tr><td><code>agent/skills/<name>.ts</code></td><td>Generated content, with <code>defineSkill</code> from <code>@cursor/july/skills</code>.</td></tr></tbody></table><p>Flat markdown:</p><div class="language-md vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">md</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
|
|
2
2
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">description: Use when a pull request needs a structured approval checklist.</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#005CC5;--shiki-light-font-weight:bold;--shiki-dark:#79B8FF;--shiki-dark-font-weight:bold;">---</span></span>
|
|
4
4
|
<span class="line"></span>
|
|
@@ -6,10 +6,10 @@ import{_ as e,c as i,o as t,ag as a}from"./chunks/framework.CAZyNGu9.js";const c
|
|
|
6
6
|
<span class="line"></span>
|
|
7
7
|
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">1.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Call </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\`inspect_pr\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> and confirm required checks passed.</span></span>
|
|
8
8
|
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">2.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Summarize the PR title, author, and remaining risks.</span></span>
|
|
9
|
-
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">3.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Call </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\`approve_pr\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> only after an explicit request; it requires approval.</span></span></code></pre></div><p>TypeScript, when the content must be generated or carry inline sibling files:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineSkill } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
9
|
+
<span class="line"><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">3.</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> Call </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\`approve_pr\`</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> only after an explicit request; it requires approval.</span></span></code></pre></div><p>TypeScript, when the content must be generated or carry inline sibling files:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineSkill } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/skills"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
10
10
|
<span class="line"></span>
|
|
11
11
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineSkill</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
12
12
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> description: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Research unfamiliar topics before answering."</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
13
13
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> markdown: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"Gather evidence first, then answer with the key facts."</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
14
14
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> files: { </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"references/checklist.md"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"# Checklist</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\n\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">- Find sources.</span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">\\n</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
15
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="how-skills-reach-the-model" tabindex="-1">How skills reach the model <a class="header-anchor" href="#how-skills-reach-the-model" aria-label="Permalink to "How skills reach the model""></a></h2><p>On the local runtime, skills land in the session workspace at <code>.cursor/skills/<name>/SKILL.md</code>, and the harness advertises and loads them natively. On the cloud runtime, skills aren't materialized. The VM only sees skills that exist in the cloud repo itself, and <code>validate</code> warns about the combination.</p><h2 id="instructions-skills-or-tools" tabindex="-1">Instructions, skills, or tools? <a class="header-anchor" href="#instructions-skills-or-tools" aria-label="Permalink to "Instructions, skills, or tools?""></a></h2><p>Instructions are always in context: identity, tool-choice rules, the output contract. Keep them short. Skills load when relevant: procedures, checklists, house style. Reach for a skill when the model needs to <em>follow</em> something but only sometimes needs it loaded. Tools are typed, executable behavior: anything that must be correct every time belongs in tool code, not in prose the model might paraphrase.</p><p>A good skill description is a routing rule, not a title. Say <em>when</em> to use it, like "Use when a pull request needs a structured approval checklist," because the description is all the model sees before deciding to load it.</p><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><p>Continue with these pages:</p><ul><li><a href="./instructions.html">Instructions</a>: what stays always-on</li><li><a href="./tools.html">Tools</a>: when prose needs to become code</li><li><a href="./project-layout.html">Project layout</a>: where skills sit in the tree</li></ul>`,17)])])}const u=e(
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><h2 id="how-skills-reach-the-model" tabindex="-1">How skills reach the model <a class="header-anchor" href="#how-skills-reach-the-model" aria-label="Permalink to "How skills reach the model""></a></h2><p>On the local runtime, skills land in the session workspace at <code>.cursor/skills/<name>/SKILL.md</code>, and the harness advertises and loads them natively. On the cloud runtime, skills aren't materialized. The VM only sees skills that exist in the cloud repo itself, and <code>validate</code> warns about the combination.</p><h2 id="instructions-skills-or-tools" tabindex="-1">Instructions, skills, or tools? <a class="header-anchor" href="#instructions-skills-or-tools" aria-label="Permalink to "Instructions, skills, or tools?""></a></h2><p>Instructions are always in context: identity, tool-choice rules, the output contract. Keep them short. Skills load when relevant: procedures, checklists, house style. Reach for a skill when the model needs to <em>follow</em> something but only sometimes needs it loaded. Tools are typed, executable behavior: anything that must be correct every time belongs in tool code, not in prose the model might paraphrase.</p><p>A good skill description is a routing rule, not a title. Say <em>when</em> to use it, like "Use when a pull request needs a structured approval checklist," because the description is all the model sees before deciding to load it.</p><h2 id="what-s-next" tabindex="-1">What's next <a class="header-anchor" href="#what-s-next" aria-label="Permalink to "What's next""></a></h2><p>Continue with these pages:</p><ul><li><a href="./instructions.html">Instructions</a>: what stays always-on</li><li><a href="./tools.html">Tools</a>: when prose needs to become code</li><li><a href="./project-layout.html">Project layout</a>: where skills sit in the tree</li></ul>`,17)])])}const u=e(l,[["render",n]]);export{c as __pageData,u as default};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{_ as e,c as i,o as t,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),
|
|
1
|
+
import{_ as e,c as i,o as t,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms.","frontmatter":{"title":"Skills","description":"On-demand procedures the model loads only when relevant, in three authoring forms."},"headers":[],"relativePath":"reference/skills.md","filePath":"reference/skills.md"}'),l={name:"reference/skills.md"};function n(h,s,o,r,d,p){return t(),i("div",null,[...s[0]||(s[0]=[a("",17)])])}const u=e(l,[["render",n]]);export{c as __pageData,u as default};
|
package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import{_ as s,c as t,o as a,ag as n}from"./chunks/framework.CAZyNGu9.js";const u=JSON.parse('{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/.","frontmatter":{"title":"Subagents","description":"Specialist child agents the model delegates to mid-turn, each its own directory under agent/subagents/."},"headers":[],"relativePath":"reference/subagents.md","filePath":"reference/subagents.md"}'),i={name:"reference/subagents.md"};function r(o,e,l,d,h,p){return a(),t("div",null,[...e[0]||(e[0]=[n(`<h1 id="subagents" tabindex="-1">Subagents <a class="header-anchor" href="#subagents" aria-label="Permalink to "Subagents""></a></h1><p>A subagent is a specialist child agent the model can delegate to mid-turn. Each one is its own directory under <code>agent/subagents/<id>/</code>, with the same <code>agent.ts</code> + <code>instructions.md</code> shape as the root. On the Cursor harness, subagents run as SDK custom subagents: the parent model delegates through the harness <code>task</code> tool, and the stream records <code>subagent.called</code> and <code>subagent.completed</code>.</p><div class="language-text vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">text</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span>agent/subagents/researcher/</span></span>
|
|
2
2
|
<span class="line"><span>├── agent.ts # description (required), model (optional)</span></span>
|
|
3
3
|
<span class="line"><span>└── instructions.md # the subagent's own system prompt</span></span></code></pre></div><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/subagents/researcher/agent.ts</span></span>
|
|
4
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineAgent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
4
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineAgent } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
5
5
|
<span class="line"></span>
|
|
6
6
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineAgent</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
7
7
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> description:</span></span>
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import{_ as i,c as a,o as e,ag as t}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse('{"title":"Tools","description":"Define typed actions the model can call, gate the sensitive ones on approval, and call any server tool without a model turn.","frontmatter":{"title":"Tools","description":"Define typed actions the model can call, gate the sensitive ones on approval, and call any server tool without a model turn."},"headers":[],"relativePath":"reference/tools.md","filePath":"reference/tools.md"}'),n={name:"reference/tools.md"};function l(h,s,o,p,r,d){return e(),a("div",null,[...s[0]||(s[0]=[t(`<h1 id="tools" tabindex="-1">Tools <a class="header-anchor" href="#tools" aria-label="Permalink to "Tools""></a></h1><p>A tool is a typed action the model can call: hit an API, run a query, write a file. Each file in <code>agent/tools/</code> defines one tool, and the filename becomes the tool name the model sees. Tools come in two execution flavors: server tools run in-process on the serve host, and agent tools run as scripts where the agent runs. Every server tool can also be called directly, with no model turn.</p><h2 id="define-a-server-tool" tabindex="-1">Define a server tool <a class="header-anchor" href="#define-a-server-tool" aria-label="Permalink to "Define a server tool""></a></h2><p>By default, <code>execute</code> runs in-process on the serving host with full access to <code>process.env</code> and your <code>agent/lib/</code> code. Server tools require the <code>local</code> runtime.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/tools/inspect_pr.ts</span></span>
|
|
2
|
-
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
2
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/tools"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
3
3
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { z } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "zod"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
4
4
|
<span class="line"></span>
|
|
5
5
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -9,7 +9,7 @@ import{_ as i,c as a,o as e,ag as t}from"./chunks/framework.CAZyNGu9.js";const c
|
|
|
9
9
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> async</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> execute</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({ </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">prUrl</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> }, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">ctx</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) {</span></span>
|
|
10
10
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> return</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { prUrl, checks: [</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"unit"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;">"lint"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">], ready: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">true</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> };</span></span>
|
|
11
11
|
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
12
|
-
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>A tool definition needs a filename slug (the model-facing name), a <code>description</code> written for the model, an optional <code>inputSchema</code>, and the code that runs it. With a Zod <code>inputSchema</code>, the input is validated before <code>execute</code> runs and the input type is inferred. A plain JSON Schema object is forwarded as-is and the input arrives as raw JSON.</p><h3 id="the-ctx-parameter" tabindex="-1">The <code>ctx</code> parameter <a class="header-anchor" href="#the-ctx-parameter" aria-label="Permalink to "The \`ctx\` parameter""></a></h3><p><code>execute</code> receives a <code>ctx</code> with the runtime accessors:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>ctx.toolCallId</code></td><td>The call id, matching the <code>actions.requested</code> / <code>action.result</code> stream events</td></tr><tr><td><code>ctx.session</code></td><td>Read-only session info: id, channel, mode, auth</td></tr><tr><td><code>ctx.workspaceDir</code></td><td>The session's workspace directory</td></tr><tr><td><code>ctx.host.mcp</code></td><td>Authored MCP connections: <code>names()</code>, <code>listTools(name)</code>, <code>callTool(name, tool, args)</code></td></tr><tr><td><code>ctx.host.github</code> / <code>ctx.host.slack</code></td><td>Shared host clients when those packs are configured</td></tr></tbody></table><h3 id="return-values" tabindex="-1">Return values <a class="header-anchor" href="#return-values" aria-label="Permalink to "Return values""></a></h3><p><code>execute</code> may return a string (passed to the model verbatim), a JSON-shaped value (serialized), or the envelope <code>{ content: [...], isError? }</code> for rich results. Returns must be JSON-shaped: use object literals or <code>type</code> aliases. An <code>interface</code> type fails assignability (no index signature), and tsx won't catch it. Your typecheck will.</p><p>Throwing inside <code>execute</code> reports an error result to the model (<code>isError: true</code>). The turn and the server keep running.</p><h2 id="define-an-agent-tool" tabindex="-1">Define an agent tool <a class="header-anchor" href="#define-an-agent-tool" aria-label="Permalink to "Define an agent tool""></a></h2><p>Set <code>execution: "agent"</code> and the tool materializes as a shell script that runs where the Cursor agent runs: the local harness workspace or the cloud VM. The script receives JSON arguments on stdin and prints its result on stdout. This is the only tool flavor available to <code>runtime: "cloud"</code> agents.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@
|
|
12
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><p>A tool definition needs a filename slug (the model-facing name), a <code>description</code> written for the model, an optional <code>inputSchema</code>, and the code that runs it. With a Zod <code>inputSchema</code>, the input is validated before <code>execute</code> runs and the input type is inferred. A plain JSON Schema object is forwarded as-is and the input arrives as raw JSON.</p><h3 id="the-ctx-parameter" tabindex="-1">The <code>ctx</code> parameter <a class="header-anchor" href="#the-ctx-parameter" aria-label="Permalink to "The \`ctx\` parameter""></a></h3><p><code>execute</code> receives a <code>ctx</code> with the runtime accessors:</p><table tabindex="0"><thead><tr><th>Member</th><th>What it is</th></tr></thead><tbody><tr><td><code>ctx.toolCallId</code></td><td>The call id, matching the <code>actions.requested</code> / <code>action.result</code> stream events</td></tr><tr><td><code>ctx.session</code></td><td>Read-only session info: id, channel, mode, auth</td></tr><tr><td><code>ctx.workspaceDir</code></td><td>The session's workspace directory</td></tr><tr><td><code>ctx.host.mcp</code></td><td>Authored MCP connections: <code>names()</code>, <code>listTools(name)</code>, <code>callTool(name, tool, args)</code></td></tr><tr><td><code>ctx.host.github</code> / <code>ctx.host.slack</code></td><td>Shared host clients when those packs are configured</td></tr></tbody></table><h3 id="return-values" tabindex="-1">Return values <a class="header-anchor" href="#return-values" aria-label="Permalink to "Return values""></a></h3><p><code>execute</code> may return a string (passed to the model verbatim), a JSON-shaped value (serialized), or the envelope <code>{ content: [...], isError? }</code> for rich results. Returns must be JSON-shaped: use object literals or <code>type</code> aliases. An <code>interface</code> type fails assignability (no index signature), and tsx won't catch it. Your typecheck will.</p><p>Throwing inside <code>execute</code> reports an error result to the model (<code>isError: true</code>). The turn and the server keep running.</p><h2 id="define-an-agent-tool" tabindex="-1">Define an agent tool <a class="header-anchor" href="#define-an-agent-tool" aria-label="Permalink to "Define an agent tool""></a></h2><p>Set <code>execution: "agent"</code> and the tool materializes as a shell script that runs where the Cursor agent runs: the local harness workspace or the cloud VM. The script receives JSON arguments on stdin and prints its result on stdout. This is the only tool flavor available to <code>runtime: "cloud"</code> agents.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineTool } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/tools"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
13
13
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { z } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "zod"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
14
14
|
<span class="line"></span>
|
|
15
15
|
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineTool</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,c as o,o as t,ag as l}from"./chunks/framework.CAZyNGu9.js";const f=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),r={name:"scaffolding-agents.md"};function i(s,e,n,d,h,c){return t(),o("div",null,[...e[0]||(e[0]=[l('<h1 id="scaffold-an-agent-with-cursor" tabindex="-1">Scaffold an agent with Cursor <a class="header-anchor" href="#scaffold-an-agent-with-cursor" aria-label="Permalink to "Scaffold an agent with Cursor""></a></h1><p>Turn an idea into a verified agent while Cursor guides you through each decision.</p><h2 id="what-does-the-create-agent-skill-do" tabindex="-1">What does the create-agent skill do? <a class="header-anchor" href="#what-does-the-create-agent-skill-do" aria-label="Permalink to "What does the create-agent skill do?""></a></h2><p>The bundled <a href="./../skills/create-agent/SKILL.html"><code>create-agent</code> skill</a> turns your goal into a small working project. Have Cursor read that file and follow it (monorepo path: <code>packages/agent-serve/skills/create-agent/SKILL.md</code>).</p><p>Cursor will:</p><ul><li>Ask only for choices missing from your prompt</li><li>Recommend defaults based on what you want to build</li><li>Show you the plan and file tree before writing files</li><li>Create the agent after you confirm the plan</li><li>Run structural checks, a real turn, and a smoke eval</li></ul><p>Use this skill for a new agent. Use <a href="./hillclimbing.html"><code>hillclimb</code></a> (<code>skills/hillclimb/SKILL.md</code>) when an existing agent works but needs better results.</p><h2 id="how-do-i-start-a-guided-scaffold" tabindex="-1">How do I start a guided scaffold? <a class="header-anchor" href="#how-do-i-start-a-guided-scaffold" aria-label="Permalink to "How do I start a guided scaffold?""></a></h2><p>Describe the outcome and any constraints you already know:</p><blockquote><p>Build a local weather agent for the playground. Give it one tool for current conditions and add a smoke eval. Guide me through the remaining decisions.</p></blockquote><p>More detail means fewer questions. Include a channel, runtime, model, or required integration when those choices are fixed.</p><h2 id="which-choices-will-cursor-ask-me-to-make" tabindex="-1">Which choices will Cursor ask me to make? <a class="header-anchor" href="#which-choices-will-cursor-ask-me-to-make" aria-label="Permalink to "Which choices will Cursor ask me to make?""></a></h2><p>Cursor fills gaps in two short rounds:</p><ul><li><strong>Identity:</strong> purpose, project name, and location</li><li><strong>Runtime:</strong> local or cloud</li><li><strong>Model:</strong> the default model or another Cursor model</li><li><strong>Channels:</strong> playground and HTTP, Slack, GitHub, a webhook, or a schedule</li><li><strong>MCP connections:</strong> remote or local MCP servers</li><li><strong>Capabilities:</strong> tools, skills, subagents, hooks, seed files, approvals, and evals</li></ul><p>Questions adapt to your goal. A playground chat agent won't get cloud-repository questions. A local agent won't get cloud setup questions.</p><h2 id="what-happens-before-cursor-writes-files" tabindex="-1">What happens before Cursor writes files? <a class="header-anchor" href="#what-happens-before-cursor-writes-files" aria-label="Permalink to "What happens before Cursor writes files?""></a></h2><p>Cursor shows one plan with the choices it made and the folders it will create. Choose <strong>Scaffold it</strong> to continue or <strong>Adjust something</strong> to change the plan.</p><p>No files change before you approve this step.</p><h2 id="what-will-cursor-create" tabindex="-1">What will Cursor create? <a class="header-anchor" href="#what-will-cursor-create" aria-label="Permalink to "What will Cursor create?""></a></h2><p>A first version usually includes:</p><ul><li><code>agent/agent.ts</code> for the model and runtime</li><li><code>agent/instructions.md</code> for the always-on prompt</li><li>One or two tools under <code>agent/tools/</code></li><li>Any channels or MCP connections you selected</li><li><code>evals/evals.config.ts</code> and one smoke eval</li></ul><p>Cursor keeps the first version small. Side-effecting server tools use <code>needsApproval</code>. Deterministic setup, such as fetching a pull request, stays in host code instead of model instructions.</p><p>See <a href="./reference/project-layout.html">Project layout</a> for every supported folder.</p><h2 id="how-does-cursor-verify-the-scaffold" tabindex="-1">How does Cursor verify the scaffold? <a class="header-anchor" href="#how-does-cursor-verify-the-scaffold" aria-label="Permalink to "How does Cursor verify the scaffold?""></a></h2><p>Cursor checks the project in this order:</p><ol><li>Run <code>agentkit validate</code> and fix every error</li><li>Inspect the discovered surface with <code>info --json</code></li><li>Call each server tool directly with validated sample input</li><li>Run one end-to-end model turn</li><li>Run the smoke eval</li><li>Run the project's TypeScript check</li></ol><p>Validation, discovery, direct server-tool calls, and server startup work without a Cursor credential. Model turns and evals need <code>CURSOR_API_KEY</code> or a saved <code>agentkit login</code>.</p><h2 id="what-happens-after-the-first-agent-works" tabindex="-1">What happens after the first agent works? <a class="header-anchor" href="#what-happens-after-the-first-agent-works" aria-label="Permalink to "What happens after the first agent works?""></a></h2><p>Choose one to three fixed inputs, define what should improve, and name what must stay unchanged. Then have Cursor follow <a href="./../skills/hillclimb/SKILL.html"><code>skills/hillclimb/SKILL.md</code></a>.</p><p>The hillclimb skill measures a baseline, changes one lever, runs the same inputs again, and adds an eval for each improvement you keep.</p><h2 id="related" tabindex="-1">Related <a class="header-anchor" href="#related" aria-label="Permalink to "Related""></a></h2><ul><li><a href="./quickstart.html">Build your first PR approver</a></li><li><a href="./building-with-agents.html">Building agents with agents</a></li><li><a href="./evals.html">Evals</a></li><li><a href="./hillclimbing.html">Hillclimbing</a></li><li><a href="./reference/project-layout.html">Project layout</a></li></ul>',32)])])}const p=a(r,[["render",i]]);export{f as __pageData,p as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as a,c as o,o as t,ag as l}from"./chunks/framework.CAZyNGu9.js";const f=JSON.parse('{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent.","frontmatter":{"title":"Scaffold an agent with Cursor","description":"Use the bundled create-agent skill to plan, build, and verify a new agent."},"headers":[],"relativePath":"scaffolding-agents.md","filePath":"scaffolding-agents.md"}'),r={name:"scaffolding-agents.md"};function i(s,e,n,d,h,c){return t(),o("div",null,[...e[0]||(e[0]=[l("",32)])])}const p=a(r,[["render",i]]);export{f as __pageData,p as default};
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import{_ as e,c as t,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse(`{"title":"Storage","description":"Point agentkit's durable storage at a backend you own with defineStorage.","frontmatter":{"title":"Storage","description":"Point agentkit's durable storage at a backend you own with defineStorage."},"headers":[],"relativePath":"storage.md","filePath":"storage.md"}`),n={name:"storage.md"};function o(d,s,r,h,l,p){return i(),t("div",null,[...s[0]||(s[0]=[a(`<h1 id="storage" tabindex="-1">Storage <a class="header-anchor" href="#storage" aria-label="Permalink to "Storage""></a></h1><p>agentkit owns durable storage for sessions, continuation tokens, reminders, playground eval history, and live A/B samples. It chooses the keys (under <code>agentkit/v1/</code>), when to read and write, and how to restore after restart.</p><p>Keys have bounded length: caller-controlled segments (channel ids, continuation tokens) are URI-encoded, and any segment past 256 encoded bytes is replaced by its <code>sha256:…</code> digest — deterministically, so writes and lookups always agree. Backends can rely on this instead of imposing their own key-length caps (which would silently drop writes, since a throwing <code>put</code> is at-most-once).</p><p>By default that storage lives under <code>--state-root</code> on local disk. Fine for one machine; it does not survive replacing the host.</p><p>To keep the same framework storage across hosts, plug in a key-value backend with <code>agent/storage.ts</code>. You provide <code>put</code> / <code>get</code> / <code>delete</code> / <code>list</code>. agentkit does the rest.</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// agent/storage.ts</span></span>
|
|
2
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">import</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> { defineStorage } </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">from</span><span style="--shiki-light:#032F62;--shiki-dark:#9ECBFF;"> "@cursor/july/storage"</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">;</span></span>
|
|
3
|
+
<span class="line"></span>
|
|
4
|
+
<span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineStorage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
5
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> put</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">, </span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">value</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> db.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">upsert</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key, value),</span></span>
|
|
6
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> db.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">get</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key),</span></span>
|
|
7
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> delete</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">key</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> db.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">delete</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(key),</span></span>
|
|
8
|
+
<span class="line"><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> list</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">: (</span><span style="--shiki-light:#E36209;--shiki-dark:#FFAB70;">prefix</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">) </span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">=></span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> db.</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;">listByPrefix</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">(prefix), </span><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;">// [{ key, value }], key order</span></span>
|
|
9
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><div class="note custom-block github-alert"><p class="custom-block-title">NOTE</p><p>Import paths here use <code>@cursor/july/storage</code>. On projects still using <code>@anysphere/agent-serve</code>, swap the import. See <a href="./README.html#run-the-cli">Run the CLI</a> for the full rename table.</p></div><h2 id="which-methods-to-provide" tabindex="-1">Which methods to provide <a class="header-anchor" href="#which-methods-to-provide" aria-label="Permalink to "Which methods to provide""></a></h2><table tabindex="0"><thead><tr><th>Method</th><th>Required</th><th>Role</th></tr></thead><tbody><tr><td><code>put</code></td><td>Yes</td><td>Write or update a value</td></tr><tr><td><code>get</code></td><td>For restore</td><td>Look up one key</td></tr><tr><td><code>list</code></td><td>For restore</td><td>Return entries under a prefix, in key order</td></tr><tr><td><code>delete</code></td><td>For cleanup</td><td>Remove a key</td></tr></tbody></table><p>A throwing <code>put</code> is logged and dropped. It never fails a turn. When resolving a missing continuation token, a throwing <code>get</code> fails the follow-up so a store outage does not open a new session. Return <code>undefined</code> only for a real miss.</p><h2 id="policy" tabindex="-1">Policy <a class="header-anchor" href="#policy" aria-label="Permalink to "Policy""></a></h2><p>Two knobs change behavior:</p><div class="language-ts vp-adaptive-theme"><button title="Copy Code" class="copy"></button><span class="lang">ts</span><pre class="shiki shiki-themes github-light github-dark vp-code" tabindex="0"><code><span class="line"><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;">export</span><span style="--shiki-light:#D73A49;--shiki-dark:#F97583;"> default</span><span style="--shiki-light:#6F42C1;--shiki-dark:#B392F0;"> defineStorage</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">({</span></span>
|
|
10
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> policy: {</span></span>
|
|
11
|
+
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Batch event writes while the session is busy (default: once per turn)</span></span>
|
|
12
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> debounceMs: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">30_000</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">,</span></span>
|
|
13
|
+
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // Cap how much loads at serve start, or "off" to restore on demand</span></span>
|
|
14
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> restore: { maxSessions: </span><span style="--shiki-light:#005CC5;--shiki-dark:#79B8FF;">500</span><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
15
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;"> },</span></span>
|
|
16
|
+
<span class="line"><span style="--shiki-light:#6A737D;--shiki-dark:#6A737D;"> // put / get / delete / list …</span></span>
|
|
17
|
+
<span class="line"><span style="--shiki-light:#24292E;--shiki-dark:#E1E4E8;">});</span></span></code></pre></div><table tabindex="0"><thead><tr><th>Knob</th><th>Default</th><th>Meaning</th></tr></thead><tbody><tr><td><code>debounceMs</code></td><td>unset (once per turn)</td><td>Wait this long after activity before writing event batches</td></tr><tr><td><code>restore</code></td><td>caps below</td><td>How much to load at serve start</td></tr><tr><td><code>restore.maxSessions</code></td><td><code>1000</code></td><td>Max sessions loaded at serve start</td></tr><tr><td><code>restore.maxAgeMs</code></td><td>30 days</td><td>Skip older sessions at serve start</td></tr><tr><td><code>restore.maxTotalBytes</code></td><td>1 GiB</td><td>Stop loading once this budget is reached</td></tr></tbody></table><p>Set <code>restore: "off"</code> on high-traffic hosts. Sessions then load when a follow-up arrives instead of at startup.</p><h2 id="restore-after-restart" tabindex="-1">Restore after restart <a class="header-anchor" href="#restore-after-restart" aria-label="Permalink to "Restore after restart""></a></h2><p>With <code>get</code> and <code>list</code>, serve can rebuild local state from your store:</p><ul><li>At startup, agentkit loads recent sessions up to the restore caps. Local disk wins when both sides have the same session. Reminders hydrate the same way into <code>--state-root/reminders</code>.</li><li>On demand, a missing continuation token resolves through the store and resumes that session.</li><li>Playground eval history and A/B aggregates can load from the same sink.</li></ul><p>A turn in flight at crash time is not replayed. The next follow-up resumes from the last flushed state.</p>`,19)])])}const g=e(n,[["render",o]]);export{c as __pageData,g as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{_ as e,c as t,o as i,ag as a}from"./chunks/framework.CAZyNGu9.js";const c=JSON.parse(`{"title":"Storage","description":"Point agentkit's durable storage at a backend you own with defineStorage.","frontmatter":{"title":"Storage","description":"Point agentkit's durable storage at a backend you own with defineStorage."},"headers":[],"relativePath":"storage.md","filePath":"storage.md"}`),n={name:"storage.md"};function o(d,s,r,h,l,p){return i(),t("div",null,[...s[0]||(s[0]=[a("",19)])])}const g=e(n,[["render",o]]);export{c as __pageData,g as default};
|