@cursor/july 0.1.39 → 0.1.41
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 +4 -3
- package/dist/bin/agent-serve.js +28 -9
- package/dist/channels/slack/api.d.ts.map +1 -1
- package/dist/channels/slack/api.js +18 -8
- package/dist/channels/slack/attachments.d.ts +82 -0
- package/dist/channels/slack/attachments.d.ts.map +1 -0
- package/dist/channels/slack/attachments.js +520 -0
- package/dist/channels/slack/cursor-account.d.ts +7 -1
- package/dist/channels/slack/cursor-account.d.ts.map +1 -1
- package/dist/channels/slack/cursor-account.js +2 -2
- package/dist/channels/slack/defaults.d.ts.map +1 -1
- package/dist/channels/slack/defaults.js +26 -17
- package/dist/channels/slack/dispatch.d.ts +4 -3
- package/dist/channels/slack/dispatch.d.ts.map +1 -1
- package/dist/channels/slack/dispatch.js +84 -21
- package/dist/channels/slack/inbound.d.ts +6 -0
- package/dist/channels/slack/inbound.d.ts.map +1 -1
- package/dist/channels/slack/inbound.js +48 -2
- package/dist/channels/slack/index.d.ts +1 -0
- package/dist/channels/slack/index.d.ts.map +1 -1
- package/dist/channels/slack/index.js +1 -0
- package/dist/channels/slack/live-delivery.d.ts.map +1 -1
- package/dist/channels/slack/live-delivery.js +16 -4
- package/dist/channels/slack/manifest.d.ts.map +1 -1
- package/dist/channels/slack/manifest.js +1 -0
- package/dist/channels/slack/slack-channel.d.ts.map +1 -1
- package/dist/channels/slack/slack-channel.js +7 -4
- package/dist/channels/slack/types.d.ts +49 -1
- package/dist/channels/slack/types.d.ts.map +1 -1
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +6 -6
- package/dist/docs/assets/{ab.md.6cLOW7--.js → ab.md.hdxsvX5M.js} +2 -2
- package/dist/docs/assets/{app.BQ8Hihdf.js → app.mIw24pb1.js} +1 -1
- package/dist/docs/assets/{building-with-agents.md.txrcGU2B.js → building-with-agents.md.PeZaZA1P.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.BA7V8dEJ.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.BBCr8Yuy.js → VPLocalSearchBox.hOzpPwrG.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CK_NiGC-.js → theme.BtFhUYmh.js} +2 -2
- package/dist/docs/assets/{deployment.md.CuK5SNjN.js → deployment.md.BHVjVqRa.js} +4 -4
- package/dist/docs/assets/{deployment.md.CuK5SNjN.lean.js → deployment.md.BHVjVqRa.lean.js} +1 -1
- package/dist/docs/assets/{evals.md.BQXI3rXy.js → evals.md.qeoGgPw0.js} +3 -3
- package/dist/docs/assets/example-agents_index.md.xmJ87d_3.js +2 -0
- package/dist/docs/assets/{guides_webhooks.md.BERuBSJW.js → guides_webhooks.md.DB-r_er9.js} +47 -4
- package/dist/docs/assets/{guides_webhooks.md.BERuBSJW.lean.js → guides_webhooks.md.DB-r_er9.lean.js} +1 -1
- package/dist/docs/assets/index.md.BKpbkCa6.js +24 -0
- package/dist/docs/assets/{index.md.CmhptOmN.lean.js → index.md.BKpbkCa6.lean.js} +1 -1
- package/dist/docs/assets/{quickstart.md.C_b6ESpD.js → quickstart.md.rIbfahJM.js} +4 -4
- package/dist/docs/assets/{reference_cli.md.Byvrg8eu.js → reference_cli.md.DqEqQpGn.js} +5 -5
- package/dist/docs/assets/{reference_cli.md.Byvrg8eu.lean.js → reference_cli.md.DqEqQpGn.lean.js} +1 -1
- package/dist/docs/assets/{reference_hooks.md.BGDw4VLm.js → reference_hooks.md.BHeG-vjK.js} +2 -2
- package/dist/docs/assets/{reference_hooks.md.BGDw4VLm.lean.js → reference_hooks.md.BHeG-vjK.lean.js} +1 -1
- package/dist/docs/assets/{storage.md.mQDtIULc.js → storage.md.DcGSnIxX.js} +10 -4
- package/dist/docs/assets/{storage.md.mQDtIULc.lean.js → storage.md.DcGSnIxX.lean.js} +1 -1
- package/dist/docs/assets/troubleshooting.md.CkgwmVI0.js +1 -0
- package/dist/docs/assets/{troubleshooting.md.B5RVX_tL.lean.js → troubleshooting.md.CkgwmVI0.lean.js} +1 -1
- package/dist/docs/building-with-agents.html +5 -5
- package/dist/docs/concepts.html +3 -3
- package/dist/docs/deployment.html +6 -6
- package/dist/docs/evals.html +7 -7
- package/dist/docs/example-agents/approval-buddy.html +3 -3
- package/dist/docs/example-agents/benny.html +3 -3
- package/dist/docs/example-agents/bugbot.html +3 -3
- package/dist/docs/example-agents/codebase-wiki.html +3 -3
- package/dist/docs/example-agents/codeowners-review.html +3 -3
- package/dist/docs/example-agents/concierge.html +3 -3
- package/dist/docs/example-agents/fsd.html +3 -3
- package/dist/docs/example-agents/index.html +5 -5
- package/dist/docs/example-agents/knowledge-base.html +3 -3
- package/dist/docs/example-agents/oncall.html +3 -3
- package/dist/docs/example-agents/security-reviewer.html +3 -3
- package/dist/docs/example-agents/slack-agent.html +3 -3
- package/dist/docs/example-agents/weather-agent.html +3 -3
- package/dist/docs/guides/agent-to-agent.html +3 -3
- package/dist/docs/guides/cloud-runtime.html +3 -3
- package/dist/docs/guides/github.html +3 -3
- package/dist/docs/guides/human-in-the-loop.html +3 -3
- package/dist/docs/guides/mcp-oauth.html +3 -3
- package/dist/docs/guides/slack.html +3 -3
- package/dist/docs/guides/webhooks.html +49 -6
- package/dist/docs/hashmap.json +1 -1
- package/dist/docs/hillclimbing.html +3 -3
- package/dist/docs/index.html +7 -7
- package/dist/docs/quickstart.html +8 -8
- package/dist/docs/reference/agent-config.html +3 -3
- package/dist/docs/reference/artifacts.html +3 -3
- package/dist/docs/reference/channels.html +3 -3
- package/dist/docs/reference/cli.html +8 -8
- package/dist/docs/reference/connections.html +3 -3
- package/dist/docs/reference/hooks.html +5 -5
- package/dist/docs/reference/http-api.html +3 -3
- package/dist/docs/reference/instructions.html +3 -3
- package/dist/docs/reference/playground.html +3 -3
- package/dist/docs/reference/project-layout.html +3 -3
- package/dist/docs/reference/prompt.html +3 -3
- package/dist/docs/reference/schedules.html +3 -3
- package/dist/docs/reference/sessions.html +3 -3
- package/dist/docs/reference/skills.html +3 -3
- package/dist/docs/reference/subagents.html +3 -3
- package/dist/docs/reference/tools.html +3 -3
- package/dist/docs/scaffolding-agents.html +3 -3
- package/dist/docs/storage.html +14 -8
- package/dist/docs/troubleshooting.html +5 -5
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +22 -2
- package/dist/internal/cli-deploy.d.ts +6 -0
- package/dist/internal/cli-deploy.d.ts.map +1 -1
- package/dist/internal/cli-deploy.js +14 -4
- package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
- package/dist/internal/cli-mcp-oauth.js +3 -1
- package/dist/internal/cli-mcp.js +4 -4
- package/dist/internal/cursor-event-relay.d.ts +45 -0
- package/dist/internal/cursor-event-relay.d.ts.map +1 -1
- package/dist/internal/cursor-event-relay.js +96 -2
- package/dist/internal/deploy-client.js +1 -1
- package/dist/internal/discovery.d.ts.map +1 -1
- package/dist/internal/discovery.js +35 -7
- package/dist/internal/distribution.d.ts.map +1 -1
- package/dist/internal/distribution.js +3 -1
- package/dist/internal/durable-session-store.d.ts +48 -0
- package/dist/internal/durable-session-store.d.ts.map +1 -0
- package/dist/internal/durable-session-store.js +86 -0
- package/dist/internal/hosting.d.ts +1 -1
- package/dist/internal/hosting.js +2 -2
- package/dist/internal/init-project.d.ts +34 -0
- package/dist/internal/init-project.d.ts.map +1 -1
- package/dist/internal/init-project.js +121 -2
- package/dist/internal/ledger-serving.d.ts +101 -0
- package/dist/internal/ledger-serving.d.ts.map +1 -0
- package/dist/internal/ledger-serving.js +174 -0
- package/dist/internal/listen-port.d.ts +22 -0
- package/dist/internal/listen-port.d.ts.map +1 -0
- package/dist/internal/listen-port.js +77 -0
- package/dist/internal/mcp-oauth.d.ts +12 -1
- package/dist/internal/mcp-oauth.d.ts.map +1 -1
- package/dist/internal/mcp-oauth.js +25 -3
- package/dist/internal/playground/static.d.ts +21 -4
- package/dist/internal/playground/static.d.ts.map +1 -1
- package/dist/internal/playground/static.js +82 -18
- package/dist/internal/sdk-runner.d.ts.map +1 -1
- package/dist/internal/sdk-runner.js +10 -1
- package/dist/internal/server.d.ts.map +1 -1
- package/dist/internal/server.js +67 -49
- package/dist/internal/session-engine.d.ts +57 -1
- package/dist/internal/session-engine.d.ts.map +1 -1
- package/dist/internal/session-engine.js +117 -28
- package/dist/internal/slack-provision-client.js +1 -1
- package/dist/internal/workspace.d.ts +6 -2
- package/dist/internal/workspace.d.ts.map +1 -1
- package/dist/internal/workspace.js +10 -2
- package/dist/kv/memory-kv.d.ts +23 -0
- package/dist/kv/memory-kv.d.ts.map +1 -0
- package/dist/kv/memory-kv.js +103 -0
- package/dist/kv.d.ts +22 -0
- package/dist/kv.d.ts.map +1 -0
- package/dist/kv.js +20 -0
- package/dist/ledger/session-ledger.d.ts +204 -0
- package/dist/ledger/session-ledger.d.ts.map +1 -0
- package/dist/ledger/session-ledger.js +382 -0
- package/dist/ledger.d.ts +11 -0
- package/dist/ledger.d.ts.map +1 -0
- package/dist/ledger.js +9 -0
- package/dist/playground/assets/index-B3HBneZZ.js +85 -0
- package/dist/playground/assets/index-Bqk9nplh.css +1 -0
- package/dist/playground/index.html +2 -2
- package/dist/storage-backends/cursor-hosted.d.ts +25 -3
- package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
- package/dist/storage-backends/cursor-hosted.js +50 -2
- package/dist/storage-backends/file-kv.d.ts +5 -2
- package/dist/storage-backends/file-kv.d.ts.map +1 -1
- package/dist/storage-backends/file-kv.js +107 -7
- package/dist/storage.d.ts +60 -5
- package/dist/storage.d.ts.map +1 -1
- package/dist/storage.js +28 -4
- package/dist/types.d.ts +123 -3
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js +14 -0
- package/docs/README.md +10 -7
- package/docs/ab.md +2 -2
- package/docs/building-with-agents.md +1 -1
- package/docs/deployment.md +34 -11
- package/docs/evals.md +3 -3
- package/docs/example-agents/index.md +1 -1
- package/docs/guides/webhooks.md +87 -0
- package/docs/quickstart.md +7 -8
- package/docs/reference/cli.md +15 -6
- package/docs/reference/hooks.md +8 -2
- package/docs/storage.md +67 -7
- package/docs/troubleshooting.md +10 -2
- package/package.json +20 -7
- package/skills/create-agent/SKILL.md +1 -1
- package/src/bin/agent-serve.ts +27 -11
- package/src/channels/slack/api.ts +19 -14
- package/src/channels/slack/attachments.ts +635 -0
- package/src/channels/slack/cursor-account.ts +8 -0
- package/src/channels/slack/defaults.ts +34 -18
- package/src/channels/slack/dispatch.ts +121 -6
- package/src/channels/slack/inbound.ts +60 -0
- package/src/channels/slack/index.ts +1 -0
- package/src/channels/slack/live-delivery.ts +17 -3
- package/src/channels/slack/manifest.ts +1 -0
- package/src/channels/slack/slack-channel.ts +7 -0
- package/src/channels/slack/types.ts +47 -1
- package/src/index.ts +9 -0
- package/src/internal/cli-ax.ts +25 -1
- package/src/internal/cli-deploy.ts +22 -4
- package/src/internal/cli-mcp-oauth.ts +3 -1
- package/src/internal/cli-mcp.ts +4 -4
- package/src/internal/cursor-event-relay.ts +168 -0
- package/src/internal/deploy-client.ts +1 -1
- package/src/internal/discovery.ts +42 -5
- package/src/internal/distribution.ts +3 -1
- package/src/internal/durable-session-store.ts +95 -0
- package/src/internal/hosting.ts +2 -2
- package/src/internal/init-project.ts +151 -2
- package/src/internal/ledger-serving.ts +240 -0
- package/src/internal/listen-port.ts +85 -0
- package/src/internal/mcp-oauth.ts +29 -4
- package/src/internal/playground/static.ts +111 -20
- package/src/internal/sdk-runner.ts +11 -1
- package/src/internal/server.ts +76 -62
- package/src/internal/session-engine.ts +192 -16
- package/src/internal/slack-provision-client.ts +1 -1
- package/src/internal/workspace.ts +14 -3
- package/src/kv/memory-kv.ts +99 -0
- package/src/kv.ts +27 -0
- package/src/ledger/session-ledger.ts +535 -0
- package/src/ledger.ts +29 -0
- package/src/storage-backends/cursor-hosted.ts +108 -3
- package/src/storage-backends/file-kv.ts +128 -12
- package/src/storage.ts +90 -6
- package/src/types.ts +130 -4
- package/dist/channels/slack/post-update-delivery.d.ts +0 -85
- package/dist/channels/slack/post-update-delivery.d.ts.map +0 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.B-VTH4As.js +0 -1
- package/dist/docs/assets/example-agents_index.md.DgGBwckv.js +0 -2
- package/dist/docs/assets/index.md.CmhptOmN.js +0 -24
- package/dist/docs/assets/troubleshooting.md.B5RVX_tL.js +0 -1
- package/dist/internal/json-dir-store.d.ts +0 -32
- package/dist/internal/json-dir-store.d.ts.map +0 -1
- package/dist/internal/persistence-coordinator.d.ts +0 -127
- package/dist/internal/persistence-coordinator.d.ts.map +0 -1
- package/dist/multi-tenant.d.ts +0 -80
- package/dist/multi-tenant.d.ts.map +0 -1
- package/dist/multi-tenant.js +0 -69
- package/dist/persistence.d.ts +0 -184
- package/dist/persistence.d.ts.map +0 -1
- package/dist/playground/assets/index-BRhBbnd4.css +0 -1
- package/dist/playground/assets/index-_2WKw9a-.js +0 -85
- package/dist/storage-backends/postgres-kv.d.ts +0 -82
- package/dist/storage-backends/postgres-kv.d.ts.map +0 -1
- package/dist/storage-backends/postgres-kv.js +0 -185
- package/src/storage-backends/postgres-kv.ts +0 -253
- /package/dist/docs/assets/{ab.md.6cLOW7--.lean.js → ab.md.hdxsvX5M.lean.js} +0 -0
- /package/dist/docs/assets/{building-with-agents.md.txrcGU2B.lean.js → building-with-agents.md.PeZaZA1P.lean.js} +0 -0
- /package/dist/docs/assets/{evals.md.BQXI3rXy.lean.js → evals.md.qeoGgPw0.lean.js} +0 -0
- /package/dist/docs/assets/{example-agents_index.md.DgGBwckv.lean.js → example-agents_index.md.xmJ87d_3.lean.js} +0 -0
- /package/dist/docs/assets/{quickstart.md.C_b6ESpD.lean.js → quickstart.md.rIbfahJM.lean.js} +0 -0
|
@@ -15,17 +15,6 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
15
15
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
16
16
|
});
|
|
17
17
|
};
|
|
18
|
-
var __rest = (this && this.__rest) || function (s, e) {
|
|
19
|
-
var t = {};
|
|
20
|
-
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
21
|
-
t[p] = s[p];
|
|
22
|
-
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
23
|
-
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
24
|
-
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
25
|
-
t[p[i]] = s[p[i]];
|
|
26
|
-
}
|
|
27
|
-
return t;
|
|
28
|
-
};
|
|
29
18
|
import { mkdir, rm, writeFile } from "node:fs/promises";
|
|
30
19
|
import { dirname, join } from "node:path";
|
|
31
20
|
import { mergeABInstructions, resolveABMaxPlaygroundSessions, resolveABSplit, } from "../ab.js";
|
|
@@ -33,6 +22,8 @@ import { slackThreadPermalink } from "../channels/slack/links.js";
|
|
|
33
22
|
import { SlackAskDedupeStore, SlackNudgeStore, } from "../channels/slack/nudge-store.js";
|
|
34
23
|
import { resolveDedicatedSlackHostBinding } from "../channels/slack/slack-channel.js";
|
|
35
24
|
import { isCursorHostedFilesAvailable } from "../files-backends/cursor-hosted.js";
|
|
25
|
+
import { SessionLedger, supportsSessionLedgerKv, } from "../ledger/session-ledger.js";
|
|
26
|
+
import { fileKv } from "../storage-backends/file-kv.js";
|
|
36
27
|
import { DEFAULT_MODEL, DIRECT_TOOL_CALL_CHANNEL_ID, isHostOauthConnectionTransport, isSymbolicConnectionTransport, } from "../types.js";
|
|
37
28
|
import { ABCollector } from "./ab-collector.js";
|
|
38
29
|
import { foldABStream } from "./ab-fold.js";
|
|
@@ -43,6 +34,7 @@ import { samePrincipal } from "./auth.js";
|
|
|
43
34
|
import { mergeCloudOptions, resolveSessionRuntime } from "./cloud-merge.js";
|
|
44
35
|
import { applyCloudUsageToEvents, cloudSdkAgentIdFromEvents, isUnpricedCompletedTurn, mapSdkTokenUsage, } from "./cloud-turn-cost.js";
|
|
45
36
|
import { isDevMode } from "./dev-mode.js";
|
|
37
|
+
import { ledgerKeyPrefix, namespacedKv, storageCasKv, } from "./durable-session-store.js";
|
|
46
38
|
import { EventLogStore } from "./event-log.js";
|
|
47
39
|
import { TurnEventMapper } from "./event-mapper.js";
|
|
48
40
|
import { selectFrameworkStorageDefinition } from "./framework-storage-selection.js";
|
|
@@ -51,6 +43,7 @@ import { createHostKvApi } from "./host-kv.js";
|
|
|
51
43
|
import { createHostPlatforms, createHostSlackClient, } from "./host-platforms.js";
|
|
52
44
|
import { formatContinuationToken, newContinuationKey, newSessionId, newToolCallId, } from "./ids.js";
|
|
53
45
|
import { validateToolInput } from "./json-schema.js";
|
|
46
|
+
import { LedgerServing, newLedgerPodId } from "./ledger-serving.js";
|
|
54
47
|
import { McpHost } from "./mcp-host.js";
|
|
55
48
|
import { buildSessionContextBlock, SCHEDULE_CHANNEL_PREFIX, } from "./prompt-context.js";
|
|
56
49
|
import { assertCloudCanHonorAccountServersFilters } from "./resolved-connections.js";
|
|
@@ -211,6 +204,67 @@ export class SessionEngine {
|
|
|
211
204
|
for (const channel of options.project.channels) {
|
|
212
205
|
this.channelsById.set(channel.id, channel.definition);
|
|
213
206
|
}
|
|
207
|
+
this.ledgerServing = this.buildLedgerServing(options);
|
|
208
|
+
}
|
|
209
|
+
/**
|
|
210
|
+
* Ledger-mode wiring (`serving: "ledger"`): resolve a CAS-capable
|
|
211
|
+
* durable-session store and build the delivery seam. Resident agents
|
|
212
|
+
* (the default) return undefined and never touch ledger keys.
|
|
213
|
+
*/
|
|
214
|
+
buildLedgerServing(options) {
|
|
215
|
+
if (options.project.agent.serving !== "ledger") {
|
|
216
|
+
return undefined;
|
|
217
|
+
}
|
|
218
|
+
const ledgerKv = this.resolveDurableSessionStore(options);
|
|
219
|
+
return new LedgerServing({
|
|
220
|
+
ledger: new SessionLedger({ kv: ledgerKv, podId: newLedgerPodId() }),
|
|
221
|
+
deliverTurn: (request) => this.send(request.channelId, request.message, Object.assign(Object.assign({}, request.options), { continuationToken: request.continuationToken, ledgerDelivery: true })),
|
|
222
|
+
logger: this.logger,
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Pick the KV the ledger coordinates on, in precedence order:
|
|
227
|
+
*
|
|
228
|
+
* 1. `options.durableSessionStore` — an explicit store separate from
|
|
229
|
+
* agent state (advanced deployments, tests).
|
|
230
|
+
* 2. The authored storage backend (`agent/storage.ts`) when it
|
|
231
|
+
* implements the `cas` group — one backend serves both the storage
|
|
232
|
+
* API and the durable session API.
|
|
233
|
+
* 3. No authored storage: a file store under `<stateRoot>/ledger-kv`
|
|
234
|
+
* (same place resident state lives; single-process only).
|
|
235
|
+
*
|
|
236
|
+
* An authored backend without `cas` fails fast: silently falling back
|
|
237
|
+
* to local files would fork coordination away from the deployment's
|
|
238
|
+
* durable store. The check demands exactly the methods the
|
|
239
|
+
* coordination-only ledger uses — `listKeys` is not one of them.
|
|
240
|
+
*
|
|
241
|
+
* Whatever store wins, the returned handle is scoped here — once —
|
|
242
|
+
* under `agentkit/v1/<agent>/durable-session/`. The ledger speaks bare
|
|
243
|
+
* `session/…` / `ledger/…` keys; namespacing is this boundary's job,
|
|
244
|
+
* exactly like `host.kv`'s agent scoping.
|
|
245
|
+
*/
|
|
246
|
+
resolveDurableSessionStore(options) {
|
|
247
|
+
const namespace = ledgerKeyPrefix(options.project.name);
|
|
248
|
+
const explicit = options.durableSessionStore;
|
|
249
|
+
if (explicit !== undefined) {
|
|
250
|
+
if (!supportsSessionLedgerKv(explicit)) {
|
|
251
|
+
throw new Error(`Agent "${options.project.name}" declares serving: "ledger", but the configured durableSessionStore is not CAS-capable (getWithVersion / putIfAbsent / putIfVersion). Provide a store implementing those methods (see @cursor/july/kv).`);
|
|
252
|
+
}
|
|
253
|
+
return namespacedKv(explicit, namespace);
|
|
254
|
+
}
|
|
255
|
+
const casArgs = {
|
|
256
|
+
agentName: options.project.name,
|
|
257
|
+
projectRoot: options.project.rootDir,
|
|
258
|
+
};
|
|
259
|
+
const authored = options.project.storage;
|
|
260
|
+
if (authored !== undefined) {
|
|
261
|
+
if (authored.cas === undefined) {
|
|
262
|
+
throw new Error(`Agent "${options.project.name}" declares serving: "ledger", which needs conditional writes, but the storage backend in agent/storage.ts does not implement the cas group. Add cas: {...} to defineStorage (fileKv and cursorHostedStorage already include it), or pass an explicit durableSessionStore.`);
|
|
263
|
+
}
|
|
264
|
+
return namespacedKv(storageCasKv(authored, casArgs), namespace);
|
|
265
|
+
}
|
|
266
|
+
const fallback = fileKv({ dir: join(options.stateRoot, "ledger-kv") });
|
|
267
|
+
return namespacedKv(storageCasKv(fallback, casArgs), namespace);
|
|
214
268
|
}
|
|
215
269
|
/**
|
|
216
270
|
* Attach serve-time resolved connections (peers, Cursor account bridge).
|
|
@@ -349,6 +403,12 @@ export class SessionEngine {
|
|
|
349
403
|
return __awaiter(this, arguments, void 0, function* (channelId, message, options = {}) {
|
|
350
404
|
var _a;
|
|
351
405
|
var _b, _c, _d, _e, _f;
|
|
406
|
+
// Ledger-mode agents acquire the session lease before any turn runs;
|
|
407
|
+
// only the seam's own lease-holding deliveries fall through to the
|
|
408
|
+
// resident path.
|
|
409
|
+
if (this.ledgerServing !== undefined && options.ledgerDelivery !== true) {
|
|
410
|
+
return this.ledgerServing.deliver(channelId, message, options);
|
|
411
|
+
}
|
|
352
412
|
const auth = (_b = options.auth) !== null && _b !== void 0 ? _b : null;
|
|
353
413
|
let existing = options.continuationToken === undefined
|
|
354
414
|
? undefined
|
|
@@ -365,12 +425,14 @@ export class SessionEngine {
|
|
|
365
425
|
// Refresh harness cwd when the caller supplies a newer worktree (e.g. PR
|
|
366
426
|
// synchronize). Leave the durable continuation key unchanged.
|
|
367
427
|
let record = existing;
|
|
368
|
-
|
|
369
|
-
options.workspaceDir !== existing.workspaceOverride
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
record = yield this.updateRecord(existing.sessionId, (current) => (Object.assign(Object.assign({}, current), {
|
|
428
|
+
const refreshWorkspace = options.workspaceDir !== undefined &&
|
|
429
|
+
options.workspaceDir !== existing.workspaceOverride;
|
|
430
|
+
if (refreshWorkspace ||
|
|
431
|
+
options.workspaceFiles !== undefined ||
|
|
432
|
+
options.images !== undefined) {
|
|
433
|
+
record = yield this.updateRecord(existing.sessionId, (current) => (Object.assign(Object.assign({}, current), { workspaceOverride: refreshWorkspace
|
|
434
|
+
? options.workspaceDir
|
|
435
|
+
: current.workspaceOverride, pendingWorkspaceFiles: mergePendingWorkspaceFiles(current.pendingWorkspaceFiles, options.workspaceFiles), pendingImages: mergePendingImages(current.pendingImages, options.images) })));
|
|
374
436
|
}
|
|
375
437
|
// Refresh the cloud attach the same way: a follow-up send carries the
|
|
376
438
|
// caller's CURRENT cloud options (e.g. a PR attach re-derived per wake),
|
|
@@ -399,6 +461,7 @@ export class SessionEngine {
|
|
|
399
461
|
channelState,
|
|
400
462
|
workspaceOverride: options.workspaceDir,
|
|
401
463
|
pendingWorkspaceFiles: options.workspaceFiles,
|
|
464
|
+
pendingImages: options.images,
|
|
402
465
|
cloudOverride: options.cloud,
|
|
403
466
|
sdkAgentId: options.sdkAgentId,
|
|
404
467
|
turnCount: 0,
|
|
@@ -918,13 +981,19 @@ export class SessionEngine {
|
|
|
918
981
|
stateRoot: this.stateRoot,
|
|
919
982
|
});
|
|
920
983
|
const pendingFiles = record.pendingWorkspaceFiles;
|
|
984
|
+
const pendingImages = record.pendingImages;
|
|
921
985
|
if (pendingFiles !== undefined &&
|
|
922
986
|
Object.keys(pendingFiles).length > 0) {
|
|
923
987
|
yield writeWorkspaceFiles(harnessCwd, pendingFiles);
|
|
924
|
-
|
|
925
|
-
|
|
926
|
-
|
|
927
|
-
|
|
988
|
+
}
|
|
989
|
+
if ((pendingFiles !== undefined &&
|
|
990
|
+
Object.keys(pendingFiles).length > 0) ||
|
|
991
|
+
(pendingImages !== undefined && pendingImages.length > 0)) {
|
|
992
|
+
yield this.updateRecord(sessionId, (current) => (Object.assign(Object.assign({}, current), { pendingWorkspaceFiles: current.pendingWorkspaceFiles === pendingFiles
|
|
993
|
+
? undefined
|
|
994
|
+
: current.pendingWorkspaceFiles, pendingImages: current.pendingImages === pendingImages
|
|
995
|
+
? undefined
|
|
996
|
+
: current.pendingImages })));
|
|
928
997
|
}
|
|
929
998
|
// The harness only loads the scaffolded AGENTS.md when the session
|
|
930
999
|
// workspace is its own project root. When the harness cwd is borrowed
|
|
@@ -945,7 +1014,7 @@ export class SessionEngine {
|
|
|
945
1014
|
update.type === "tool-call-delta") {
|
|
946
1015
|
yield yieldEventLoop();
|
|
947
1016
|
}
|
|
948
|
-
}), signal);
|
|
1017
|
+
}), signal, pendingImages);
|
|
949
1018
|
this.activeToolContexts.set(sessionId, { record, turnId, emit });
|
|
950
1019
|
try {
|
|
951
1020
|
outcome = yield this.runner.runTurn(request);
|
|
@@ -1024,7 +1093,7 @@ export class SessionEngine {
|
|
|
1024
1093
|
return Object.assign(Object.assign(Object.assign({}, outcome), (finalResult === undefined ? {} : { result: finalResult })), (finalUsage === undefined ? {} : { usage: finalUsage }));
|
|
1025
1094
|
});
|
|
1026
1095
|
}
|
|
1027
|
-
buildTurnRequest(record, agent, turnId, prompt, isFirstTurn, instructionsInvisibleToHarness, emit, onUpdate, signal) {
|
|
1096
|
+
buildTurnRequest(record, agent, turnId, prompt, isFirstTurn, instructionsInvisibleToHarness, emit, onUpdate, signal, images) {
|
|
1028
1097
|
var _a, _b, _c;
|
|
1029
1098
|
// Per-session cloud attach (channel/tool handoff) forces cloud runtime
|
|
1030
1099
|
// even when the agent defaults to local for chat server tools.
|
|
@@ -1078,9 +1147,9 @@ export class SessionEngine {
|
|
|
1078
1147
|
turnPrompt = `${preamble}\n\n${turnPrompt}`;
|
|
1079
1148
|
}
|
|
1080
1149
|
}
|
|
1081
|
-
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ sessionId: record.sessionId }, (record.sdkAgentId === undefined
|
|
1150
|
+
return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ sessionId: record.sessionId }, (record.sdkAgentId === undefined
|
|
1082
1151
|
? {}
|
|
1083
|
-
: { sdkAgentId: record.sdkAgentId })), { workspaceDir: this.harnessCwd(record), sandbox: ((_c = this.project.agent.local) === null || _c === void 0 ? void 0 : _c.sandbox) === true, runnerStateDir: join(this.stateRoot, "runner"), prompt: turnPrompt, isFirstTurn }), (agent.model === undefined ? {} : { model: agent.model })), { runtime }), (mergedCloud === undefined ? {} : { cloud: mergedCloud })), { customTools: runtime === "local" ? this.buildCustomTools(record, turnId, emit) : {}, mcpServers: this.buildMcpServers(runtime, record.sessionId), subagents: buildRunnerSubagents(agent), onUpdate,
|
|
1152
|
+
: { sdkAgentId: record.sdkAgentId })), { workspaceDir: this.harnessCwd(record), sandbox: ((_c = this.project.agent.local) === null || _c === void 0 ? void 0 : _c.sandbox) === true, runnerStateDir: join(this.stateRoot, "runner"), prompt: turnPrompt, isFirstTurn }), (images !== undefined && images.length > 0 ? { images } : {})), (agent.model === undefined ? {} : { model: agent.model })), { runtime }), (mergedCloud === undefined ? {} : { cloud: mergedCloud })), { customTools: runtime === "local" ? this.buildCustomTools(record, turnId, emit) : {}, mcpServers: this.buildMcpServers(runtime, record.sessionId), subagents: buildRunnerSubagents(agent), onUpdate,
|
|
1084
1153
|
signal,
|
|
1085
1154
|
// Local follow-ups expire any lingering active run so a preempted turn
|
|
1086
1155
|
// (or one orphaned by a crashed process) never blocks this send.
|
|
@@ -2412,22 +2481,42 @@ export class SessionEngine {
|
|
|
2412
2481
|
/** Drain running turns, dispatches, and pending writes, then dispose. */
|
|
2413
2482
|
close() {
|
|
2414
2483
|
return __awaiter(this, void 0, void 0, function* () {
|
|
2415
|
-
var _a, _b, _c;
|
|
2484
|
+
var _a, _b, _c, _d;
|
|
2416
2485
|
this.approvals.cancelAll("deny");
|
|
2486
|
+
// Ledger deliveries spawn turns, so settle them before activeTurns.
|
|
2487
|
+
yield (_a = this.ledgerServing) === null || _a === void 0 ? void 0 : _a.close();
|
|
2417
2488
|
yield Promise.allSettled([...this.activeTurns.values()]);
|
|
2418
2489
|
yield Promise.allSettled([...this.backgroundWork]);
|
|
2419
2490
|
yield Promise.allSettled([...this.dispatchChains.values()]);
|
|
2420
2491
|
yield Promise.allSettled([...this.updateChains.values()]);
|
|
2421
2492
|
yield this.logs.flushAll();
|
|
2422
|
-
yield (
|
|
2493
|
+
yield (_b = this.storage) === null || _b === void 0 ? void 0 : _b.close();
|
|
2423
2494
|
yield this.mcpHost.close();
|
|
2424
|
-
yield (
|
|
2495
|
+
yield (_d = (_c = this.runner).dispose) === null || _d === void 0 ? void 0 : _d.call(_c);
|
|
2425
2496
|
});
|
|
2426
2497
|
}
|
|
2427
2498
|
}
|
|
2428
2499
|
/** Parallel event-stream loads during the startup bulk restore. */
|
|
2429
2500
|
const RESTORE_FETCH_CONCURRENCY = 8;
|
|
2430
2501
|
/** NDJSON payload for a restored event stream; undefined when empty. */
|
|
2502
|
+
function mergePendingImages(current, incoming) {
|
|
2503
|
+
if (incoming === undefined) {
|
|
2504
|
+
return current;
|
|
2505
|
+
}
|
|
2506
|
+
if (current === undefined || current.length === 0) {
|
|
2507
|
+
return incoming;
|
|
2508
|
+
}
|
|
2509
|
+
return [...current, ...incoming];
|
|
2510
|
+
}
|
|
2511
|
+
function mergePendingWorkspaceFiles(current, incoming) {
|
|
2512
|
+
if (incoming === undefined) {
|
|
2513
|
+
return current;
|
|
2514
|
+
}
|
|
2515
|
+
if (current === undefined) {
|
|
2516
|
+
return incoming;
|
|
2517
|
+
}
|
|
2518
|
+
return Object.assign(Object.assign({}, current), incoming);
|
|
2519
|
+
}
|
|
2431
2520
|
function eventsNdjson(events) {
|
|
2432
2521
|
if (events.length === 0) {
|
|
2433
2522
|
return undefined;
|
|
@@ -250,7 +250,7 @@ function mapErrorResponse(response, bodyText, context) {
|
|
|
250
250
|
case 401:
|
|
251
251
|
return new SlackProvisionApiError("The Cursor API key was rejected. Run `agent-sdk login` again or update CURSOR_API_KEY.", { status: 401 });
|
|
252
252
|
case 403:
|
|
253
|
-
return new SlackProvisionApiError(`${serverError !== null && serverError !== void 0 ? serverError : "Not authorized"} — Slack provisioning needs team
|
|
253
|
+
return new SlackProvisionApiError(`${serverError !== null && serverError !== void 0 ? serverError : "Not authorized"} — Slack provisioning needs team membership and the cloud-agent entitlement on that team.`, { status: 403 });
|
|
254
254
|
case 404: {
|
|
255
255
|
// Fastify's route-not-found envelope means we hit the wrong host
|
|
256
256
|
// (api2 vs api.cursor.com), not a closed gate.
|
|
@@ -108,7 +108,11 @@ export declare function materializeWorkspace(options: MaterializeWorkspaceOption
|
|
|
108
108
|
export declare function buildSkillMd(skill: DiscoveredSkill): string;
|
|
109
109
|
/**
|
|
110
110
|
* Write relative path → contents under `workspaceDir`, refusing paths that
|
|
111
|
-
* escape the directory.
|
|
111
|
+
* escape the directory. Values may be utf8 strings or base64 blob envelopes.
|
|
112
112
|
*/
|
|
113
|
-
export declare function writeWorkspaceFiles(workspaceDir: string, files: Record<string, string
|
|
113
|
+
export declare function writeWorkspaceFiles(workspaceDir: string, files: Record<string, string | {
|
|
114
|
+
encoding: "base64";
|
|
115
|
+
data: string;
|
|
116
|
+
mimeType?: string;
|
|
117
|
+
}>): Promise<void>;
|
|
114
118
|
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,SAAS,CAapB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAA8B,GAC/D,MAAM,CA8CR;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACjC,MAAM,CA6BR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,MAAM,CAeR;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAkCf;AAqGD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAO3D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAgBH,OAAO,KAAK,EACV,eAAe,EACf,cAAc,EACd,aAAa,EACd,MAAM,aAAa,CAAC;AAIrB,MAAM,WAAW,2BAA2B;IAC1C,KAAK,EAAE,aAAa,CAAC;IACrB,YAAY,EAAE,MAAM,CAAC;IACrB;;;OAGG;IACH,IAAI,EAAE,OAAO,CAAC;IACd;;;;;;;OAOG;IACH,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAOjE;AAED,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;;GAKG;AACH,eAAO,MAAM,4BAA4B,mBAAmB,CAAC;AAE7D;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAClC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,GAAG,SAAS,GAC/B,MAAM,GAAG,SAAS,CAapB;AAED;;;;;GAKG;AACH,wBAAgB,sBAAsB,CACpC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,GAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAA8B,GAC/D,MAAM,CA8CR;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACjC,MAAM,CA6BR;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,cAAc,EAAE,OAAO,CAAC;IAAC,kBAAkB,CAAC,EAAE,MAAM,CAAA;CAAE,GAChE,MAAM,CAeR;AAED;;;;;;;GAOG;AACH,wBAAsB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAcrE;AAED,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,2BAA2B,GACnC,OAAO,CAAC,IAAI,CAAC,CAkCf;AAqGD;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,MAAM,CAO3D;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CACvC,YAAY,EAAE,MAAM,EACpB,KAAK,EAAE,MAAM,CACX,MAAM,EACN,MAAM,GAAG;IAAE,QAAQ,EAAE,QAAQ,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CACjE,GACA,OAAO,CAAC,IAAI,CAAC,CAcf"}
|
|
@@ -352,14 +352,22 @@ export function buildSkillMd(skill) {
|
|
|
352
352
|
}
|
|
353
353
|
/**
|
|
354
354
|
* Write relative path → contents under `workspaceDir`, refusing paths that
|
|
355
|
-
* escape the directory.
|
|
355
|
+
* escape the directory. Values may be utf8 strings or base64 blob envelopes.
|
|
356
356
|
*/
|
|
357
357
|
export function writeWorkspaceFiles(workspaceDir, files) {
|
|
358
358
|
return __awaiter(this, void 0, void 0, function* () {
|
|
359
359
|
for (const [relativePath, contents] of Object.entries(files)) {
|
|
360
360
|
const target = resolveWorkspaceWritePath(workspaceDir, relativePath);
|
|
361
361
|
yield mkdir(dirname(target), { recursive: true });
|
|
362
|
-
|
|
362
|
+
if (typeof contents === "string") {
|
|
363
|
+
yield writeFile(target, contents, "utf8");
|
|
364
|
+
}
|
|
365
|
+
else if (contents.encoding === "base64") {
|
|
366
|
+
yield writeFile(target, Buffer.from(contents.data, "base64"));
|
|
367
|
+
}
|
|
368
|
+
else {
|
|
369
|
+
throw new Error(`Unsupported workspace file encoding for ${relativePath}`);
|
|
370
|
+
}
|
|
363
371
|
}
|
|
364
372
|
});
|
|
365
373
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory {@link HostKvCasApi} — the test/dev implementation of the
|
|
3
|
+
* interface module (`@cursor/july/kv`), exported at
|
|
4
|
+
* `@cursor/july/kv/memory`.
|
|
5
|
+
*
|
|
6
|
+
* The memory KV *is* the dev shim: tests and local runs exercise the
|
|
7
|
+
* same CAS coordination paths that hosted serving uses, not a mock of an
|
|
8
|
+
* RPC. Values are deep-copied on both write and
|
|
9
|
+
* read so callers can never observe (or cause) shared-reference mutation.
|
|
10
|
+
*/
|
|
11
|
+
import type { StorageCasTable } from "../storage.js";
|
|
12
|
+
import type { HostKvCasApi } from "../types.js";
|
|
13
|
+
/** Create an empty in-memory CAS-capable KV. */
|
|
14
|
+
export declare function createMemoryKv(): HostKvCasApi;
|
|
15
|
+
/**
|
|
16
|
+
* In-memory `cas` group for `defineStorage` — a complete conditional-write
|
|
17
|
+
* group for sinks whose plain methods are inert or live elsewhere (test
|
|
18
|
+
* fixtures, an off-hosting no-op sink). Non-durable and process-local by
|
|
19
|
+
* construction; a real deployment backend should implement CAS against
|
|
20
|
+
* its own store instead.
|
|
21
|
+
*/
|
|
22
|
+
export declare function memoryCasTable(): StorageCasTable;
|
|
23
|
+
//# sourceMappingURL=memory-kv.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"memory-kv.d.ts","sourceRoot":"","sources":["../../src/kv/memory-kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,eAAe,CAAC;AACrD,OAAO,KAAK,EACV,YAAY,EAIb,MAAM,aAAa,CAAC;AAErB,gDAAgD;AAChD,wBAAgB,cAAc,IAAI,YAAY,CA4D7C;AAED;;;;;;GAMG;AACH,wBAAgB,cAAc,IAAI,eAAe,CAShD"}
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* In-memory {@link HostKvCasApi} — the test/dev implementation of the
|
|
3
|
+
* interface module (`@cursor/july/kv`), exported at
|
|
4
|
+
* `@cursor/july/kv/memory`.
|
|
5
|
+
*
|
|
6
|
+
* The memory KV *is* the dev shim: tests and local runs exercise the
|
|
7
|
+
* same CAS coordination paths that hosted serving uses, not a mock of an
|
|
8
|
+
* RPC. Values are deep-copied on both write and
|
|
9
|
+
* read so callers can never observe (or cause) shared-reference mutation.
|
|
10
|
+
*/
|
|
11
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
12
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
13
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
14
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
15
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
16
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
17
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
18
|
+
});
|
|
19
|
+
};
|
|
20
|
+
/** Create an empty in-memory CAS-capable KV. */
|
|
21
|
+
export function createMemoryKv() {
|
|
22
|
+
const entries = new Map();
|
|
23
|
+
let versionCounter = 0;
|
|
24
|
+
const nextVersion = () => {
|
|
25
|
+
versionCounter += 1;
|
|
26
|
+
return `v${versionCounter}`;
|
|
27
|
+
};
|
|
28
|
+
const snapshot = (key) => {
|
|
29
|
+
const entry = entries.get(key);
|
|
30
|
+
if (entry === undefined) {
|
|
31
|
+
return undefined;
|
|
32
|
+
}
|
|
33
|
+
return { value: structuredClone(entry.value), version: entry.version };
|
|
34
|
+
};
|
|
35
|
+
return {
|
|
36
|
+
get(key) {
|
|
37
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
38
|
+
var _a;
|
|
39
|
+
return (_a = snapshot(key)) === null || _a === void 0 ? void 0 : _a.value;
|
|
40
|
+
});
|
|
41
|
+
},
|
|
42
|
+
put(key, value) {
|
|
43
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
44
|
+
entries.set(key, {
|
|
45
|
+
value: structuredClone(value),
|
|
46
|
+
version: nextVersion(),
|
|
47
|
+
});
|
|
48
|
+
});
|
|
49
|
+
},
|
|
50
|
+
delete(key) {
|
|
51
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
52
|
+
entries.delete(key);
|
|
53
|
+
});
|
|
54
|
+
},
|
|
55
|
+
getWithVersion(key) {
|
|
56
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
57
|
+
return snapshot(key);
|
|
58
|
+
});
|
|
59
|
+
},
|
|
60
|
+
putIfAbsent(key, value) {
|
|
61
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
+
if (entries.has(key)) {
|
|
63
|
+
return { ok: false, current: snapshot(key) };
|
|
64
|
+
}
|
|
65
|
+
const version = nextVersion();
|
|
66
|
+
entries.set(key, { value: structuredClone(value), version });
|
|
67
|
+
return { ok: true, version };
|
|
68
|
+
});
|
|
69
|
+
},
|
|
70
|
+
putIfVersion(key, value, expectedVersion) {
|
|
71
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
const entry = entries.get(key);
|
|
73
|
+
if (entry === undefined || entry.version !== expectedVersion) {
|
|
74
|
+
return { ok: false, current: snapshot(key) };
|
|
75
|
+
}
|
|
76
|
+
const version = nextVersion();
|
|
77
|
+
entries.set(key, { value: structuredClone(value), version });
|
|
78
|
+
return { ok: true, version };
|
|
79
|
+
});
|
|
80
|
+
},
|
|
81
|
+
listKeys(prefix) {
|
|
82
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
83
|
+
return [...entries.keys()].filter((key) => key.startsWith(prefix)).sort();
|
|
84
|
+
});
|
|
85
|
+
},
|
|
86
|
+
};
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* In-memory `cas` group for `defineStorage` — a complete conditional-write
|
|
90
|
+
* group for sinks whose plain methods are inert or live elsewhere (test
|
|
91
|
+
* fixtures, an off-hosting no-op sink). Non-durable and process-local by
|
|
92
|
+
* construction; a real deployment backend should implement CAS against
|
|
93
|
+
* its own store instead.
|
|
94
|
+
*/
|
|
95
|
+
export function memoryCasTable() {
|
|
96
|
+
const kv = createMemoryKv();
|
|
97
|
+
return {
|
|
98
|
+
getWithVersion: (key) => kv.getWithVersion(key),
|
|
99
|
+
putIfAbsent: (key, value) => kv.putIfAbsent(key, value),
|
|
100
|
+
putIfVersion: (key, value, expectedVersion) => kv.putIfVersion(key, value, expectedVersion),
|
|
101
|
+
listKeys: (prefix) => kv.listKeys(prefix),
|
|
102
|
+
};
|
|
103
|
+
}
|
package/dist/kv.d.ts
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CAS-capable KV **interface** — `@cursor/july/kv`.
|
|
3
|
+
*
|
|
4
|
+
* This module is implementation-free on purpose: it is the contract a
|
|
5
|
+
* bring-your-own KV implements so coordination protocols (conditional
|
|
6
|
+
* writes are the substrate for the upcoming session ledger) can run on
|
|
7
|
+
* it. {@link HostKvCasApi} is the conditional-write superset of the plain
|
|
8
|
+
* {@link HostKvApi}; {@link supportsKvCas} is the runtime probe for
|
|
9
|
+
* stores of unknown provenance — a `defineStorage` backend declares CAS
|
|
10
|
+
* through its `cas` group instead, so it never needs probing.
|
|
11
|
+
*
|
|
12
|
+
* Implementations live elsewhere:
|
|
13
|
+
*
|
|
14
|
+
* - `@cursor/july/kv/memory` — `createMemoryKv`, the test/dev shim.
|
|
15
|
+
* - The storage backends implement the same operations as the `cas`
|
|
16
|
+
* group on `defineStorage` (see `StorageCasTable` in
|
|
17
|
+
* `@cursor/july/storage`): `fileKv` (single-process) and
|
|
18
|
+
* `cursorHostedStorage` (control-plane proxy). See `docs/storage.md`.
|
|
19
|
+
*/
|
|
20
|
+
export type { HostKvApi, HostKvCasApi, KvCasResult, KvVersionedEntry, } from "./types.js";
|
|
21
|
+
export { supportsKvCas } from "./types.js";
|
|
22
|
+
//# sourceMappingURL=kv.d.ts.map
|
package/dist/kv.d.ts.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kv.d.ts","sourceRoot":"","sources":["../src/kv.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;GAkBG;AAEH,YAAY,EACV,SAAS,EACT,YAAY,EACZ,WAAW,EACX,gBAAgB,GACjB,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
|
package/dist/kv.js
ADDED
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The CAS-capable KV **interface** — `@cursor/july/kv`.
|
|
3
|
+
*
|
|
4
|
+
* This module is implementation-free on purpose: it is the contract a
|
|
5
|
+
* bring-your-own KV implements so coordination protocols (conditional
|
|
6
|
+
* writes are the substrate for the upcoming session ledger) can run on
|
|
7
|
+
* it. {@link HostKvCasApi} is the conditional-write superset of the plain
|
|
8
|
+
* {@link HostKvApi}; {@link supportsKvCas} is the runtime probe for
|
|
9
|
+
* stores of unknown provenance — a `defineStorage` backend declares CAS
|
|
10
|
+
* through its `cas` group instead, so it never needs probing.
|
|
11
|
+
*
|
|
12
|
+
* Implementations live elsewhere:
|
|
13
|
+
*
|
|
14
|
+
* - `@cursor/july/kv/memory` — `createMemoryKv`, the test/dev shim.
|
|
15
|
+
* - The storage backends implement the same operations as the `cas`
|
|
16
|
+
* group on `defineStorage` (see `StorageCasTable` in
|
|
17
|
+
* `@cursor/july/storage`): `fileKv` (single-process) and
|
|
18
|
+
* `cursorHostedStorage` (control-plane proxy). See `docs/storage.md`.
|
|
19
|
+
*/
|
|
20
|
+
export { supportsKvCas } from "./types.js";
|