@cursor/july 0.1.3 → 0.1.4

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 (134) hide show
  1. package/dist/bin/agent-serve.d.ts +1 -1
  2. package/dist/bin/agent-serve.js +40 -16
  3. package/dist/channels/slack/log.d.ts +1 -1
  4. package/dist/channels/slack/log.d.ts.map +1 -1
  5. package/dist/channels/slack/log.js +4 -5
  6. package/dist/channels/slack/setup.js +1 -1
  7. package/dist/channels/slack/socket-mode.d.ts.map +1 -1
  8. package/dist/channels/slack/socket-mode.js +10 -9
  9. package/dist/docs/404.html +2 -2
  10. package/dist/docs/ab.html +3 -3
  11. package/dist/docs/assets/{app.BR0RbIdx.js → app.DF-Yx4OP.js} +1 -1
  12. package/dist/docs/assets/chunks/@localSearchIndexroot.0XrheBv2.js +1 -0
  13. package/dist/docs/assets/chunks/{VPLocalSearchBox.qjsVTneI.js → VPLocalSearchBox.DSeJSudL.js} +1 -1
  14. package/dist/docs/assets/chunks/{theme.2Kg8jIp_.js → theme.DZVLTXOC.js} +2 -2
  15. package/dist/docs/assets/{index.md.m81y7TY7.js → index.md.Cylk70gg.js} +1 -1
  16. package/dist/docs/building-with-agents.html +3 -3
  17. package/dist/docs/concepts.html +3 -3
  18. package/dist/docs/deployment.html +3 -3
  19. package/dist/docs/evals.html +3 -3
  20. package/dist/docs/guides/agent-to-agent.html +3 -3
  21. package/dist/docs/guides/cloud-runtime.html +3 -3
  22. package/dist/docs/guides/github.html +3 -3
  23. package/dist/docs/guides/human-in-the-loop.html +3 -3
  24. package/dist/docs/guides/slack.html +3 -3
  25. package/dist/docs/guides/webhooks.html +3 -3
  26. package/dist/docs/hashmap.json +1 -1
  27. package/dist/docs/hillclimbing.html +3 -3
  28. package/dist/docs/index.html +5 -5
  29. package/dist/docs/quickstart.html +3 -3
  30. package/dist/docs/reference/agent-config.html +3 -3
  31. package/dist/docs/reference/channels.html +3 -3
  32. package/dist/docs/reference/cli.html +3 -3
  33. package/dist/docs/reference/connections.html +3 -3
  34. package/dist/docs/reference/hooks.html +3 -3
  35. package/dist/docs/reference/http-api.html +3 -3
  36. package/dist/docs/reference/instructions.html +3 -3
  37. package/dist/docs/reference/playground.html +3 -3
  38. package/dist/docs/reference/project-layout.html +3 -3
  39. package/dist/docs/reference/schedules.html +3 -3
  40. package/dist/docs/reference/sessions.html +3 -3
  41. package/dist/docs/reference/skills.html +3 -3
  42. package/dist/docs/reference/subagents.html +3 -3
  43. package/dist/docs/reference/tools.html +3 -3
  44. package/dist/docs/scaffolding-agents.html +3 -3
  45. package/dist/docs/storage.html +3 -3
  46. package/dist/docs/troubleshooting.html +3 -3
  47. package/dist/internal/ab-collector.js +3 -3
  48. package/dist/internal/ab-fold.js +1 -1
  49. package/dist/internal/cli-ax.d.ts +13 -5
  50. package/dist/internal/cli-ax.d.ts.map +1 -1
  51. package/dist/internal/cli-ax.js +41 -15
  52. package/dist/internal/cli-github.js +13 -13
  53. package/dist/internal/cursor/account-mcp.js +3 -3
  54. package/dist/internal/cursor/backend-client.js +1 -1
  55. package/dist/internal/cursor/credentials.d.ts +5 -3
  56. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  57. package/dist/internal/cursor/credentials.js +9 -6
  58. package/dist/internal/cursor/github-credentials.js +3 -3
  59. package/dist/internal/cursor-event-relay.js +1 -1
  60. package/dist/internal/cursor-relay-core.d.ts +1 -1
  61. package/dist/internal/cursor-relay-core.d.ts.map +1 -1
  62. package/dist/internal/cursor-relay-core.js +2 -1
  63. package/dist/internal/cursor-slack-relay.js +1 -1
  64. package/dist/internal/distribution.d.ts +7 -0
  65. package/dist/internal/distribution.d.ts.map +1 -1
  66. package/dist/internal/distribution.js +7 -0
  67. package/dist/internal/docs-site.js +3 -3
  68. package/dist/internal/eval-run-store.d.ts.map +1 -1
  69. package/dist/internal/eval-run-store.js +8 -8
  70. package/dist/internal/github-fanout.js +2 -2
  71. package/dist/internal/host-platforms.js +5 -5
  72. package/dist/internal/mcp-endpoint.d.ts.map +1 -1
  73. package/dist/internal/mcp-endpoint.js +1 -1
  74. package/dist/internal/playground/toolchain.js +6 -6
  75. package/dist/internal/reminder-runner.d.ts.map +1 -1
  76. package/dist/internal/reminder-runner.js +11 -11
  77. package/dist/internal/resolve-prod-target.d.ts +2 -0
  78. package/dist/internal/resolve-prod-target.d.ts.map +1 -1
  79. package/dist/internal/resolve-prod-target.js +44 -21
  80. package/dist/internal/resolved-connections.js +5 -5
  81. package/dist/internal/schedule-runner.js +1 -1
  82. package/dist/internal/server.js +14 -14
  83. package/dist/internal/session-engine.d.ts.map +1 -1
  84. package/dist/internal/session-engine.js +13 -13
  85. package/dist/internal/sessions-client.d.ts +13 -0
  86. package/dist/internal/sessions-client.d.ts.map +1 -1
  87. package/dist/internal/sessions-client.js +25 -0
  88. package/dist/internal/storage-coordinator.js +6 -6
  89. package/dist/internal/update-check.d.ts +93 -0
  90. package/dist/internal/update-check.d.ts.map +1 -0
  91. package/dist/internal/update-check.js +431 -0
  92. package/dist/playground/assets/{index-D-vo2lV_.css → index-Ct_Usdm8.css} +1 -1
  93. package/dist/playground/assets/index-Dsyb-Vaj.js +319 -0
  94. package/dist/playground/index.html +2 -2
  95. package/dist/types.d.ts +3 -1
  96. package/dist/types.d.ts.map +1 -1
  97. package/docs/README.md +0 -1
  98. package/package.json +2 -1
  99. package/skills/setup-slack/SKILL.md +1 -1
  100. package/src/bin/agent-serve.ts +42 -16
  101. package/src/channels/slack/log.ts +5 -5
  102. package/src/channels/slack/setup.ts +1 -1
  103. package/src/channels/slack/socket-mode.ts +11 -9
  104. package/src/internal/ab-collector.ts +3 -3
  105. package/src/internal/ab-fold.ts +1 -1
  106. package/src/internal/cli-ax.ts +55 -16
  107. package/src/internal/cli-github.ts +13 -15
  108. package/src/internal/cursor/account-mcp.ts +3 -3
  109. package/src/internal/cursor/backend-client.ts +1 -1
  110. package/src/internal/cursor/credentials.ts +12 -7
  111. package/src/internal/cursor/github-credentials.ts +3 -3
  112. package/src/internal/cursor-event-relay.ts +1 -1
  113. package/src/internal/cursor-relay-core.ts +4 -2
  114. package/src/internal/cursor-slack-relay.ts +1 -1
  115. package/src/internal/distribution.ts +8 -0
  116. package/src/internal/docs-site.ts +3 -3
  117. package/src/internal/eval-run-store.ts +8 -10
  118. package/src/internal/github-fanout.ts +2 -2
  119. package/src/internal/host-platforms.ts +5 -5
  120. package/src/internal/mcp-endpoint.ts +1 -3
  121. package/src/internal/playground/toolchain.ts +6 -6
  122. package/src/internal/reminder-runner.ts +11 -17
  123. package/src/internal/resolve-prod-target.ts +55 -23
  124. package/src/internal/resolved-connections.ts +5 -5
  125. package/src/internal/schedule-runner.ts +1 -1
  126. package/src/internal/server.ts +14 -14
  127. package/src/internal/session-engine.ts +13 -15
  128. package/src/internal/sessions-client.ts +34 -0
  129. package/src/internal/storage-coordinator.ts +6 -6
  130. package/src/internal/update-check.ts +552 -0
  131. package/src/types.ts +3 -1
  132. package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +0 -1
  133. package/dist/playground/assets/index-x60b9q2j.js +0 -312
  134. /package/dist/docs/assets/{index.md.m81y7TY7.lean.js → index.md.Cylk70gg.lean.js} +0 -0
@@ -143,7 +143,7 @@ export class ReminderRunner {
143
143
  }
144
144
  if (restored > 0 || disarmedOrphan > 0) {
145
145
  this.logger(
146
- `[agent-serve] reminders: restored ${restored} armed reminder(s)` +
146
+ `[agentkit] reminders: restored ${restored} armed reminder(s)` +
147
147
  (disarmedOrphan > 0
148
148
  ? `; disarmed ${disarmedOrphan} without live handlers`
149
149
  : "")
@@ -174,14 +174,12 @@ export class ReminderRunner {
174
174
  }
175
175
  } catch (error) {
176
176
  const message = error instanceof Error ? error.message : String(error);
177
- this.logger(
178
- `[agent-serve] reminders: storage hydrate failed: ${message}`
179
- );
177
+ this.logger(`[agentkit] reminders: storage hydrate failed: ${message}`);
180
178
  return;
181
179
  }
182
180
  if (hydrated > 0) {
183
181
  this.logger(
184
- `[agent-serve] reminders: hydrated ${hydrated} reminder(s) from storage`
182
+ `[agentkit] reminders: hydrated ${hydrated} reminder(s) from storage`
185
183
  );
186
184
  }
187
185
  }
@@ -366,7 +364,7 @@ export class ReminderRunner {
366
364
  const timer = setTimeout(() => {
367
365
  void this.fire(record.id).catch(async (error) => {
368
366
  this.logger(
369
- `[agent-serve] reminder "${record.id}" fire failed: ${
367
+ `[agentkit] reminder "${record.id}" fire failed: ${
370
368
  error instanceof Error ? error.message : String(error)
371
369
  }`
372
370
  );
@@ -384,7 +382,7 @@ export class ReminderRunner {
384
382
  await this.afterFire(current, "skip");
385
383
  } catch (rescheduleError) {
386
384
  this.logger(
387
- `[agent-serve] reminder "${record.id}" reschedule after failure failed: ${
385
+ `[agentkit] reminder "${record.id}" reschedule after failure failed: ${
388
386
  rescheduleError instanceof Error
389
387
  ? rescheduleError.message
390
388
  : String(rescheduleError)
@@ -447,7 +445,7 @@ export class ReminderRunner {
447
445
  }
448
446
  } catch (error) {
449
447
  this.logger(
450
- `[agent-serve] reminder "${id}" until() failed: ${
448
+ `[agentkit] reminder "${id}" until() failed: ${
451
449
  error instanceof Error ? error.message : String(error)
452
450
  }`
453
451
  );
@@ -460,7 +458,7 @@ export class ReminderRunner {
460
458
  if (record.busyPolicy === "skipIfBusy") {
461
459
  await this.afterFire(record, "skip");
462
460
  this.logger(
463
- `[agent-serve] reminder "${id}" (${record.purpose}) skipped: session busy`
461
+ `[agentkit] reminder "${id}" (${record.purpose}) skipped: session busy`
464
462
  );
465
463
  return { outcome: "fired", reason: "skipped_busy" };
466
464
  }
@@ -488,7 +486,7 @@ export class ReminderRunner {
488
486
  if (latest !== undefined && latest.status === "armed") {
489
487
  await this.disarm(latest, "run_stop");
490
488
  this.logger(
491
- `[agent-serve] reminder "${id}" (${record.purpose}) disarmed: run_stop`
489
+ `[agentkit] reminder "${id}" (${record.purpose}) disarmed: run_stop`
492
490
  );
493
491
  return { outcome: "fired", reason: "run_stop" };
494
492
  }
@@ -503,15 +501,11 @@ export class ReminderRunner {
503
501
 
504
502
  if (result.action === "skip") {
505
503
  await this.afterFire(latest, "skip", result.reschedule);
506
- this.logger(
507
- `[agent-serve] reminder "${id}" (${record.purpose}) skipped`
508
- );
504
+ this.logger(`[agentkit] reminder "${id}" (${record.purpose}) skipped`);
509
505
  return { outcome: "fired", reason: "skipped" };
510
506
  }
511
507
  await this.afterFire(latest, "delivered", result.reschedule);
512
- this.logger(
513
- `[agent-serve] reminder "${id}" (${record.purpose}) delivered`
514
- );
508
+ this.logger(`[agentkit] reminder "${id}" (${record.purpose}) delivered`);
515
509
  return { outcome: "fired", reason: "delivered" };
516
510
  } finally {
517
511
  this.firing.delete(id);
@@ -613,7 +607,7 @@ export class ReminderRunner {
613
607
  return { action: "delivered" };
614
608
  } catch (retryError) {
615
609
  this.logger(
616
- `[agent-serve] reminder "${record.id}" followup failed after wait: ${
610
+ `[agentkit] reminder "${record.id}" followup failed after wait: ${
617
611
  retryError instanceof Error
618
612
  ? retryError.message
619
613
  : String(retryError)
@@ -37,6 +37,8 @@ export interface ResolveProdTargetOptions {
37
37
  apiKey?: string;
38
38
  fetchImpl?: typeof fetch;
39
39
  err?: (text: string) => void;
40
+ /** Test seam for reachability-retry backoff. */
41
+ sleep?: (ms: number) => Promise<void>;
40
42
  }
41
43
 
42
44
  export interface ResolvedProdTarget {
@@ -68,35 +70,59 @@ export async function resolveProdTarget(
68
70
  );
69
71
  }
70
72
 
71
- let detail: DeploymentDetail;
72
- try {
73
- detail = await auth.client.getDeployment({
74
- teamId: auth.teamId,
75
- slug,
76
- });
77
- } catch (error) {
78
- if (error instanceof DeployApiError) {
73
+ // A hibernated engine can briefly omit engineAccess while getPod fails
74
+ // during wake. Retry a few times before surfacing "not reachable yet".
75
+ const maxReachabilityAttempts = 5;
76
+ const sleep = options.sleep ?? sleepMs;
77
+ let detail: DeploymentDetail | undefined;
78
+ for (let attempt = 0; attempt < maxReachabilityAttempts; attempt++) {
79
+ try {
80
+ detail = await auth.client.getDeployment({
81
+ teamId: auth.teamId,
82
+ slug,
83
+ });
84
+ } catch (error) {
85
+ if (error instanceof DeployApiError) {
86
+ throw new Error(
87
+ `Deployment "${slug}" (team ${auth.teamId}): ${error.message}`
88
+ );
89
+ }
90
+ throw error;
91
+ }
92
+
93
+ // `degraded` still serves the previous ACTIVE engine; allow runtime access
94
+ // when the control plane minted engineAccess for it.
95
+ const statusOk =
96
+ detail.status === "running" || detail.status === "degraded";
97
+ if (!statusOk) {
98
+ const lastError =
99
+ detail.lastError === null || detail.lastError === undefined
100
+ ? ""
101
+ : ` ${sanitizeCustomerFacingDetail(detail.lastError)}`;
79
102
  throw new Error(
80
- `Deployment "${slug}" (team ${auth.teamId}): ${error.message}`
103
+ `Deployment "${slug}" is ${detail.status}, not running.${lastError}\n` +
104
+ `Deploy or wait: \`${CLI} deploy --slug ${slug}\` / \`${CLI} deployment ${slug}\``
81
105
  );
82
106
  }
83
- throw error;
107
+ if (detail.engineAccess !== null && detail.engineAccess !== undefined) {
108
+ break;
109
+ }
110
+ if (attempt + 1 < maxReachabilityAttempts) {
111
+ if (attempt === 0) {
112
+ err(
113
+ `${stderrPalette().dim(
114
+ `Deployment "${slug}" is waking; waiting for engine access…`
115
+ )}\n`
116
+ );
117
+ }
118
+ await sleep(1000 * (attempt + 1));
119
+ }
84
120
  }
85
121
 
86
- // `degraded` still serves the previous ACTIVE engine; allow runtime access
87
- // when the control plane minted engineAccess for it.
88
- const access = detail.engineAccess;
89
- const statusOk = detail.status === "running" || detail.status === "degraded";
90
- if (!statusOk) {
91
- const lastError =
92
- detail.lastError === null || detail.lastError === undefined
93
- ? ""
94
- : ` ${sanitizeCustomerFacingDetail(detail.lastError)}`;
95
- throw new Error(
96
- `Deployment "${slug}" is ${detail.status}, not running.${lastError}\n` +
97
- `Deploy or wait: \`${CLI} deploy --slug ${slug}\` / \`${CLI} deployment ${slug}\``
98
- );
122
+ if (detail === undefined) {
123
+ throw new Error(`Deployment "${slug}" lookup failed.`);
99
124
  }
125
+ const access = detail.engineAccess;
100
126
  if (access === null || access === undefined) {
101
127
  throw new Error(
102
128
  `Deployment "${slug}" is ${detail.status} but is not reachable yet. ` +
@@ -126,6 +152,12 @@ function sanitizeCustomerFacingDetail(message: string): string {
126
152
  .replace(/\bcursorvm\.com\b/gi, "host");
127
153
  }
128
154
 
155
+ function sleepMs(ms: number): Promise<void> {
156
+ return new Promise((resolve) => {
157
+ setTimeout(resolve, ms);
158
+ });
159
+ }
160
+
129
161
  /** Resolve the deployment slug the same way `deploy` does for a single dir. */
130
162
  export function resolveProdSlug(options: {
131
163
  dir: string;
@@ -42,7 +42,7 @@ export function validateMountConnectionsConfig(args: {
42
42
  return;
43
43
  }
44
44
  throw new Error(
45
- `[agent-serve] agent "${label}" has Cursor account MCP connections with \`servers\` filters (${filteredRefs
45
+ `[agentkit] agent "${label}" has Cursor account MCP connections with \`servers\` filters (${filteredRefs
46
46
  .map((ref) => ref.name)
47
47
  .join(
48
48
  ", "
@@ -67,7 +67,7 @@ export function assertCloudCanHonorAccountServersFilters(args: {
67
67
  return;
68
68
  }
69
69
  throw new Error(
70
- `[agent-serve] cloud turn cannot honor Cursor account \`servers\` filters (${blocked
70
+ `[agentkit] cloud turn cannot honor Cursor account \`servers\` filters (${blocked
71
71
  .map((connection) => connection.name)
72
72
  .join(
73
73
  ", "
@@ -82,7 +82,7 @@ export function assertAccountConnectionsNotAnonymous(args: {
82
82
  }): void {
83
83
  if (args.allowAnonymous === true && args.hasAccountConnections) {
84
84
  throw new Error(
85
- "[agent-serve] --allow-anonymous cannot be used with Cursor account MCP connections (defineConnection({ cursorAccount: true })); use --bearer-token or remove the account MCP connections."
85
+ "[agentkit] --allow-anonymous cannot be used with Cursor account MCP connections (defineConnection({ cursorAccount: true })); use --bearer-token or remove the account MCP connections."
86
86
  );
87
87
  }
88
88
  }
@@ -113,7 +113,7 @@ export function resolveMountConnections(args: {
113
113
  resolved.push(...peers);
114
114
  if (cloudCapable && args.publicUrl === undefined) {
115
115
  args.logger(
116
- `[agent-serve] warning: agent "${label}" has peer MCP connections (${peers
116
+ `[agentkit] warning: agent "${label}" has peer MCP connections (${peers
117
117
  .map((peer) => peer.name)
118
118
  .join(
119
119
  ", "
@@ -136,7 +136,7 @@ export function resolveMountConnections(args: {
136
136
  args.accountBridge.logPreflight(args.accountRefs);
137
137
  if (cloudCapable && args.publicUrl === undefined) {
138
138
  args.logger(
139
- `[agent-serve] agent "${label}": cloud-runtime turns omit the account bridge without --public-url (cloud agents fall back to the account's native connectors).`
139
+ `[agentkit] agent "${label}": cloud-runtime turns omit the account bridge without --public-url (cloud agents fall back to the account's native connectors).`
140
140
  );
141
141
  }
142
142
  }
@@ -90,7 +90,7 @@ export class ScheduleRunner {
90
90
  if (schedule.cron.matches(now)) {
91
91
  void this.dispatch(schedule.name).catch((error) => {
92
92
  this.logger(
93
- `[agent-serve] schedule "${schedule.name}" dispatch failed: ${
93
+ `[agentkit] schedule "${schedule.name}" dispatch failed: ${
94
94
  error instanceof Error ? error.message : String(error)
95
95
  }`
96
96
  );
@@ -234,12 +234,12 @@ export async function startServer(
234
234
  );
235
235
  }
236
236
  logger(
237
- "[agent-serve] warning: --allow-anonymous-cursor-github — every admitted HTTP caller can drive sessions holding the signed-in account's repo-scoped GitHub credential; serve this only behind a trusted boundary (e.g. an SSO proxy)"
237
+ "[agentkit] warning: --allow-anonymous-cursor-github — every admitted HTTP caller can drive sessions holding the signed-in account's repo-scoped GitHub credential; serve this only behind a trusted boundary (e.g. an SSO proxy)"
238
238
  );
239
239
  }
240
240
  if (cursorGithubConfig.scope.permissions === "contents-write") {
241
241
  logger(
242
- '[agent-serve] warning: Cursor GitHub credentials include contents:write — the host holds a push-capable token shared with model-driven tools and untrusted webhook content; prefer permissions: "pr-write" unless this agent must push code'
242
+ '[agentkit] warning: Cursor GitHub credentials include contents:write — the host holds a push-capable token shared with model-driven tools and untrusted webhook content; prefer permissions: "pr-write" unless this agent must push code'
243
243
  );
244
244
  }
245
245
  const provider = new CursorGithubCredentialProvider({
@@ -281,7 +281,7 @@ export async function startServer(
281
281
  }
282
282
  if (options.allowAnonymous === true) {
283
283
  logger(
284
- "[agent-serve] warning: --allow-anonymous admits every HTTP caller as the same principal; use only on a trusted network (e.g. Tailscale) and prefer --bearer-token for shared hosts"
284
+ "[agentkit] warning: --allow-anonymous admits every HTTP caller as the same principal; use only on a trusted network (e.g. Tailscale) and prefer --bearer-token for shared hosts"
285
285
  );
286
286
  }
287
287
  const runner =
@@ -430,7 +430,7 @@ export async function startServer(
430
430
  await definition.onStart(startArgs);
431
431
  } catch (error) {
432
432
  logger(
433
- `[agent-serve] channel "${channel.id}" onStart failed: ${
433
+ `[agentkit] channel "${channel.id}" onStart failed: ${
434
434
  error instanceof Error
435
435
  ? (error.stack ?? error.message)
436
436
  : String(error)
@@ -744,7 +744,7 @@ export async function startServer(
744
744
  await stop();
745
745
  } catch (error) {
746
746
  logger(
747
- `[agent-serve] channel onStop failed: ${
747
+ `[agentkit] channel onStop failed: ${
748
748
  error instanceof Error
749
749
  ? (error.stack ?? error.message)
750
750
  : String(error)
@@ -1331,7 +1331,7 @@ function requireCursorEventsAuth(
1331
1331
  const apiKey = (config.apiKey ?? accountKey?.apiKey ?? "").trim();
1332
1332
  if (apiKey === "") {
1333
1333
  throw new Error(
1334
- `[agent-serve] --cursor-events (serve({ cursorEvents })) requires a signed-in Cursor account: the SCM event stream is read as the host's user. ${SIGN_IN_HINT}`
1334
+ `[agentkit] --cursor-events (serve({ cursorEvents })) requires a signed-in Cursor account: the SCM event stream is read as the host's user. ${SIGN_IN_HINT}`
1335
1335
  );
1336
1336
  }
1337
1337
  return {
@@ -1367,7 +1367,7 @@ function startCursorEventRelay(input: {
1367
1367
  );
1368
1368
  if (repos.length === 0) {
1369
1369
  logger(
1370
- "[agent-serve] cursor-events: no repos configured (pass --repo owner/name); relay disabled"
1370
+ "[agentkit] cursor-events: no repos configured (pass --repo owner/name); relay disabled"
1371
1371
  );
1372
1372
  return undefined;
1373
1373
  }
@@ -1375,7 +1375,7 @@ function startCursorEventRelay(input: {
1375
1375
  const events = [...new Set(githubTargets.flatMap((target) => target.events))];
1376
1376
  if (events.length === 0) {
1377
1377
  logger(
1378
- "[agent-serve] cursor-events: no mounted agent declares a github channel; relay disabled"
1378
+ "[agentkit] cursor-events: no mounted agent declares a github channel; relay disabled"
1379
1379
  );
1380
1380
  return undefined;
1381
1381
  }
@@ -1419,13 +1419,13 @@ function startCursorEventRelay(input: {
1419
1419
  .map((target) => `${target.slug || "default"}:${target.status}`)
1420
1420
  .join(", ");
1421
1421
  logger(
1422
- `[agent-serve] cursor-events: dispatched ${formatCursorScmEventLog(event)}${outcomes === "" ? "" : ` → ${outcomes}`}`
1422
+ `[agentkit] cursor-events: dispatched ${formatCursorScmEventLog(event)}${outcomes === "" ? "" : ` → ${outcomes}`}`
1423
1423
  );
1424
1424
  },
1425
1425
  });
1426
1426
  relay.start();
1427
1427
  logger(
1428
- `[agent-serve] cursor-events: relaying ${events.length} event kind(s) for ${repos.join(", ")} from ${auth.baseUrl}`
1428
+ `[agentkit] cursor-events: relaying ${events.length} event kind(s) for ${repos.join(", ")} from ${auth.baseUrl}`
1429
1429
  );
1430
1430
  return relay;
1431
1431
  }
@@ -1611,7 +1611,7 @@ async function startCursorSlackRelay(input: {
1611
1611
  channelId: target.channelId,
1612
1612
  });
1613
1613
  logger(
1614
- `[agent-serve] cursor-slack: dispatching ${formatCursorSlackEventLog(envelope)} → ${target.runtime.slug || "default"}`
1614
+ `[agentkit] cursor-slack: dispatching ${formatCursorSlackEventLog(envelope)} → ${target.runtime.slug || "default"}`
1615
1615
  );
1616
1616
  await dispatchCursorSlackEnvelope({
1617
1617
  runtime: target.accountRuntime,
@@ -1639,7 +1639,7 @@ async function startCursorSlackRelay(input: {
1639
1639
 
1640
1640
  relay.start();
1641
1641
  logger(
1642
- `[agent-serve] cursor-slack: relaying Slack for ${targets
1642
+ `[agentkit] cursor-slack: relaying Slack for ${targets
1643
1643
  .map(
1644
1644
  (target) => `${target.agentName} (${target.runtime.slug || "default"})`
1645
1645
  )
@@ -1735,7 +1735,7 @@ async function handleRequest(
1735
1735
  response = errorResponse(403, "forbidden", error.message);
1736
1736
  } else {
1737
1737
  logger(
1738
- `[agent-serve] request failed: ${
1738
+ `[agentkit] request failed: ${
1739
1739
  error instanceof Error
1740
1740
  ? (error.stack ?? error.message)
1741
1741
  : String(error)
@@ -1749,7 +1749,7 @@ async function handleRequest(
1749
1749
  await writeFetchResponse(response, res, method);
1750
1750
  } catch (error) {
1751
1751
  logger(
1752
- `[agent-serve] response write failed: ${
1752
+ `[agentkit] response write failed: ${
1753
1753
  error instanceof Error ? error.message : String(error)
1754
1754
  }`
1755
1755
  );
@@ -249,7 +249,7 @@ export class SessionEngine {
249
249
  (sessionId) => this.sessions.eventFilePath(sessionId),
250
250
  (sessionId, error) =>
251
251
  this.logger(
252
- `[agent-serve] failed to persist events for ${sessionId}: ${describeError(error)}`
252
+ `[agentkit] failed to persist events for ${sessionId}: ${describeError(error)}`
253
253
  )
254
254
  );
255
255
  this.storage =
@@ -445,7 +445,7 @@ export class SessionEngine {
445
445
  }
446
446
  } catch (error) {
447
447
  this.logger(
448
- `[agent-serve] ab "${experiment.name}" enrollment failed (sticky skip): ${describeError(error)}`
448
+ `[agentkit] ab "${experiment.name}" enrollment failed (sticky skip): ${describeError(error)}`
449
449
  );
450
450
  variant = null;
451
451
  }
@@ -712,7 +712,7 @@ export class SessionEngine {
712
712
  this.queueDispatch(sessionId, event);
713
713
  } catch (error) {
714
714
  this.logger(
715
- `[agent-serve] failed to record event for ${sessionId}: ${describeError(error)}`
715
+ `[agentkit] failed to record event for ${sessionId}: ${describeError(error)}`
716
716
  );
717
717
  }
718
718
  };
@@ -1401,7 +1401,7 @@ export class SessionEngine {
1401
1401
  .then(() => this.dispatchEvent(sessionId, event))
1402
1402
  .catch((error) => {
1403
1403
  this.logger(
1404
- `[agent-serve] event dispatch failed for ${sessionId}: ${describeError(error)}`
1404
+ `[agentkit] event dispatch failed for ${sessionId}: ${describeError(error)}`
1405
1405
  );
1406
1406
  })
1407
1407
  .then(() => {
@@ -1446,7 +1446,7 @@ export class SessionEngine {
1446
1446
  await handler(event, channelCtx, sessionCtx);
1447
1447
  } catch (error) {
1448
1448
  this.logger(
1449
- `[agent-serve] channel "${record.channelId}" handler for ${event.type} threw: ${describeError(error)}`
1449
+ `[agentkit] channel "${record.channelId}" handler for ${event.type} threw: ${describeError(error)}`
1450
1450
  );
1451
1451
  }
1452
1452
  }
@@ -1474,7 +1474,7 @@ export class SessionEngine {
1474
1474
  });
1475
1475
  } catch (error) {
1476
1476
  this.logger(
1477
- `[agent-serve] hook "${hook.name}" handler for ${event.type} threw: ${describeError(error)}`
1477
+ `[agentkit] hook "${hook.name}" handler for ${event.type} threw: ${describeError(error)}`
1478
1478
  );
1479
1479
  }
1480
1480
  }
@@ -1616,7 +1616,7 @@ export class SessionEngine {
1616
1616
  });
1617
1617
  } catch (error) {
1618
1618
  this.logger(
1619
- `[agent-serve] ab persistSnapshots.save threw: ${describeError(error)}`
1619
+ `[agentkit] ab persistSnapshots.save threw: ${describeError(error)}`
1620
1620
  );
1621
1621
  }
1622
1622
  } else {
@@ -1825,9 +1825,7 @@ export class SessionEngine {
1825
1825
  try {
1826
1826
  await this.runBulkRestore(storage, policy);
1827
1827
  } catch (error) {
1828
- this.logger(
1829
- `[agent-serve] session restore failed: ${describeError(error)}`
1830
- );
1828
+ this.logger(`[agentkit] session restore failed: ${describeError(error)}`);
1831
1829
  }
1832
1830
  }
1833
1831
 
@@ -1884,7 +1882,7 @@ export class SessionEngine {
1884
1882
  return { record, events };
1885
1883
  } catch (error) {
1886
1884
  this.logger(
1887
- `[agent-serve] failed to restore session ${record.sessionId}: ${describeError(error)}`
1885
+ `[agentkit] failed to restore session ${record.sessionId}: ${describeError(error)}`
1888
1886
  );
1889
1887
  return undefined;
1890
1888
  }
@@ -1903,7 +1901,7 @@ export class SessionEngine {
1903
1901
  (ndjson === undefined ? 0 : Buffer.byteLength(ndjson, "utf8"));
1904
1902
  if (bytes > budget) {
1905
1903
  this.logger(
1906
- `[agent-serve] session restore stopped at the ${policy.maxTotalBytes}-byte budget after ${restored} session(s); remaining sessions restore lazily on resume`
1904
+ `[agentkit] session restore stopped at the ${policy.maxTotalBytes}-byte budget after ${restored} session(s); remaining sessions restore lazily on resume`
1907
1905
  );
1908
1906
  break outer;
1909
1907
  }
@@ -1913,13 +1911,13 @@ export class SessionEngine {
1913
1911
  restored += 1;
1914
1912
  } catch (error) {
1915
1913
  this.logger(
1916
- `[agent-serve] failed to restore session ${item.record.sessionId}: ${describeError(error)}`
1914
+ `[agentkit] failed to restore session ${item.record.sessionId}: ${describeError(error)}`
1917
1915
  );
1918
1916
  }
1919
1917
  }
1920
1918
  }
1921
1919
  if (restored > 0) {
1922
- this.logger(`[agent-serve] restored ${restored} session(s) from storage`);
1920
+ this.logger(`[agentkit] restored ${restored} session(s) from storage`);
1923
1921
  }
1924
1922
  }
1925
1923
 
@@ -1975,7 +1973,7 @@ export class SessionEngine {
1975
1973
  const events = await storage.listSessionEvents(record.sessionId);
1976
1974
  await this.materializeSession(record, eventsNdjson(events));
1977
1975
  this.logger(
1978
- `[agent-serve] lazily restored session ${record.sessionId} from storage`
1976
+ `[agentkit] lazily restored session ${record.sessionId} from storage`
1979
1977
  );
1980
1978
  return record;
1981
1979
  }
@@ -152,6 +152,40 @@ function parseSessionSummary(value: unknown): SessionSummary | undefined {
152
152
  };
153
153
  }
154
154
 
155
+ /**
156
+ * Pick the previous (most recently updated) followable session for
157
+ * `resume` / `chat --resume` when no session id was passed.
158
+ * Followable = has a non-empty continuation token (task sessions without
159
+ * one are skipped).
160
+ */
161
+ export function pickPreviousSession(
162
+ sessions: readonly SessionSummary[]
163
+ ): SessionSummary | undefined {
164
+ const followable = sessions.filter(
165
+ (s) => typeof s.continuationToken === "string" && s.continuationToken !== ""
166
+ );
167
+ if (followable.length === 0) {
168
+ return undefined;
169
+ }
170
+ return [...followable].sort((a, b) =>
171
+ b.updatedAt.localeCompare(a.updatedAt)
172
+ )[0];
173
+ }
174
+
175
+ /** Look up the most recently updated followable session id. */
176
+ export async function resolvePreviousSessionId(args: {
177
+ baseUrl: string;
178
+ auth?: RequestAuth;
179
+ fetchImpl?: typeof fetch;
180
+ }): Promise<string | undefined> {
181
+ const sessions = await listSessions({
182
+ baseUrl: args.baseUrl,
183
+ auth: args.auth,
184
+ fetchImpl: args.fetchImpl,
185
+ });
186
+ return pickPreviousSession(sessions)?.sessionId;
187
+ }
188
+
155
189
  /** Format a sessions table (id, channel, mode, turns, running, updated). */
156
190
  export function formatSessionsTable(sessions: SessionSummary[]): string {
157
191
  if (sessions.length === 0) {
@@ -317,7 +317,7 @@ export class StorageCoordinator {
317
317
  // under at-most-once). The session is unrecoverable; treat as a miss
318
318
  // so the conversation can continue rather than failing forever.
319
319
  this.logger(
320
- `[agent-serve] storage continuation entry points at missing session ${sessionId}; treating as a miss`
320
+ `[agentkit] storage continuation entry points at missing session ${sessionId}; treating as a miss`
321
321
  );
322
322
  return undefined;
323
323
  }
@@ -488,7 +488,7 @@ export class StorageCoordinator {
488
488
  return value == null ? undefined : (value as unknown as ABSnapshot);
489
489
  } catch (error) {
490
490
  this.logger(
491
- `[agent-serve] storage get(ab-snapshot) failed: ${describeError(error)}`
491
+ `[agentkit] storage get(ab-snapshot) failed: ${describeError(error)}`
492
492
  );
493
493
  return undefined;
494
494
  }
@@ -521,7 +521,7 @@ export class StorageCoordinator {
521
521
  clearTimeout(timer);
522
522
  if (!drained) {
523
523
  this.logger(
524
- `[agent-serve] storage shutdown drain timed out after ${CLOSE_DRAIN_TIMEOUT_MS}ms with ${this.pending} write(s) undelivered`
524
+ `[agentkit] storage shutdown drain timed out after ${CLOSE_DRAIN_TIMEOUT_MS}ms with ${this.pending} write(s) undelivered`
525
525
  );
526
526
  }
527
527
  }
@@ -569,7 +569,7 @@ export class StorageCoordinator {
569
569
  return Array.isArray(entries) ? entries : [];
570
570
  } catch (error) {
571
571
  this.logger(
572
- `[agent-serve] storage list(${prefix}) failed: ${describeError(error)}`
572
+ `[agentkit] storage list(${prefix}) failed: ${describeError(error)}`
573
573
  );
574
574
  return [];
575
575
  }
@@ -583,7 +583,7 @@ export class StorageCoordinator {
583
583
  this.dropped += ops.length;
584
584
  if (this.dropped <= ops.length || this.dropped % 1_000 < ops.length) {
585
585
  this.logger(
586
- `[agent-serve] storage queue full (${MAX_PENDING_OPS} pending writes); dropped ${this.dropped} write(s) so far — the sink is too slow for the traffic`
586
+ `[agentkit] storage queue full (${MAX_PENDING_OPS} pending writes); dropped ${this.dropped} write(s) so far — the sink is too slow for the traffic`
587
587
  );
588
588
  }
589
589
  return;
@@ -600,7 +600,7 @@ export class StorageCoordinator {
600
600
  }
601
601
  } catch (error) {
602
602
  this.logger(
603
- `[agent-serve] storage ${op.op}(${op.key}) failed: ${describeError(error)}`
603
+ `[agentkit] storage ${op.op}(${op.key}) failed: ${describeError(error)}`
604
604
  );
605
605
  } finally {
606
606
  this.pending -= 1;