@cursor/july 0.1.43 → 0.1.46

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 (197) hide show
  1. package/AGENTS.md +5 -3
  2. package/README.md +3 -1
  3. package/dist/channels/github/api.d.ts +25 -0
  4. package/dist/channels/github/api.d.ts.map +1 -1
  5. package/dist/channels/github/api.js +48 -0
  6. package/dist/channels/github/cursor-account.d.ts +7 -0
  7. package/dist/channels/github/cursor-account.d.ts.map +1 -1
  8. package/dist/channels/github/cursor-account.js +18 -0
  9. package/dist/channels/github/defaults.d.ts +1 -1
  10. package/dist/channels/github/defaults.js +1 -1
  11. package/dist/channels/github/github-channel.d.ts.map +1 -1
  12. package/dist/channels/github/github-channel.js +15 -7
  13. package/dist/channels/github/progress.d.ts +6 -5
  14. package/dist/channels/github/progress.d.ts.map +1 -1
  15. package/dist/channels/github/progress.js +58 -16
  16. package/dist/channels/github/state.d.ts +11 -0
  17. package/dist/channels/github/state.d.ts.map +1 -1
  18. package/dist/channels/github/state.js +1 -1
  19. package/dist/channels/github/types.d.ts +11 -3
  20. package/dist/channels/github/types.d.ts.map +1 -1
  21. package/dist/channels.d.ts +17 -0
  22. package/dist/channels.d.ts.map +1 -1
  23. package/dist/channels.js +31 -0
  24. package/dist/docs/404.html +2 -2
  25. package/dist/docs/ab.html +3 -3
  26. package/dist/docs/assets/{app.DsTLo2j1.js → app.C2NFTb-h.js} +1 -1
  27. package/dist/docs/assets/chunks/@localSearchIndexroot.B-FxvuoI.js +1 -0
  28. package/dist/docs/assets/chunks/{VPLocalSearchBox.DoVfutcV.js → VPLocalSearchBox.o1_FJGip.js} +1 -1
  29. package/dist/docs/assets/chunks/{theme.DtuVtKkc.js → theme.BcGduE7g.js} +2 -2
  30. package/dist/docs/assets/{guides_github.md.DSg0j9qj.js → guides_github.md.B8QKtIpw.js} +7 -6
  31. package/dist/docs/assets/{guides_github.md.DSg0j9qj.lean.js → guides_github.md.B8QKtIpw.lean.js} +1 -1
  32. package/dist/docs/assets/guides_opentelemetry.md.Csn7ZI25.js +27 -0
  33. package/dist/docs/assets/guides_opentelemetry.md.Csn7ZI25.lean.js +1 -0
  34. package/dist/docs/assets/index.md.COeoSkcF.js +5 -0
  35. package/dist/docs/assets/index.md.COeoSkcF.lean.js +1 -0
  36. package/dist/docs/assets/{quickstart.md.rIbfahJM.js → quickstart.md.DZxBu44y.js} +18 -49
  37. package/dist/docs/assets/quickstart.md.DZxBu44y.lean.js +1 -0
  38. package/dist/docs/assets/{reference_agent-config.md.CRmkoxd6.js → reference_agent-config.md.DHkkvcEZ.js} +9 -4
  39. package/dist/docs/assets/{reference_agent-config.md.CRmkoxd6.lean.js → reference_agent-config.md.DHkkvcEZ.lean.js} +1 -1
  40. package/dist/docs/assets/{reference_cli.md.DqEqQpGn.js → reference_cli.md.BDmjPPAm.js} +2 -2
  41. package/dist/docs/assets/{reference_hooks.md.4cbRRIIu.js → reference_hooks.md.DJE5DXcT.js} +1 -1
  42. package/dist/docs/assets/{reference_tools.md.lSrsTxYJ.js → reference_tools.md.kJfJAP2m.js} +1 -1
  43. package/dist/docs/assets/{storage.md.DcGSnIxX.js → storage.md.CJYd5YmN.js} +2 -2
  44. package/dist/docs/assets/{storage.md.DcGSnIxX.lean.js → storage.md.CJYd5YmN.lean.js} +1 -1
  45. package/dist/docs/building-with-agents.html +3 -3
  46. package/dist/docs/concepts.html +3 -3
  47. package/dist/docs/deployment.html +3 -3
  48. package/dist/docs/evals.html +3 -3
  49. package/dist/docs/example-agents/approval-buddy.html +3 -3
  50. package/dist/docs/example-agents/benny.html +3 -3
  51. package/dist/docs/example-agents/bugbot.html +3 -3
  52. package/dist/docs/example-agents/codebase-wiki.html +3 -3
  53. package/dist/docs/example-agents/codeowners-review.html +3 -3
  54. package/dist/docs/example-agents/concierge.html +3 -3
  55. package/dist/docs/example-agents/fsd.html +3 -3
  56. package/dist/docs/example-agents/index.html +3 -3
  57. package/dist/docs/example-agents/knowledge-base.html +3 -3
  58. package/dist/docs/example-agents/oncall.html +3 -3
  59. package/dist/docs/example-agents/security-reviewer.html +3 -3
  60. package/dist/docs/example-agents/slack-agent.html +3 -3
  61. package/dist/docs/example-agents/weather-agent.html +3 -3
  62. package/dist/docs/guides/agent-to-agent.html +3 -3
  63. package/dist/docs/guides/cloud-runtime.html +3 -3
  64. package/dist/docs/guides/github.html +10 -9
  65. package/dist/docs/guides/human-in-the-loop.html +3 -3
  66. package/dist/docs/guides/mcp-oauth.html +3 -3
  67. package/dist/docs/guides/opentelemetry.html +12 -5
  68. package/dist/docs/guides/slack.html +3 -3
  69. package/dist/docs/guides/webhooks.html +3 -3
  70. package/dist/docs/hashmap.json +1 -1
  71. package/dist/docs/hillclimbing.html +3 -3
  72. package/dist/docs/index.html +8 -28
  73. package/dist/docs/quickstart.html +24 -55
  74. package/dist/docs/reference/agent-config.html +11 -6
  75. package/dist/docs/reference/artifacts.html +3 -3
  76. package/dist/docs/reference/channels.html +3 -3
  77. package/dist/docs/reference/cli.html +6 -6
  78. package/dist/docs/reference/connections.html +3 -3
  79. package/dist/docs/reference/hooks.html +5 -5
  80. package/dist/docs/reference/http-api.html +3 -3
  81. package/dist/docs/reference/instructions.html +3 -3
  82. package/dist/docs/reference/playground.html +3 -3
  83. package/dist/docs/reference/project-layout.html +3 -3
  84. package/dist/docs/reference/prompt.html +3 -3
  85. package/dist/docs/reference/schedules.html +3 -3
  86. package/dist/docs/reference/sessions.html +3 -3
  87. package/dist/docs/reference/skills.html +3 -3
  88. package/dist/docs/reference/subagents.html +3 -3
  89. package/dist/docs/reference/tools.html +5 -5
  90. package/dist/docs/scaffolding-agents.html +3 -3
  91. package/dist/docs/storage.html +5 -5
  92. package/dist/docs/templates/triage.html +3 -3
  93. package/dist/docs/troubleshooting.html +3 -3
  94. package/dist/index.d.ts +2 -2
  95. package/dist/index.d.ts.map +1 -1
  96. package/dist/index.js +2 -2
  97. package/dist/internal/auth.d.ts +4 -0
  98. package/dist/internal/auth.d.ts.map +1 -1
  99. package/dist/internal/auth.js +7 -0
  100. package/dist/internal/cli-ax.js +2 -2
  101. package/dist/internal/cli-deploy.d.ts.map +1 -1
  102. package/dist/internal/cli-deploy.js +38 -7
  103. package/dist/internal/deploy-client.d.ts +8 -0
  104. package/dist/internal/deploy-client.d.ts.map +1 -1
  105. package/dist/internal/deploy-client.js +5 -2
  106. package/dist/internal/discovery.d.ts.map +1 -1
  107. package/dist/internal/discovery.js +46 -9
  108. package/dist/internal/durable-session-store.d.ts +35 -23
  109. package/dist/internal/durable-session-store.d.ts.map +1 -1
  110. package/dist/internal/durable-session-store.js +71 -26
  111. package/dist/internal/host-otel.d.ts +25 -0
  112. package/dist/internal/host-otel.d.ts.map +1 -0
  113. package/dist/internal/host-otel.js +162 -0
  114. package/dist/internal/init-project.js +10 -10
  115. package/dist/internal/ledger-serving.d.ts +135 -67
  116. package/dist/internal/ledger-serving.d.ts.map +1 -1
  117. package/dist/internal/ledger-serving.js +326 -107
  118. package/dist/internal/otel/collector.d.ts +5 -0
  119. package/dist/internal/otel/collector.d.ts.map +1 -1
  120. package/dist/internal/otel/collector.js +68 -27
  121. package/dist/internal/sdk-runner.d.ts +1 -1
  122. package/dist/internal/sdk-runner.d.ts.map +1 -1
  123. package/dist/internal/sdk-runner.js +1 -1
  124. package/dist/internal/server.d.ts.map +1 -1
  125. package/dist/internal/server.js +3 -2
  126. package/dist/internal/session-engine.d.ts +23 -18
  127. package/dist/internal/session-engine.d.ts.map +1 -1
  128. package/dist/internal/session-engine.js +83 -32
  129. package/dist/kv/memory-kv.d.ts +8 -0
  130. package/dist/kv/memory-kv.d.ts.map +1 -1
  131. package/dist/kv/memory-kv.js +8 -0
  132. package/dist/ledger/janitor.d.ts +60 -0
  133. package/dist/ledger/janitor.d.ts.map +1 -0
  134. package/dist/ledger/janitor.js +137 -0
  135. package/dist/ledger/session-ledger.d.ts +132 -43
  136. package/dist/ledger/session-ledger.d.ts.map +1 -1
  137. package/dist/ledger/session-ledger.js +282 -50
  138. package/dist/ledger.d.ts +9 -8
  139. package/dist/ledger.d.ts.map +1 -1
  140. package/dist/ledger.js +7 -7
  141. package/dist/playground/assets/{index-D-DIYQzw.js → index-6wW6SAc4.js} +19 -19
  142. package/dist/playground/assets/index-CSRYDAFw.css +1 -0
  143. package/dist/playground/index.html +2 -2
  144. package/dist/storage-backends/cursor-hosted.d.ts +5 -0
  145. package/dist/storage-backends/cursor-hosted.d.ts.map +1 -1
  146. package/dist/storage-backends/cursor-hosted.js +6 -0
  147. package/dist/types.d.ts +100 -10
  148. package/dist/types.d.ts.map +1 -1
  149. package/docs/README.md +33 -106
  150. package/docs/guides/github.md +23 -18
  151. package/docs/guides/opentelemetry.md +30 -0
  152. package/docs/quickstart.md +89 -227
  153. package/docs/reference/agent-config.md +47 -0
  154. package/docs/reference/cli.md +2 -2
  155. package/docs/reference/hooks.md +1 -1
  156. package/docs/reference/tools.md +5 -4
  157. package/docs/storage.md +26 -9
  158. package/package.json +2 -2
  159. package/skills/otel/SKILL.md +20 -2
  160. package/src/channels/github/api.ts +122 -0
  161. package/src/channels/github/cursor-account.ts +23 -0
  162. package/src/channels/github/defaults.ts +1 -1
  163. package/src/channels/github/github-channel.ts +14 -1
  164. package/src/channels/github/progress.ts +84 -19
  165. package/src/channels/github/state.ts +14 -0
  166. package/src/channels/github/types.ts +7 -3
  167. package/src/channels.ts +38 -0
  168. package/src/index.ts +2 -0
  169. package/src/internal/auth.ts +10 -0
  170. package/src/internal/cli-ax.ts +2 -2
  171. package/src/internal/cli-deploy.ts +58 -3
  172. package/src/internal/deploy-client.ts +11 -0
  173. package/src/internal/discovery.ts +49 -0
  174. package/src/internal/durable-session-store.ts +66 -27
  175. package/src/internal/host-otel.ts +252 -0
  176. package/src/internal/init-project.ts +10 -10
  177. package/src/internal/ledger-serving.ts +439 -148
  178. package/src/internal/otel/collector.ts +135 -50
  179. package/src/internal/sdk-runner.ts +6 -0
  180. package/src/internal/server.ts +7 -2
  181. package/src/internal/session-engine.ts +127 -39
  182. package/src/kv/memory-kv.ts +8 -0
  183. package/src/ledger/janitor.ts +193 -0
  184. package/src/ledger/session-ledger.ts +372 -68
  185. package/src/ledger.ts +21 -6
  186. package/src/storage-backends/cursor-hosted.ts +17 -2
  187. package/src/types.ts +108 -10
  188. package/dist/docs/assets/chunks/@localSearchIndexroot.BZx4pmZL.js +0 -1
  189. package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.js +0 -20
  190. package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.lean.js +0 -1
  191. package/dist/docs/assets/index.md.CMc5FP7E.js +0 -25
  192. package/dist/docs/assets/index.md.CMc5FP7E.lean.js +0 -1
  193. package/dist/docs/assets/quickstart.md.rIbfahJM.lean.js +0 -1
  194. package/dist/playground/assets/index-DQTH622f.css +0 -1
  195. /package/dist/docs/assets/{reference_cli.md.DqEqQpGn.lean.js → reference_cli.md.BDmjPPAm.lean.js} +0 -0
  196. /package/dist/docs/assets/{reference_hooks.md.4cbRRIIu.lean.js → reference_hooks.md.DJE5DXcT.lean.js} +0 -0
  197. /package/dist/docs/assets/{reference_tools.md.lSrsTxYJ.lean.js → reference_tools.md.kJfJAP2m.lean.js} +0 -0
@@ -27,6 +27,15 @@ const CONTENT_MAX = 2_048;
27
27
  export interface OtelCollector {
28
28
  onEvent(event: SessionEvent, session: SessionInfo): void;
29
29
  close(): void;
30
+ /** Merge author tags onto the session; paints open spans immediately. */
31
+ setSessionAttributes(
32
+ sessionId: string,
33
+ attributes: Record<string, AttrValue>
34
+ ): void;
35
+ /** Session tags previously set by {@link setSessionAttributes}. */
36
+ getSessionAttributes(
37
+ sessionId: string
38
+ ): Record<string, AttrValue> | undefined;
30
39
  }
31
40
 
32
41
  interface TurnState {
@@ -49,6 +58,7 @@ export function createOtelCollector(
49
58
  log: (line: string) => void
50
59
  ): OtelCollector {
51
60
  const sessions = new Map<string, SessionState>();
61
+ const extraBySession = new Map<string, Record<string, AttrValue>>();
52
62
  const metrics = runtime.meter ? buildMetrics(runtime.meter) : undefined;
53
63
  const logOpts =
54
64
  runtime.config.logs === false ? undefined : runtime.config.logs;
@@ -71,6 +81,17 @@ export function createOtelCollector(
71
81
  state.span.end();
72
82
  sessions.delete(sessionId);
73
83
  }
84
+ extraBySession.clear();
85
+ },
86
+ setSessionAttributes(sessionId, attributes) {
87
+ const bag = extraBySession.get(sessionId) ?? {};
88
+ Object.assign(bag, attributes);
89
+ extraBySession.set(sessionId, bag);
90
+ paintOpenSpans(sessionId, attributes);
91
+ },
92
+ getSessionAttributes(sessionId) {
93
+ const bag = extraBySession.get(sessionId);
94
+ return bag === undefined ? undefined : { ...bag };
74
95
  },
75
96
  };
76
97
 
@@ -215,7 +236,7 @@ export function createOtelCollector(
215
236
  {
216
237
  kind: SpanKind.INTERNAL,
217
238
  startTime,
218
- attributes: attrs({
239
+ attributes: join(event.sessionId, {
219
240
  "cursor.conversation.id": event.sessionId,
220
241
  "cursor.tool.name": call.toolName,
221
242
  "cursor.tool.kind": "builtin",
@@ -287,12 +308,15 @@ export function createOtelCollector(
287
308
  span.end(startTime);
288
309
  turn?.tools.delete(event.data.callId);
289
310
  }
290
- metrics?.toolCalls.add(1, {
291
- "cursor.tool.name": event.data.toolName,
292
- "cursor.tool.kind": "builtin",
293
- "cursor.tool.status": status,
294
- "agent_sdk.agent": agentName,
295
- });
311
+ metrics?.toolCalls.add(
312
+ 1,
313
+ join(event.sessionId, {
314
+ "cursor.tool.name": event.data.toolName,
315
+ "cursor.tool.kind": "builtin",
316
+ "cursor.tool.status": status,
317
+ "agent_sdk.agent": agentName,
318
+ })
319
+ );
296
320
  emitLog(
297
321
  "action.result",
298
322
  event.data.isError ? SeverityNumber.ERROR : SeverityNumber.INFO,
@@ -327,7 +351,7 @@ export function createOtelCollector(
327
351
  {
328
352
  kind: SpanKind.INTERNAL,
329
353
  startTime,
330
- attributes: attrs({
354
+ attributes: join(event.sessionId, {
331
355
  "cursor.conversation.id": event.sessionId,
332
356
  "agent_sdk.agent": agentName,
333
357
  "agent_sdk.turn_id": event.turnId,
@@ -343,10 +367,13 @@ export function createOtelCollector(
343
367
  trace.setSpan(context.active(), turn.span)
344
368
  );
345
369
  turn.subagents.set(event.data.callId, span);
346
- metrics?.subagents.add(1, {
347
- "agent_sdk.agent": agentName,
348
- "agent_sdk.subagent_name": event.data.name ?? "unknown",
349
- });
370
+ metrics?.subagents.add(
371
+ 1,
372
+ join(event.sessionId, {
373
+ "agent_sdk.agent": agentName,
374
+ "agent_sdk.subagent_name": event.data.name ?? "unknown",
375
+ })
376
+ );
350
377
  return;
351
378
  }
352
379
  case "subagent.completed": {
@@ -389,7 +416,7 @@ export function createOtelCollector(
389
416
  "agent_sdk.usage.reasoning_tokens": usage.reasoningTokens,
390
417
  })
391
418
  );
392
- recordTokens(usage);
419
+ recordTokens(event.sessionId, usage);
393
420
  }
394
421
  if (cost !== undefined) {
395
422
  turn.span.setAttributes(
@@ -399,18 +426,24 @@ export function createOtelCollector(
399
426
  "agent_sdk.cost_source": cost.source,
400
427
  })
401
428
  );
402
- metrics?.cost.add(cost.totalUsd, {
403
- "cursor.model.name": cost.model,
404
- "agent_sdk.agent": agentName,
405
- });
429
+ metrics?.cost.add(
430
+ cost.totalUsd,
431
+ join(event.sessionId, {
432
+ "cursor.model.name": cost.model,
433
+ "agent_sdk.agent": agentName,
434
+ })
435
+ );
406
436
  }
407
437
  turn.span.setStatus({ code: SpanStatusCode.OK });
408
438
  turn.span.end(startTime);
409
439
  sessions.get(event.sessionId)?.turns.delete(event.turnId);
410
- metrics?.turns.add(1, {
411
- "agent_sdk.agent": agentName,
412
- "agent_sdk.turn_status": "completed",
413
- });
440
+ metrics?.turns.add(
441
+ 1,
442
+ join(event.sessionId, {
443
+ "agent_sdk.agent": agentName,
444
+ "agent_sdk.turn_status": "completed",
445
+ })
446
+ );
414
447
  emitLog(
415
448
  "turn.completed",
416
449
  SeverityNumber.INFO,
@@ -441,10 +474,13 @@ export function createOtelCollector(
441
474
  }
442
475
  turn.span.end(startTime);
443
476
  sessions.get(event.sessionId)?.turns.delete(event.turnId);
444
- metrics?.turns.add(1, {
445
- "agent_sdk.agent": agentName,
446
- "agent_sdk.turn_status": "failed",
447
- });
477
+ metrics?.turns.add(
478
+ 1,
479
+ join(event.sessionId, {
480
+ "agent_sdk.agent": agentName,
481
+ "agent_sdk.turn_status": "failed",
482
+ })
483
+ );
448
484
  emitLog(
449
485
  "turn.failed",
450
486
  SeverityNumber.ERROR,
@@ -531,7 +567,7 @@ export function createOtelCollector(
531
567
  {
532
568
  kind: SpanKind.INTERNAL,
533
569
  startTime: args.startTime,
534
- attributes: attrs({
570
+ attributes: join(args.sessionId, {
535
571
  "cursor.conversation.id": args.sessionId,
536
572
  "agent_sdk.agent": agentName,
537
573
  "agent_sdk.channel": args.channelId,
@@ -549,10 +585,13 @@ export function createOtelCollector(
549
585
  };
550
586
  sessions.set(args.sessionId, state);
551
587
  if (!args.restored) {
552
- metrics?.sessions.add(1, {
553
- "agent_sdk.agent": agentName,
554
- "agent_sdk.channel": args.channelId,
555
- });
588
+ metrics?.sessions.add(
589
+ 1,
590
+ join(args.sessionId, {
591
+ "agent_sdk.agent": agentName,
592
+ "agent_sdk.channel": args.channelId,
593
+ })
594
+ );
556
595
  }
557
596
  return state;
558
597
  }
@@ -600,7 +639,7 @@ export function createOtelCollector(
600
639
  {
601
640
  kind: SpanKind.INTERNAL,
602
641
  startTime: args.startTime,
603
- attributes: attrs({
642
+ attributes: join(args.sessionId, {
604
643
  "cursor.conversation.id": args.sessionId,
605
644
  "agent_sdk.agent": agentName,
606
645
  "agent_sdk.turn_id": args.turnId,
@@ -666,34 +705,77 @@ export function createOtelCollector(
666
705
  );
667
706
  state.span.end(args.endTime);
668
707
  sessions.delete(args.sessionId);
708
+ extraBySession.delete(args.sessionId);
669
709
  }
670
710
 
671
- function recordTokens(usage: {
672
- inputTokens: number;
673
- outputTokens: number;
674
- cacheReadTokens: number;
675
- cacheWriteTokens: number;
676
- reasoningTokens?: number;
677
- }): void {
711
+ function extra(sessionId: string): Record<string, AttrValue> {
712
+ return extraBySession.get(sessionId) ?? {};
713
+ }
714
+
715
+ function join(
716
+ sessionId: string,
717
+ rest: Record<string, AttrValue | undefined>
718
+ ): Record<string, AttrValue> {
719
+ return attrs({ ...extra(sessionId), ...rest });
720
+ }
721
+
722
+ function paintOpenSpans(
723
+ sessionId: string,
724
+ incoming: Record<string, AttrValue>
725
+ ): void {
726
+ const state = sessions.get(sessionId);
727
+ if (state === undefined) {
728
+ return;
729
+ }
730
+ const painted = attrs(incoming);
731
+ if (Object.keys(painted).length === 0) {
732
+ return;
733
+ }
734
+ state.span.setAttributes(painted);
735
+ for (const turn of state.turns.values()) {
736
+ turn.span.setAttributes(painted);
737
+ for (const span of turn.tools.values()) {
738
+ span.setAttributes(painted);
739
+ }
740
+ for (const span of turn.subagents.values()) {
741
+ span.setAttributes(painted);
742
+ }
743
+ }
744
+ }
745
+
746
+ function recordTokens(
747
+ sessionId: string,
748
+ usage: {
749
+ inputTokens: number;
750
+ outputTokens: number;
751
+ cacheReadTokens: number;
752
+ cacheWriteTokens: number;
753
+ reasoningTokens?: number;
754
+ }
755
+ ): void {
678
756
  if (metrics === undefined) {
679
757
  return;
680
758
  }
681
759
  const agent = agentName;
682
760
  // Wire token types match enterprise export (`cache_creation`, not write).
683
- addTokens(usage.inputTokens, "input", agent);
684
- addTokens(usage.outputTokens, "output", agent);
685
- addTokens(usage.cacheReadTokens, "cache_read", agent);
686
- addTokens(usage.cacheWriteTokens, "cache_creation", agent);
761
+ addTokens(sessionId, usage.inputTokens, "input", agent);
762
+ addTokens(sessionId, usage.outputTokens, "output", agent);
763
+ addTokens(sessionId, usage.cacheReadTokens, "cache_read", agent);
764
+ addTokens(sessionId, usage.cacheWriteTokens, "cache_creation", agent);
687
765
  if (usage.reasoningTokens !== undefined) {
688
766
  // Reasoning is Agent-SDK-only; enterprise wire has no reasoning enum.
689
- metrics.tokens.add(usage.reasoningTokens, {
690
- "cursor.token.type": "reasoning",
691
- "agent_sdk.agent": agent,
692
- });
767
+ metrics.tokens.add(
768
+ usage.reasoningTokens,
769
+ join(sessionId, {
770
+ "cursor.token.type": "reasoning",
771
+ "agent_sdk.agent": agent,
772
+ })
773
+ );
693
774
  }
694
775
  }
695
776
 
696
777
  function addTokens(
778
+ sessionId: string,
697
779
  value: number,
698
780
  type: "input" | "output" | "cache_read" | "cache_creation",
699
781
  agent: string
@@ -701,10 +783,13 @@ export function createOtelCollector(
701
783
  if (metrics === undefined || value === 0) {
702
784
  return;
703
785
  }
704
- metrics.tokens.add(value, {
705
- "cursor.token.type": type,
706
- "agent_sdk.agent": agent,
707
- });
786
+ metrics.tokens.add(
787
+ value,
788
+ join(sessionId, {
789
+ "cursor.token.type": type,
790
+ "agent_sdk.agent": agent,
791
+ })
792
+ );
708
793
  }
709
794
 
710
795
  /** Content opt-in for failure text (same gate as tool payloads). */
@@ -52,6 +52,7 @@ export type RunnerPrewarmRequest = Pick<
52
52
  | "workspaceDir"
53
53
  | "runnerStateDir"
54
54
  | "sandbox"
55
+ | "tools"
55
56
  | "mcpServers"
56
57
  | "subagents"
57
58
  | "model"
@@ -373,6 +374,11 @@ export class CursorSdkRunner implements AgentRunner {
373
374
  this.options.store ?? (await this.getStore(request.runnerStateDir));
374
375
  return {
375
376
  ...this.buildSharedOptions(request),
377
+ // The built-in tool allowlist rides AgentOptions, not `local`, and is
378
+ // deliberately absent from openCloudAgent's options: the SDK rejects
379
+ // tool restrictions on cloud agents. Passed on create *and* resume
380
+ // (both flow through here) — the SDK does not persist it across runs.
381
+ ...(request.tools === undefined ? {} : { tools: request.tools }),
376
382
  local: {
377
383
  cwd: request.workspaceDir,
378
384
  settingSources: ["project"],
@@ -17,6 +17,7 @@ import { join } from "node:path";
17
17
  import {
18
18
  type CursorGithubRepoScope,
19
19
  createCursorAccountGithubTokenResolver,
20
+ cursorGithubPermissionsForChannel,
20
21
  type GithubCursorAccountRuntime,
21
22
  getGithubCursorAccountRuntime,
22
23
  parseCursorGithubRepoScope,
@@ -435,6 +436,7 @@ export async function startServer(
435
436
  logger,
436
437
  platforms: hostPlatforms,
437
438
  otel: otelCollector,
439
+ otelMeter: otelRuntime?.meter,
438
440
  });
439
441
  // Rehydrate sessions from the authored storage sink before any
440
442
  // channel or route can address them (continuation tokens must resolve).
@@ -1868,8 +1870,11 @@ function resolveCursorGithubEventConfig(input: {
1868
1870
  ]),
1869
1871
  ];
1870
1872
  const permissions = resolveCursorGithubPermissions(
1871
- input.targets.map(
1872
- (target) => target.accountRuntime.scope?.permissions ?? "pr-write"
1873
+ input.targets.map((target) =>
1874
+ cursorGithubPermissionsForChannel(
1875
+ target.accountRuntime.options,
1876
+ target.accountRuntime.scope?.permissions
1877
+ )
1873
1878
  )
1874
1879
  );
1875
1880
  const scope = parseCursorGithubRepoScope(repos, permissions);