@cursor/july 0.1.108 → 0.1.109
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 +2 -6
- package/README.md +3 -6
- package/dist/channels/bitbucket/api.d.ts +41 -0
- package/dist/channels/bitbucket/api.d.ts.map +1 -1
- package/dist/channels/bitbucket/api.js +260 -0
- package/dist/channels/bitbucket/binding.d.ts +4 -0
- package/dist/channels/bitbucket/binding.d.ts.map +1 -1
- package/dist/channels/bitbucket/binding.js +16 -0
- package/dist/channels/bitbucket/index.d.ts +1 -1
- package/dist/channels/bitbucket/index.d.ts.map +1 -1
- package/dist/channels/bitbucket/index.js +1 -1
- package/dist/channels/gitlab/api.d.ts +27 -0
- package/dist/channels/gitlab/api.d.ts.map +1 -1
- package/dist/channels/gitlab/api.js +88 -0
- package/dist/channels/gitlab/binding.d.ts +5 -0
- package/dist/channels/gitlab/binding.d.ts.map +1 -1
- package/dist/channels/gitlab/binding.js +10 -0
- package/dist/channels/gitlab/index.d.ts +1 -1
- package/dist/channels/gitlab/index.d.ts.map +1 -1
- package/dist/channels/gitlab/index.js +1 -1
- package/dist/channels/slack/dispatch.d.ts +10 -0
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +20 -3
- package/dist/channels/slack/slack-channel.d.ts +12 -5
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +59 -8
- package/dist/docs/404.html +2 -2
- package/dist/docs/assets/{app.BASKM3M4.js → app.Cr-wVbnB.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.js → building-with-agents.md.D0KbSkJn.js} +2 -2
- package/dist/docs/assets/{building-with-agents.md.CUSWxlP_.lean.js → building-with-agents.md.D0KbSkJn.lean.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.CFVQ4S17.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BOKxlYGP.js → VPLocalSearchBox.CVQERt56.js} +1 -1
- package/dist/docs/assets/chunks/{theme.DbDZW-zb.js → theme.Dnsd3XOn.js} +2 -2
- package/dist/docs/assets/concepts.md.B4o63Gul.js +1 -0
- package/dist/docs/assets/evals.md.C7JLjoEP.js +211 -0
- package/dist/docs/assets/evals.md.C7JLjoEP.lean.js +1 -0
- package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.js +10 -0
- package/dist/docs/assets/guides_bitbucket.md.DZPzmUjU.lean.js +1 -0
- package/dist/docs/assets/{guides_github.md.BH33UEBJ.js → guides_github.md.TZaTZlfz.js} +13 -3
- package/dist/docs/assets/{guides_github.md.BH33UEBJ.lean.js → guides_github.md.TZaTZlfz.lean.js} +1 -1
- package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.js +14 -0
- package/dist/docs/assets/guides_gitlab.md.BmqwQfdG.lean.js +1 -0
- package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.js → guides_webhooks.md.CJK484ex.js} +2 -2
- package/dist/docs/assets/{hillclimbing.md.CpTGTCle.js → hillclimbing.md.BOiVo1tf.js} +1 -1
- package/dist/docs/assets/index.md.DD9Q2XuJ.js +5 -0
- package/dist/docs/assets/{index.md.BjH1w2ZW.lean.js → index.md.DD9Q2XuJ.lean.js} +1 -1
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.js → reference_channels.md.CAo-iK4j.js} +2 -2
- package/dist/docs/assets/{reference_channels.md.D-qTqwcq.lean.js → reference_channels.md.CAo-iK4j.lean.js} +1 -1
- package/dist/docs/assets/{reference_cli.md.Ca26u0Es.js → reference_cli.md.Deg7849l.js} +1 -1
- package/dist/docs/assets/{reference_extensions.md.CPWt00ds.js → reference_extensions.md.ZAVUyuEX.js} +2 -2
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.js → reference_hooks.md.BlM_bOg6.js} +3 -3
- package/dist/docs/assets/{reference_hooks.md.Ddt5DdgJ.lean.js → reference_hooks.md.BlM_bOg6.lean.js} +1 -1
- package/dist/docs/assets/{reference_http-api.md.oySXBO8o.js → reference_http-api.md.BwaCo-VO.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.js → reference_playground.md.DLnoaczX.js} +1 -1
- package/dist/docs/assets/{reference_playground.md.4myJPxrf.lean.js → reference_playground.md.DLnoaczX.lean.js} +1 -1
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.js → reference_project-layout.md.BEU8MtQV.js} +3 -3
- package/dist/docs/assets/{reference_project-layout.md.DuBu9a96.lean.js → reference_project-layout.md.BEU8MtQV.lean.js} +1 -1
- package/dist/docs/assets/reference_sessions.md.CyXV1MUw.js +1 -0
- package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.js +35 -0
- package/dist/docs/assets/skills_deploy.md.CWqi_ZxW.lean.js +1 -0
- package/dist/docs/assets/{skills_evals.md.BhovOvrl.js → skills_evals.md.DFxYPErF.js} +3 -3
- package/dist/docs/assets/skills_evals.md.DFxYPErF.lean.js +1 -0
- package/dist/docs/assets/{skills_framework-map.md.D-tFZhFS.js → skills_framework-map.md.BxLSOhSY.js} +1 -1
- package/dist/docs/assets/skills_index.md.DL7EHaQ-.js +1 -0
- package/dist/docs/assets/skills_index.md.DL7EHaQ-.lean.js +1 -0
- package/dist/docs/assets/{storage.md.BOHeqk2M.js → storage.md.BUrhJ-Zz.js} +4 -4
- package/dist/docs/assets/{storage.md.BOHeqk2M.lean.js → storage.md.BUrhJ-Zz.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +5 -5
- package/dist/docs/building-with-agents.md +3 -2
- package/dist/docs/concepts.html +5 -5
- package/dist/docs/concepts.md +2 -4
- package/dist/docs/deployment.html +4 -4
- package/dist/docs/evals.html +161 -35
- package/dist/docs/evals.md +612 -297
- package/dist/docs/guides/agent-to-agent.html +4 -4
- package/dist/docs/guides/bitbucket.html +36 -0
- package/dist/docs/guides/bitbucket.md +84 -0
- package/dist/docs/guides/cloud-agents.html +4 -4
- package/dist/docs/guides/convert-automation.html +4 -4
- package/dist/docs/guides/github.html +17 -7
- package/dist/docs/guides/github.md +31 -0
- package/dist/docs/guides/gitlab.html +40 -0
- package/dist/docs/guides/gitlab.md +92 -0
- package/dist/docs/guides/grokbot-agents.html +4 -4
- package/dist/docs/guides/human-in-the-loop.html +4 -4
- package/dist/docs/guides/improve.html +4 -4
- package/dist/docs/guides/mcp-oauth.html +4 -4
- package/dist/docs/guides/opentelemetry.html +4 -4
- package/dist/docs/guides/slack.html +5 -5
- package/dist/docs/guides/webhooks.html +6 -6
- package/dist/docs/guides/webhooks.md +4 -2
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +6 -6
- package/dist/docs/hillclimbing.md +2 -2
- package/dist/docs/index.html +6 -6
- package/dist/docs/index.md +10 -6
- package/dist/docs/llms-full.txt +1113 -778
- package/dist/docs/llms.txt +6 -5
- package/dist/docs/quickstart.html +4 -4
- package/dist/docs/reference/agent-config.html +4 -4
- package/dist/docs/reference/artifacts.html +4 -4
- package/dist/docs/reference/channels.html +6 -6
- package/dist/docs/reference/channels.md +16 -3
- package/dist/docs/reference/cli.html +6 -6
- package/dist/docs/reference/cli.md +6 -4
- package/dist/docs/reference/connections.html +4 -4
- package/dist/docs/reference/extensions.html +7 -7
- package/dist/docs/reference/extensions.md +0 -3
- package/dist/docs/reference/hooks.html +7 -7
- package/dist/docs/reference/hooks.md +9 -12
- package/dist/docs/reference/http-api.html +6 -6
- package/dist/docs/reference/http-api.md +2 -3
- package/dist/docs/reference/instructions.html +4 -4
- package/dist/docs/reference/playground.html +5 -5
- package/dist/docs/reference/playground.md +0 -4
- package/dist/docs/reference/project-layout.html +7 -7
- package/dist/docs/reference/project-layout.md +1 -8
- package/dist/docs/reference/prompt.html +4 -4
- package/dist/docs/reference/result.html +4 -4
- package/dist/docs/reference/schedules.html +4 -4
- package/dist/docs/reference/sessions.html +5 -5
- package/dist/docs/reference/sessions.md +1 -2
- package/dist/docs/reference/skills.html +4 -4
- package/dist/docs/reference/subagents.html +4 -4
- package/dist/docs/reference/tools.html +4 -4
- package/dist/docs/scaffolding-agents.html +4 -4
- package/dist/docs/skills/create-agent.html +4 -4
- package/dist/docs/skills/debug.html +4 -4
- package/dist/docs/skills/deploy.html +61 -0
- package/dist/docs/skills/deploy.md +161 -0
- package/dist/docs/skills/evals.html +8 -8
- package/dist/docs/skills/evals.md +44 -6
- package/dist/docs/skills/framework-map.html +5 -5
- package/dist/docs/skills/framework-map.md +1 -2
- package/dist/docs/skills/github.html +4 -4
- package/dist/docs/skills/hillclimb.html +4 -4
- package/dist/docs/skills/index.html +6 -6
- package/dist/docs/skills/index.md +1 -1
- package/dist/docs/skills/mcp-auth.html +4 -4
- package/dist/docs/skills/otel.html +4 -4
- package/dist/docs/skills/setup-slack.html +4 -4
- package/dist/docs/storage.html +8 -8
- package/dist/docs/storage.md +15 -24
- package/dist/docs/templates/agentic-owners.html +4 -4
- package/dist/docs/templates/agents-md.html +4 -4
- package/dist/docs/templates/code-wiki.html +4 -4
- package/dist/docs/templates/demo.html +4 -4
- package/dist/docs/templates/grokbot-agents.html +4 -4
- package/dist/docs/templates/pr-autofixer.html +4 -4
- package/dist/docs/templates/security-help.html +4 -4
- package/dist/docs/templates/security-reviewer.html +4 -4
- package/dist/docs/templates/triage.html +4 -4
- package/dist/docs/troubleshooting.html +4 -4
- package/dist/extensions.d.ts +2 -3
- package/dist/extensions.d.ts.map +1 -1
- package/dist/extensions.js +2 -5
- package/dist/index.d.ts +2 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -2
- package/dist/internal/authored-alias-hooks.d.ts +5 -0
- package/dist/internal/authored-alias-hooks.d.ts.map +1 -1
- package/dist/internal/authored-alias-hooks.js +17 -0
- package/dist/internal/authored-loaders.d.ts +4 -0
- package/dist/internal/authored-loaders.d.ts.map +1 -1
- package/dist/internal/authored-loaders.js +21 -2
- package/dist/internal/cli-ax.d.ts +1 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +1 -2
- package/dist/internal/continuation-channel.d.ts.map +1 -1
- package/dist/internal/continuation-channel.js +2 -2
- package/dist/internal/continuation-identity.js +8 -3
- package/dist/internal/discovery/agent.d.ts +1 -1
- package/dist/internal/discovery/agent.d.ts.map +1 -1
- package/dist/internal/discovery/agent.js +0 -5
- package/dist/internal/discovery/extension-overlay.d.ts +1 -2
- package/dist/internal/discovery/extension-overlay.d.ts.map +1 -1
- package/dist/internal/discovery/extension-overlay.js +0 -14
- package/dist/internal/discovery/extensions.d.ts +1 -2
- package/dist/internal/discovery/extensions.d.ts.map +1 -1
- package/dist/internal/discovery/extensions.js +4 -22
- package/dist/internal/discovery/info.d.ts.map +1 -1
- package/dist/internal/discovery/info.js +42 -24
- package/dist/internal/discovery/modules.js +0 -1
- package/dist/internal/discovery/project.d.ts.map +1 -1
- package/dist/internal/discovery/project.js +0 -16
- package/dist/internal/eval-runner.js +0 -1
- package/dist/internal/framework-file-storage.d.ts +4 -5
- package/dist/internal/framework-file-storage.d.ts.map +1 -1
- package/dist/internal/framework-file-storage.js +4 -5
- package/dist/internal/framework-storage-selection.d.ts +2 -2
- package/dist/internal/framework-storage-selection.js +2 -2
- package/dist/internal/init-scaffold.d.ts.map +1 -1
- package/dist/internal/init-scaffold.js +1 -2
- package/dist/internal/install-cursor-skills.d.ts +5 -2
- package/dist/internal/install-cursor-skills.d.ts.map +1 -1
- package/dist/internal/install-cursor-skills.js +25 -5
- package/dist/internal/run-client.d.ts +1 -1
- package/dist/internal/sdk-runner.js +1 -1
- package/dist/internal/server.js +0 -14
- package/dist/internal/session-engine.d.ts +5 -35
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +17 -162
- package/dist/internal/storage-coordinator.d.ts +5 -19
- package/dist/internal/storage-coordinator.d.ts.map +1 -1
- package/dist/internal/storage-coordinator.js +3 -62
- package/dist/internal/storage-roles.d.ts +4 -9
- package/dist/internal/storage-roles.d.ts.map +1 -1
- package/dist/internal/storage-roles.js +2 -2
- package/dist/playground/assets/index-Bhxzrcf6.css +1 -0
- package/dist/playground/assets/index-CqLX5uF3.js +67 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted-v2.d.ts +4 -5
- package/dist/storage-backends/cursor-hosted-v2.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted-v2.js +4 -5
- package/dist/storage-backends/cursor-hosted.d.ts +1 -2
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +0 -30
- package/dist/storage-backends/file-kv.d.ts +9 -12
- package/dist/storage-backends/file-kv.d.ts.map +1 -1
- package/dist/storage-backends/file-kv.js +11 -47
- package/dist/storage-protocol.d.ts +3 -11
- package/dist/storage-protocol.d.ts.map +1 -1
- package/dist/storage-protocol.js +3 -11
- package/dist/storage.d.ts +8 -36
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +8 -44
- package/dist/types.d.ts +20 -57
- package/dist/types.d.ts.map +1 -1
- package/docs/README.md +10 -6
- package/docs/building-with-agents.md +3 -2
- package/docs/concepts.md +2 -4
- package/docs/evals.md +613 -298
- package/docs/guides/bitbucket.md +89 -0
- package/docs/guides/github.md +31 -0
- package/docs/guides/gitlab.md +97 -0
- package/docs/guides/webhooks.md +4 -2
- package/docs/hillclimbing.md +2 -2
- package/docs/reference/channels.md +16 -3
- package/docs/reference/cli.md +6 -4
- package/docs/reference/extensions.md +0 -3
- package/docs/reference/hooks.md +9 -12
- package/docs/reference/http-api.md +2 -3
- package/docs/reference/playground.md +0 -4
- package/docs/reference/project-layout.md +1 -8
- package/docs/reference/sessions.md +1 -2
- package/docs/skills/index.md +2 -2
- package/docs/storage.md +15 -24
- package/package.json +1 -7
- package/skills/deploy/SKILL.md +169 -0
- package/skills/evals/SKILL.md +45 -8
- package/skills/framework-map/SKILL.md +1 -2
- package/src/channels/bitbucket/api.ts +341 -0
- package/src/channels/bitbucket/binding.ts +25 -0
- package/src/channels/bitbucket/index.ts +2 -0
- package/src/channels/gitlab/api.ts +123 -0
- package/src/channels/gitlab/binding.ts +12 -0
- package/src/channels/gitlab/index.ts +1 -0
- package/src/channels/slack/dispatch.ts +30 -0
- package/src/channels/slack/slack-channel.ts +69 -7
- package/src/extensions.ts +2 -6
- package/src/index.ts +0 -3
- package/src/internal/authored-alias-hooks.ts +32 -0
- package/src/internal/authored-loaders.ts +26 -2
- package/src/internal/cli-ax.ts +1 -2
- package/src/internal/continuation-channel.ts +2 -1
- package/src/internal/continuation-identity.ts +10 -2
- package/src/internal/discovery/agent.ts +1 -7
- package/src/internal/discovery/extension-overlay.ts +0 -18
- package/src/internal/discovery/extensions.ts +2 -26
- package/src/internal/discovery/info.ts +3 -13
- package/src/internal/discovery/modules.ts +0 -1
- package/src/internal/discovery/project.ts +0 -16
- package/src/internal/eval-runner.ts +0 -1
- package/src/internal/framework-file-storage.ts +4 -5
- package/src/internal/framework-storage-selection.ts +2 -2
- package/src/internal/init-scaffold.ts +1 -2
- package/src/internal/install-cursor-skills.ts +38 -5
- package/src/internal/run-client.ts +1 -1
- package/src/internal/sdk-runner.ts +1 -1
- package/src/internal/server.ts +0 -16
- package/src/internal/session-engine.ts +14 -202
- package/src/internal/storage-coordinator.ts +5 -76
- package/src/internal/storage-roles.ts +4 -9
- package/src/storage-backends/cursor-hosted-v2.ts +4 -7
- package/src/storage-backends/cursor-hosted.ts +0 -37
- package/src/storage-backends/file-kv.ts +10 -51
- package/src/storage-protocol.ts +3 -17
- package/src/storage.ts +10 -101
- package/src/types.ts +19 -56
- package/templates/demo/README.md +10 -6
- package/templates/demo/agent/channels/github.ts +2 -0
- package/templates/demo/agent/channels/queue.ts +6 -2
- package/templates/demo/agent/lib/repos.ts +5 -0
- package/templates/demo/init.json +25 -0
- package/dist/ab.d.ts +0 -209
- package/dist/ab.d.ts.map +0 -1
- package/dist/ab.js +0 -246
- package/dist/docs/ab.html +0 -80
- package/dist/docs/ab.md +0 -332
- package/dist/docs/assets/ab.md.mlVgqvSk.js +0 -54
- package/dist/docs/assets/ab.md.mlVgqvSk.lean.js +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BHZYsNVi.js +0 -1
- package/dist/docs/assets/concepts.md.DgEcZOfT.js +0 -1
- package/dist/docs/assets/evals.md.C1ekS3k2.js +0 -85
- package/dist/docs/assets/evals.md.C1ekS3k2.lean.js +0 -1
- package/dist/docs/assets/index.md.BjH1w2ZW.js +0 -5
- package/dist/docs/assets/reference_sessions.md.CueyOHSL.js +0 -1
- package/dist/docs/assets/skills_ab.md.CsFNatVx.js +0 -26
- package/dist/docs/assets/skills_ab.md.CsFNatVx.lean.js +0 -1
- package/dist/docs/assets/skills_evals.md.BhovOvrl.lean.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.js +0 -1
- package/dist/docs/assets/skills_index.md.DKwIxzGg.lean.js +0 -1
- package/dist/docs/skills/ab.html +0 -52
- package/dist/docs/skills/ab.md +0 -50
- package/dist/internal/ab-collector.d.ts +0 -44
- package/dist/internal/ab-collector.d.ts.map +0 -1
- package/dist/internal/ab-collector.js +0 -142
- package/dist/internal/ab-fold.d.ts +0 -36
- package/dist/internal/ab-fold.d.ts.map +0 -1
- package/dist/internal/ab-fold.js +0 -175
- package/dist/internal/ab-snapshot.d.ts +0 -68
- package/dist/internal/ab-snapshot.d.ts.map +0 -1
- package/dist/internal/ab-snapshot.js +0 -208
- package/dist/internal/discovery/ab.d.ts +0 -9
- package/dist/internal/discovery/ab.d.ts.map +0 -1
- package/dist/internal/discovery/ab.js +0 -113
- package/dist/playground/assets/index-BMDqAeXu.js +0 -67
- package/dist/playground/assets/index-LUgJoWdL.css +0 -1
- package/docs/ab.md +0 -337
- package/skills/ab/SKILL.md +0 -58
- package/src/ab.ts +0 -430
- package/src/internal/ab-collector.ts +0 -200
- package/src/internal/ab-fold.ts +0 -232
- package/src/internal/ab-snapshot.ts +0 -331
- package/src/internal/discovery/ab.ts +0 -131
- /package/dist/docs/assets/{concepts.md.DgEcZOfT.lean.js → concepts.md.B4o63Gul.lean.js} +0 -0
- /package/dist/docs/assets/{guides_webhooks.md.DKdA43Qm.lean.js → guides_webhooks.md.CJK484ex.lean.js} +0 -0
- /package/dist/docs/assets/{hillclimbing.md.CpTGTCle.lean.js → hillclimbing.md.BOiVo1tf.lean.js} +0 -0
- /package/dist/docs/assets/{reference_cli.md.Ca26u0Es.lean.js → reference_cli.md.Deg7849l.lean.js} +0 -0
- /package/dist/docs/assets/{reference_extensions.md.CPWt00ds.lean.js → reference_extensions.md.ZAVUyuEX.lean.js} +0 -0
- /package/dist/docs/assets/{reference_http-api.md.oySXBO8o.lean.js → reference_http-api.md.BwaCo-VO.lean.js} +0 -0
- /package/dist/docs/assets/{reference_sessions.md.CueyOHSL.lean.js → reference_sessions.md.CyXV1MUw.lean.js} +0 -0
- /package/dist/docs/assets/{skills_framework-map.md.D-tFZhFS.lean.js → skills_framework-map.md.BxLSOhSY.lean.js} +0 -0
|
@@ -1,19 +1,17 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* File-backed `defineStorage` helper: a file-per-key KV store plus
|
|
3
|
-
* file-backed `evals`
|
|
2
|
+
* File-backed `defineStorage` helper: a file-per-key KV store plus a
|
|
3
|
+
* file-backed `evals` table.
|
|
4
4
|
*
|
|
5
5
|
* Implements the whole `defineStorage` surface with zero external
|
|
6
6
|
* dependencies: the four KV methods against a flat directory of JSON files
|
|
7
7
|
* (one file per key, filename = URI-encoded key), the `cas`
|
|
8
8
|
* group (single-process conditional writes — see the `cas` member below),
|
|
9
|
-
* eval runs as
|
|
10
|
-
*
|
|
11
|
-
*
|
|
12
|
-
*
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
* overwriting each other's history. Swap this for a real backend
|
|
16
|
-
* (Postgres, S3, …) in production; the contracts are identical.
|
|
9
|
+
* and eval runs as `eval-runs/<agent>/<runId>.json`. KV keys carry the
|
|
10
|
+
* agent name inside the framework key scheme, but the evals table has no
|
|
11
|
+
* such scheme — the agent subdirectory keeps agents sharing one storage
|
|
12
|
+
* `dir` from mixing or overwriting each other's history. Swap this for a
|
|
13
|
+
* real backend (Postgres, S3, …) in production; the contracts are
|
|
14
|
+
* identical.
|
|
17
15
|
*
|
|
18
16
|
* Layout notes:
|
|
19
17
|
* - KV filenames encode the full key (`encodeURIComponent(key) + ".json"`),
|
|
@@ -29,7 +27,6 @@
|
|
|
29
27
|
|
|
30
28
|
import { createHash, randomUUID } from "node:crypto";
|
|
31
29
|
import {
|
|
32
|
-
appendFile,
|
|
33
30
|
mkdir,
|
|
34
31
|
readdir,
|
|
35
32
|
readFile,
|
|
@@ -38,10 +35,8 @@ import {
|
|
|
38
35
|
writeFile,
|
|
39
36
|
} from "node:fs/promises";
|
|
40
37
|
import { isAbsolute, join } from "node:path";
|
|
41
|
-
import type { ABSnapshot } from "../ab.js";
|
|
42
38
|
import type { EvalRunSnapshot } from "../evals.js";
|
|
43
39
|
import type {
|
|
44
|
-
StorageABTable,
|
|
45
40
|
StorageCasTable,
|
|
46
41
|
StorageConfig,
|
|
47
42
|
StorageContext,
|
|
@@ -63,7 +58,6 @@ type FileKvMethods = Required<
|
|
|
63
58
|
> & {
|
|
64
59
|
cas: StorageCasTable;
|
|
65
60
|
evals: StorageEvalsTable;
|
|
66
|
-
abs: StorageABTable;
|
|
67
61
|
};
|
|
68
62
|
|
|
69
63
|
/** File-backed `defineStorage` methods, ready to spread into `defineStorage({...})`. */
|
|
@@ -72,12 +66,10 @@ export function fileKv(options?: FileKvOptions): FileKvMethods {
|
|
|
72
66
|
const dir = options?.dir ?? ".agent-serve/kv";
|
|
73
67
|
return isAbsolute(dir) ? dir : join(ctx.projectRoot, dir);
|
|
74
68
|
};
|
|
75
|
-
// The evals
|
|
76
|
-
//
|
|
69
|
+
// The evals table is scoped per agent (KV keys already carry the agent
|
|
70
|
+
// name via the framework key scheme).
|
|
77
71
|
const evalRunsDir = (ctx: StorageContext): string =>
|
|
78
72
|
join(resolveDir(ctx), "eval-runs", encodeURIComponent(ctx.agentName));
|
|
79
|
-
const abDir = (ctx: StorageContext): string =>
|
|
80
|
-
join(resolveDir(ctx), "ab", encodeURIComponent(ctx.agentName));
|
|
81
73
|
const filePath = (ctx: StorageContext, key: string): string =>
|
|
82
74
|
join(resolveDir(ctx), `${encodeURIComponent(key)}.json`);
|
|
83
75
|
const readRaw = async (
|
|
@@ -270,39 +262,6 @@ export function fileKv(options?: FileKvOptions): FileKvMethods {
|
|
|
270
262
|
return runs;
|
|
271
263
|
},
|
|
272
264
|
},
|
|
273
|
-
|
|
274
|
-
// A/B metrics: append-only sample log + latest aggregate snapshot,
|
|
275
|
-
// both under ab/<agent>/.
|
|
276
|
-
abs: {
|
|
277
|
-
async putSample(sample, ctx): Promise<void> {
|
|
278
|
-
const dir = abDir(ctx);
|
|
279
|
-
await mkdir(dir, { recursive: true });
|
|
280
|
-
await appendFile(
|
|
281
|
-
join(dir, "samples.ndjson"),
|
|
282
|
-
`${JSON.stringify(sample)}\n`,
|
|
283
|
-
"utf8"
|
|
284
|
-
);
|
|
285
|
-
},
|
|
286
|
-
async putSnapshot(snapshot, ctx): Promise<void> {
|
|
287
|
-
await writeJsonAtomic({
|
|
288
|
-
dir: abDir(ctx),
|
|
289
|
-
fileName: "snapshot.json",
|
|
290
|
-
value: snapshot,
|
|
291
|
-
});
|
|
292
|
-
},
|
|
293
|
-
async getSnapshot(ctx): Promise<ABSnapshot | undefined> {
|
|
294
|
-
try {
|
|
295
|
-
return JSON.parse(
|
|
296
|
-
await readFile(join(abDir(ctx), "snapshot.json"), "utf8")
|
|
297
|
-
) as ABSnapshot;
|
|
298
|
-
} catch (error) {
|
|
299
|
-
if ((error as NodeJS.ErrnoException).code === "ENOENT") {
|
|
300
|
-
return undefined;
|
|
301
|
-
}
|
|
302
|
-
throw error;
|
|
303
|
-
}
|
|
304
|
-
},
|
|
305
|
-
},
|
|
306
265
|
};
|
|
307
266
|
}
|
|
308
267
|
|
package/src/storage-protocol.ts
CHANGED
|
@@ -39,10 +39,9 @@ const DURABLE_SESSION_RECORD_KEY_RE =
|
|
|
39
39
|
* | `{root}/{agent}/continuation/{channelId}/{token}` | `{ sessionId }` |
|
|
40
40
|
* | `{root}/{agent}/kv/{key}` | Author JSON via `HostContext.kv` |
|
|
41
41
|
*
|
|
42
|
-
* The `eval-runs`
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
* sees them.
|
|
42
|
+
* The `eval-runs` family is minted only by the table `defineStorage`
|
|
43
|
+
* derives over the KV core; a backend that authors a dedicated
|
|
44
|
+
* `StorageConfig.evals` group never sees it.
|
|
46
45
|
*/
|
|
47
46
|
function createStorageKeys(root: string) {
|
|
48
47
|
return {
|
|
@@ -94,19 +93,6 @@ function createStorageKeys(root: string) {
|
|
|
94
93
|
evalRun: (agent: string, runId: string): string =>
|
|
95
94
|
`${root}/${agent}/eval-runs/${keySegment(runId)}`,
|
|
96
95
|
evalRunsPrefix: (agent: string): string => `${root}/${agent}/eval-runs/`,
|
|
97
|
-
/**
|
|
98
|
-
* One A/B metric sample (derived `abs` table); the segments mirror the
|
|
99
|
-
* dedicated table's row identity (experiment + sessionId + at).
|
|
100
|
-
*/
|
|
101
|
-
abSample: (
|
|
102
|
-
agent: string,
|
|
103
|
-
experiment: string,
|
|
104
|
-
sessionId: string,
|
|
105
|
-
at: string
|
|
106
|
-
): string =>
|
|
107
|
-
`${root}/${agent}/ab-samples/${keySegment(experiment)}/${keySegment(sessionId)}/${keySegment(at)}`,
|
|
108
|
-
/** Latest aggregate A/B snapshot (derived `abs` table, LWW). */
|
|
109
|
-
abSnapshot: (agent: string): string => `${root}/${agent}/ab-snapshot`,
|
|
110
96
|
} as const;
|
|
111
97
|
}
|
|
112
98
|
|
package/src/storage.ts
CHANGED
|
@@ -4,16 +4,15 @@
|
|
|
4
4
|
* Author `agent/storage.ts` with {@link defineStorage} to mirror the
|
|
5
5
|
* framework's durable state into storage you own (a database, S3, a data
|
|
6
6
|
* pipeline, …). Without it, state lives under `--state-root` on local disk
|
|
7
|
-
* only, and eval
|
|
7
|
+
* only, and eval history stays in process memory.
|
|
8
8
|
*
|
|
9
9
|
* The sink is a plain key-value store — put/get/delete/list, no schema —
|
|
10
10
|
* plus a conditional-write group ({@link StorageConfig.cas}; optional).
|
|
11
11
|
* Implementing that small KV core is enough for
|
|
12
|
-
* FULL functionality: eval-run
|
|
13
|
-
*
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* not as required-or-lose-history hooks:
|
|
12
|
+
* FULL functionality: eval-run history is derived over the core when the
|
|
13
|
+
* optional dedicated table ({@link StorageConfig.evals}) is not authored —
|
|
14
|
+
* that group exists as a backend-native optimization (a real table, an
|
|
15
|
+
* analytics pipeline), not as a required-or-lose-history hook:
|
|
17
16
|
*
|
|
18
17
|
* ```ts
|
|
19
18
|
* import { defineStorage } from "@cursor/july/storage";
|
|
@@ -25,7 +24,6 @@
|
|
|
25
24
|
* list: (prefix) => db.listByPrefix(prefix), // [{ key, value }] in key order
|
|
26
25
|
* cas: { getWithVersion: ..., putIfAbsent: ..., putIfVersion: ..., listKeys: ... },
|
|
27
26
|
* evals: { put: ..., delete: ..., list: ... }, // eval-runs table
|
|
28
|
-
* abs: { putSample: ... }, // A/B table
|
|
29
27
|
* });
|
|
30
28
|
* ```
|
|
31
29
|
*
|
|
@@ -51,9 +49,7 @@
|
|
|
51
49
|
* interface is the durable mirror.
|
|
52
50
|
*/
|
|
53
51
|
|
|
54
|
-
import type { ABMetricSample } from "./ab.js";
|
|
55
52
|
import type { EvalRunSnapshot } from "./evals.js";
|
|
56
|
-
import type { ABSnapshot } from "./internal/ab-snapshot.js";
|
|
57
53
|
import { brandDefinition } from "./internal/brand.js";
|
|
58
54
|
import { storageKeys } from "./storage-protocol.js";
|
|
59
55
|
import type { JsonValue, KvCasResult, KvVersionedEntry } from "./types.js";
|
|
@@ -161,24 +157,6 @@ export interface StorageEvalsTable {
|
|
|
161
157
|
list(ctx: StorageContext): EvalRunSnapshot[] | Promise<EvalRunSnapshot[]>;
|
|
162
158
|
}
|
|
163
159
|
|
|
164
|
-
/**
|
|
165
|
-
* Dedicated table for live A/B metrics: one row per cumulative metric
|
|
166
|
-
* sample (unique per `experiment` + `sessionId` + `at` — one boundary
|
|
167
|
-
* event emits a sample per enrolled experiment), plus — optionally — the latest
|
|
168
|
-
* aggregate snapshot so a replacement host with no local sessions can
|
|
169
|
-
* still serve the A/Bs surface.
|
|
170
|
-
*/
|
|
171
|
-
export interface StorageABTable {
|
|
172
|
-
/** Append one cumulative metric sample (turn complete/fail). */
|
|
173
|
-
putSample(sample: ABMetricSample, ctx: StorageContext): void | Promise<void>;
|
|
174
|
-
/** Upsert the latest aggregate snapshot (framework-throttled). Optional. */
|
|
175
|
-
putSnapshot?(snapshot: ABSnapshot, ctx: StorageContext): void | Promise<void>;
|
|
176
|
-
/** Latest saved aggregate snapshot (replacement-host backfill). Optional. */
|
|
177
|
-
getSnapshot?(
|
|
178
|
-
ctx: StorageContext
|
|
179
|
-
): ABSnapshot | undefined | null | Promise<ABSnapshot | undefined | null>;
|
|
180
|
-
}
|
|
181
|
-
|
|
182
160
|
/**
|
|
183
161
|
* Conditional writes (CAS) — the coordination tier of the storage backend
|
|
184
162
|
* contract. Plain storage works without it, so existing backends keep
|
|
@@ -186,9 +164,8 @@ export interface StorageABTable {
|
|
|
186
164
|
* it, so implementing this group yourself only comes up for BYO storage.
|
|
187
165
|
*
|
|
188
166
|
* Grouped under {@link StorageConfig.cas} rather than as loose methods —
|
|
189
|
-
* matching the `evals`
|
|
190
|
-
*
|
|
191
|
-
* half-implementation.
|
|
167
|
+
* matching the `evals` table group — so `defineStorage` validates the
|
|
168
|
+
* whole group at once: there is no meaningful half-implementation.
|
|
192
169
|
*
|
|
193
170
|
* Version tokens are opaque per-key strings that change on every
|
|
194
171
|
* successful write (counter, UUID, content hash — whatever is cheap for
|
|
@@ -234,14 +211,6 @@ export interface StorageConfig {
|
|
|
234
211
|
* memory (lost on restart).
|
|
235
212
|
*/
|
|
236
213
|
evals?: StorageEvalsTable;
|
|
237
|
-
/**
|
|
238
|
-
* Dedicated A/B table — a backend-native optimization, not a
|
|
239
|
-
* requirement. When omitted, `defineStorage` derives it over the KV
|
|
240
|
-
* core: `putSample` and `putSnapshot` need only core `put` (always
|
|
241
|
-
* present), `getSnapshot` additionally needs core `get`. Session event
|
|
242
|
-
* logs remain the assignment/fold source of truth either way.
|
|
243
|
-
*/
|
|
244
|
-
abs?: StorageABTable;
|
|
245
214
|
/**
|
|
246
215
|
* Conditional writes (CAS). Optional for plain storage — existing
|
|
247
216
|
* backends keep working without it. The built-in backends (`fileKv`,
|
|
@@ -260,7 +229,7 @@ export interface StorageConfig {
|
|
|
260
229
|
delete?(key: string, ctx: StorageContext): void | Promise<void>;
|
|
261
230
|
/**
|
|
262
231
|
* Point lookup. Optional — required for **lazy restore** (resolving a
|
|
263
|
-
* continuation token on a replacement host)
|
|
232
|
+
* continuation token on a replacement host).
|
|
264
233
|
* Return `undefined`/`null` only for a **definitive** miss: on the lazy
|
|
265
234
|
* restore path a throw propagates and fails the follow-up (retryable) —
|
|
266
235
|
* a store outage must not read as "unknown token", which would fork the
|
|
@@ -346,34 +315,16 @@ export function defineStorage(config: StorageConfig): StorageDefinition {
|
|
|
346
315
|
);
|
|
347
316
|
}
|
|
348
317
|
}
|
|
349
|
-
if (config.abs !== undefined) {
|
|
350
|
-
if (typeof config.abs.putSample !== "function") {
|
|
351
|
-
throw new Error(
|
|
352
|
-
"defineStorage: abs.putSample must be a function when the abs table is set"
|
|
353
|
-
);
|
|
354
|
-
}
|
|
355
|
-
for (const hook of ["putSnapshot", "getSnapshot"] as const) {
|
|
356
|
-
const value = config.abs[hook];
|
|
357
|
-
if (value !== undefined && typeof value !== "function") {
|
|
358
|
-
throw new Error(
|
|
359
|
-
`defineStorage: abs.${hook} must be a function when set`
|
|
360
|
-
);
|
|
361
|
-
}
|
|
362
|
-
}
|
|
363
|
-
}
|
|
364
318
|
// Validate eagerly so a bad policy fails at discovery, not first flush.
|
|
365
319
|
resolveStoragePolicy(config.policy);
|
|
366
320
|
// A backend that implements only the KV core gets full functionality:
|
|
367
|
-
// the dedicated
|
|
368
|
-
// the core when absent.
|
|
321
|
+
// the dedicated table is a backend-native optimization, derived over
|
|
322
|
+
// the core when absent. An authored group always wins.
|
|
369
323
|
const derivedEvals =
|
|
370
324
|
config.evals === undefined ? deriveEvalsTable(config) : undefined;
|
|
371
|
-
const derivedAbs =
|
|
372
|
-
config.abs === undefined ? deriveAbsTable(config) : undefined;
|
|
373
325
|
return brandDefinition("storage", {
|
|
374
326
|
...config,
|
|
375
327
|
...(derivedEvals === undefined ? {} : { evals: derivedEvals }),
|
|
376
|
-
...(derivedAbs === undefined ? {} : { abs: derivedAbs }),
|
|
377
328
|
});
|
|
378
329
|
}
|
|
379
330
|
|
|
@@ -408,48 +359,6 @@ function deriveEvalsTable(
|
|
|
408
359
|
};
|
|
409
360
|
}
|
|
410
361
|
|
|
411
|
-
/**
|
|
412
|
-
* A/B table over the KV core. Each sample lands as its own key (identity
|
|
413
|
-
* = experiment + sessionId + at, matching the dedicated table's row
|
|
414
|
-
* uniqueness): appending to one array value would need read-modify-write
|
|
415
|
-
* — lost updates under concurrent writers without CAS, and unbounded
|
|
416
|
-
* value growth — while a key per sample keeps `putSample` a blind put
|
|
417
|
-
* with real append-only semantics. The aggregate snapshot lives at one
|
|
418
|
-
* fixed key via plain `put` (last-write-wins is correct for "latest").
|
|
419
|
-
* Requires only core `put`; `getSnapshot` is included when core `get`
|
|
420
|
-
* exists.
|
|
421
|
-
*/
|
|
422
|
-
function deriveAbsTable(config: StorageConfig): StorageABTable {
|
|
423
|
-
const get = config.get;
|
|
424
|
-
return {
|
|
425
|
-
putSample: (sample, ctx) =>
|
|
426
|
-
config.put(
|
|
427
|
-
storageKeys.abSample(
|
|
428
|
-
ctx.agentName,
|
|
429
|
-
sample.experiment,
|
|
430
|
-
sample.sessionId,
|
|
431
|
-
sample.at
|
|
432
|
-
),
|
|
433
|
-
sample as unknown as JsonValue,
|
|
434
|
-
ctx
|
|
435
|
-
),
|
|
436
|
-
putSnapshot: (snapshot, ctx) =>
|
|
437
|
-
config.put(
|
|
438
|
-
storageKeys.abSnapshot(ctx.agentName),
|
|
439
|
-
snapshot as unknown as JsonValue,
|
|
440
|
-
ctx
|
|
441
|
-
),
|
|
442
|
-
...(get === undefined
|
|
443
|
-
? {}
|
|
444
|
-
: {
|
|
445
|
-
getSnapshot: async (ctx: StorageContext) => {
|
|
446
|
-
const value = await get(storageKeys.abSnapshot(ctx.agentName), ctx);
|
|
447
|
-
return (value ?? undefined) as ABSnapshot | undefined;
|
|
448
|
-
},
|
|
449
|
-
}),
|
|
450
|
-
};
|
|
451
|
-
}
|
|
452
|
-
|
|
453
362
|
// ============================================================================
|
|
454
363
|
// Policy resolution
|
|
455
364
|
// ============================================================================
|
package/src/types.ts
CHANGED
|
@@ -10,7 +10,6 @@
|
|
|
10
10
|
|
|
11
11
|
import type { InteractionUpdate, SDKCustomTool, ToolName } from "@cursor/sdk";
|
|
12
12
|
import type { z } from "zod";
|
|
13
|
-
import type { ABConfigFile } from "./ab.js";
|
|
14
13
|
import type { FileSystem } from "./filesystem.js";
|
|
15
14
|
import type {
|
|
16
15
|
ContinuationClaim,
|
|
@@ -55,7 +54,6 @@ export type DefinitionKind =
|
|
|
55
54
|
| "reminder"
|
|
56
55
|
| "hook"
|
|
57
56
|
| "eval"
|
|
58
|
-
| "ab"
|
|
59
57
|
| "storage"
|
|
60
58
|
| "artifacts"
|
|
61
59
|
| "otel"
|
|
@@ -1202,8 +1200,8 @@ export type DisabledConnectionDefinition =
|
|
|
1202
1200
|
/**
|
|
1203
1201
|
* `export default disable()` / `disableSkill()` / `disableHook()` /
|
|
1204
1202
|
* `disableChannel()` / `disableSchedule()` / `disableSubagent()` /
|
|
1205
|
-
* `disableInstructions()` / `
|
|
1206
|
-
*
|
|
1203
|
+
* `disableInstructions()` / `disableArtifacts()` in a directory mount
|
|
1204
|
+
* removes that contribution from the matching overlay slot.
|
|
1207
1205
|
*/
|
|
1208
1206
|
export type DisabledDefinition = BrandedDefinition<"disabled">;
|
|
1209
1207
|
|
|
@@ -1232,8 +1230,6 @@ export interface DiscoveredExtension {
|
|
|
1232
1230
|
instructions: boolean;
|
|
1233
1231
|
/** Workspace seed paths the mount contributed. */
|
|
1234
1232
|
seedFiles: string[];
|
|
1235
|
-
/** Composed A/B experiment names (`<ns>__<name>`). */
|
|
1236
|
-
abs: string[];
|
|
1237
1233
|
/** Composed artifact kind names (`<ns>__<kind>`). */
|
|
1238
1234
|
artifactKinds: string[];
|
|
1239
1235
|
}
|
|
@@ -1615,15 +1611,6 @@ export interface PendingAuth {
|
|
|
1615
1611
|
|
|
1616
1612
|
export type SessionEventPayload =
|
|
1617
1613
|
| { type: "session.started"; data: { channelId: string; dryRun?: boolean } }
|
|
1618
|
-
| {
|
|
1619
|
-
/**
|
|
1620
|
-
* Sticky A/B enrollment for one experiment (`defineAB` under `agent/ab`).
|
|
1621
|
-
* Appended at session creation (before the first turn). `variant` is a
|
|
1622
|
-
* key of the experiment's `variants`, or `null` for sticky skip.
|
|
1623
|
-
*/
|
|
1624
|
-
type: "ab.assigned";
|
|
1625
|
-
data: { experiment: string; variant: string | null };
|
|
1626
|
-
}
|
|
1627
1614
|
| {
|
|
1628
1615
|
/** Cursor SDK agent id is known (cloud: `bc-…`; local: session id). */
|
|
1629
1616
|
type: "agent.bound";
|
|
@@ -1813,8 +1800,8 @@ export interface TurnUsage {
|
|
|
1813
1800
|
|
|
1814
1801
|
/**
|
|
1815
1802
|
* Dollar cost of one turn's token usage (one agent loop pass).
|
|
1816
|
-
* Recorded on `turn.completed` events so traces, the playground,
|
|
1817
|
-
*
|
|
1803
|
+
* Recorded on `turn.completed` events so traces, the playground, and the
|
|
1804
|
+
* CLI can aggregate spend. Computed by
|
|
1818
1805
|
* `POST /v1/models/estimate-cost` — billed usage events when available
|
|
1819
1806
|
* (credits, discounts, CTF), otherwise live catalog pricing.
|
|
1820
1807
|
*/
|
|
@@ -1841,8 +1828,7 @@ export type SessionMode = "chat" | "task";
|
|
|
1841
1828
|
|
|
1842
1829
|
/**
|
|
1843
1830
|
* Why the session exists. `"eval"` is regression traffic (`defineEval` /
|
|
1844
|
-
* `agent-sdk eval` / playground Evals)
|
|
1845
|
-
* enrollment. Default `"live"`.
|
|
1831
|
+
* `agent-sdk eval` / playground Evals). Default `"live"`.
|
|
1846
1832
|
*/
|
|
1847
1833
|
export type SessionPurpose = "live" | "eval";
|
|
1848
1834
|
|
|
@@ -1859,12 +1845,6 @@ export interface SessionInfo {
|
|
|
1859
1845
|
asOf?: string;
|
|
1860
1846
|
auth: AuthContext | null;
|
|
1861
1847
|
title?: string;
|
|
1862
|
-
/**
|
|
1863
|
-
* Sticky A/B arms for this session (`defineAB`): experiment name → variant
|
|
1864
|
-
* key, or `null` for sticky skip. Present after enrollment at session
|
|
1865
|
-
* create (live traffic only). Tools/hooks/harness overlays read this.
|
|
1866
|
-
*/
|
|
1867
|
-
abs?: Readonly<Record<string, string | null>>;
|
|
1868
1848
|
/**
|
|
1869
1849
|
* Channel-local continuation key when the session is addressable for
|
|
1870
1850
|
* follow-ups / reminders. Null when the session is not re-keyable.
|
|
@@ -1885,20 +1865,14 @@ export interface SessionRecord {
|
|
|
1885
1865
|
channelId: string;
|
|
1886
1866
|
mode: SessionMode;
|
|
1887
1867
|
/**
|
|
1888
|
-
* `"eval"` for harness sessions
|
|
1889
|
-
*
|
|
1868
|
+
* `"eval"` for harness sessions. Older records omit this (treated as
|
|
1869
|
+
* `"live"`).
|
|
1890
1870
|
*/
|
|
1891
1871
|
purpose?: SessionPurpose;
|
|
1892
1872
|
/** Frozen at create from {@link SendMessageOptions.dryRun}. */
|
|
1893
1873
|
dryRun?: boolean;
|
|
1894
1874
|
/** Frozen at create from {@link SendMessageOptions.asOf}. */
|
|
1895
1875
|
asOf?: string;
|
|
1896
|
-
/**
|
|
1897
|
-
* Denormalized sticky A/B arms (mirrors durable `ab.assigned` events) so
|
|
1898
|
-
* the agent loop / tools can read arms without re-folding the log. Source
|
|
1899
|
-
* of truth for stickiness remains the event stream.
|
|
1900
|
-
*/
|
|
1901
|
-
abs?: Record<string, string | null>;
|
|
1902
1876
|
/** Channel-local continuation key; null when the session is not addressable. */
|
|
1903
1877
|
continuationKey: string | null;
|
|
1904
1878
|
/**
|
|
@@ -2083,8 +2057,8 @@ export interface SendMessageOptions {
|
|
|
2083
2057
|
/** Session display title (applied when creating a new session). */
|
|
2084
2058
|
title?: string;
|
|
2085
2059
|
/**
|
|
2086
|
-
* Session purpose at create time. `"eval"`
|
|
2087
|
-
*
|
|
2060
|
+
* Session purpose at create time. `"eval"` marks regression traffic so
|
|
2061
|
+
* hooks, `defineResult`, and telemetry can tell it from live sessions.
|
|
2088
2062
|
*/
|
|
2089
2063
|
purpose?: SessionPurpose;
|
|
2090
2064
|
/**
|
|
@@ -2574,6 +2548,14 @@ export interface ChannelMeta {
|
|
|
2574
2548
|
* `deploymentEventTypes`.
|
|
2575
2549
|
*/
|
|
2576
2550
|
factoryEventTypes?: readonly string[];
|
|
2551
|
+
/**
|
|
2552
|
+
* For Slack packs: the Events API event types this channel dispatches on
|
|
2553
|
+
* (`app_mention`, `message`), derived from `engagement`. Extracted into
|
|
2554
|
+
* the deploy manifest as `eventTypes` so hosted v2 fanout subscribes to
|
|
2555
|
+
* exactly these. Local Socket Mode ignores it (the socket delivers
|
|
2556
|
+
* whatever the app manifest subscribed to).
|
|
2557
|
+
*/
|
|
2558
|
+
slackEventTypes?: readonly string[];
|
|
2577
2559
|
/**
|
|
2578
2560
|
* For Slack packs with the opt-in channel watch: the allowlisted channels
|
|
2579
2561
|
* (ids or `#names`) this channel dispatches on without a mention. Surfaced
|
|
@@ -3226,15 +3208,6 @@ export interface DiscoveredHook {
|
|
|
3226
3208
|
definition: HookDefinition;
|
|
3227
3209
|
}
|
|
3228
3210
|
|
|
3229
|
-
/** Live A/B metrics experiment (`agent/ab.ts` or `agent/ab/<name>.ts`). */
|
|
3230
|
-
export interface DiscoveredAB {
|
|
3231
|
-
name: string;
|
|
3232
|
-
/** File stem the experiment was loaded from (`ab` or a path under `ab/`). */
|
|
3233
|
-
source?: string;
|
|
3234
|
-
/** Branded `defineAB({ ... })` config (see `@cursor/july/ab`). */
|
|
3235
|
-
definition: BrandedDefinition<"ab">;
|
|
3236
|
-
}
|
|
3237
|
-
|
|
3238
3211
|
export interface SeedFile {
|
|
3239
3212
|
/** Path inside the session workspace. */
|
|
3240
3213
|
relativePath: string;
|
|
@@ -3315,10 +3288,6 @@ export interface AgentProject {
|
|
|
3315
3288
|
/** Named reminder handlers from `agent/reminders/*` (optional / additive). */
|
|
3316
3289
|
reminders?: DiscoveredReminder[];
|
|
3317
3290
|
hooks: DiscoveredHook[];
|
|
3318
|
-
/** Live A/B metric experiments (`defineAB`). */
|
|
3319
|
-
abs: DiscoveredAB[];
|
|
3320
|
-
/** Optional `agent/ab.config.ts` (`defineABConfig`). */
|
|
3321
|
-
abConfig?: ABConfigFile;
|
|
3322
3291
|
/** Optional `agent/storage.ts` (`defineStorage`). */
|
|
3323
3292
|
storage?: StorageDefinition;
|
|
3324
3293
|
/** Optional `agent/artifacts.ts` (`defineArtifacts`). */
|
|
@@ -3415,6 +3384,8 @@ export interface AgentProjectInfo {
|
|
|
3415
3384
|
deploymentEventTypes?: readonly string[];
|
|
3416
3385
|
/** Change Monitor checkpoint or Factory issue event types the channel dispatches on, when declared. */
|
|
3417
3386
|
factoryEventTypes?: readonly string[];
|
|
3387
|
+
/** Slack Events API event types the channel dispatches on, when declared. */
|
|
3388
|
+
slackEventTypes?: readonly string[];
|
|
3418
3389
|
/** Slack channels watched for posts (opt-in channel watch), when declared. */
|
|
3419
3390
|
slackChannelPosts?: readonly string[];
|
|
3420
3391
|
}>;
|
|
@@ -3422,14 +3393,6 @@ export interface AgentProjectInfo {
|
|
|
3422
3393
|
/** Named reminder handlers (`agent/reminders/<name>.ts`) when present. */
|
|
3423
3394
|
reminders?: Array<{ name: string }>;
|
|
3424
3395
|
hooks: string[];
|
|
3425
|
-
/** Live A/B experiment names (`defineAB` under `agent/ab`). */
|
|
3426
|
-
abs: string[];
|
|
3427
|
-
/** Playground fold / durable-sink meta from `agent/ab.config.ts`. */
|
|
3428
|
-
abConfig?: {
|
|
3429
|
-
maxPlaygroundSessions?: number;
|
|
3430
|
-
durableSamples: boolean;
|
|
3431
|
-
durableSnapshots: boolean;
|
|
3432
|
-
};
|
|
3433
3396
|
/** Project storage sink from `agent/storage.ts`, when authored. */
|
|
3434
3397
|
storage?: { name?: string };
|
|
3435
3398
|
otel?: { serviceName?: string; enabled: true };
|
package/templates/demo/README.md
CHANGED
|
@@ -7,19 +7,22 @@ walkthrough and comments the result.
|
|
|
7
7
|
npx @cursor/july init ./my-demo --template demo
|
|
8
8
|
```
|
|
9
9
|
|
|
10
|
+
`init` asks which repos to watch. Skip the prompt with
|
|
11
|
+
`--var repos=owner/repo`.
|
|
12
|
+
|
|
10
13
|
## Run
|
|
11
14
|
|
|
15
|
+
Connect GitHub in Cursor for those repos. Then sign the host in:
|
|
16
|
+
|
|
12
17
|
```bash
|
|
13
18
|
agent-sdk login
|
|
14
19
|
agent-sdk dev
|
|
15
20
|
```
|
|
16
21
|
|
|
17
|
-
In the playground, run `/queue/pr` with a PR URL or `owner/repo#N
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
webhooks (`GITHUB_WEBHOOK_SECRET`). The host needs `GITHUB_TOKEN` or
|
|
22
|
-
`gh auth` to read the PR and comment.
|
|
22
|
+
In the playground, run `/queue/pr` with a PR URL or `owner/repo#N` from
|
|
23
|
+
a watched repo. On GitHub, label a PR `demo` or comment `/demo`. Events
|
|
24
|
+
and API calls use your Cursor GitHub connection. Turns are sandboxed
|
|
25
|
+
with `read` and `grep` only.
|
|
23
26
|
|
|
24
27
|
```text
|
|
25
28
|
POST /<slug>/v1/channels/queue/pr
|
|
@@ -29,5 +32,6 @@ POST /<slug>/v1/channels/queue/pr
|
|
|
29
32
|
|
|
30
33
|
## Files to edit
|
|
31
34
|
|
|
35
|
+
- `agent/lib/repos.ts`: watched repos
|
|
32
36
|
- `agent/instructions.md`: how to record
|
|
33
37
|
- `evals/demo.eval.ts`: smoke case
|
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
parseGitHubPrRef,
|
|
7
7
|
} from "@cursor/july/channels/github";
|
|
8
8
|
import { startDemo } from "../lib/collect.js";
|
|
9
|
+
import { REPOS } from "../lib/repos.js";
|
|
9
10
|
|
|
10
11
|
let send: SendMessageFn | undefined;
|
|
11
12
|
|
|
@@ -21,6 +22,7 @@ function wake(url: string, github: GitHubHandle) {
|
|
|
21
22
|
export default githubChannel({
|
|
22
23
|
botName: "demo-agent",
|
|
23
24
|
webhookEvents: ["pull_request", "issue_comment"],
|
|
25
|
+
cursorAccount: { repos: REPOS },
|
|
24
26
|
deliverReplies: false,
|
|
25
27
|
onStart: async (args: ChannelStartArgs) => {
|
|
26
28
|
send = args.send;
|
|
@@ -2,6 +2,7 @@ import { defineChannel, POST } from "@cursor/july/channels";
|
|
|
2
2
|
import { parseGitHubPrRef } from "@cursor/july/channels/github";
|
|
3
3
|
import { z } from "zod";
|
|
4
4
|
import { startDemo } from "../lib/collect.js";
|
|
5
|
+
import { REPOS, watches } from "../lib/repos.js";
|
|
5
6
|
|
|
6
7
|
export default defineChannel({
|
|
7
8
|
routes: [
|
|
@@ -12,9 +13,12 @@ export default defineChannel({
|
|
|
12
13
|
}),
|
|
13
14
|
handler: async (_req, { send, host, body }) => {
|
|
14
15
|
const ref = parseGitHubPrRef(body.pr);
|
|
15
|
-
if (ref === undefined) {
|
|
16
|
+
if (ref === undefined || !watches(`${ref.owner}/${ref.repo}`)) {
|
|
16
17
|
return Response.json(
|
|
17
|
-
{
|
|
18
|
+
{
|
|
19
|
+
ok: false,
|
|
20
|
+
error: `need a PR URL or owner/repo#N in ${REPOS.join(", ")}`,
|
|
21
|
+
},
|
|
18
22
|
{ status: 400 }
|
|
19
23
|
);
|
|
20
24
|
}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
{
|
|
2
|
+
"questions": [
|
|
3
|
+
{
|
|
4
|
+
"id": "repos",
|
|
5
|
+
"prompt": "Which GitHub repos should this agent record walkthroughs for?",
|
|
6
|
+
"hint": "Comma-separated owner/repo. One GitHub owner.",
|
|
7
|
+
"placeholder": "acme/api, acme/web",
|
|
8
|
+
"parse": "owner-repo-list"
|
|
9
|
+
}
|
|
10
|
+
],
|
|
11
|
+
"replace": [
|
|
12
|
+
{
|
|
13
|
+
"file": "agent/lib/repos.ts",
|
|
14
|
+
"find": "[\"owner/repo\"]",
|
|
15
|
+
"answer": "repos",
|
|
16
|
+
"as": "json-array"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"file": "README.md",
|
|
20
|
+
"find": "owner/repo",
|
|
21
|
+
"answer": "repos",
|
|
22
|
+
"as": "first"
|
|
23
|
+
}
|
|
24
|
+
]
|
|
25
|
+
}
|