@cursor/july 0.1.103 → 0.1.104

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 (186) hide show
  1. package/dist/channels/change-monitors/change-monitors-channel.d.ts +5 -0
  2. package/dist/channels/change-monitors/change-monitors-channel.d.ts.map +1 -0
  3. package/dist/channels/change-monitors/change-monitors-channel.js +41 -0
  4. package/dist/channels/change-monitors/index.d.ts +4 -0
  5. package/dist/channels/change-monitors/index.d.ts.map +1 -0
  6. package/dist/channels/change-monitors/index.js +2 -0
  7. package/dist/channels/change-monitors/types.d.ts +39 -0
  8. package/dist/channels/change-monitors/types.d.ts.map +1 -0
  9. package/dist/channels/change-monitors/types.js +1 -0
  10. package/dist/channels/github/defaults.d.ts.map +1 -1
  11. package/dist/channels/github/defaults.js +4 -0
  12. package/dist/channels/github/progress.d.ts +22 -0
  13. package/dist/channels/github/progress.d.ts.map +1 -1
  14. package/dist/channels/github/progress.js +32 -5
  15. package/dist/channels/issues/index.d.ts +4 -0
  16. package/dist/channels/issues/index.d.ts.map +1 -0
  17. package/dist/channels/issues/index.js +2 -0
  18. package/dist/channels/issues/issues-channel.d.ts +5 -0
  19. package/dist/channels/issues/issues-channel.d.ts.map +1 -0
  20. package/dist/channels/issues/issues-channel.js +37 -0
  21. package/dist/channels/issues/types.d.ts +33 -0
  22. package/dist/channels/issues/types.d.ts.map +1 -0
  23. package/dist/channels/issues/types.js +1 -0
  24. package/dist/docs/404.html +2 -2
  25. package/dist/docs/ab.html +4 -4
  26. package/dist/docs/assets/{app.DW9pXkpL.js → app.DbMWUyGb.js} +1 -1
  27. package/dist/docs/assets/chunks/@localSearchIndexroot.Bqsulb9K.js +1 -0
  28. package/dist/docs/assets/chunks/{VPLocalSearchBox.CdEIUwDg.js → VPLocalSearchBox.DcNeTh9o.js} +1 -1
  29. package/dist/docs/assets/chunks/{theme.YZMHgPgg.js → theme.DMjhY3gl.js} +2 -2
  30. package/dist/docs/assets/{guides_github.md.DKYiT9do.js → guides_github.md.c0gdGJ-D.js} +1 -1
  31. package/dist/docs/assets/{guides_github.md.DKYiT9do.lean.js → guides_github.md.c0gdGJ-D.lean.js} +1 -1
  32. package/dist/docs/assets/{reference_channels.md.Dz8Cnudp.js → reference_channels.md.DBGcaB7m.js} +2 -2
  33. package/dist/docs/assets/{reference_channels.md.Dz8Cnudp.lean.js → reference_channels.md.DBGcaB7m.lean.js} +1 -1
  34. package/dist/docs/building-with-agents.html +4 -4
  35. package/dist/docs/concepts.html +4 -4
  36. package/dist/docs/deployment.html +4 -4
  37. package/dist/docs/design/filesystem.md +376 -0
  38. package/dist/docs/evals.html +4 -4
  39. package/dist/docs/guides/agent-to-agent.html +4 -4
  40. package/dist/docs/guides/cloud-agents.html +4 -4
  41. package/dist/docs/guides/convert-automation.html +4 -4
  42. package/dist/docs/guides/github.html +6 -6
  43. package/dist/docs/guides/github.md +5 -0
  44. package/dist/docs/guides/human-in-the-loop.html +4 -4
  45. package/dist/docs/guides/mcp-oauth.html +4 -4
  46. package/dist/docs/guides/opentelemetry.html +4 -4
  47. package/dist/docs/guides/slack.html +4 -4
  48. package/dist/docs/guides/webhooks.html +4 -4
  49. package/dist/docs/hashmap.json +1 -1
  50. package/dist/docs/hillclimbing.html +4 -4
  51. package/dist/docs/index.html +4 -4
  52. package/dist/docs/llms-full.txt +406 -0
  53. package/dist/docs/llms.txt +1 -0
  54. package/dist/docs/quickstart.html +4 -4
  55. package/dist/docs/reference/agent-config.html +4 -4
  56. package/dist/docs/reference/artifacts.html +4 -4
  57. package/dist/docs/reference/channels.html +6 -6
  58. package/dist/docs/reference/channels.md +20 -0
  59. package/dist/docs/reference/cli.html +4 -4
  60. package/dist/docs/reference/connections.html +4 -4
  61. package/dist/docs/reference/extensions.html +4 -4
  62. package/dist/docs/reference/hooks.html +4 -4
  63. package/dist/docs/reference/http-api.html +4 -4
  64. package/dist/docs/reference/instructions.html +4 -4
  65. package/dist/docs/reference/playground.html +4 -4
  66. package/dist/docs/reference/project-layout.html +4 -4
  67. package/dist/docs/reference/prompt.html +4 -4
  68. package/dist/docs/reference/result.html +4 -4
  69. package/dist/docs/reference/schedules.html +4 -4
  70. package/dist/docs/reference/sessions.html +4 -4
  71. package/dist/docs/reference/skills.html +4 -4
  72. package/dist/docs/reference/subagents.html +4 -4
  73. package/dist/docs/reference/tools.html +4 -4
  74. package/dist/docs/scaffolding-agents.html +4 -4
  75. package/dist/docs/skills/ab.html +4 -4
  76. package/dist/docs/skills/create-agent.html +4 -4
  77. package/dist/docs/skills/debug.html +4 -4
  78. package/dist/docs/skills/evals.html +4 -4
  79. package/dist/docs/skills/framework-map.html +4 -4
  80. package/dist/docs/skills/github.html +4 -4
  81. package/dist/docs/skills/hillclimb.html +4 -4
  82. package/dist/docs/skills/index.html +4 -4
  83. package/dist/docs/skills/mcp-auth.html +4 -4
  84. package/dist/docs/skills/otel.html +4 -4
  85. package/dist/docs/skills/setup-slack.html +4 -4
  86. package/dist/docs/storage.html +4 -4
  87. package/dist/docs/templates/agentic-owners.html +4 -4
  88. package/dist/docs/templates/agents-md.html +4 -4
  89. package/dist/docs/templates/code-wiki.html +4 -4
  90. package/dist/docs/templates/demo.html +4 -4
  91. package/dist/docs/templates/pr-autofixer.html +4 -4
  92. package/dist/docs/templates/security-help.html +4 -4
  93. package/dist/docs/templates/security-reviewer.html +4 -4
  94. package/dist/docs/templates/triage.html +4 -4
  95. package/dist/docs/troubleshooting.html +4 -4
  96. package/dist/filesystem.d.ts +440 -0
  97. package/dist/filesystem.d.ts.map +1 -0
  98. package/dist/filesystem.js +1694 -0
  99. package/dist/index.d.ts +2 -0
  100. package/dist/index.d.ts.map +1 -1
  101. package/dist/index.js +1 -0
  102. package/dist/internal/continuation-channel.d.ts +4 -2
  103. package/dist/internal/continuation-channel.d.ts.map +1 -1
  104. package/dist/internal/continuation-channel.js +21 -12
  105. package/dist/internal/continuation-identity.d.ts +13 -5
  106. package/dist/internal/continuation-identity.d.ts.map +1 -1
  107. package/dist/internal/continuation-identity.js +74 -35
  108. package/dist/internal/discovery/agent.d.ts.map +1 -1
  109. package/dist/internal/discovery/agent.js +80 -8
  110. package/dist/internal/discovery/info.d.ts.map +1 -1
  111. package/dist/internal/discovery/info.js +3 -0
  112. package/dist/internal/factory-resource-channel.d.ts +33 -0
  113. package/dist/internal/factory-resource-channel.d.ts.map +1 -0
  114. package/dist/internal/factory-resource-channel.js +77 -0
  115. package/dist/internal/filesystem/errors.d.ts +64 -0
  116. package/dist/internal/filesystem/errors.d.ts.map +1 -0
  117. package/dist/internal/filesystem/errors.js +175 -0
  118. package/dist/internal/filesystem/format.d.ts +28 -0
  119. package/dist/internal/filesystem/format.d.ts.map +1 -0
  120. package/dist/internal/filesystem/format.js +213 -0
  121. package/dist/internal/filesystem/merge.d.ts +34 -0
  122. package/dist/internal/filesystem/merge.d.ts.map +1 -0
  123. package/dist/internal/filesystem/merge.js +196 -0
  124. package/dist/internal/filesystem/scratch.d.ts +59 -0
  125. package/dist/internal/filesystem/scratch.d.ts.map +1 -0
  126. package/dist/internal/filesystem/scratch.js +212 -0
  127. package/dist/internal/filesystem/sdk-schemas.d.ts +29 -0
  128. package/dist/internal/filesystem/sdk-schemas.d.ts.map +1 -0
  129. package/dist/internal/filesystem/sdk-schemas.js +153 -0
  130. package/dist/internal/filesystem/tools.d.ts +42 -0
  131. package/dist/internal/filesystem/tools.d.ts.map +1 -0
  132. package/dist/internal/filesystem/tools.js +618 -0
  133. package/dist/internal/filesystem/walk.d.ts +74 -0
  134. package/dist/internal/filesystem/walk.d.ts.map +1 -0
  135. package/dist/internal/filesystem/walk.js +339 -0
  136. package/dist/internal/guest-network.d.ts +5 -2
  137. package/dist/internal/guest-network.d.ts.map +1 -1
  138. package/dist/internal/guest-network.js +7 -2
  139. package/dist/internal/hosted-delivery.d.ts.map +1 -1
  140. package/dist/internal/hosted-delivery.js +12 -2
  141. package/dist/internal/sdk-runner.d.ts +1 -1
  142. package/dist/internal/sdk-runner.d.ts.map +1 -1
  143. package/dist/internal/sdk-runner.js +3 -1
  144. package/dist/internal/session-engine.d.ts +22 -0
  145. package/dist/internal/session-engine.d.ts.map +1 -1
  146. package/dist/internal/session-engine.js +362 -40
  147. package/dist/internal/testing/factory-resource-fixtures.d.ts +48 -0
  148. package/dist/internal/testing/factory-resource-fixtures.d.ts.map +1 -0
  149. package/dist/internal/testing/factory-resource-fixtures.js +41 -0
  150. package/dist/playground/assets/{index-59KvgREd.js → index-8YiozU89.js} +38 -38
  151. package/dist/playground/index.html +1 -1
  152. package/dist/types.d.ts +51 -3
  153. package/dist/types.d.ts.map +1 -1
  154. package/docs/design/filesystem.md +376 -0
  155. package/docs/guides/github.md +5 -0
  156. package/docs/reference/channels.md +20 -0
  157. package/package.json +16 -2
  158. package/src/channels/change-monitors/change-monitors-channel.ts +62 -0
  159. package/src/channels/change-monitors/index.ts +8 -0
  160. package/src/channels/change-monitors/types.ts +44 -0
  161. package/src/channels/github/defaults.ts +4 -0
  162. package/src/channels/github/progress.ts +76 -10
  163. package/src/channels/issues/index.ts +9 -0
  164. package/src/channels/issues/issues-channel.ts +51 -0
  165. package/src/channels/issues/types.ts +41 -0
  166. package/src/filesystem.ts +2074 -0
  167. package/src/index.ts +28 -0
  168. package/src/internal/continuation-channel.ts +29 -12
  169. package/src/internal/continuation-identity.ts +122 -37
  170. package/src/internal/discovery/agent.ts +87 -1
  171. package/src/internal/discovery/info.ts +3 -0
  172. package/src/internal/factory-resource-channel.ts +122 -0
  173. package/src/internal/filesystem/errors.ts +220 -0
  174. package/src/internal/filesystem/format.ts +276 -0
  175. package/src/internal/filesystem/merge.ts +195 -0
  176. package/src/internal/filesystem/scratch.ts +255 -0
  177. package/src/internal/filesystem/sdk-schemas.ts +204 -0
  178. package/src/internal/filesystem/tools.ts +821 -0
  179. package/src/internal/filesystem/walk.ts +369 -0
  180. package/src/internal/guest-network.ts +8 -2
  181. package/src/internal/hosted-delivery.ts +18 -1
  182. package/src/internal/sdk-runner.ts +4 -0
  183. package/src/internal/session-engine.ts +439 -29
  184. package/src/internal/testing/factory-resource-fixtures.ts +85 -0
  185. package/src/types.ts +49 -3
  186. package/dist/docs/assets/chunks/@localSearchIndexroot.nrl1ifBq.js +0 -1
@@ -25,6 +25,7 @@ import { SlackAskDedupeStore, SlackNudgeStore, } from "../channels/slack/nudge-s
25
25
  import { resolveDedicatedSlackHostBinding } from "../channels/slack/slack-channel.js";
26
26
  import { AGENT_SERVE_USER_STORE_FILES_SOURCE_ID, agentStoreKeys, DEPLOYMENT_STORE_MOUNT_PATH, USER_STORE_MOUNT_PATH, } from "../files.js";
27
27
  import { cursorHostedFiles, isCursorHostedFilesAvailable, isCursorUserStoreFilesAvailable, } from "../files-backends/cursor-hosted.js";
28
+ import { isFileSystemToolAlias, isMutatingFileSystemTool, localFileSystem, resolveFileSystemTools, resolveHostHarnessToolOptions, tempFs, unionFs, writeWorkspaceFilesToRoot, } from "../filesystem.js";
28
29
  import { storageKeysForArchitecture } from "../storage.js";
29
30
  import { DEFAULT_MODEL, DIRECT_TOOL_CALL_CHANNEL_ID, isCursorAccountTransport, isHostOauthConnectionTransport, isSymbolicConnectionTransport, } from "../types.js";
30
31
  import { ABCollector } from "./ab-collector.js";
@@ -43,6 +44,8 @@ import { describeError } from "./describe-error.js";
43
44
  import { isDevMode } from "./dev-mode.js";
44
45
  import { EventLogStore } from "./event-log.js";
45
46
  import { TurnEventMapper } from "./event-mapper.js";
47
+ import { applyWebScratchUpdate, ingestHostAgentToolsScratch, remapScratchPaths, } from "./filesystem/scratch.js";
48
+ import { fileSystemTool, hostFileToolsFromAuthored, rootFileToolsFromAuthored, synthesizeFileSystemTools, } from "./filesystem/tools.js";
46
49
  import { selectFrameworkStorageDefinition } from "./framework-storage-selection.js";
47
50
  import { createHostFilesApi } from "./host-files.js";
48
51
  import { createHostKvApi } from "./host-kv.js";
@@ -69,7 +72,7 @@ import { TurnGovernor } from "./turn-governor.js";
69
72
  import { TurnLeaseStore } from "./turn-lease-store.js";
70
73
  import { TurnOutbox } from "./turn-outbox.js";
71
74
  import { resolveAgentV2Hosting } from "./v2-hosting.js";
72
- import { buildAgentsMdContent, buildCloudMemorySection, buildCloudWorkspaceSection, ensureOwnGitRoot, isNestedInGitRepo, materializeWorkspace, SERVER_TOOLS_MCP_SERVER_NAME, writeWorkspaceFiles, } from "./workspace.js";
75
+ import { buildAgentsMdContent, buildCloudMemorySection, buildCloudWorkspaceSection, ensureOwnGitRoot, isNestedInGitRepo, materializeWorkspace, SERVER_TOOLS_MCP_SERVER_NAME, } from "./workspace.js";
73
76
  import { syncWorkspaceToStore } from "./workspace-sync.js";
74
77
  export const HTTP_CHANNEL_ID = "http";
75
78
  export { SCHEDULE_CHANNEL_PREFIX } from "./prompt-context.js";
@@ -218,6 +221,12 @@ export class SessionEngine {
218
221
  this.cloudCostBackfillDone = new Set();
219
222
  /** Deduped in-flight cloud cost backfills, keyed by session id. */
220
223
  this.cloudCostBackfill = new Map();
224
+ /** Per-session FileSystem handle cache (not a tree snapshot). */
225
+ this.sessionRoots = new Map();
226
+ /** In-flight factory resolves, so the first turn and a racing callTool share one handle. */
227
+ this.sessionRootInflight = new Map();
228
+ /** Per-turn `unionFs({ "/": authored, "/tmp": tempFs() })`. Dropped at end of turn. */
229
+ this.turnRoots = new Map();
221
230
  this.project = options.project;
222
231
  applyAgentContinuationDefaults(this.project);
223
232
  this.stateRoot = options.stateRoot;
@@ -1252,6 +1261,224 @@ export class SessionEngine {
1252
1261
  return this.interrupt(existing.sessionId);
1253
1262
  });
1254
1263
  }
1264
+ hasRootOverride() {
1265
+ return this.project.agent.root !== undefined;
1266
+ }
1267
+ /**
1268
+ * FileSystem for this turn or `callTool`. Authored `root` (static or
1269
+ * factory) is cached per session when `cache` is set; unscoped
1270
+ * `callTool` passes the invocation id and does not cache, so factories
1271
+ * cannot share one tree across callers. A static handle is used as
1272
+ * authored — every session sees that same object. Host-default agents
1273
+ * get `localFileSystem` against the harness cwd — same path verbs as
1274
+ * the Cursor SDK natives, always through the synthesized tools.
1275
+ */
1276
+ resolveFileSystem(options) {
1277
+ return __awaiter(this, void 0, void 0, function* () {
1278
+ const authored = this.project.agent.root;
1279
+ if (authored === undefined) {
1280
+ return localFileSystem({ cwd: options.cwd });
1281
+ }
1282
+ const authoredRoot = yield this.resolveAuthoredFileSystem(options);
1283
+ if (options.cache) {
1284
+ const existing = this.turnRoots.get(options.sessionId);
1285
+ if (existing !== undefined) {
1286
+ return existing.root;
1287
+ }
1288
+ }
1289
+ const root = unionFs({
1290
+ "/": authoredRoot,
1291
+ "/tmp": tempFs(),
1292
+ });
1293
+ if (options.cache && this.isTurnRunning(options.sessionId)) {
1294
+ this.turnRoots.set(options.sessionId, { root, cwd: options.cwd });
1295
+ }
1296
+ return root;
1297
+ });
1298
+ }
1299
+ resolveAuthoredFileSystem(options) {
1300
+ return __awaiter(this, void 0, void 0, function* () {
1301
+ const authored = this.project.agent.root;
1302
+ if (authored === undefined) {
1303
+ throw new Error("resolveAuthoredFileSystem requires an authored root");
1304
+ }
1305
+ if (options.cache) {
1306
+ const cached = this.sessionRoots.get(options.sessionId);
1307
+ if (cached !== undefined) {
1308
+ return cached;
1309
+ }
1310
+ const inflight = this.sessionRootInflight.get(options.sessionId);
1311
+ if (inflight !== undefined) {
1312
+ return inflight;
1313
+ }
1314
+ }
1315
+ const resolve = () => __awaiter(this, void 0, void 0, function* () {
1316
+ if (typeof authored !== "function") {
1317
+ return authored;
1318
+ }
1319
+ const host = this.hostForSession(options.cache ? options.sessionId : undefined);
1320
+ const ctx = Object.assign(Object.assign({ sessionId: options.sessionId, agentName: this.project.agent.name }, (options.continuationKey === undefined
1321
+ ? {}
1322
+ : { continuationKey: options.continuationKey })), { host: { files: host.files, reminders: host.reminders } });
1323
+ return yield authored(ctx);
1324
+ });
1325
+ if (!options.cache) {
1326
+ return resolve();
1327
+ }
1328
+ const pending = resolve();
1329
+ this.sessionRootInflight.set(options.sessionId, pending);
1330
+ try {
1331
+ const resolved = yield pending;
1332
+ this.sessionRoots.set(options.sessionId, resolved);
1333
+ return resolved;
1334
+ }
1335
+ finally {
1336
+ this.sessionRootInflight.delete(options.sessionId);
1337
+ }
1338
+ });
1339
+ }
1340
+ dropTurnFileSystem(sessionId) {
1341
+ this.turnRoots.delete(sessionId);
1342
+ }
1343
+ prepareScratchToolInput(options) {
1344
+ return __awaiter(this, void 0, void 0, function* () {
1345
+ if (options.sessionId === undefined) {
1346
+ return options.input;
1347
+ }
1348
+ const turn = this.turnRoots.get(options.sessionId);
1349
+ if (turn === undefined) {
1350
+ return options.input;
1351
+ }
1352
+ yield ingestHostAgentToolsScratch({
1353
+ cwd: turn.cwd,
1354
+ root: turn.root,
1355
+ });
1356
+ return remapScratchPaths(options.input, turn.cwd);
1357
+ });
1358
+ }
1359
+ withTurnScratchTools(tools, sessionId) {
1360
+ const turn = this.turnRoots.get(sessionId);
1361
+ if (turn === undefined) {
1362
+ return tools;
1363
+ }
1364
+ return tools.map((tool) => {
1365
+ const execute = tool.definition.execute;
1366
+ if (typeof execute !== "function") {
1367
+ return tool;
1368
+ }
1369
+ return Object.assign(Object.assign({}, tool), { definition: Object.assign(Object.assign({}, tool.definition), { execute: (input, ctx) => __awaiter(this, void 0, void 0, function* () {
1370
+ const remapped = yield this.prepareScratchToolInput({
1371
+ sessionId,
1372
+ input: input !== null &&
1373
+ typeof input === "object" &&
1374
+ !Array.isArray(input)
1375
+ ? input
1376
+ : {},
1377
+ });
1378
+ return execute(remapped, ctx);
1379
+ }) }) });
1380
+ });
1381
+ }
1382
+ nativeFileSystemOutcome(options) {
1383
+ return __awaiter(this, void 0, void 0, function* () {
1384
+ var _a;
1385
+ const { toolName, input, callId } = options;
1386
+ if (!isFileSystemToolAlias(toolName)) {
1387
+ return undefined;
1388
+ }
1389
+ // Same policy the authored callTool path asks: a dry-run write is
1390
+ // answered by the host. Native edit/delete used to return before
1391
+ // decideToolCall and persist through the FileSystem.
1392
+ const decision = decideToolCall({
1393
+ dryRun: options.dryRun === true,
1394
+ effect: isMutatingFileSystemTool(toolName) ? "write" : "read",
1395
+ input,
1396
+ });
1397
+ if (decision.kind === "answer") {
1398
+ return {
1399
+ callId,
1400
+ toolName,
1401
+ isError: false,
1402
+ result: decision.result,
1403
+ durationMs: 0,
1404
+ sessionId: options.sessionId,
1405
+ };
1406
+ }
1407
+ const root = yield this.resolveFileSystem({
1408
+ sessionId: (_a = options.sessionId) !== null && _a !== void 0 ? _a : callId,
1409
+ continuationKey: options.continuationKey,
1410
+ cache: options.sessionId !== undefined,
1411
+ cwd: options.cwd,
1412
+ });
1413
+ const rawArgs = input !== null && typeof input === "object" && !Array.isArray(input)
1414
+ ? input
1415
+ : {};
1416
+ const args = yield this.prepareScratchToolInput({
1417
+ sessionId: options.sessionId,
1418
+ input: rawArgs,
1419
+ });
1420
+ const tool = fileSystemTool(root, toolName, args);
1421
+ const execute = tool === null || tool === void 0 ? void 0 : tool.definition.execute;
1422
+ if (tool === undefined || typeof execute !== "function") {
1423
+ // A resolved root owns this native name. Falling through would let
1424
+ // an authored lookalike run, or surface UnknownToolError after we
1425
+ // already advertised the FileSystem tool.
1426
+ return {
1427
+ callId,
1428
+ toolName,
1429
+ isError: true,
1430
+ result: {
1431
+ status: "error",
1432
+ error: { message: `FileSystem cannot handle ${toolName}` },
1433
+ },
1434
+ durationMs: 0,
1435
+ sessionId: options.sessionId,
1436
+ errorMessage: `FileSystem cannot handle ${toolName}`,
1437
+ };
1438
+ }
1439
+ const validation = validateToolInput(tool.definition.inputSchema, args);
1440
+ if (!validation.ok) {
1441
+ return {
1442
+ callId,
1443
+ toolName,
1444
+ isError: true,
1445
+ result: {
1446
+ status: "error",
1447
+ error: { message: validation.message },
1448
+ },
1449
+ durationMs: 0,
1450
+ sessionId: options.sessionId,
1451
+ errorMessage: validation.message,
1452
+ };
1453
+ }
1454
+ try {
1455
+ const value = yield execute(validation.value, {
1456
+ toolCallId: callId,
1457
+ workspaceDir: options.cwd,
1458
+ });
1459
+ return {
1460
+ callId,
1461
+ toolName,
1462
+ isError: false,
1463
+ result: normalizeToolResult(value),
1464
+ durationMs: 0,
1465
+ sessionId: options.sessionId,
1466
+ };
1467
+ }
1468
+ catch (error) {
1469
+ const message = error instanceof Error ? error.message : String(error);
1470
+ return {
1471
+ callId,
1472
+ toolName,
1473
+ isError: true,
1474
+ result: { status: "error", error: { message } },
1475
+ durationMs: 0,
1476
+ sessionId: options.sessionId,
1477
+ errorMessage: message,
1478
+ };
1479
+ }
1480
+ });
1481
+ }
1255
1482
  /**
1256
1483
  * Local harness cwd for a session: per-send override, else the shared
1257
1484
  * `agent.local.workspaceDir`, else `<agent.local.cwd>/<sessionId>`, else
@@ -1298,14 +1525,16 @@ export class SessionEngine {
1298
1525
  const workspaceDir = (_a = agent.local) === null || _a === void 0 ? void 0 : _a.workspaceDir;
1299
1526
  if (workspaceDir === undefined ||
1300
1527
  agent.runtime !== "local" ||
1528
+ this.hasRootOverride() ||
1301
1529
  this.runner.prewarm === undefined) {
1302
1530
  return;
1303
1531
  }
1304
1532
  const startedAt = Date.now();
1305
1533
  try {
1306
- const outcome = yield this.runner.prewarm(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ workspaceDir, runnerStateDir: join(this.stateRoot, "runner"), sandbox: ((_b = agent.local) === null || _b === void 0 ? void 0 : _b.sandbox) === true }, (agent.allowedTools === undefined
1534
+ const harness = resolveHostHarnessToolOptions(agent.allowedTools);
1535
+ const outcome = yield this.runner.prewarm(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ workspaceDir, runnerStateDir: join(this.stateRoot, "runner"), sandbox: ((_b = agent.local) === null || _b === void 0 ? void 0 : _b.sandbox) === true }, (harness.tools === undefined ? {} : { tools: harness.tools })), (harness.disallowedTools === undefined
1307
1536
  ? {}
1308
- : { tools: agent.allowedTools })), {
1537
+ : { disallowedTools: harness.disallowedTools })), {
1309
1538
  // No session yet, so auth'd connections are omitted rather than
1310
1539
  // warmed without an identity; the per-send flag still has to match
1311
1540
  // the turns' requests or the warmed executor is one no turn asks for.
@@ -1333,7 +1562,7 @@ export class SessionEngine {
1333
1562
  }
1334
1563
  executeTurn(record, turnId, message, isFirstTurn, signal) {
1335
1564
  return __awaiter(this, void 0, void 0, function* () {
1336
- var _a, _b, _c, _d, _e, _f, _g;
1565
+ var _a, _b, _c, _d, _e, _f, _g, _h;
1337
1566
  const sessionId = record.sessionId;
1338
1567
  const workspaceDir = this.scaffoldDir(record);
1339
1568
  const harnessCwd = this.harnessCwd(record);
@@ -1380,22 +1609,24 @@ export class SessionEngine {
1380
1609
  // cwd is overridden (e.g. a PR worktree). A/B variant instruction
1381
1610
  // overlays are applied via agentForSession.
1382
1611
  const agent = this.agentForSession(record);
1383
- yield materializeWorkspace({
1384
- agent,
1385
- workspaceDir,
1386
- seed: isFirstTurn,
1387
- stateRoot: this.stateRoot,
1388
- });
1389
- this.materializedWorkspaces.add(sessionId);
1390
- // Must precede the carrier: the harness resolves rules, skills,
1391
- // `mcp.json` and hooks from its git root, so a workspace nested in an
1392
- // outer repo would load that repo's hooks instead of the ones written
1393
- // just below. Only for directories this session owns a borrowed
1394
- // checkout or worktree keeps its own root.
1395
- if (!this.hasBorrowedWorkspace(record)) {
1396
- yield ensureOwnGitRoot(harnessCwd);
1612
+ if (!this.hasRootOverride()) {
1613
+ yield materializeWorkspace({
1614
+ agent,
1615
+ workspaceDir,
1616
+ seed: isFirstTurn,
1617
+ stateRoot: this.stateRoot,
1618
+ });
1619
+ this.materializedWorkspaces.add(sessionId);
1620
+ // Must precede the carrier: the harness resolves rules, skills,
1621
+ // `mcp.json` and hooks from its git root, so a workspace nested in an
1622
+ // outer repo would load that repo's hooks instead of the ones written
1623
+ // just below. Only for directories this session owns — a borrowed
1624
+ // checkout or worktree keeps its own root.
1625
+ if (!this.hasBorrowedWorkspace(record)) {
1626
+ yield ensureOwnGitRoot(harnessCwd);
1627
+ }
1628
+ yield this.materializeNudgeCarrier(record, harnessCwd);
1397
1629
  }
1398
- yield this.materializeNudgeCarrier(record, harnessCwd);
1399
1630
  // Baseline before the agent can run, so a follow-up that arrives and
1400
1631
  // drains before the first tool boundary still counts as an increase.
1401
1632
  yield this.baselineDeliveredNudges(record);
@@ -1403,7 +1634,13 @@ export class SessionEngine {
1403
1634
  const pendingImages = record.pendingImages;
1404
1635
  if (pendingFiles !== undefined &&
1405
1636
  Object.keys(pendingFiles).length > 0) {
1406
- yield writeWorkspaceFiles(harnessCwd, pendingFiles);
1637
+ const root = yield this.resolveFileSystem({
1638
+ sessionId,
1639
+ continuationKey: (_a = record.continuationKey) !== null && _a !== void 0 ? _a : undefined,
1640
+ cache: true,
1641
+ cwd: harnessCwd,
1642
+ });
1643
+ yield writeWorkspaceFilesToRoot(root, pendingFiles);
1407
1644
  }
1408
1645
  if ((pendingFiles !== undefined &&
1409
1646
  Object.keys(pendingFiles).length > 0) ||
@@ -1423,6 +1660,14 @@ export class SessionEngine {
1423
1660
  (this.hasBorrowedWorkspace(record) ||
1424
1661
  (yield isNestedInGitRepo(harnessCwd)));
1425
1662
  const request = yield this.buildTurnRequest(record, agent, turnId, message, isFirstTurn, instructionsInvisibleToHarness, emit, (update) => __awaiter(this, void 0, void 0, function* () {
1663
+ const turn = this.turnRoots.get(sessionId);
1664
+ if (turn !== undefined) {
1665
+ update = yield applyWebScratchUpdate({
1666
+ cwd: turn.cwd,
1667
+ root: turn.root,
1668
+ update,
1669
+ });
1670
+ }
1426
1671
  mapper.handleUpdate(update);
1427
1672
  // Yield so the HTTP NDJSON writer can flush tool start/result
1428
1673
  // events while sibling parallel tools are still executing.
@@ -1454,6 +1699,7 @@ export class SessionEngine {
1454
1699
  }
1455
1700
  finally {
1456
1701
  permit.release();
1702
+ this.dropTurnFileSystem(sessionId);
1457
1703
  this.approvals.cancelSession(sessionId, "deny");
1458
1704
  this.auths.cancelSession(sessionId, "deny");
1459
1705
  yield this.clearPendingApprovals(sessionId);
@@ -1468,15 +1714,15 @@ export class SessionEngine {
1468
1714
  const title = mapper.title;
1469
1715
  yield this.updateRecord(sessionId, (current) => (Object.assign(Object.assign({}, current), { title })));
1470
1716
  }
1471
- const finalResult = (_a = outcome.result) !== null && _a !== void 0 ? _a : mapper.finalText;
1472
- const finalUsage = (_b = outcome.usage) !== null && _b !== void 0 ? _b : mapper.usage;
1717
+ const finalResult = (_b = outcome.result) !== null && _b !== void 0 ? _b : mapper.finalText;
1718
+ const finalUsage = (_c = outcome.usage) !== null && _c !== void 0 ? _c : mapper.usage;
1473
1719
  const finalCost = finalUsage === undefined
1474
1720
  ? undefined
1475
1721
  : yield this.estimateTurnCost({
1476
- model: (_c = this.project.agent.model) !== null && _c !== void 0 ? _c : DEFAULT_MODEL,
1722
+ model: (_d = this.project.agent.model) !== null && _d !== void 0 ? _d : DEFAULT_MODEL,
1477
1723
  usage: finalUsage,
1478
1724
  agentId: record.sdkAgentId,
1479
- conversationId: (_d = record.sdkAgentId) !== null && _d !== void 0 ? _d : sessionId,
1725
+ conversationId: (_e = record.sdkAgentId) !== null && _e !== void 0 ? _e : sessionId,
1480
1726
  });
1481
1727
  if (finalCost !== undefined) {
1482
1728
  outcome = Object.assign(Object.assign({}, outcome), { cost: finalCost });
@@ -1524,21 +1770,21 @@ export class SessionEngine {
1524
1770
  data: {
1525
1771
  message: interrupted
1526
1772
  ? "turn interrupted"
1527
- : ((_e = outcome.errorMessage) !== null && _e !== void 0 ? _e : (outcome.status === "cancelled"
1773
+ : ((_f = outcome.errorMessage) !== null && _f !== void 0 ? _f : (outcome.status === "cancelled"
1528
1774
  ? "turn cancelled"
1529
1775
  : "turn failed")),
1530
1776
  },
1531
1777
  });
1532
1778
  }
1533
1779
  const current = yield this.sessions.get(sessionId);
1534
- const mode = (_f = current === null || current === void 0 ? void 0 : current.mode) !== null && _f !== void 0 ? _f : record.mode;
1780
+ const mode = (_g = current === null || current === void 0 ? void 0 : current.mode) !== null && _g !== void 0 ? _g : record.mode;
1535
1781
  if (mode === "task") {
1536
1782
  yield this.appendEvent(sessionId, outcome.status === "finished"
1537
1783
  ? { type: "session.completed", turnId, data: {} }
1538
1784
  : {
1539
1785
  type: "session.failed",
1540
1786
  turnId,
1541
- data: { message: (_g = outcome.errorMessage) !== null && _g !== void 0 ? _g : "task failed" },
1787
+ data: { message: (_h = outcome.errorMessage) !== null && _h !== void 0 ? _h : "task failed" },
1542
1788
  });
1543
1789
  }
1544
1790
  else {
@@ -1649,6 +1895,7 @@ export class SessionEngine {
1649
1895
  buildTurnRequest(record, agent, turnId, prompt, isFirstTurn, instructionsInvisibleToHarness, emit, onUpdate, signal, images) {
1650
1896
  return __awaiter(this, void 0, void 0, function* () {
1651
1897
  var _a, _b, _c;
1898
+ var _d;
1652
1899
  // Per-session cloud attach (channel/tool handoff) forces cloud runtime
1653
1900
  // even when the agent defaults to local for chat server tools.
1654
1901
  const runtime = resolveSessionRuntime({
@@ -1659,6 +1906,15 @@ export class SessionEngine {
1659
1906
  // allowlist, and a restriction that silently does not apply is worse
1660
1907
  // than a refused turn. Non-local agents already fail discovery; this
1661
1908
  // guards hybrid agents' per-send cloud sessions.
1909
+ //
1910
+ // Factory roots omit `allowedTools` at discovery (the live handle is
1911
+ // resolved per session). The allowlist guard below therefore never
1912
+ // fires for `defineAgent({ root: (ctx) => … })` with omitted `tools`,
1913
+ // and a per-send `cloud` attach would skip the virtual-root allowlist
1914
+ // and run unrestricted on a VM. Any authored root refuses non-local turns.
1915
+ if (runtime !== "local" && this.hasRootOverride()) {
1916
+ throw new Error(`Agent "${agent.name}" declares root, which cannot be served on ${runtime} turns. Refusing the session rather than running it against the host VM.`);
1917
+ }
1662
1918
  if (runtime !== "local" && agent.allowedTools !== undefined) {
1663
1919
  throw new Error(`Agent "${agent.name}" declares a built-in tool allowlist (tools), which cannot be enforced on ${runtime} turns. Refusing the session rather than running it unrestricted.`);
1664
1920
  }
@@ -1679,6 +1935,38 @@ export class SessionEngine {
1679
1935
  override: record.cloudOverride,
1680
1936
  })
1681
1937
  : undefined;
1938
+ const authoredRoot = this.hasRootOverride();
1939
+ const root = runtime === "local"
1940
+ ? yield this.resolveFileSystem({
1941
+ sessionId: record.sessionId,
1942
+ continuationKey: (_d = record.continuationKey) !== null && _d !== void 0 ? _d : undefined,
1943
+ cache: true,
1944
+ cwd: this.harnessCwd(record),
1945
+ })
1946
+ : undefined;
1947
+ const harnessTools = runtime === "local" && root !== undefined
1948
+ ? authoredRoot
1949
+ ? {
1950
+ tools: resolveFileSystemTools({
1951
+ root,
1952
+ tools: agent.allowedTools,
1953
+ }),
1954
+ }
1955
+ : resolveHostHarnessToolOptions(agent.allowedTools)
1956
+ : undefined;
1957
+ const fileTools = root === undefined
1958
+ ? []
1959
+ : synthesizeFileSystemTools(root, authoredRoot
1960
+ ? rootFileToolsFromAuthored(agent.allowedTools)
1961
+ : hostFileToolsFromAuthored(agent.allowedTools));
1962
+ // Host-default keeps native SemanticSearch (the host index).
1963
+ // `localFileSystem.search` is empty, so synthesizing would
1964
+ // replace a working index with an empty custom tool.
1965
+ const synthesized = root === undefined
1966
+ ? []
1967
+ : this.withTurnScratchTools(authoredRoot
1968
+ ? fileTools
1969
+ : fileTools.filter((tool) => tool.name !== "SemanticSearch"), record.sessionId);
1682
1970
  let turnPrompt = prompt;
1683
1971
  if (isFirstTurn) {
1684
1972
  const contextBlock = buildSessionContextBlock({
@@ -1732,6 +2020,16 @@ export class SessionEngine {
1732
2020
  }
1733
2021
  turnPrompt = `${preamble}${sections}\n\n${turnPrompt}`;
1734
2022
  }
2023
+ else if (runtime === "local" && authoredRoot) {
2024
+ // Virtual roots skip materialize, so AGENTS.md never lands on disk.
2025
+ // Ship the same preamble the borrowed-cwd local path uses.
2026
+ const preamble = buildAgentsMdContent(Object.assign(Object.assign({}, agent), { tools: [...agent.tools, ...synthesized] }), { includeScripts: true });
2027
+ const workspaceInfo = `<user_info>\nWorkspace Path: /\n</user_info>`;
2028
+ turnPrompt =
2029
+ preamble === ""
2030
+ ? `${workspaceInfo}\n\n${turnPrompt}`
2031
+ : `${workspaceInfo}\n\n${preamble}\n\n${turnPrompt}`;
2032
+ }
1735
2033
  else if (runtime === "local" && instructionsInvisibleToHarness) {
1736
2034
  // Local workspace whose AGENTS.md the harness will not load. With a
1737
2035
  // borrowed harness cwd, agent tool scripts live only in the durable
@@ -1746,9 +2044,14 @@ export class SessionEngine {
1746
2044
  }
1747
2045
  return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ sessionId: record.sessionId }, (record.sdkAgentId === undefined
1748
2046
  ? {}
1749
- : { sdkAgentId: record.sdkAgentId })), { workspaceDir: this.harnessCwd(record), sandbox: ((_c = this.project.agent.local) === null || _c === void 0 ? void 0 : _c.sandbox) === true }), (runtime === "local" && agent.allowedTools !== undefined
1750
- ? { tools: agent.allowedTools }
1751
- : {})), { runnerStateDir: join(this.stateRoot, "runner"), prompt: turnPrompt, isFirstTurn }), (images !== undefined && images.length > 0 ? { images } : {})), (agent.model === undefined ? {} : { model: agent.model })), { runtime, agentName: agent.name }), (mergedCloud === undefined ? {} : { cloud: mergedCloud })), {
2047
+ : { sdkAgentId: record.sdkAgentId })), { workspaceDir: this.harnessCwd(record), sandbox: authoredRoot
2048
+ ? false
2049
+ : ((_c = this.project.agent.local) === null || _c === void 0 ? void 0 : _c.sandbox) === true }), (runtime === "local" && harnessTools !== undefined
2050
+ ? Object.assign(Object.assign({}, (harnessTools.tools === undefined
2051
+ ? {}
2052
+ : { tools: harnessTools.tools })), (harnessTools.disallowedTools === undefined
2053
+ ? {}
2054
+ : { disallowedTools: harnessTools.disallowedTools })) : {})), { runnerStateDir: join(this.stateRoot, "runner"), prompt: turnPrompt, isFirstTurn }), (images !== undefined && images.length > 0 ? { images } : {})), (agent.model === undefined ? {} : { model: agent.model })), { runtime, agentName: agent.name }), (mergedCloud === undefined ? {} : { cloud: mergedCloud })), {
1752
2055
  // The hosted Grok Bot harness reads no workspace AGENTS.md: grokbot
1753
2056
  // turns carry the composed instructions into the hosted session,
1754
2057
  // which surfaces them in the Sand system prompt. The box never sees
@@ -1759,7 +2062,7 @@ export class SessionEngine {
1759
2062
  : undefined }), (runtime === "cloud" && !isCursorHostedFilesAvailable()
1760
2063
  ? { agentServeAgent: this.project.name }
1761
2064
  : {})), { customTools: runtime === "local"
1762
- ? yield this.buildCustomTools(record, agent, turnId, emit)
2065
+ ? yield this.buildCustomTools(record, agent, turnId, emit, synthesized)
1763
2066
  : {}, mcpServers: this.buildMcpServers(runtime, record.sessionId, yield this.evaluateConnectionAuth(record)) }), (runtime === "local" && this.hasAttachedAuthedConnections()
1764
2067
  ? { perSendMcpServers: true }
1765
2068
  : {})), { subagents: buildRunnerSubagents(agent), onUpdate,
@@ -1982,8 +2285,8 @@ export class SessionEngine {
1982
2285
  return evaluated;
1983
2286
  });
1984
2287
  }
1985
- buildCustomTools(record, agent, turnId, emit) {
1986
- return __awaiter(this, void 0, void 0, function* () {
2288
+ buildCustomTools(record_1, agent_1, turnId_1, emit_1) {
2289
+ return __awaiter(this, arguments, void 0, function* (record, agent, turnId, emit, extraTools = []) {
1987
2290
  const tools = {};
1988
2291
  const register = (tool) => {
1989
2292
  tools[tool.name] = Object.assign(Object.assign(Object.assign({ description: tool.description, inputSchema: tool.inputSchema }, (tool.outputSchema === undefined
@@ -2003,7 +2306,7 @@ export class SessionEngine {
2003
2306
  });
2004
2307
  }) });
2005
2308
  };
2006
- for (const tool of agent.tools) {
2309
+ for (const tool of [...agent.tools, ...extraTools]) {
2007
2310
  if (tool.execution !== "server") {
2008
2311
  continue;
2009
2312
  }
@@ -2672,6 +2975,7 @@ export class SessionEngine {
2672
2975
  callTool(toolName_1) {
2673
2976
  return __awaiter(this, arguments, void 0, function* (toolName, input = {}, options = {}) {
2674
2977
  var _a;
2978
+ var _b, _c;
2675
2979
  const callId = newToolCallId(toolName);
2676
2980
  // Identity resolves before the tool lookup: advertised connection tools
2677
2981
  // only exist relative to a session (per-session auth), so finding them
@@ -2681,6 +2985,24 @@ export class SessionEngine {
2681
2985
  const session = identity.session;
2682
2986
  let workspaceDir = identity.workspaceDir;
2683
2987
  let scratchDir = identity.scratchDir;
2988
+ if (isFileSystemToolAlias(toolName) &&
2989
+ identity.busy &&
2990
+ record !== undefined &&
2991
+ isMutatingFileSystemTool(toolName)) {
2992
+ throw new SessionBusyError(record.sessionId);
2993
+ }
2994
+ const native = yield this.nativeFileSystemOutcome({
2995
+ toolName,
2996
+ input,
2997
+ callId,
2998
+ sessionId: record === null || record === void 0 ? void 0 : record.sessionId,
2999
+ continuationKey: (_c = (_b = record === null || record === void 0 ? void 0 : record.continuationKey) !== null && _b !== void 0 ? _b : session.continuationKey) !== null && _c !== void 0 ? _c : undefined,
3000
+ cwd: workspaceDir,
3001
+ dryRun: (record === null || record === void 0 ? void 0 : record.dryRun) === true,
3002
+ });
3003
+ if (native !== undefined) {
3004
+ return native;
3005
+ }
2684
3006
  let tool = this.project.agent.tools.find((t) => t.name === toolName);
2685
3007
  if (tool === undefined &&
2686
3008
  this.project.agent.connections.some((c) => c.advertiseTools === true)) {
@@ -2769,7 +3091,8 @@ export class SessionEngine {
2769
3091
  const turnMaterialized = record !== undefined &&
2770
3092
  identity.busy &&
2771
3093
  this.materializedWorkspaces.has(record.sessionId);
2772
- if (record === undefined || workspaceUnavailable || !turnMaterialized) {
3094
+ if (!this.hasRootOverride() &&
3095
+ (record === undefined || workspaceUnavailable || !turnMaterialized)) {
2773
3096
  yield materializeWorkspace({
2774
3097
  agent: this.project.agent,
2775
3098
  workspaceDir: record === undefined || workspaceUnavailable
@@ -3548,7 +3871,8 @@ export class SessionEngine {
3548
3871
  }
3549
3872
  runCloudTurnCostBackfill(sessionId) {
3550
3873
  return __awaiter(this, void 0, void 0, function* () {
3551
- var _a, _b;
3874
+ var _a;
3875
+ var _b, _c;
3552
3876
  const log = yield this.logs.get(sessionId);
3553
3877
  const events = yield log.snapshot(0);
3554
3878
  if (!events.some((event) => isUnpricedCompletedTurn(event))) {
@@ -3559,9 +3883,7 @@ export class SessionEngine {
3559
3883
  return;
3560
3884
  }
3561
3885
  const record = yield this.sessions.get(sessionId);
3562
- const sdkAgentId = (_a = ((record === null || record === void 0 ? void 0 : record.sdkAgentId) !== undefined && record.sdkAgentId.startsWith("bc-")
3563
- ? record.sdkAgentId
3564
- : undefined)) !== null && _a !== void 0 ? _a : cloudSdkAgentIdFromEvents(events);
3886
+ const sdkAgentId = (_b = (((_a = record === null || record === void 0 ? void 0 : record.sdkAgentId) === null || _a === void 0 ? void 0 : _a.startsWith("bc-")) ? record.sdkAgentId : undefined)) !== null && _b !== void 0 ? _b : cloudSdkAgentIdFromEvents(events);
3565
3887
  if (sdkAgentId === undefined) {
3566
3888
  return;
3567
3889
  }
@@ -3569,7 +3891,7 @@ export class SessionEngine {
3569
3891
  if (billed === undefined) {
3570
3892
  return;
3571
3893
  }
3572
- const model = (_b = this.project.agent.model) !== null && _b !== void 0 ? _b : DEFAULT_MODEL;
3894
+ const model = (_c = this.project.agent.model) !== null && _c !== void 0 ? _c : DEFAULT_MODEL;
3573
3895
  const patched = applyCloudUsageToEvents(events, billed, model);
3574
3896
  if (patched === undefined) {
3575
3897
  return;
@@ -0,0 +1,48 @@
1
+ /**
2
+ * Factory resource continuation fixtures shared by July and the control
3
+ * plane identity suite. Pure data: no imports, so server-shared can load
4
+ * this file by relative path without pulling `@cursor/july`.
5
+ */
6
+ export declare const FACTORY_CHECKPOINT_NAME: string;
7
+ export declare const FACTORY_ISSUE_NAME: string;
8
+ export interface FactoryCheckpointResourceFixture {
9
+ name: string;
10
+ deployment: string;
11
+ runKey: string;
12
+ issues: {
13
+ title: string;
14
+ };
15
+ evidenceSummary: string;
16
+ planRevision: string;
17
+ createTime: string;
18
+ description: string;
19
+ }
20
+ export interface FactoryIssueResourceFixture {
21
+ name: string;
22
+ title: string;
23
+ body: string;
24
+ state: "STATE_OPEN";
25
+ createTime: string;
26
+ updateTime: string;
27
+ path: string;
28
+ etag: string;
29
+ }
30
+ export interface CheckpointCreatedPayloadFixture {
31
+ eventId: string;
32
+ eventType: "checkpoint.created";
33
+ teamId: string;
34
+ occurredAtMs: number;
35
+ checkpoint: FactoryCheckpointResourceFixture;
36
+ }
37
+ export interface IssueCreatedPayloadFixture {
38
+ eventId: string;
39
+ eventType: "issue.created";
40
+ teamId: string;
41
+ occurredAtMs: number;
42
+ issue: FactoryIssueResourceFixture;
43
+ }
44
+ export declare const FACTORY_CHECKPOINT_RESOURCE: FactoryCheckpointResourceFixture;
45
+ export declare const FACTORY_ISSUE_RESOURCE: FactoryIssueResourceFixture;
46
+ export declare const CHECKPOINT_CREATED_PAYLOAD: CheckpointCreatedPayloadFixture;
47
+ export declare const ISSUE_CREATED_PAYLOAD: IssueCreatedPayloadFixture;
48
+ //# sourceMappingURL=factory-resource-fixtures.d.ts.map