@cursor/july 0.1.33 → 0.1.35

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (171) hide show
  1. package/README.md +1 -1
  2. package/dist/artifacts.d.ts.map +1 -1
  3. package/dist/artifacts.js +0 -5
  4. package/dist/bin/agent-serve.d.ts +1 -0
  5. package/dist/bin/agent-serve.d.ts.map +1 -1
  6. package/dist/bin/agent-serve.js +32 -2
  7. package/dist/channels/github/types.d.ts +10 -7
  8. package/dist/channels/github/types.d.ts.map +1 -1
  9. package/dist/docs/404.html +2 -2
  10. package/dist/docs/ab.html +3 -3
  11. package/dist/docs/assets/{app.CgZqLyWL.js → app.D5Mv1T0U.js} +1 -1
  12. package/dist/docs/assets/chunks/@localSearchIndexroot.Cu7b6o1D.js +1 -0
  13. package/dist/docs/assets/chunks/{VPLocalSearchBox.C4KigoQn.js → VPLocalSearchBox.CMq_BQce.js} +1 -1
  14. package/dist/docs/assets/chunks/{theme.C_Ty4yT7.js → theme.C6D9UPLK.js} +2 -2
  15. package/dist/docs/assets/{example-agents_weather-agent.md.Dmrcphhl.js → example-agents_weather-agent.md.BADkPqxQ.js} +6 -4
  16. package/dist/docs/assets/example-agents_weather-agent.md.BADkPqxQ.lean.js +1 -0
  17. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.js +9 -0
  18. package/dist/docs/assets/guides_cloud-runtime.md.CDJGvVC4.lean.js +1 -0
  19. package/dist/docs/building-with-agents.html +3 -3
  20. package/dist/docs/concepts.html +3 -3
  21. package/dist/docs/deployment.html +3 -3
  22. package/dist/docs/evals.html +3 -3
  23. package/dist/docs/example-agents/approval-buddy.html +3 -3
  24. package/dist/docs/example-agents/benny.html +3 -3
  25. package/dist/docs/example-agents/bugbot.html +3 -3
  26. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  27. package/dist/docs/example-agents/codeowners-review.html +3 -3
  28. package/dist/docs/example-agents/concierge.html +3 -3
  29. package/dist/docs/example-agents/fsd.html +3 -3
  30. package/dist/docs/example-agents/index.html +3 -3
  31. package/dist/docs/example-agents/knowledge-base.html +3 -3
  32. package/dist/docs/example-agents/oncall.html +3 -3
  33. package/dist/docs/example-agents/security-reviewer.html +3 -3
  34. package/dist/docs/example-agents/slack-agent.html +3 -3
  35. package/dist/docs/example-agents/weather-agent.html +10 -8
  36. package/dist/docs/guides/agent-to-agent.html +3 -3
  37. package/dist/docs/guides/cloud-runtime.html +5 -5
  38. package/dist/docs/guides/github.html +3 -3
  39. package/dist/docs/guides/human-in-the-loop.html +3 -3
  40. package/dist/docs/guides/mcp-oauth.html +3 -3
  41. package/dist/docs/guides/slack.html +3 -3
  42. package/dist/docs/guides/webhooks.html +3 -3
  43. package/dist/docs/hashmap.json +1 -1
  44. package/dist/docs/hillclimbing.html +3 -3
  45. package/dist/docs/index.html +3 -3
  46. package/dist/docs/quickstart.html +3 -3
  47. package/dist/docs/reference/agent-config.html +3 -3
  48. package/dist/docs/reference/channels.html +3 -3
  49. package/dist/docs/reference/cli.html +3 -3
  50. package/dist/docs/reference/connections.html +3 -3
  51. package/dist/docs/reference/hooks.html +3 -3
  52. package/dist/docs/reference/http-api.html +3 -3
  53. package/dist/docs/reference/instructions.html +3 -3
  54. package/dist/docs/reference/playground.html +3 -3
  55. package/dist/docs/reference/project-layout.html +3 -3
  56. package/dist/docs/reference/prompt.html +3 -3
  57. package/dist/docs/reference/schedules.html +3 -3
  58. package/dist/docs/reference/sessions.html +3 -3
  59. package/dist/docs/reference/skills.html +3 -3
  60. package/dist/docs/reference/subagents.html +3 -3
  61. package/dist/docs/reference/tools.html +3 -3
  62. package/dist/docs/scaffolding-agents.html +3 -3
  63. package/dist/docs/storage.html +3 -3
  64. package/dist/docs/troubleshooting.html +3 -3
  65. package/dist/files-backends/agent-store-presigned-url.d.ts +3 -11
  66. package/dist/files.d.ts +20 -0
  67. package/dist/files.d.ts.map +1 -1
  68. package/dist/files.js +20 -0
  69. package/dist/index.d.ts +2 -2
  70. package/dist/index.d.ts.map +1 -1
  71. package/dist/index.js +2 -2
  72. package/dist/internal/artifacts-store.d.ts +14 -6
  73. package/dist/internal/artifacts-store.d.ts.map +1 -1
  74. package/dist/internal/artifacts-store.js +160 -16
  75. package/dist/internal/cli-convert-automation.d.ts +39 -0
  76. package/dist/internal/cli-convert-automation.d.ts.map +1 -0
  77. package/dist/internal/cli-convert-automation.js +280 -0
  78. package/dist/internal/cli-deploy.d.ts +2 -0
  79. package/dist/internal/cli-deploy.d.ts.map +1 -1
  80. package/dist/internal/cli-deploy.js +1 -1
  81. package/dist/internal/cli-mcp-oauth.d.ts +23 -0
  82. package/dist/internal/cli-mcp-oauth.d.ts.map +1 -1
  83. package/dist/internal/cli-mcp-oauth.js +57 -33
  84. package/dist/internal/convert-automation/convert-workflow.d.ts +10 -0
  85. package/dist/internal/convert-automation/convert-workflow.d.ts.map +1 -0
  86. package/dist/internal/convert-automation/convert-workflow.js +998 -0
  87. package/dist/internal/convert-automation/index.d.ts +3 -0
  88. package/dist/internal/convert-automation/index.d.ts.map +1 -0
  89. package/dist/internal/convert-automation/index.js +1 -0
  90. package/dist/internal/convert-automation/slug.d.ts +11 -0
  91. package/dist/internal/convert-automation/slug.d.ts.map +1 -0
  92. package/dist/internal/convert-automation/slug.js +36 -0
  93. package/dist/internal/convert-automation/types.d.ts +191 -0
  94. package/dist/internal/convert-automation/types.d.ts.map +1 -0
  95. package/dist/internal/convert-automation/types.js +13 -0
  96. package/dist/internal/deploy-client.d.ts +31 -0
  97. package/dist/internal/deploy-client.d.ts.map +1 -1
  98. package/dist/internal/deploy-client.js +48 -0
  99. package/dist/internal/discovery.d.ts.map +1 -1
  100. package/dist/internal/discovery.js +3 -32
  101. package/dist/internal/host-kv.d.ts +6 -2
  102. package/dist/internal/host-kv.d.ts.map +1 -1
  103. package/dist/internal/init-project.d.ts +1 -0
  104. package/dist/internal/init-project.d.ts.map +1 -1
  105. package/dist/internal/init-project.js +1 -1
  106. package/dist/internal/mcp-endpoint.d.ts +6 -0
  107. package/dist/internal/mcp-endpoint.d.ts.map +1 -1
  108. package/dist/internal/mcp-endpoint.js +168 -0
  109. package/dist/internal/resolved-connections.d.ts +15 -0
  110. package/dist/internal/resolved-connections.d.ts.map +1 -1
  111. package/dist/internal/resolved-connections.js +12 -5
  112. package/dist/internal/server.d.ts.map +1 -1
  113. package/dist/internal/server.js +75 -7
  114. package/dist/internal/session-engine.d.ts +56 -3
  115. package/dist/internal/session-engine.d.ts.map +1 -1
  116. package/dist/internal/session-engine.js +262 -84
  117. package/dist/internal/storage-coordinator.d.ts +9 -16
  118. package/dist/internal/storage-coordinator.d.ts.map +1 -1
  119. package/dist/internal/storage-coordinator.js +7 -52
  120. package/dist/internal/storage-roles.d.ts +78 -0
  121. package/dist/internal/storage-roles.d.ts.map +1 -0
  122. package/dist/internal/storage-roles.js +24 -0
  123. package/dist/internal/workspace.d.ts +36 -5
  124. package/dist/internal/workspace.d.ts.map +1 -1
  125. package/dist/internal/workspace.js +66 -0
  126. package/dist/memory.d.ts +22 -6
  127. package/dist/memory.d.ts.map +1 -1
  128. package/dist/memory.js +100 -8
  129. package/dist/playground/assets/{index-CVlCAcUx.js → index-D7OV8B_H.js} +50 -50
  130. package/dist/playground/assets/index-DOb96C0M.css +1 -0
  131. package/dist/playground/index.html +2 -2
  132. package/dist/storage.d.ts +0 -4
  133. package/dist/storage.d.ts.map +1 -1
  134. package/dist/storage.js +0 -4
  135. package/dist/types.d.ts +18 -0
  136. package/dist/types.d.ts.map +1 -1
  137. package/docs/example-agents/weather-agent.md +29 -11
  138. package/docs/guides/cloud-runtime.md +6 -4
  139. package/package.json +3 -1
  140. package/src/artifacts.ts +0 -6
  141. package/src/bin/agent-serve.ts +36 -2
  142. package/src/channels/github/types.ts +10 -7
  143. package/src/files.ts +27 -0
  144. package/src/index.ts +6 -1
  145. package/src/internal/artifacts-store.ts +185 -22
  146. package/src/internal/cli-convert-automation.ts +352 -0
  147. package/src/internal/cli-deploy.ts +1 -1
  148. package/src/internal/cli-mcp-oauth.ts +69 -31
  149. package/src/internal/convert-automation/convert-workflow.ts +1422 -0
  150. package/src/internal/convert-automation/index.ts +10 -0
  151. package/src/internal/convert-automation/slug.ts +38 -0
  152. package/src/internal/convert-automation/types.ts +199 -0
  153. package/src/internal/deploy-client.ts +78 -0
  154. package/src/internal/discovery.ts +3 -37
  155. package/src/internal/host-kv.ts +6 -2
  156. package/src/internal/init-project.ts +1 -1
  157. package/src/internal/mcp-endpoint.ts +243 -0
  158. package/src/internal/resolved-connections.ts +32 -6
  159. package/src/internal/server.ts +99 -1
  160. package/src/internal/session-engine.ts +345 -103
  161. package/src/internal/storage-coordinator.ts +15 -63
  162. package/src/internal/storage-roles.ts +86 -0
  163. package/src/internal/workspace.ts +81 -6
  164. package/src/memory.ts +126 -10
  165. package/src/storage.ts +0 -6
  166. package/src/types.ts +15 -0
  167. package/dist/docs/assets/chunks/@localSearchIndexroot.B1uHGxBZ.js +0 -1
  168. package/dist/docs/assets/example-agents_weather-agent.md.Dmrcphhl.lean.js +0 -1
  169. package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.js +0 -9
  170. package/dist/docs/assets/guides_cloud-runtime.md.BZ2GA7Es.lean.js +0 -1
  171. package/dist/playground/assets/index-BRhBbnd4.css +0 -1
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The three unrelated jobs `defineStorage` currently does, named separately.
3
+ *
4
+ * {@link import("./storage-coordinator.js").StorageCoordinator} implements all
5
+ * three today over one sink and one delivery queue. Splitting the *types* is
6
+ * the seam that lets each job change independently:
7
+ *
8
+ * - {@link FrameworkSessionStore} is framework state. Session records, event
9
+ * chunks, and the continuation index are how a session survives the process,
10
+ * so they belong to Agent Serve, not to the agent. Today they persist only
11
+ * when the author writes `agent/storage.ts` — the defect this seam exists to
12
+ * let us fix, by giving the framework its own provider that is automatic and
13
+ * not author-configurable.
14
+ * - {@link AuthorKvStore} is author state: whatever `ctx.host.kv` was handed.
15
+ * It converges onto the author file plane, which is a different destination
16
+ * from the one above.
17
+ * - {@link EvalAbStore} is playground/experiment bookkeeping with its own
18
+ * dedicated tables, and follows neither.
19
+ *
20
+ * Consumers should depend on the narrowest role they use. That is what keeps a
21
+ * later change to framework persistence from silently reaching author KV, and
22
+ * it is why these are interfaces rather than a comment on one class.
23
+ */
24
+ import type { ABMetricSample } from "../ab.js";
25
+ import type { StorageContext } from "../storage.js";
26
+ import type { JsonValue, SessionEvent, SessionRecord } from "../types.js";
27
+ import type { ABSnapshot } from "./ab-snapshot.js";
28
+ import type { EvalRunStorage } from "./eval-run-store.js";
29
+ /**
30
+ * Framework-owned session durability: what has to be true for a session to
31
+ * outlive the process that served it.
32
+ *
33
+ * Writes are fire-and-forget by design — a throwing backend is logged and its
34
+ * write dropped, because storage must never stall or fail a turn. That is
35
+ * at-most-once, and it is the property Track F later has to tighten, since a
36
+ * dropped record is a session that cannot be restored.
37
+ */
38
+ export interface FrameworkSessionStore {
39
+ /** Durable session-record update; coalesced until the next flush. */
40
+ sessionRecord(record: SessionRecord): void;
41
+ /** One appended session event; batched per turn or debounce window. */
42
+ event(event: SessionEvent): void;
43
+ /** Marks an event delivered, for backends that track dispatch. */
44
+ eventDispatched(event: SessionEvent): void;
45
+ /** Flush everything buffered for one session (ordered: events, record). */
46
+ flushSession(sessionId: string, reason?: StorageContext["reason"]): void;
47
+ /** True when the backend can list every session in one bulk read. */
48
+ readonly canBulkRestore: boolean;
49
+ /** True when the backend is the Cursor-hosted one rather than an authored sink. */
50
+ readonly isCursorHosted: boolean;
51
+ listSessions(): Promise<SessionRecord[]>;
52
+ listSessionsFromSink(): Promise<SessionRecord[]>;
53
+ listSessionEvents(sessionId: string): Promise<SessionEvent[]>;
54
+ getSessionById(sessionId: string): Promise<SessionRecord | undefined>;
55
+ getSessionByContinuation(channelId: string, continuationKey: string): Promise<SessionRecord | undefined>;
56
+ }
57
+ /**
58
+ * Author-facing durable JSON behind `ctx.host.kv`.
59
+ *
60
+ * Deployment-wide on purpose: the point is state an author saves in one
61
+ * session and reads back in a later one, so unlike `ctx.host.files` there is
62
+ * no session scope to default to.
63
+ */
64
+ export interface AuthorKvStore {
65
+ /** False when no backend is configured; callers fall back to local disk. */
66
+ readonly supportsAuthorKv: boolean;
67
+ kvGet(authorKey: string): Promise<JsonValue | undefined>;
68
+ kvPut(authorKey: string, value: JsonValue): Promise<void>;
69
+ kvDelete(authorKey: string): Promise<void>;
70
+ }
71
+ /** Playground eval batches and live A/B metrics, on their own tables. */
72
+ export interface EvalAbStore {
73
+ evalRuns(): EvalRunStorage | undefined;
74
+ abSample(sample: ABMetricSample): void;
75
+ abSnapshot(snapshot: ABSnapshot): void;
76
+ getLatestAbSnapshot(): Promise<ABSnapshot | undefined>;
77
+ }
78
+ //# sourceMappingURL=storage-roles.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-roles.d.ts","sourceRoot":"","sources":["../../src/internal/storage-roles.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAC/C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AACpD,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAE1D;;;;;;;;GAQG;AACH,MAAM,WAAW,qBAAqB;IACpC,qEAAqE;IACrE,aAAa,CAAC,MAAM,EAAE,aAAa,GAAG,IAAI,CAAC;IAC3C,uEAAuE;IACvE,KAAK,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IACjC,kEAAkE;IAClE,eAAe,CAAC,KAAK,EAAE,YAAY,GAAG,IAAI,CAAC;IAC3C,2EAA2E;IAC3E,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IAEzE,qEAAqE;IACrE,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IACjC,mFAAmF;IACnF,QAAQ,CAAC,cAAc,EAAE,OAAO,CAAC;IAEjC,YAAY,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACzC,oBAAoB,IAAI,OAAO,CAAC,aAAa,EAAE,CAAC,CAAC;IACjD,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAAC;IAC9D,cAAc,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;IACtE,wBAAwB,CACtB,SAAS,EAAE,MAAM,EACjB,eAAe,EAAE,MAAM,GACtB,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAAC;CACvC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,aAAa;IAC5B,4EAA4E;IAC5E,QAAQ,CAAC,gBAAgB,EAAE,OAAO,CAAC;IACnC,KAAK,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,SAAS,GAAG,SAAS,CAAC,CAAC;IACzD,KAAK,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC1D,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CAC5C;AAED,yEAAyE;AACzE,MAAM,WAAW,WAAW;IAC1B,QAAQ,IAAI,cAAc,GAAG,SAAS,CAAC;IACvC,QAAQ,CAAC,MAAM,EAAE,cAAc,GAAG,IAAI,CAAC;IACvC,UAAU,CAAC,QAAQ,EAAE,UAAU,GAAG,IAAI,CAAC;IACvC,mBAAmB,IAAI,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC,CAAC;CACxD"}
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The three unrelated jobs `defineStorage` currently does, named separately.
3
+ *
4
+ * {@link import("./storage-coordinator.js").StorageCoordinator} implements all
5
+ * three today over one sink and one delivery queue. Splitting the *types* is
6
+ * the seam that lets each job change independently:
7
+ *
8
+ * - {@link FrameworkSessionStore} is framework state. Session records, event
9
+ * chunks, and the continuation index are how a session survives the process,
10
+ * so they belong to Agent Serve, not to the agent. Today they persist only
11
+ * when the author writes `agent/storage.ts` — the defect this seam exists to
12
+ * let us fix, by giving the framework its own provider that is automatic and
13
+ * not author-configurable.
14
+ * - {@link AuthorKvStore} is author state: whatever `ctx.host.kv` was handed.
15
+ * It converges onto the author file plane, which is a different destination
16
+ * from the one above.
17
+ * - {@link EvalAbStore} is playground/experiment bookkeeping with its own
18
+ * dedicated tables, and follows neither.
19
+ *
20
+ * Consumers should depend on the narrowest role they use. That is what keeps a
21
+ * later change to framework persistence from silently reaching author KV, and
22
+ * it is why these are interfaces rather than a comment on one class.
23
+ */
24
+ export {};
@@ -17,16 +17,28 @@ export interface MaterializeWorkspaceOptions {
17
17
  seed: boolean;
18
18
  /**
19
19
  * Agent state root. `<stateRoot>/memory/` (the durable cross-session
20
- * directory the memory hook journals into) is created and symlinked into
21
- * the workspace as `memory` so the agent reads it with plain file tools.
22
- *
23
- * TODO(agent-store): replace with the mounted AgentStore path so cloud
24
- * VMs see the same directory.
20
+ * directory the memory hook journals into on hosting a local mirror of
21
+ * the Agent Store journal) is created and symlinked into the workspace as
22
+ * `memory` so the agent reads it with plain file tools. Cloud VMs have no
23
+ * materialized workspace; they read the store mount directly (see
24
+ * {@link buildCloudMemorySection}).
25
25
  */
26
26
  stateRoot: string;
27
27
  }
28
+ /**
29
+ * First-turn preamble section for cloud-runtime sessions on hosted
30
+ * deployments: cloud VMs read the memory journal from the store mount.
31
+ */
32
+ export declare function buildCloudMemorySection(agentName: string): string;
28
33
  /** Relative path of an agent-side tool script inside the session workspace. */
29
34
  export declare function agentToolScriptPath(toolName: string): string;
35
+ /**
36
+ * Reserved MCP connection name under which authored server tools are served
37
+ * to cloud turns (the session-bound tool MCP endpoint). Shared between the
38
+ * turn's MCP config and the first-prompt server-tool catalog so the model is
39
+ * told exactly where those tools live.
40
+ */
41
+ export declare const SERVER_TOOLS_MCP_SERVER_NAME = "agentsdk-tools";
30
42
  /**
31
43
  * Always-on identity line prepended when composing instructions. Sourced from
32
44
  * {@link ResolvedAgent.name} (`defineAgent({ name })`, else package/dir name)
@@ -47,15 +59,34 @@ export declare function withIdentityPreamble(name: string, instructions: string
47
59
  export declare function buildAgentToolsCatalog(tools: DiscoveredTool[], options?: {
48
60
  includeScripts: boolean;
49
61
  }): string;
62
+ /**
63
+ * Markdown catalog of authored server tools for the cloud first prompt.
64
+ *
65
+ * Server tools execute on the serve host and reach cloud turns only as MCP
66
+ * tools on {@link SERVER_TOOLS_MCP_SERVER_NAME}. Instructions reference them
67
+ * by bare name, and the agent-tool catalog teaches a "recreate the script if
68
+ * missing" pattern — without this section a cloud model that cannot find a
69
+ * script for a server tool improvises a local substitute instead of calling
70
+ * the real tool, so its host-side effects silently never happen.
71
+ */
72
+ export declare function buildServerToolsCatalog(tools: DiscoveredTool[], options: {
73
+ mcpServerName: string;
74
+ }): string;
50
75
  /**
51
76
  * The full AGENTS.md-equivalent context for an agent: instructions, identity
52
77
  * section, and the agent-side tool catalog. Written to the session workspace
53
78
  * as `AGENTS.md`, and inlined into the first turn's prompt when the harness
54
79
  * cannot discover that file (cloud runtime, or a local workspace the harness
55
80
  * will not treat as the project root — see {@link isNestedInGitRepo}).
81
+ *
82
+ * `serverToolsMcpName` is cloud-only: when the turn's MCP config carries the
83
+ * session-bound server-tool endpoint, the catalog names that server so the
84
+ * model calls the real tools instead of inventing local stand-ins. Local
85
+ * runtimes omit it — there the harness exposes server tools natively.
56
86
  */
57
87
  export declare function buildAgentsMdContent(agent: ResolvedAgent, options: {
58
88
  includeScripts: boolean;
89
+ serverToolsMcpName?: string;
59
90
  }): string;
60
91
  /**
61
92
  * True when `dir` sits strictly inside a git repository (a `.git` exists in
@@ -1 +1 @@
1
- {"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/internal/workspace.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAeH,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,+EAA+E;AAC/E,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED;;;;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,CA6CR;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,aAAa,EACpB,OAAO,EAAE;IAAE,cAAc,EAAE,OAAO,CAAA;CAAE,GACnC,MAAM,CAUR;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,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAMf"}
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,CA6CR;AAED;;;;;;;;;GASG;AACH,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,cAAc,EAAE,EACvB,OAAO,EAAE;IAAE,aAAa,EAAE,MAAM,CAAA;CAAE,GACjC,MAAM,CA4BR;AAED;;;;;;;;;;;GAWG;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,CAAC,MAAM,EAAE,MAAM,CAAC,GAC5B,OAAO,CAAC,IAAI,CAAC,CAMf"}
@@ -17,13 +17,33 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
17
17
  };
18
18
  import { chmod, copyFile, lstat, mkdir, readlink, rm, stat, symlink, writeFile, } from "node:fs/promises";
19
19
  import { dirname, join, parse, relative, resolve, sep } from "node:path";
20
+ import { agentStoreKeys, DEPLOYMENT_STORE_MOUNT_PATH } from "../files.js";
20
21
  import { MEMORY_DIR_NAME } from "../memory.js";
21
22
  import { parseFrontmatter, serializeFrontmatter } from "./frontmatter.js";
22
23
  import { buildIdentitySection } from "./prompt-context.js";
24
+ /**
25
+ * First-turn preamble section for cloud-runtime sessions on hosted
26
+ * deployments: cloud VMs read the memory journal from the store mount.
27
+ */
28
+ export function buildCloudMemorySection(agentName) {
29
+ const dir = `${DEPLOYMENT_STORE_MOUNT_PATH}/${agentStoreKeys.memoryDir(agentName)}`;
30
+ return [
31
+ "## Shared session memory",
32
+ "",
33
+ `The cross-session memory journal (the \`memory/\` directory your instructions may reference) lives at \`${dir}\` on this machine — read \`${dir}/journal.jsonl\` with your normal file tools.`,
34
+ ].join("\n");
35
+ }
23
36
  /** Relative path of an agent-side tool script inside the session workspace. */
24
37
  export function agentToolScriptPath(toolName) {
25
38
  return `.agent-serve/tools/${toolName}.sh`;
26
39
  }
40
+ /**
41
+ * Reserved MCP connection name under which authored server tools are served
42
+ * to cloud turns (the session-bound tool MCP endpoint). Shared between the
43
+ * turn's MCP config and the first-prompt server-tool catalog so the model is
44
+ * told exactly where those tools live.
45
+ */
46
+ export const SERVER_TOOLS_MCP_SERVER_NAME = "agentsdk-tools";
27
47
  /**
28
48
  * Always-on identity line prepended when composing instructions. Sourced from
29
49
  * {@link ResolvedAgent.name} (`defineAgent({ name })`, else package/dir name)
@@ -104,12 +124,53 @@ export function buildAgentToolsCatalog(tools, options = { includeScripts: false
104
124
  }
105
125
  return `${parts.join("\n").trimEnd()}\n`;
106
126
  }
127
+ /**
128
+ * Markdown catalog of authored server tools for the cloud first prompt.
129
+ *
130
+ * Server tools execute on the serve host and reach cloud turns only as MCP
131
+ * tools on {@link SERVER_TOOLS_MCP_SERVER_NAME}. Instructions reference them
132
+ * by bare name, and the agent-tool catalog teaches a "recreate the script if
133
+ * missing" pattern — without this section a cloud model that cannot find a
134
+ * script for a server tool improvises a local substitute instead of calling
135
+ * the real tool, so its host-side effects silently never happen.
136
+ */
137
+ export function buildServerToolsCatalog(tools, options) {
138
+ const serverTools = tools.filter((tool) => tool.execution === "server");
139
+ if (serverTools.length === 0) {
140
+ return "";
141
+ }
142
+ const parts = [
143
+ "## Server tools",
144
+ "",
145
+ `These tools execute on the agent-serve host, not in this environment. They are available ONLY as MCP tools on the \`${options.mcpServerName}\` MCP server — list that server's tools and call them by name through your MCP tooling.`,
146
+ "There are no local scripts for these tools. NEVER create, edit, or run a local script or other substitute for them: a local re-implementation cannot produce their real effects on the host.",
147
+ "",
148
+ ];
149
+ for (const tool of serverTools) {
150
+ parts.push(`### \`${tool.name}\``);
151
+ parts.push("");
152
+ parts.push(tool.description.trim());
153
+ parts.push("");
154
+ parts.push("Input schema:");
155
+ parts.push("");
156
+ parts.push("```json");
157
+ parts.push(JSON.stringify(tool.inputSchema, null, 2));
158
+ parts.push("```");
159
+ parts.push("");
160
+ }
161
+ return `${parts.join("\n").trimEnd()}\n`;
162
+ }
107
163
  /**
108
164
  * The full AGENTS.md-equivalent context for an agent: instructions, identity
109
165
  * section, and the agent-side tool catalog. Written to the session workspace
110
166
  * as `AGENTS.md`, and inlined into the first turn's prompt when the harness
111
167
  * cannot discover that file (cloud runtime, or a local workspace the harness
112
168
  * will not treat as the project root — see {@link isNestedInGitRepo}).
169
+ *
170
+ * `serverToolsMcpName` is cloud-only: when the turn's MCP config carries the
171
+ * session-bound server-tool endpoint, the catalog names that server so the
172
+ * model calls the real tools instead of inventing local stand-ins. Local
173
+ * runtimes omit it — there the harness exposes server tools natively.
113
174
  */
114
175
  export function buildAgentsMdContent(agent, options) {
115
176
  var _a;
@@ -120,6 +181,11 @@ export function buildAgentsMdContent(agent, options) {
120
181
  buildAgentToolsCatalog(agent.tools, {
121
182
  includeScripts: options.includeScripts,
122
183
  }),
184
+ options.serverToolsMcpName === undefined
185
+ ? ""
186
+ : buildServerToolsCatalog(agent.tools, {
187
+ mcpServerName: options.serverToolsMcpName,
188
+ }),
123
189
  ]
124
190
  .filter((part) => part !== "")
125
191
  .join("\n\n");
package/dist/memory.d.ts CHANGED
@@ -16,11 +16,13 @@
16
16
  * path — typically a server tool under `agent/tools/`, which can resolve
17
17
  * state via `ctx.stateRoot`.
18
18
  *
19
- * TODO(agent-store): once agent-serve can mount the agent's AgentStore
20
- * (durable S3-backed filesystem shared across serve hosts and cloud VMs),
21
- * ship an AgentStore-backed backend and make it the default. The journal
22
- * format is designed to survive that move unchanged.
19
+ * On Cursor-managed hosting the default is {@link agentStoreMemoryBackend}:
20
+ * the journal lives on the deployment's Agent Store (survives deploys,
21
+ * visible on cloud VMs under the store mount) and is mirrored to
22
+ * `<stateRoot>/memory/journal.jsonl` so the workspace symlink read path
23
+ * keeps working for local-runtime turns.
23
24
  */
25
+ import { type FileSink } from "./files.js";
24
26
  import type { HookDefinition, TurnUsage } from "./types.js";
25
27
  /** Name of the shared memory directory under the agent state root. */
26
28
  export declare const MEMORY_DIR_NAME = "memory";
@@ -41,10 +43,11 @@ export type TurnMemoryRecord = {
41
43
  result?: string;
42
44
  usage?: TurnUsage;
43
45
  };
44
- /** Where turn records go. Receives the agent's state root per append. */
46
+ /** Where turn records go. Receives the agent's state root and name per append. */
45
47
  export interface MemoryBackend {
46
48
  appendTurn(record: TurnMemoryRecord, ctx: {
47
49
  stateRoot: string;
50
+ agentName: string;
48
51
  }): Promise<void>;
49
52
  }
50
53
  export interface FileMemoryBackendOptions {
@@ -55,11 +58,24 @@ export interface FileMemoryBackendOptions {
55
58
  maxJournalBytes?: number;
56
59
  }
57
60
  /**
58
- * Default backend: append-only JSONL at `<stateRoot>/memory/journal.jsonl`
61
+ * Local default backend: append-only JSONL at `<stateRoot>/memory/journal.jsonl`
59
62
  * — the directory the framework symlinks into session workspaces. Rotated
60
63
  * segments stay alongside as `journal-<epoch-ms>.jsonl`.
61
64
  */
62
65
  export declare function fileMemoryBackend(options?: FileMemoryBackendOptions): MemoryBackend;
66
+ export interface AgentStoreMemoryBackendOptions {
67
+ /** Sink override (tests). Defaults to the deployment's Agent Store. */
68
+ sink?: FileSink;
69
+ /** Rotation threshold, same meaning as {@link FileMemoryBackendOptions}. */
70
+ maxJournalBytes?: number;
71
+ }
72
+ /**
73
+ * Journal on the deployment's Agent Store — durable across deploys, visible
74
+ * on cloud VMs under the store mount. Appends are read-modify-write with
75
+ * etag preconditions (retried on a lost race), then mirrored to
76
+ * `<stateRoot>/memory/journal.jsonl` for the workspace symlink read path.
77
+ */
78
+ export declare function agentStoreMemoryBackend(options?: AgentStoreMemoryBackendOptions): MemoryBackend;
63
79
  export interface MemoryHookOptions {
64
80
  /** Where records go. Defaults to {@link fileMemoryBackend}. */
65
81
  backend?: MemoryBackend;
@@ -1 +1 @@
1
- {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAKH,OAAO,KAAK,EAAe,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,sEAAsE;AACtE,eAAO,MAAM,eAAe,WAAW,CAAC;AAExC,gDAAgD;AAChD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,yEAAyE;AACzE,MAAM,WAAW,aAAa;IAC5B,UAAU,CACR,MAAM,EAAE,gBAAgB,EACxB,GAAG,EAAE;QAAE,SAAS,EAAE,MAAM,CAAA;KAAE,GACzB,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,aAAa,CAgCf;AAED,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,cAAc,CAuF1E"}
1
+ {"version":3,"file":"memory.d.ts","sourceRoot":"","sources":["../src/memory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAKH,OAAO,EAAqC,KAAK,QAAQ,EAAE,MAAM,YAAY,CAAC;AAM9E,OAAO,KAAK,EAAe,cAAc,EAAE,SAAS,EAAE,MAAM,YAAY,CAAC;AAEzE,sEAAsE;AACtE,eAAO,MAAM,eAAe,WAAW,CAAC;AAExC,gDAAgD;AAChD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,+CAA+C;IAC/C,EAAE,EAAE,MAAM,CAAC;IACX,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,MAAM,EAAE,WAAW,GAAG,QAAQ,CAAC;IAC/B,+CAA+C;IAC/C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kEAAkE;IAClE,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0DAA0D;IAC1D,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,4EAA4E;IAC5E,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,SAAS,CAAC;CACnB,CAAC;AAEF,kFAAkF;AAClF,MAAM,WAAW,aAAa;IAC5B,UAAU,CACR,MAAM,EAAE,gBAAgB,EACxB,GAAG,EAAE;QAAE,SAAS,EAAE,MAAM,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,GAC5C,OAAO,CAAC,IAAI,CAAC,CAAC;CAClB;AAED,MAAM,WAAW,wBAAwB;IACvC;;;OAGG;IACH,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;GAIG;AACH,wBAAgB,iBAAiB,CAC/B,OAAO,GAAE,wBAA6B,GACrC,aAAa,CAgCf;AAED,MAAM,WAAW,8BAA8B;IAC7C,uEAAuE;IACvE,IAAI,CAAC,EAAE,QAAQ,CAAC;IAChB,4EAA4E;IAC5E,eAAe,CAAC,EAAE,MAAM,CAAC;CAC1B;AAED;;;;;GAKG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,GAAE,8BAAmC,GAC3C,aAAa,CAsEf;AAqBD,MAAM,WAAW,iBAAiB;IAChC,+DAA+D;IAC/D,OAAO,CAAC,EAAE,aAAa,CAAC;IACxB,yEAAyE;IACzE,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAMD;;;;;;;;GAQG;AACH,wBAAgB,UAAU,CAAC,OAAO,GAAE,iBAAsB,GAAG,cAAc,CA0F1E"}
package/dist/memory.js CHANGED
@@ -16,10 +16,11 @@
16
16
  * path — typically a server tool under `agent/tools/`, which can resolve
17
17
  * state via `ctx.stateRoot`.
18
18
  *
19
- * TODO(agent-store): once agent-serve can mount the agent's AgentStore
20
- * (durable S3-backed filesystem shared across serve hosts and cloud VMs),
21
- * ship an AgentStore-backed backend and make it the default. The journal
22
- * format is designed to survive that move unchanged.
19
+ * On Cursor-managed hosting the default is {@link agentStoreMemoryBackend}:
20
+ * the journal lives on the deployment's Agent Store (survives deploys,
21
+ * visible on cloud VMs under the store mount) and is mirrored to
22
+ * `<stateRoot>/memory/journal.jsonl` so the workspace symlink read path
23
+ * keeps working for local-runtime turns.
23
24
  */
24
25
  var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
25
26
  function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
@@ -30,13 +31,16 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
30
31
  step((generator = generator.apply(thisArg, _arguments || [])).next());
31
32
  });
32
33
  };
33
- import { appendFile, mkdir, rename, stat } from "node:fs/promises";
34
+ import { randomUUID } from "node:crypto";
35
+ import { appendFile, mkdir, rename, stat, writeFile } from "node:fs/promises";
34
36
  import { join } from "node:path";
37
+ import { agentStoreKeys, FileConflictError } from "./files.js";
38
+ import { cursorHostedFiles, isCursorHostedFilesAvailable, } from "./files-backends/cursor-hosted.js";
35
39
  import { defineHook } from "./hooks.js";
36
40
  /** Name of the shared memory directory under the agent state root. */
37
41
  export const MEMORY_DIR_NAME = "memory";
38
42
  /**
39
- * Default backend: append-only JSONL at `<stateRoot>/memory/journal.jsonl`
43
+ * Local default backend: append-only JSONL at `<stateRoot>/memory/journal.jsonl`
40
44
  * — the directory the framework symlinks into session workspaces. Rotated
41
45
  * segments stay alongside as `journal-<epoch-ms>.jsonl`.
42
46
  */
@@ -76,6 +80,91 @@ export function fileMemoryBackend(options = {}) {
76
80
  },
77
81
  };
78
82
  }
83
+ /**
84
+ * Journal on the deployment's Agent Store — durable across deploys, visible
85
+ * on cloud VMs under the store mount. Appends are read-modify-write with
86
+ * etag preconditions (retried on a lost race), then mirrored to
87
+ * `<stateRoot>/memory/journal.jsonl` for the workspace symlink read path.
88
+ */
89
+ export function agentStoreMemoryBackend(options = {}) {
90
+ var _a, _b;
91
+ const sink = (_a = options.sink) !== null && _a !== void 0 ? _a : cursorHostedFiles();
92
+ const maxJournalBytes = (_b = options.maxJournalBytes) !== null && _b !== void 0 ? _b : 5 * 1024 * 1024;
93
+ // Appends are chained per journal key (same shape as fileMemoryBackend);
94
+ // a failed append must not poison the chain for later turns.
95
+ const appendChains = new Map();
96
+ const append = (record, ctx) => __awaiter(this, void 0, void 0, function* () {
97
+ const key = agentStoreKeys.memoryJournal(ctx.agentName);
98
+ const line = Buffer.from(`${JSON.stringify(record)}\n`, "utf8");
99
+ for (let attempt = 0; attempt < 3; attempt += 1) {
100
+ const current = yield sink.get(key);
101
+ const currentBody = current === undefined
102
+ ? new Uint8Array(0)
103
+ : current instanceof Uint8Array
104
+ ? current
105
+ : current.body;
106
+ const etag = current === undefined || current instanceof Uint8Array
107
+ ? undefined
108
+ : current.etag;
109
+ let next;
110
+ let rotatedStamp;
111
+ if (currentBody.byteLength >= maxJournalBytes) {
112
+ rotatedStamp = `${Date.now()}-${randomUUID().slice(0, 8)}`;
113
+ yield sink.put(agentStoreKeys.memoryJournalRotated(ctx.agentName, rotatedStamp), currentBody, { ifMatch: null });
114
+ next = line;
115
+ }
116
+ else {
117
+ next = Buffer.concat([currentBody, line]);
118
+ }
119
+ try {
120
+ yield sink.put(key, next, {
121
+ ifMatch: current === undefined ? null : etag,
122
+ });
123
+ }
124
+ catch (error) {
125
+ if (error instanceof FileConflictError && attempt < 2) {
126
+ continue;
127
+ }
128
+ throw error;
129
+ }
130
+ yield mirrorJournalLocally(ctx.stateRoot, next);
131
+ if (rotatedStamp !== undefined) {
132
+ // Rotated segments sit beside the live journal locally too, so the
133
+ // workspace symlink read path keeps pre-rotation history.
134
+ yield writeFile(join(ctx.stateRoot, MEMORY_DIR_NAME, `journal-${rotatedStamp}.jsonl`), currentBody);
135
+ }
136
+ return;
137
+ }
138
+ });
139
+ return {
140
+ appendTurn(record, ctx) {
141
+ return __awaiter(this, void 0, void 0, function* () {
142
+ var _a;
143
+ const key = agentStoreKeys.memoryJournal(ctx.agentName);
144
+ const prior = (_a = appendChains.get(key)) !== null && _a !== void 0 ? _a : Promise.resolve();
145
+ const next = prior.catch(() => { }).then(() => append(record, ctx));
146
+ appendChains.set(key, next);
147
+ yield next;
148
+ });
149
+ },
150
+ };
151
+ }
152
+ /** Atomic full rewrite of the local mirror; also hydrates a fresh pod after a deploy. */
153
+ function mirrorJournalLocally(stateRoot, contents) {
154
+ return __awaiter(this, void 0, void 0, function* () {
155
+ const dir = join(stateRoot, MEMORY_DIR_NAME);
156
+ yield mkdir(dir, { recursive: true });
157
+ const tmp = join(dir, `.tmp-${randomUUID()}`);
158
+ yield writeFile(tmp, contents);
159
+ yield rename(tmp, join(dir, "journal.jsonl"));
160
+ });
161
+ }
162
+ /** Hosted deployments journal to the Agent Store; local dev to plain files. */
163
+ function defaultMemoryBackend() {
164
+ return isCursorHostedFilesAvailable()
165
+ ? agentStoreMemoryBackend()
166
+ : fileMemoryBackend();
167
+ }
79
168
  function truncate(text, max) {
80
169
  return text.length <= max ? text : `${text.slice(0, max)}…`;
81
170
  }
@@ -90,7 +179,7 @@ function truncate(text, max) {
90
179
  */
91
180
  export function memoryHook(options = {}) {
92
181
  var _a, _b;
93
- const backend = (_a = options.backend) !== null && _a !== void 0 ? _a : fileMemoryBackend();
182
+ const backend = (_a = options.backend) !== null && _a !== void 0 ? _a : defaultMemoryBackend();
94
183
  const maxTextLength = (_b = options.maxTextLength) !== null && _b !== void 0 ? _b : 2000;
95
184
  // Inbound message per turn (truncated at receipt so large pastes are not
96
185
  // retained), keyed `<sessionId>/<turnId>` — `message.received` and the
@@ -123,7 +212,10 @@ export function memoryHook(options = {}) {
123
212
  if (usage !== undefined) {
124
213
  entry.usage = usage;
125
214
  }
126
- yield backend.appendTurn(entry, { stateRoot: ctx.stateRoot });
215
+ yield backend.appendTurn(entry, {
216
+ stateRoot: ctx.stateRoot,
217
+ agentName: ctx.agent.name,
218
+ });
127
219
  });
128
220
  const sweepSession = (ctx) => {
129
221
  for (const key of pendingMessages.keys()) {