@cursor/july 0.1.1 → 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (199) hide show
  1. package/AGENTS.md +24 -2
  2. package/README.md +25 -15
  3. package/dist/bin/agent-serve.js +101 -12
  4. package/dist/channels/github/api.d.ts.map +1 -1
  5. package/dist/channels/github/api.js +31 -14
  6. package/dist/channels/github/cursor-account.d.ts +43 -0
  7. package/dist/channels/github/cursor-account.d.ts.map +1 -0
  8. package/dist/channels/github/cursor-account.js +95 -0
  9. package/dist/channels/github/github-channel.d.ts.map +1 -1
  10. package/dist/channels/github/github-channel.js +46 -9
  11. package/dist/channels/github/index.d.ts +2 -2
  12. package/dist/channels/github/index.js +2 -2
  13. package/dist/channels/github/types.d.ts +17 -0
  14. package/dist/channels/github/types.d.ts.map +1 -1
  15. package/dist/channels/slack/slack-channel.d.ts +8 -2
  16. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  17. package/dist/channels/slack/slack-channel.js +8 -0
  18. package/dist/channels/slack/types.d.ts +24 -3
  19. package/dist/channels/slack/types.d.ts.map +1 -1
  20. package/dist/channels/slack/types.js +15 -1
  21. package/dist/docs/404.html +2 -2
  22. package/dist/docs/ab.html +8 -8
  23. package/dist/docs/assets/{ab.md.COdXkces.js → ab.md.BMCZ6Hd7.js} +3 -3
  24. package/dist/docs/assets/{ab.md.COdXkces.lean.js → ab.md.BMCZ6Hd7.lean.js} +1 -1
  25. package/dist/docs/assets/{app.DqfFEmJd.js → app.Oje4vhlk.js} +1 -1
  26. package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +1 -0
  27. package/dist/docs/assets/chunks/{VPLocalSearchBox.BaLEdS15.js → VPLocalSearchBox.H5XZ2zCB.js} +1 -1
  28. package/dist/docs/assets/chunks/{theme.CZRvu_0q.js → theme.CTR_TuaE.js} +2 -2
  29. package/dist/docs/assets/{deployment.md.Dx1TYNk5.js → deployment.md.DTKwE15Z.js} +3 -3
  30. package/dist/docs/assets/{deployment.md.Dx1TYNk5.lean.js → deployment.md.DTKwE15Z.lean.js} +1 -1
  31. package/dist/docs/assets/{evals.md.DPZ_MAnI.js → evals.md.DAgEc_hL.js} +3 -3
  32. package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.js → guides_agent-to-agent.md.Bpzgq2Pq.js} +1 -1
  33. package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.js → guides_cloud-runtime.md.gVzabdQL.js} +1 -1
  34. package/dist/docs/assets/{guides_github.md.DwbKhCeS.js → guides_github.md.DOOCpqsW.js} +11 -4
  35. package/dist/docs/assets/{guides_github.md.DwbKhCeS.lean.js → guides_github.md.DOOCpqsW.lean.js} +1 -1
  36. package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.js → guides_human-in-the-loop.md.DlUqsp1S.js} +2 -2
  37. package/dist/docs/assets/{guides_slack.md.bv41fHfW.js → guides_slack.md.CCwqHvSV.js} +4 -4
  38. package/dist/docs/assets/{guides_slack.md.bv41fHfW.lean.js → guides_slack.md.CCwqHvSV.lean.js} +1 -1
  39. package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.js → guides_webhooks.md.B1EswtUu.js} +2 -2
  40. package/dist/docs/assets/index.md.m81y7TY7.js +20 -0
  41. package/dist/docs/assets/{index.md.BPKcj5AI.lean.js → index.md.m81y7TY7.lean.js} +1 -1
  42. package/dist/docs/assets/quickstart.md.CfU8_uTC.js +192 -0
  43. package/dist/docs/assets/quickstart.md.CfU8_uTC.lean.js +1 -0
  44. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.js → reference_agent-config.md.DrW2JUM8.js} +4 -4
  45. package/dist/docs/assets/{reference_agent-config.md.Bpd7HQwf.lean.js → reference_agent-config.md.DrW2JUM8.lean.js} +1 -1
  46. package/dist/docs/assets/{reference_channels.md.D7JTR03W.js → reference_channels.md.DdmiKgqf.js} +4 -4
  47. package/dist/docs/assets/{reference_channels.md.D7JTR03W.lean.js → reference_channels.md.DdmiKgqf.lean.js} +1 -1
  48. package/dist/docs/assets/{reference_connections.md.C3vNH_DE.js → reference_connections.md.zaEYCLHT.js} +1 -1
  49. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.js → reference_hooks.md.DyLVfE1O.js} +1 -1
  50. package/dist/docs/assets/{reference_hooks.md.BCEc3MyM.lean.js → reference_hooks.md.DyLVfE1O.lean.js} +1 -1
  51. package/dist/docs/assets/{reference_http-api.md.DBAahtdz.js → reference_http-api.md.Dx_nmDG6.js} +1 -1
  52. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.js → reference_instructions.md.CgoV-YEb.js} +9 -7
  53. package/dist/docs/assets/{reference_instructions.md.BC05LEQ8.lean.js → reference_instructions.md.CgoV-YEb.lean.js} +1 -1
  54. package/dist/docs/assets/{reference_schedules.md.D7qijxLk.js → reference_schedules.md.w_F2mXB6.js} +2 -2
  55. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.js → reference_skills.md.B_jHN7JL.js} +3 -3
  56. package/dist/docs/assets/{reference_skills.md.VQnlBT3Q.lean.js → reference_skills.md.B_jHN7JL.lean.js} +1 -1
  57. package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.js → reference_subagents.md.zWAMNfi1.js} +1 -1
  58. package/dist/docs/assets/{reference_tools.md.DF5kwlt0.js → reference_tools.md.CqgJroI0.js} +2 -2
  59. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.js +1 -0
  60. package/dist/docs/assets/scaffolding-agents.md.C3pTrmoE.lean.js +1 -0
  61. package/dist/docs/assets/storage.md.CVnInNiN.js +17 -0
  62. package/dist/docs/assets/storage.md.CVnInNiN.lean.js +1 -0
  63. package/dist/docs/building-with-agents.html +4 -4
  64. package/dist/docs/concepts.html +4 -4
  65. package/dist/docs/deployment.html +7 -7
  66. package/dist/docs/evals.html +7 -7
  67. package/dist/docs/guides/agent-to-agent.html +6 -6
  68. package/dist/docs/guides/cloud-runtime.html +5 -5
  69. package/dist/docs/guides/github.html +14 -7
  70. package/dist/docs/guides/human-in-the-loop.html +6 -6
  71. package/dist/docs/guides/slack.html +8 -8
  72. package/dist/docs/guides/webhooks.html +6 -6
  73. package/dist/docs/hashmap.json +1 -1
  74. package/dist/docs/hillclimbing.html +5 -5
  75. package/dist/docs/index.html +7 -7
  76. package/dist/docs/quickstart.html +180 -23
  77. package/dist/docs/reference/agent-config.html +7 -7
  78. package/dist/docs/reference/channels.html +8 -8
  79. package/dist/docs/reference/cli.html +4 -4
  80. package/dist/docs/reference/connections.html +5 -5
  81. package/dist/docs/reference/hooks.html +5 -5
  82. package/dist/docs/reference/http-api.html +6 -6
  83. package/dist/docs/reference/instructions.html +13 -11
  84. package/dist/docs/reference/playground.html +4 -4
  85. package/dist/docs/reference/project-layout.html +4 -4
  86. package/dist/docs/reference/schedules.html +7 -7
  87. package/dist/docs/reference/sessions.html +4 -4
  88. package/dist/docs/reference/skills.html +6 -6
  89. package/dist/docs/reference/subagents.html +6 -6
  90. package/dist/docs/reference/tools.html +7 -7
  91. package/dist/docs/scaffolding-agents.html +5 -5
  92. package/dist/docs/storage.html +41 -0
  93. package/dist/docs/troubleshooting.html +4 -4
  94. package/dist/index.d.ts +2 -0
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +1 -0
  97. package/dist/internal/cli-deploy.d.ts +52 -0
  98. package/dist/internal/cli-deploy.d.ts.map +1 -0
  99. package/dist/internal/cli-deploy.js +731 -0
  100. package/dist/internal/cursor/backend-client.d.ts +10 -1
  101. package/dist/internal/cursor/backend-client.d.ts.map +1 -1
  102. package/dist/internal/cursor/backend-client.js +79 -1
  103. package/dist/internal/cursor/github-credentials.d.ts +44 -0
  104. package/dist/internal/cursor/github-credentials.d.ts.map +1 -0
  105. package/dist/internal/cursor/github-credentials.js +195 -0
  106. package/dist/internal/deploy-client.d.ts +176 -0
  107. package/dist/internal/deploy-client.d.ts.map +1 -0
  108. package/dist/internal/deploy-client.js +375 -0
  109. package/dist/internal/discovery.d.ts.map +1 -1
  110. package/dist/internal/discovery.js +73 -5
  111. package/dist/internal/distribution.d.ts.map +1 -1
  112. package/dist/internal/distribution.js +1 -0
  113. package/dist/internal/eval-run-store.d.ts +22 -3
  114. package/dist/internal/eval-run-store.d.ts.map +1 -1
  115. package/dist/internal/eval-run-store.js +37 -19
  116. package/dist/internal/handleAgentServeTrigger.d.ts.map +1 -1
  117. package/dist/internal/handleAgentServeTrigger.js +10 -12
  118. package/dist/internal/host-platforms.d.ts +7 -2
  119. package/dist/internal/host-platforms.d.ts.map +1 -1
  120. package/dist/internal/host-platforms.js +15 -10
  121. package/dist/internal/hosting.d.ts +37 -0
  122. package/dist/internal/hosting.d.ts.map +1 -0
  123. package/dist/internal/hosting.js +67 -0
  124. package/dist/internal/reminder-runner.d.ts +7 -0
  125. package/dist/internal/reminder-runner.d.ts.map +1 -1
  126. package/dist/internal/reminder-runner.js +50 -6
  127. package/dist/internal/reminder-store.d.ts +2 -0
  128. package/dist/internal/reminder-store.d.ts.map +1 -1
  129. package/dist/internal/reminder-store.js +18 -0
  130. package/dist/internal/server.d.ts.map +1 -1
  131. package/dist/internal/server.js +173 -42
  132. package/dist/internal/session-engine.d.ts +49 -0
  133. package/dist/internal/session-engine.d.ts.map +1 -1
  134. package/dist/internal/session-engine.js +246 -17
  135. package/dist/internal/storage-coordinator.d.ts +139 -0
  136. package/dist/internal/storage-coordinator.d.ts.map +1 -0
  137. package/dist/internal/storage-coordinator.js +499 -0
  138. package/dist/playground/assets/cursor-icons-outline-BxTT_FVJ.woff2 +0 -0
  139. package/dist/playground/assets/index-B1Qc9h2u.css +1 -0
  140. package/dist/playground/assets/{index-FlWjhg3x.js → index-CpDYCj8W.js} +42 -42
  141. package/dist/playground/index.html +2 -2
  142. package/dist/storage.d.ts +204 -0
  143. package/dist/storage.d.ts.map +1 -0
  144. package/dist/storage.js +153 -0
  145. package/dist/types.d.ts +44 -3
  146. package/dist/types.d.ts.map +1 -1
  147. package/docs/README.md +3 -2
  148. package/docs/guides/github.md +43 -8
  149. package/docs/guides/slack.md +1 -1
  150. package/docs/quickstart.md +329 -51
  151. package/docs/reference/instructions.md +8 -6
  152. package/docs/scaffolding-agents.md +1 -1
  153. package/docs/storage.md +98 -0
  154. package/package.json +8 -1
  155. package/skills/github/SKILL.md +9 -1
  156. package/src/bin/agent-serve.ts +139 -0
  157. package/src/channels/github/api.ts +42 -23
  158. package/src/channels/github/cursor-account.ts +165 -0
  159. package/src/channels/github/github-channel.ts +66 -6
  160. package/src/channels/github/index.ts +2 -2
  161. package/src/channels/github/types.ts +19 -0
  162. package/src/channels/slack/slack-channel.ts +17 -3
  163. package/src/channels/slack/types.ts +44 -3
  164. package/src/index.ts +13 -0
  165. package/src/internal/cli-deploy.ts +940 -0
  166. package/src/internal/cursor/backend-client.ts +103 -1
  167. package/src/internal/cursor/github-credentials.ts +248 -0
  168. package/src/internal/deploy-client.ts +591 -0
  169. package/src/internal/discovery.ts +88 -1
  170. package/src/internal/distribution.ts +1 -0
  171. package/src/internal/eval-run-store.ts +48 -19
  172. package/src/internal/handleAgentServeTrigger.ts +10 -12
  173. package/src/internal/host-platforms.ts +28 -11
  174. package/src/internal/hosting.ts +77 -0
  175. package/src/internal/reminder-runner.ts +50 -6
  176. package/src/internal/reminder-store.ts +21 -0
  177. package/src/internal/server.ts +213 -27
  178. package/src/internal/session-engine.ts +285 -7
  179. package/src/internal/storage-coordinator.ts +615 -0
  180. package/src/storage.ts +325 -0
  181. package/src/types.ts +40 -2
  182. package/dist/docs/assets/chunks/@localSearchIndexroot.CcVk1uKq.js +0 -1
  183. package/dist/docs/assets/index.md.BPKcj5AI.js +0 -20
  184. package/dist/docs/assets/quickstart.md.tVPiGK_L.js +0 -35
  185. package/dist/docs/assets/quickstart.md.tVPiGK_L.lean.js +0 -1
  186. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.js +0 -1
  187. package/dist/docs/assets/scaffolding-agents.md.CyYfWGdc.lean.js +0 -1
  188. package/dist/playground/assets/cursor-icons-outline-oY2V_mvK.woff2 +0 -0
  189. package/dist/playground/assets/index-1K-hG-7p.css +0 -1
  190. /package/dist/docs/assets/{evals.md.DPZ_MAnI.lean.js → evals.md.DAgEc_hL.lean.js} +0 -0
  191. /package/dist/docs/assets/{guides_agent-to-agent.md.CrtrsySy.lean.js → guides_agent-to-agent.md.Bpzgq2Pq.lean.js} +0 -0
  192. /package/dist/docs/assets/{guides_cloud-runtime.md.CYlNMTNp.lean.js → guides_cloud-runtime.md.gVzabdQL.lean.js} +0 -0
  193. /package/dist/docs/assets/{guides_human-in-the-loop.md.Dvuctx7s.lean.js → guides_human-in-the-loop.md.DlUqsp1S.lean.js} +0 -0
  194. /package/dist/docs/assets/{guides_webhooks.md.hFTik3lf.lean.js → guides_webhooks.md.B1EswtUu.lean.js} +0 -0
  195. /package/dist/docs/assets/{reference_connections.md.C3vNH_DE.lean.js → reference_connections.md.zaEYCLHT.lean.js} +0 -0
  196. /package/dist/docs/assets/{reference_http-api.md.DBAahtdz.lean.js → reference_http-api.md.Dx_nmDG6.lean.js} +0 -0
  197. /package/dist/docs/assets/{reference_schedules.md.D7qijxLk.lean.js → reference_schedules.md.w_F2mXB6.lean.js} +0 -0
  198. /package/dist/docs/assets/{reference_subagents.md.CIRAVcPK.lean.js → reference_subagents.md.zWAMNfi1.lean.js} +0 -0
  199. /package/dist/docs/assets/{reference_tools.md.DF5kwlt0.lean.js → reference_tools.md.CqgJroI0.lean.js} +0 -0
@@ -21,36 +21,47 @@ import { discoverEvals, filterDiscoveredEvals, runDiscoveredEvals, } from "./eva
21
21
  const INTERRUPTED_BATCH_ERROR = "Eval run interrupted (serve process exited before completion)";
22
22
  const INTERRUPTED_CASE_ERROR = "Eval case interrupted (serve process exited before completion)";
23
23
  export class EvalRunStore {
24
- constructor(projectRoot, logger) {
24
+ constructor(projectRoot, logger,
25
+ /**
26
+ * Project-wide sink from `agent/storage.ts` (`defineStorage`),
27
+ * used when `evals.config.ts` sets no `persistRuns` of its own.
28
+ */
29
+ fallbackPersistence) {
25
30
  this.projectRoot = projectRoot;
26
31
  this.logger = logger;
32
+ this.fallbackPersistence = fallbackPersistence;
27
33
  this.runs = new Map();
28
34
  this.hydrated = false;
29
35
  /** Per-run persist chain so intermediate saves cannot overwrite a later final write. */
30
36
  this.persistChains = new Map();
31
37
  }
38
+ /** `evals.config.ts` `persistRuns` wins; `defineStorage` is fallback. */
39
+ resolvePersist(config) {
40
+ var _a;
41
+ return (_a = config.persistRuns) !== null && _a !== void 0 ? _a : this.fallbackPersistence;
42
+ }
32
43
  list() {
33
44
  return __awaiter(this, void 0, void 0, function* () {
34
- yield this.ensureHydrated();
45
+ yield this.hydrate();
35
46
  const { evals, config } = yield discoverEvals(this.projectRoot);
36
47
  return {
37
48
  evals: evals.map((e) => (Object.assign(Object.assign({ id: e.id, fileId: e.fileId }, (e.definition.description === undefined
38
49
  ? {}
39
50
  : { description: e.definition.description })), (e.definition.tags === undefined ? {} : { tags: e.definition.tags })))),
40
- config: snapshotListConfig(config),
51
+ config: snapshotListConfig(config, this.resolvePersist(config) !== undefined),
41
52
  };
42
53
  });
43
54
  }
44
55
  get(runId) {
45
56
  return __awaiter(this, void 0, void 0, function* () {
46
- yield this.ensureHydrated();
57
+ yield this.hydrate();
47
58
  return this.runs.get(runId);
48
59
  });
49
60
  }
50
61
  /** Newest-first snapshots for playground rehydrate after navigation/reload. */
51
62
  listRuns() {
52
63
  return __awaiter(this, void 0, void 0, function* () {
53
- yield this.ensureHydrated();
64
+ yield this.hydrate();
54
65
  return this.sortedRuns();
55
66
  });
56
67
  }
@@ -61,7 +72,7 @@ export class EvalRunStore {
61
72
  */
62
73
  listRunsWithActive() {
63
74
  return __awaiter(this, void 0, void 0, function* () {
64
- yield this.ensureHydrated();
75
+ yield this.hydrate();
65
76
  const activeRunId = this.activeRunId;
66
77
  return Object.assign({ runs: this.sortedRuns() }, (activeRunId === undefined ? {} : { activeRunId }));
67
78
  });
@@ -71,7 +82,7 @@ export class EvalRunStore {
71
82
  }
72
83
  start() {
73
84
  return __awaiter(this, arguments, void 0, function* (input = {}) {
74
- yield this.ensureHydrated();
85
+ yield this.hydrate();
75
86
  if (this.activeRunId !== undefined) {
76
87
  const active = this.runs.get(this.activeRunId);
77
88
  if (active !== undefined && active.status === "running") {
@@ -103,12 +114,12 @@ export class EvalRunStore {
103
114
  done: 0,
104
115
  },
105
116
  cases,
106
- config: snapshotRunConfig(config),
117
+ config: snapshotRunConfig(config, this.resolvePersist(config) !== undefined),
107
118
  };
108
119
  this.runs.set(runId, snapshot);
109
120
  this.activeRunId = runId;
110
121
  yield this.pruneOldRuns(config);
111
- yield this.enqueuePersist(snapshot, config.persistRuns);
122
+ yield this.enqueuePersist(snapshot, this.resolvePersist(config));
112
123
  this.logger(`[agent-serve] eval run ${runId}: starting ${cases.length} case(s)`);
113
124
  void this.execute(runId, Object.assign(Object.assign({ baseUrl: loopbackUrl, evals: selected, config }, (input.bearerToken === undefined
114
125
  ? {}
@@ -119,7 +130,14 @@ export class EvalRunStore {
119
130
  sortedRuns() {
120
131
  return [...this.runs.values()].sort((a, b) => b.startedAt.localeCompare(a.startedAt));
121
132
  }
122
- ensureHydrated() {
133
+ /**
134
+ * Hydrate playground eval history from durable persistence
135
+ * (`evals.config.ts` `persistRuns`, else the `defineStorage`
136
+ * fallback). Called eagerly from the serve startup restore step —
137
+ * alongside session restore — and lazily as a safety net by every read.
138
+ * Idempotent; concurrent callers share one pass.
139
+ */
140
+ hydrate() {
123
141
  return __awaiter(this, void 0, void 0, function* () {
124
142
  if (this.hydrated) {
125
143
  return;
@@ -134,7 +152,7 @@ export class EvalRunStore {
134
152
  return __awaiter(this, void 0, void 0, function* () {
135
153
  try {
136
154
  const { config } = yield discoverEvals(this.projectRoot);
137
- const persist = config.persistRuns;
155
+ const persist = this.resolvePersist(config);
138
156
  if (persist === undefined) {
139
157
  this.hydrated = true;
140
158
  return;
@@ -187,7 +205,7 @@ export class EvalRunStore {
187
205
  continue;
188
206
  }
189
207
  this.runs.delete(stale.runId);
190
- yield this.persistDelete(stale.runId, config.persistRuns);
208
+ yield this.persistDelete(stale.runId, this.resolvePersist(config));
191
209
  }
192
210
  });
193
211
  }
@@ -283,7 +301,7 @@ export class EvalRunStore {
283
301
  this.applyCaseResult(runId, result);
284
302
  const run = this.runs.get(runId);
285
303
  if (run !== undefined) {
286
- void this.enqueuePersist(run, opts.config.persistRuns);
304
+ void this.enqueuePersist(run, this.resolvePersist(opts.config));
287
305
  }
288
306
  } }));
289
307
  const run = this.runs.get(runId);
@@ -292,7 +310,7 @@ export class EvalRunStore {
292
310
  }
293
311
  run.status = "completed";
294
312
  run.finishedAt = new Date().toISOString();
295
- yield this.enqueuePersist(run, opts.config.persistRuns);
313
+ yield this.enqueuePersist(run, this.resolvePersist(opts.config));
296
314
  this.logger(`[agent-serve] eval run ${runId}: done — ${run.summary.passed} passed, ${run.summary.failed} failed`);
297
315
  }
298
316
  catch (error) {
@@ -303,7 +321,7 @@ export class EvalRunStore {
303
321
  run.status = "failed";
304
322
  run.finishedAt = new Date().toISOString();
305
323
  run.error = error instanceof Error ? error.message : String(error);
306
- yield this.enqueuePersist(run, opts.config.persistRuns);
324
+ yield this.enqueuePersist(run, this.resolvePersist(opts.config));
307
325
  this.logger(`[agent-serve] eval run ${runId}: failed — ${run.error}`);
308
326
  }
309
327
  finally {
@@ -365,13 +383,13 @@ function markInterruptedRun(run) {
365
383
  }
366
384
  }
367
385
  }
368
- function snapshotListConfig(config) {
386
+ function snapshotListConfig(config, durableRuns) {
369
387
  return Object.assign(Object.assign(Object.assign({}, (config.maxConcurrency === undefined
370
388
  ? {}
371
- : { maxConcurrency: config.maxConcurrency })), (config.timeoutMs === undefined ? {} : { timeoutMs: config.timeoutMs })), { maxPlaygroundRuns: resolveEvalMaxPlaygroundRuns(config.maxPlaygroundRuns), durableRuns: config.persistRuns !== undefined });
389
+ : { maxConcurrency: config.maxConcurrency })), (config.timeoutMs === undefined ? {} : { timeoutMs: config.timeoutMs })), { maxPlaygroundRuns: resolveEvalMaxPlaygroundRuns(config.maxPlaygroundRuns), durableRuns });
372
390
  }
373
- function snapshotRunConfig(config) {
374
- const list = snapshotListConfig(config);
391
+ function snapshotRunConfig(config, durableRuns) {
392
+ const list = snapshotListConfig(config, durableRuns);
375
393
  return Object.assign(Object.assign(Object.assign({}, (list.maxConcurrency === undefined
376
394
  ? {}
377
395
  : { maxConcurrency: list.maxConcurrency })), (list.timeoutMs === undefined ? {} : { timeoutMs: list.timeoutMs })), { maxPlaygroundRuns: list.maxPlaygroundRuns, durableRuns: list.durableRuns });
@@ -1 +1 @@
1
- {"version":3,"file":"handleAgentServeTrigger.d.ts","sourceRoot":"","sources":["../../src/internal/handleAgentServeTrigger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,6BAA6B;IAC5C,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,uEAAuE;IACvE,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,sBAAsB,GAAG,4BAA4B,CAAC;AAElE,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC;KAC7D,CAAC,CAAC;CACJ,GAAG,6BAA6B,EAAE,CAkBlC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CAYlC"}
1
+ {"version":3,"file":"handleAgentServeTrigger.d.ts","sourceRoot":"","sources":["../../src/internal/handleAgentServeTrigger.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAMH,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,6BAA6B,CAAC;AACxE,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAEtD,MAAM,WAAW,6BAA6B;IAC5C,4DAA4D;IAC5D,IAAI,EAAE,MAAM,CAAC;IACb,oEAAoE;IACpE,OAAO,EAAE,oBAAoB,CAAC;IAC9B,uEAAuE;IACvE,IAAI,EAAE,kBAAkB,CAAC;CAC1B;AAED,MAAM,WAAW,4BAA4B;IAC3C,IAAI,EAAE,QAAQ,CAAC;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;IACzB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED,MAAM,MAAM,sBAAsB,GAAG,4BAA4B,CAAC;AAElE,MAAM,WAAW,6BAA6B;IAC5C,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,OAAO,CAAC;CACf;AAED,MAAM,WAAW,uBAAuB;IACtC,EAAE,EAAE,OAAO,CAAC;IACZ,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,OAAO,EAAE,6BAA6B,EAAE,CAAC;CAC1C;AAED;;;GAGG;AACH,wBAAgB,2BAA2B,CAAC,KAAK,EAAE;IACjD,MAAM,EAAE,KAAK,CAAC;QACZ,IAAI,EAAE,MAAM,CAAC;QACb,QAAQ,EAAE,KAAK,CAAC;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,UAAU,EAAE,MAAM,CAAA;SAAE,CAAC,CAAC;QACpD,gBAAgB,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,kBAAkB,CAAC;KAC7D,CAAC,CAAC;CACJ,GAAG,6BAA6B,EAAE,CAgBlC;AAED;;GAEG;AACH,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,sBAAsB,GAC5B,OAAO,CAAC,uBAAuB,CAAC,CAYlC"}
@@ -26,19 +26,17 @@ import { dispatchGitHubWebhook, getGitHubChannelOptions, } from "../channels/git
26
26
  export function collectGitHubTriggerTargets(input) {
27
27
  const targets = [];
28
28
  for (const mount of input.mounts) {
29
- const github = mount.channels.find((channel) => channel.id === "github");
30
- if (github === undefined) {
31
- continue;
32
- }
33
- const options = getGitHubChannelOptions(github.definition);
34
- if (options === undefined) {
35
- continue;
29
+ for (const channel of mount.channels) {
30
+ const options = getGitHubChannelOptions(channel.definition);
31
+ if (options === undefined) {
32
+ continue;
33
+ }
34
+ targets.push({
35
+ slug: mount.slug,
36
+ options,
37
+ args: mount.buildHandlerArgs(channel.id),
38
+ });
36
39
  }
37
- targets.push({
38
- slug: mount.slug,
39
- options,
40
- args: mount.buildHandlerArgs("github"),
41
- });
42
40
  }
43
41
  return targets;
44
42
  }
@@ -2,6 +2,7 @@
2
2
  * Host-side GitHub + Slack clients shared across tools, channel routes,
3
3
  * schedules, and channel packs — same injection pattern as MCP.
4
4
  */
5
+ import type { GitHubChannelCredentials } from "../channels/github/types.js";
5
6
  import type { HostGitHubClient, HostSlackClient } from "../types.js";
6
7
  export interface HostPlatforms {
7
8
  github: HostGitHubClient;
@@ -12,13 +13,16 @@ export interface HostPlatforms {
12
13
  * `app` = GitHub App installation token (preferred in production).
13
14
  * `env` / `gh` = local PAT / CLI fallbacks when App creds are unset.
14
15
  */
15
- export type HostGitHubAuthSource = "app" | "env" | "gh" | "unavailable";
16
+ export type HostGitHubAuthSource = "app" | "cursor-account" | "env" | "gh" | "unavailable";
17
+ export interface HostPlatformsOptions {
18
+ githubCredentials?: GitHubChannelCredentials;
19
+ }
16
20
  /**
17
21
  * Build host platforms from ambient credentials. Prefer App installation
18
22
  * auth when configured; otherwise fall back to PAT / `gh auth` for local
19
23
  * testing. Webhook-scoped calls should still prefer `ctx.github`.
20
24
  */
21
- export declare function createHostPlatforms(): HostPlatforms;
25
+ export declare function createHostPlatforms(options?: HostPlatformsOptions): HostPlatforms;
22
26
  /**
23
27
  * Detect ambient host GitHub auth without throwing.
24
28
  * Order matches {@link createGitHubOctokit}: App installation, then
@@ -36,5 +40,6 @@ export declare function resolveHostGitHubAuthSource(): Promise<HostGitHubAuthSou
36
40
  export declare function warmupHostGitHubAuth(options: {
37
41
  logger: (line: string) => void;
38
42
  github?: HostGitHubClient;
43
+ authSource?: HostGitHubAuthSource;
39
44
  }): Promise<HostGitHubAuthSource>;
40
45
  //# sourceMappingURL=host-platforms.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"host-platforms.d.ts","sourceRoot":"","sources":["../../src/internal/host-platforms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAYH,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAAG,KAAK,GAAG,KAAK,GAAG,IAAI,GAAG,aAAa,CAAC;AAExE;;;;GAIG;AACH,wBAAgB,mBAAmB,IAAI,aAAa,CA4BnD;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAejF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,gBAAgB,CAAC;CAC3B,GAAG,OAAO,CAAC,oBAAoB,CAAC,CA8ChC"}
1
+ {"version":3,"file":"host-platforms.d.ts","sourceRoot":"","sources":["../../src/internal/host-platforms.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAWH,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,6BAA6B,CAAC;AAE5E,OAAO,KAAK,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,aAAa,CAAC;AAErE,MAAM,WAAW,aAAa;IAC5B,MAAM,EAAE,gBAAgB,CAAC;IACzB,KAAK,EAAE,eAAe,CAAC;CACxB;AAED;;;;GAIG;AACH,MAAM,MAAM,oBAAoB,GAC5B,KAAK,GACL,gBAAgB,GAChB,KAAK,GACL,IAAI,GACJ,aAAa,CAAC;AAElB,MAAM,WAAW,oBAAoB;IACnC,iBAAiB,CAAC,EAAE,wBAAwB,CAAC;CAC9C;AAED;;;;GAIG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,GAAE,oBAAyB,GACjC,aAAa,CA8Bf;AAED;;;;GAIG;AACH,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAejF;AAED;;;;;;;GAOG;AACH,wBAAsB,oBAAoB,CAAC,OAAO,EAAE;IAClD,MAAM,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC/B,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,UAAU,CAAC,EAAE,oBAAoB,CAAC;CACnC,GAAG,OAAO,CAAC,oBAAoB,CAAC,CAgDhC"}
@@ -20,13 +20,15 @@ import { tryResolveBotToken } from "../channels/slack/credentials.js";
20
20
  * auth when configured; otherwise fall back to PAT / `gh auth` for local
21
21
  * testing. Webhook-scoped calls should still prefer `ctx.github`.
22
22
  */
23
- export function createHostPlatforms() {
23
+ export function createHostPlatforms(options = {}) {
24
24
  let octokitPromise;
25
25
  let slackPromise;
26
26
  return {
27
27
  github: {
28
28
  getOctokit: () => {
29
- octokitPromise !== null && octokitPromise !== void 0 ? octokitPromise : (octokitPromise = createGitHubOctokit({}));
29
+ octokitPromise !== null && octokitPromise !== void 0 ? octokitPromise : (octokitPromise = createGitHubOctokit({
30
+ credentials: options.githubCredentials,
31
+ }));
30
32
  return octokitPromise;
31
33
  },
32
34
  },
@@ -76,7 +78,8 @@ export function resolveHostGitHubAuthSource() {
76
78
  */
77
79
  export function warmupHostGitHubAuth(options) {
78
80
  return __awaiter(this, void 0, void 0, function* () {
79
- const source = yield resolveHostGitHubAuthSource();
81
+ var _a;
82
+ const source = (_a = options.authSource) !== null && _a !== void 0 ? _a : (yield resolveHostGitHubAuthSource());
80
83
  if (source === "unavailable") {
81
84
  options.logger("[agent-serve] GitHub auth: unavailable (set GITHUB_APP_ID + GITHUB_APP_PRIVATE_KEY + GITHUB_APP_INSTALLATION_ID, or GITHUB_TOKEN / GH_TOKEN, or run `gh auth login`)");
82
85
  return source;
@@ -90,13 +93,15 @@ export function warmupHostGitHubAuth(options) {
90
93
  options.logger(`[agent-serve] GitHub auth: failed to export GH_TOKEN for gh CLI: ${error instanceof Error ? error.message : String(error)}`);
91
94
  }
92
95
  }
93
- const label = source === "app"
94
- ? exportedGhToken
95
- ? "GitHub App installation token (also exported as GH_TOKEN for gh CLI)"
96
- : "GitHub App installation token"
97
- : source === "env"
98
- ? "GITHUB_TOKEN/GH_TOKEN"
99
- : "gh auth token";
96
+ const label = source === "cursor-account"
97
+ ? "Cursor account repo-scoped credential (also exported as GH_TOKEN for gh CLI)"
98
+ : source === "app"
99
+ ? exportedGhToken
100
+ ? "GitHub App installation token (also exported as GH_TOKEN for gh CLI)"
101
+ : "GitHub App installation token"
102
+ : source === "env"
103
+ ? "GITHUB_TOKEN/GH_TOKEN"
104
+ : "gh auth token";
100
105
  if (options.github === undefined) {
101
106
  options.logger(`[agent-serve] GitHub auth: ${label}`);
102
107
  return source;
@@ -0,0 +1,37 @@
1
+ /**
2
+ * Client-side mirrors of the Agent Serve hosting validation rules
3
+ * (backend/server/src/agentServe/agentServeShared.ts). Shared by discovery
4
+ * (`hosting` block diagnostics on `agentkit validate`) and the deploy /
5
+ * secrets CLI verbs (actionable errors before any network call). The
6
+ * backend stays authoritative — these exist so mistakes fail fast and
7
+ * locally with the same grammar the server enforces.
8
+ */
9
+ /** `hosting.egressDomains` cap (backend caps the deploy body at 20). */
10
+ export declare const MAX_EGRESS_DOMAINS = 20;
11
+ /** Max secrets per deployment. */
12
+ export declare const MAX_SECRETS = 32;
13
+ /** Max secret value size in bytes. */
14
+ export declare const MAX_SECRET_VALUE_BYTES = 4096;
15
+ /** Max secret name length. */
16
+ export declare const MAX_SECRET_NAME_LENGTH = 64;
17
+ /** Secret names the platform injects; user writes are rejected. */
18
+ export declare const RESERVED_SECRET_NAME_PREFIX = "CURSOR_";
19
+ /** Returns a human error message, or undefined when the domain is valid. */
20
+ export declare function validateEgressDomain(domain: string): string | undefined;
21
+ /**
22
+ * Returns a human error message, or undefined when the name is a valid
23
+ * secret name. Grammar only — reserved names are checked separately so the
24
+ * manifest's declarative `secretNames` can mention them with a softer
25
+ * diagnostic than the hard write-time rejection.
26
+ */
27
+ export declare function validateSecretName(name: string): string | undefined;
28
+ /** True when the platform reserves this name (`CURSOR_*`); writes are rejected. */
29
+ export declare function isReservedSecretName(name: string): boolean;
30
+ /**
31
+ * Human error for a secret name a user is trying to write or delete:
32
+ * grammar plus the reserved `CURSOR_*` prefix.
33
+ */
34
+ export declare function validateSettableSecretName(name: string): string | undefined;
35
+ /** `owner/name` — mirrors the backend's cursor-event repo grammar. */
36
+ export declare function isValidCursorEventRepo(repo: string): boolean;
37
+ //# sourceMappingURL=hosting.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hosting.d.ts","sourceRoot":"","sources":["../../src/internal/hosting.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,wEAAwE;AACxE,eAAO,MAAM,kBAAkB,KAAK,CAAC;AACrC,kCAAkC;AAClC,eAAO,MAAM,WAAW,KAAK,CAAC;AAC9B,sCAAsC;AACtC,eAAO,MAAM,sBAAsB,OAAO,CAAC;AAC3C,8BAA8B;AAC9B,eAAO,MAAM,sBAAsB,KAAK,CAAC;AACzC,mEAAmE;AACnE,eAAO,MAAM,2BAA2B,YAAY,CAAC;AASrD,4EAA4E;AAC5E,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAKvE;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAQnE;AAED,mFAAmF;AACnF,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE1D;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAS3E;AAID,sEAAsE;AACtE,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAE5D"}
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Client-side mirrors of the Agent Serve hosting validation rules
3
+ * (backend/server/src/agentServe/agentServeShared.ts). Shared by discovery
4
+ * (`hosting` block diagnostics on `agentkit validate`) and the deploy /
5
+ * secrets CLI verbs (actionable errors before any network call). The
6
+ * backend stays authoritative — these exist so mistakes fail fast and
7
+ * locally with the same grammar the server enforces.
8
+ */
9
+ /** `hosting.egressDomains` cap (backend caps the deploy body at 20). */
10
+ export const MAX_EGRESS_DOMAINS = 20;
11
+ /** Max secrets per deployment. */
12
+ export const MAX_SECRETS = 32;
13
+ /** Max secret value size in bytes. */
14
+ export const MAX_SECRET_VALUE_BYTES = 4096;
15
+ /** Max secret name length. */
16
+ export const MAX_SECRET_NAME_LENGTH = 64;
17
+ /** Secret names the platform injects; user writes are rejected. */
18
+ export const RESERVED_SECRET_NAME_PREFIX = "CURSOR_";
19
+ const SECRET_NAME_PATTERN = /^[A-Z][A-Z0-9_]*$/;
20
+ // Lowercase hostname with >=2 labels, an alphabetic TLD, and at most one
21
+ // leading `*.` wildcard. Labels: alphanumeric with interior hyphens.
22
+ const EGRESS_DOMAIN_PATTERN = /^(\*\.)?([a-z0-9]([a-z0-9-]*[a-z0-9])?\.)+[a-z]+$/;
23
+ /** Returns a human error message, or undefined when the domain is valid. */
24
+ export function validateEgressDomain(domain) {
25
+ if (EGRESS_DOMAIN_PATTERN.test(domain)) {
26
+ return undefined;
27
+ }
28
+ return `Invalid egress domain ${JSON.stringify(domain)}: use a lowercase hostname with at least two labels and an alphabetic TLD (e.g. "api.example.com"), optionally with a single leading "*." wildcard.`;
29
+ }
30
+ /**
31
+ * Returns a human error message, or undefined when the name is a valid
32
+ * secret name. Grammar only — reserved names are checked separately so the
33
+ * manifest's declarative `secretNames` can mention them with a softer
34
+ * diagnostic than the hard write-time rejection.
35
+ */
36
+ export function validateSecretName(name) {
37
+ if (name.length > MAX_SECRET_NAME_LENGTH) {
38
+ return `Secret name ${JSON.stringify(name)} is too long (max ${MAX_SECRET_NAME_LENGTH} characters).`;
39
+ }
40
+ if (!SECRET_NAME_PATTERN.test(name)) {
41
+ return `Invalid secret name ${JSON.stringify(name)}: use UPPER_SNAKE_CASE starting with a letter (${SECRET_NAME_PATTERN}).`;
42
+ }
43
+ return undefined;
44
+ }
45
+ /** True when the platform reserves this name (`CURSOR_*`); writes are rejected. */
46
+ export function isReservedSecretName(name) {
47
+ return name.startsWith(RESERVED_SECRET_NAME_PREFIX);
48
+ }
49
+ /**
50
+ * Human error for a secret name a user is trying to write or delete:
51
+ * grammar plus the reserved `CURSOR_*` prefix.
52
+ */
53
+ export function validateSettableSecretName(name) {
54
+ const nameError = validateSecretName(name);
55
+ if (nameError !== undefined) {
56
+ return nameError;
57
+ }
58
+ if (isReservedSecretName(name)) {
59
+ return `Secret name ${JSON.stringify(name)} is platform-reserved (CURSOR_*); the platform injects those values automatically.`;
60
+ }
61
+ return undefined;
62
+ }
63
+ const CURSOR_EVENT_REPO_PATTERN = /^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/;
64
+ /** `owner/name` — mirrors the backend's cursor-event repo grammar. */
65
+ export function isValidCursorEventRepo(repo) {
66
+ return CURSOR_EVENT_REPO_PATTERN.test(repo) && !repo.includes("..");
67
+ }
@@ -25,6 +25,13 @@ export declare class ReminderRunner {
25
25
  get storeRoot(): string;
26
26
  /** Start deadline timers for armed reminders (call after restore). */
27
27
  start(): Promise<void>;
28
+ /**
29
+ * Pull reminder records from `defineStorage` into `<stateRoot>/reminders`
30
+ * when local disk is empty for that id. Failures are logged and skipped.
31
+ */
32
+ private hydrateFromStorage;
33
+ /** Persist locally and mirror into the authored storage sink when present. */
34
+ private persist;
28
35
  stop(): void;
29
36
  create(input: ReminderCreateInput): Promise<ReminderInfo>;
30
37
  list(filter?: {
@@ -1 +1 @@
1
- {"version":3,"file":"reminder-runner.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAEV,mBAAmB,EAGnB,YAAY,EAEb,MAAM,aAAa,CAAC;AASrB,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE;IAFzC,YACE,UAAU,EAAE,MAAM,EACT,oBAAoB,EAAE,MAAM,EAAE,EAIxC;CACF;AAyDD,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,OAAO,CAAS;IAExB,YACmB,MAAM,EAAE,aAAa,EACrB,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAe,EAG3D;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,sEAAsE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA4B3B;IAED,IAAI,IAAI,IAAI,CAOX;IAEK,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8D9D;IAEK,IAAI,CAAC,MAAM,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA4B1B;IAEK,MAAM,CACV,EAAE,EAAE,MAAM,EACV,MAAM,SAAoB,GACzB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAkBnC;IAED,iFAAiF;IAC3E,qBAAqB,CACzB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAUjB;IAED,uDAAuD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1C,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAQD;IAED,OAAO,CAAC,QAAQ;IA4ChB,OAAO,CAAC,UAAU;YAQJ,IAAI;YAiHJ,aAAa;IAY3B,OAAO,CAAC,eAAe;IAsBvB;;;OAGG;YACW,mBAAmB;YAcnB,aAAa;YAcb,YAAY;IA0C1B,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,iBAAiB;YAeX,MAAM;YAYN,SAAS;CAoFxB;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
1
+ {"version":3,"file":"reminder-runner.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-runner.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,OAAO,KAAK,EAEV,mBAAmB,EAGnB,YAAY,EAEb,MAAM,aAAa,CAAC;AASrB,OAAO,EAEL,KAAK,cAAc,EAEpB,MAAM,qBAAqB,CAAC;AAE7B,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAE3E,OAAO,EAAE,uBAAuB,EAAE,MAAM,wBAAwB,CAAC;AAEjE,qBAAa,oBAAqB,SAAQ,KAAK;IAG3C,QAAQ,CAAC,oBAAoB,EAAE,MAAM,EAAE;IAFzC,YACE,UAAU,EAAE,MAAM,EACT,oBAAoB,EAAE,MAAM,EAAE,EAIxC;CACF;AAyDD,qBAAa,cAAc;IAUvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM;IAVzB,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAgB;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAmC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqC;IAC5D,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAqB;IAC5C,uEAAuE;IACvE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAoC;IAC9D,OAAO,CAAC,OAAO,CAAS;IAExB,YACmB,MAAM,EAAE,aAAa,EACrB,MAAM,GAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAe,EAG3D;IAED,IAAI,SAAS,IAAI,MAAM,CAEtB;IAED,sEAAsE;IAChE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CA+B3B;IAED;;;OAGG;YACW,kBAAkB;IA+BhC,8EAA8E;YAChE,OAAO;IAKrB,IAAI,IAAI,IAAI,CAOX;IAEK,MAAM,CAAC,KAAK,EAAE,mBAAmB,GAAG,OAAO,CAAC,YAAY,CAAC,CA8D9D;IAEK,IAAI,CAAC,MAAM,CAAC,EAAE;QAClB,MAAM,CAAC,EAAE,cAAc,CAAC,QAAQ,CAAC,CAAC;QAClC,OAAO,CAAC,EAAE,MAAM,CAAC;QACjB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CA4B1B;IAEK,MAAM,CACV,EAAE,EAAE,MAAM,EACV,MAAM,SAAoB,GACzB,OAAO,CAAC,YAAY,GAAG,SAAS,CAAC,CAkBnC;IAED,iFAAiF;IAC3E,qBAAqB,CACzB,iBAAiB,EAAE,MAAM,EACzB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,CAAC,CAUjB;IAED,uDAAuD;IACjD,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC;QAC1C,UAAU,EAAE,MAAM,CAAC;QACnB,OAAO,EAAE,OAAO,GAAG,MAAM,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;KACjB,CAAC,CAQD;IAED,OAAO,CAAC,QAAQ;IA4ChB,OAAO,CAAC,UAAU;YAQJ,IAAI;YAiHJ,aAAa;IAY3B,OAAO,CAAC,eAAe;IAsBvB;;;OAGG;YACW,mBAAmB;YAcnB,aAAa;YAcb,YAAY;IA0C1B,OAAO,CAAC,gBAAgB;IAyDxB,OAAO,CAAC,iBAAiB;YAeX,MAAM;YAYN,SAAS;CAoFxB;AAGD,YAAY,EAAE,cAAc,EAAE,MAAM,qBAAqB,CAAC"}
@@ -91,6 +91,9 @@ export class ReminderRunner {
91
91
  if (this.started)
92
92
  return;
93
93
  this.started = true;
94
+ // Materialize sink-backed reminders onto local disk before arming
95
+ // (local wins when both sides have the same id).
96
+ yield this.hydrateFromStorage();
94
97
  const armed = yield this.store.listArmed();
95
98
  let restored = 0;
96
99
  let disarmedOrphan = 0;
@@ -114,6 +117,47 @@ export class ReminderRunner {
114
117
  }
115
118
  });
116
119
  }
120
+ /**
121
+ * Pull reminder records from `defineStorage` into `<stateRoot>/reminders`
122
+ * when local disk is empty for that id. Failures are logged and skipped.
123
+ */
124
+ hydrateFromStorage() {
125
+ return __awaiter(this, void 0, void 0, function* () {
126
+ const storage = this.engine.storage;
127
+ if (storage === undefined || !storage.canBulkRestore) {
128
+ return;
129
+ }
130
+ let hydrated = 0;
131
+ try {
132
+ const remote = yield storage.listReminders();
133
+ for (const record of remote) {
134
+ const local = yield this.store.get(record.id);
135
+ if (local !== undefined) {
136
+ continue;
137
+ }
138
+ // Local write only — re-mirroring would just echo the sink.
139
+ yield this.store.save(record);
140
+ hydrated += 1;
141
+ }
142
+ }
143
+ catch (error) {
144
+ const message = error instanceof Error ? error.message : String(error);
145
+ this.logger(`[agent-serve] reminders: storage hydrate failed: ${message}`);
146
+ return;
147
+ }
148
+ if (hydrated > 0) {
149
+ this.logger(`[agent-serve] reminders: hydrated ${hydrated} reminder(s) from storage`);
150
+ }
151
+ });
152
+ }
153
+ /** Persist locally and mirror into the authored storage sink when present. */
154
+ persist(record) {
155
+ return __awaiter(this, void 0, void 0, function* () {
156
+ var _a;
157
+ yield this.store.save(record);
158
+ (_a = this.engine.storage) === null || _a === void 0 ? void 0 : _a.reminder(record);
159
+ });
160
+ }
117
161
  stop() {
118
162
  this.started = false;
119
163
  for (const timer of this.timers.values()) {
@@ -168,7 +212,7 @@ export class ReminderRunner {
168
212
  createdAt: now,
169
213
  updatedAt: now,
170
214
  };
171
- yield this.store.save(record);
215
+ yield this.persist(record);
172
216
  this.handlers.set(id, {
173
217
  run: input.run,
174
218
  untilFn,
@@ -216,7 +260,7 @@ export class ReminderRunner {
216
260
  }
217
261
  this.clearTimer(id);
218
262
  const updated = Object.assign(Object.assign({}, record), { status: "cancelled", disarmReason: reason, updatedAt: new Date().toISOString() });
219
- yield this.store.save(updated);
263
+ yield this.persist(updated);
220
264
  this.handlers.delete(id);
221
265
  return toInfo(updated);
222
266
  });
@@ -518,7 +562,7 @@ export class ReminderRunner {
518
562
  return __awaiter(this, void 0, void 0, function* () {
519
563
  this.clearTimer(record.id);
520
564
  const updated = Object.assign(Object.assign({}, record), { status: "disarmed", disarmReason: reason, updatedAt: new Date().toISOString() });
521
- yield this.store.save(updated);
565
+ yield this.persist(updated);
522
566
  this.handlers.delete(record.id);
523
567
  });
524
568
  }
@@ -552,14 +596,14 @@ export class ReminderRunner {
552
596
  scheduleKind: reschedule.delay !== undefined ? "delay" : "at", scheduleValue: reschedule.delay !== undefined
553
597
  ? String(reschedule.delay)
554
598
  : String(reschedule.at), updatedAt: new Date().toISOString() });
555
- yield this.store.save(updated);
599
+ yield this.persist(updated);
556
600
  this.armTimer(updated);
557
601
  return;
558
602
  }
559
603
  if (oneShot) {
560
604
  this.clearTimer(current.id);
561
605
  const updated = Object.assign(Object.assign({}, current), { fireCount: current.fireCount + 1, status: "completed", disarmReason: "one_shot_complete", updatedAt: new Date().toISOString() });
562
- yield this.store.save(updated);
606
+ yield this.persist(updated);
563
607
  this.handlers.delete(current.id);
564
608
  return;
565
609
  }
@@ -575,7 +619,7 @@ export class ReminderRunner {
575
619
  throw new Error(`Reminder "${current.id}" has recurring status with scheduleKind=${current.scheduleKind}`);
576
620
  }
577
621
  const updated = Object.assign(Object.assign({}, current), { fireCount: current.fireCount + 1, nextFireAtMs, updatedAt: new Date().toISOString() });
578
- yield this.store.save(updated);
622
+ yield this.persist(updated);
579
623
  this.armTimer(updated);
580
624
  });
581
625
  }
@@ -44,6 +44,8 @@ export interface ReminderRecord {
44
44
  createdAt: string;
45
45
  updatedAt: string;
46
46
  }
47
+ /** Narrow a sink value to a {@link ReminderRecord} (startup hydrate). */
48
+ export declare function isReminderRecord(value: unknown): value is ReminderRecord;
47
49
  export declare class ReminderStore {
48
50
  private readonly rootDir;
49
51
  constructor(rootDir: string);
@@ -1 +1 @@
1
- {"version":3,"file":"reminder-store.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,yBAAyB,EAAG,CAAU,CAAC;AAEpD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,yBAAyB,CAAC;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,oBAAoB,CAAC;IACnC,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,MAAM,EAAI;IAEhD,OAAO,CAAC,QAAQ;IAIV,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhC;IAEK,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAiBtC;IAEK,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3C;IAEK,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAsBzD;IAEK,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhD;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtC;CACF"}
1
+ {"version":3,"file":"reminder-store.d.ts","sourceRoot":"","sources":["../../src/internal/reminder-store.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAWH,OAAO,KAAK,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,EACf,MAAM,aAAa,CAAC;AAErB,eAAO,MAAM,yBAAyB,EAAG,CAAU,CAAC;AAEpD,YAAY,EACV,kBAAkB,EAClB,oBAAoB,EACpB,cAAc,GACf,MAAM,aAAa,CAAC;AAErB,yDAAyD;AACzD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,yBAAyB,CAAC;IAC1C,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,MAAM,CAAC;IAChB,mEAAmE;IACnE,SAAS,EAAE,MAAM,CAAC;IAClB,yEAAyE;IACzE,iBAAiB,EAAE,MAAM,CAAC;IAC1B,0DAA0D;IAC1D,MAAM,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IACjC,YAAY,EAAE,oBAAoB,CAAC;IACnC,4EAA4E;IAC5E,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,6DAA6D;IAC7D,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB;;;;OAIG;IACH,aAAa,EAAE,OAAO,CAAC;IACvB,yEAAyE;IACzE,UAAU,EAAE,OAAO,CAAC;IACpB,+EAA+E;IAC/E,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,kBAAkB,CAAC;IAC/B,MAAM,EAAE,cAAc,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AAED,yEAAyE;AACzE,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,cAAc,CAkBxE;AAED,qBAAa,aAAa;IACZ,OAAO,CAAC,QAAQ,CAAC,OAAO;IAApC,YAA6B,OAAO,EAAE,MAAM,EAAI;IAEhD,OAAO,CAAC,QAAQ;IAIV,UAAU,IAAI,OAAO,CAAC,IAAI,CAAC,CAEhC;IAEK,IAAI,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAiBtC;IAEK,SAAS,IAAI,OAAO,CAAC,cAAc,EAAE,CAAC,CAG3C;IAEK,GAAG,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,GAAG,SAAS,CAAC,CAsBzD;IAEK,IAAI,CAAC,MAAM,EAAE,cAAc,GAAG,OAAO,CAAC,IAAI,CAAC,CAYhD;IAEK,MAAM,CAAC,EAAE,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEtC;CACF"}
@@ -18,6 +18,24 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
18
18
  import { mkdir, readdir, readFile, rename, rm, writeFile, } from "node:fs/promises";
19
19
  import { join } from "node:path";
20
20
  export const REMINDER_SNAPSHOT_VERSION = 1;
21
+ /** Narrow a sink value to a {@link ReminderRecord} (startup hydrate). */
22
+ export function isReminderRecord(value) {
23
+ if (value === null || typeof value !== "object" || Array.isArray(value)) {
24
+ return false;
25
+ }
26
+ const record = value;
27
+ return (record.version === REMINDER_SNAPSHOT_VERSION &&
28
+ typeof record.id === "string" &&
29
+ record.id !== "" &&
30
+ typeof record.purpose === "string" &&
31
+ typeof record.channelId === "string" &&
32
+ typeof record.continuationToken === "string" &&
33
+ typeof record.scheduleKind === "string" &&
34
+ typeof record.scheduleValue === "string" &&
35
+ typeof record.status === "string" &&
36
+ typeof record.nextFireAtMs === "number" &&
37
+ Number.isFinite(record.nextFireAtMs));
38
+ }
21
39
  export class ReminderStore {
22
40
  constructor(rootDir) {
23
41
  this.rootDir = rootDir;
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAkBH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAkFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAmf3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA2BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAmFrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAapE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAYD,6EAA6E;AAC7E,MAAM,WAAW,0BAA0B;IACzC,oEAAoE;IACpE,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED;;;;GAIG;AACH,wBAAsB,WAAW,CAC/B,MAAM,EAAE,UAAU,EAAE,EACpB,OAAO,GAAE,YAAY,GAAG,0BAA+B,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAolB3B"}