@cursor/july 0.1.41 → 0.1.43

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 (195) hide show
  1. package/AGENTS.md +10 -3
  2. package/dist/bin/agent-serve.js +3 -1
  3. package/dist/channels/github/api.d.ts +5 -0
  4. package/dist/channels/github/api.d.ts.map +1 -1
  5. package/dist/channels/github/api.js +18 -0
  6. package/dist/channels/github/defaults.d.ts +4 -5
  7. package/dist/channels/github/defaults.d.ts.map +1 -1
  8. package/dist/channels/github/defaults.js +27 -1
  9. package/dist/channels/github/github-channel.d.ts.map +1 -1
  10. package/dist/channels/github/github-channel.js +28 -5
  11. package/dist/channels/github/index.d.ts +1 -0
  12. package/dist/channels/github/index.d.ts.map +1 -1
  13. package/dist/channels/github/index.js +1 -0
  14. package/dist/channels/github/progress.d.ts +54 -0
  15. package/dist/channels/github/progress.d.ts.map +1 -0
  16. package/dist/channels/github/progress.js +168 -0
  17. package/dist/channels/github/state.d.ts +2 -0
  18. package/dist/channels/github/state.d.ts.map +1 -1
  19. package/dist/channels/github/state.js +1 -1
  20. package/dist/channels/github/types.d.ts +8 -4
  21. package/dist/channels/github/types.d.ts.map +1 -1
  22. package/dist/channels/slack/slack-channel.d.ts +4 -0
  23. package/dist/channels/slack/slack-channel.d.ts.map +1 -1
  24. package/dist/channels/slack/slack-channel.js +4 -0
  25. package/dist/docs/404.html +2 -2
  26. package/dist/docs/ab.html +4 -4
  27. package/dist/docs/assets/{app.mIw24pb1.js → app.DsTLo2j1.js} +1 -1
  28. package/dist/docs/assets/chunks/@localSearchIndexroot.BZx4pmZL.js +1 -0
  29. package/dist/docs/assets/chunks/{VPLocalSearchBox.hOzpPwrG.js → VPLocalSearchBox.DoVfutcV.js} +1 -1
  30. package/dist/docs/assets/chunks/{theme.BtFhUYmh.js → theme.DtuVtKkc.js} +2 -2
  31. package/dist/docs/assets/{deployment.md.BHVjVqRa.js → deployment.md.Cdp4rTE4.js} +1 -1
  32. package/dist/docs/assets/{guides_github.md.R2QlpR75.js → guides_github.md.DSg0j9qj.js} +29 -3
  33. package/dist/docs/assets/{guides_github.md.R2QlpR75.lean.js → guides_github.md.DSg0j9qj.lean.js} +1 -1
  34. package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.js +20 -0
  35. package/dist/docs/assets/guides_opentelemetry.md.DmyUwC5R.lean.js +1 -0
  36. package/dist/docs/assets/{index.md.BKpbkCa6.js → index.md.CMc5FP7E.js} +2 -1
  37. package/dist/docs/assets/{reference_channels.md.BIabFUAI.js → reference_channels.md.MN8iDy8V.js} +1 -1
  38. package/dist/docs/assets/reference_hooks.md.4cbRRIIu.js +14 -0
  39. package/dist/docs/assets/{reference_hooks.md.BHeG-vjK.lean.js → reference_hooks.md.4cbRRIIu.lean.js} +1 -1
  40. package/dist/docs/assets/{reference_project-layout.md._XdeMahr.js → reference_project-layout.md.D3MdHM2z.js} +2 -1
  41. package/dist/docs/assets/templates_triage.md.CConZt1z.js +11 -0
  42. package/dist/docs/assets/templates_triage.md.CConZt1z.lean.js +1 -0
  43. package/dist/docs/building-with-agents.html +5 -5
  44. package/dist/docs/concepts.html +5 -5
  45. package/dist/docs/deployment.html +6 -6
  46. package/dist/docs/evals.html +4 -4
  47. package/dist/docs/example-agents/approval-buddy.html +4 -4
  48. package/dist/docs/example-agents/benny.html +4 -4
  49. package/dist/docs/example-agents/bugbot.html +4 -4
  50. package/dist/docs/example-agents/codebase-wiki.html +4 -4
  51. package/dist/docs/example-agents/codeowners-review.html +4 -4
  52. package/dist/docs/example-agents/concierge.html +4 -4
  53. package/dist/docs/example-agents/fsd.html +4 -4
  54. package/dist/docs/example-agents/index.html +5 -5
  55. package/dist/docs/example-agents/knowledge-base.html +4 -4
  56. package/dist/docs/example-agents/oncall.html +4 -4
  57. package/dist/docs/example-agents/security-reviewer.html +4 -4
  58. package/dist/docs/example-agents/slack-agent.html +4 -4
  59. package/dist/docs/example-agents/weather-agent.html +4 -4
  60. package/dist/docs/guides/agent-to-agent.html +4 -4
  61. package/dist/docs/guides/cloud-runtime.html +5 -5
  62. package/dist/docs/guides/github.html +33 -7
  63. package/dist/docs/guides/human-in-the-loop.html +4 -4
  64. package/dist/docs/guides/mcp-oauth.html +4 -4
  65. package/dist/docs/guides/opentelemetry.html +44 -0
  66. package/dist/docs/guides/slack.html +4 -4
  67. package/dist/docs/guides/webhooks.html +4 -4
  68. package/dist/docs/hashmap.json +1 -1
  69. package/dist/docs/hillclimbing.html +4 -4
  70. package/dist/docs/index.html +7 -6
  71. package/dist/docs/quickstart.html +4 -4
  72. package/dist/docs/reference/agent-config.html +4 -4
  73. package/dist/docs/reference/artifacts.html +4 -4
  74. package/dist/docs/reference/channels.html +6 -6
  75. package/dist/docs/reference/cli.html +4 -4
  76. package/dist/docs/reference/connections.html +4 -4
  77. package/dist/docs/reference/hooks.html +9 -7
  78. package/dist/docs/reference/http-api.html +4 -4
  79. package/dist/docs/reference/instructions.html +4 -4
  80. package/dist/docs/reference/playground.html +4 -4
  81. package/dist/docs/reference/project-layout.html +7 -6
  82. package/dist/docs/reference/prompt.html +4 -4
  83. package/dist/docs/reference/schedules.html +4 -4
  84. package/dist/docs/reference/sessions.html +4 -4
  85. package/dist/docs/reference/skills.html +4 -4
  86. package/dist/docs/reference/subagents.html +4 -4
  87. package/dist/docs/reference/tools.html +4 -4
  88. package/dist/docs/scaffolding-agents.html +4 -4
  89. package/dist/docs/storage.html +4 -4
  90. package/dist/docs/templates/triage.html +35 -0
  91. package/dist/docs/troubleshooting.html +4 -4
  92. package/dist/hooks.d.ts +3 -1
  93. package/dist/hooks.d.ts.map +1 -1
  94. package/dist/hooks.js +3 -1
  95. package/dist/index.d.ts +2 -0
  96. package/dist/index.d.ts.map +1 -1
  97. package/dist/index.js +1 -0
  98. package/dist/internal/cli-ax.d.ts +1 -0
  99. package/dist/internal/cli-ax.d.ts.map +1 -1
  100. package/dist/internal/cli-ax.js +18 -3
  101. package/dist/internal/discovery.d.ts.map +1 -1
  102. package/dist/internal/discovery.js +36 -4
  103. package/dist/internal/distribution.d.ts.map +1 -1
  104. package/dist/internal/distribution.js +1 -0
  105. package/dist/internal/init-project.d.ts +24 -0
  106. package/dist/internal/init-project.d.ts.map +1 -1
  107. package/dist/internal/init-project.js +126 -7
  108. package/dist/internal/otel/attrs.d.ts +7 -0
  109. package/dist/internal/otel/attrs.d.ts.map +1 -0
  110. package/dist/internal/otel/attrs.js +13 -0
  111. package/dist/internal/otel/collector.d.ts +16 -0
  112. package/dist/internal/otel/collector.d.ts.map +1 -0
  113. package/dist/internal/otel/collector.js +564 -0
  114. package/dist/internal/otel/config.d.ts +42 -0
  115. package/dist/internal/otel/config.d.ts.map +1 -0
  116. package/dist/internal/otel/config.js +236 -0
  117. package/dist/internal/otel/http.d.ts +11 -0
  118. package/dist/internal/otel/http.d.ts.map +1 -0
  119. package/dist/internal/otel/http.js +97 -0
  120. package/dist/internal/otel/runtime.d.ts +21 -0
  121. package/dist/internal/otel/runtime.d.ts.map +1 -0
  122. package/dist/internal/otel/runtime.js +188 -0
  123. package/dist/internal/server.d.ts.map +1 -1
  124. package/dist/internal/server.js +25 -1
  125. package/dist/internal/session-engine.d.ts +10 -1
  126. package/dist/internal/session-engine.d.ts.map +1 -1
  127. package/dist/internal/session-engine.js +36 -2
  128. package/dist/memory.d.ts +4 -0
  129. package/dist/memory.d.ts.map +1 -1
  130. package/dist/memory.js +4 -0
  131. package/dist/otel.d.ts +88 -0
  132. package/dist/otel.d.ts.map +1 -0
  133. package/dist/otel.js +64 -0
  134. package/dist/playground/assets/{index-B3HBneZZ.js → index-D-DIYQzw.js} +31 -31
  135. package/dist/playground/assets/index-DQTH622f.css +1 -0
  136. package/dist/playground/index.html +2 -2
  137. package/dist/types.d.ts +31 -4
  138. package/dist/types.d.ts.map +1 -1
  139. package/docs/README.md +3 -0
  140. package/docs/deployment.md +2 -1
  141. package/docs/guides/github.md +79 -6
  142. package/docs/guides/opentelemetry.md +184 -0
  143. package/docs/reference/channels.md +3 -1
  144. package/docs/reference/hooks.md +25 -5
  145. package/docs/reference/project-layout.md +2 -0
  146. package/docs/templates/triage.md +147 -0
  147. package/package.json +23 -1
  148. package/skills/create-agent/SKILL.md +2 -2
  149. package/skills/debug/SKILL.md +4 -0
  150. package/skills/framework-map/SKILL.md +2 -0
  151. package/skills/otel/SKILL.md +80 -0
  152. package/src/bin/agent-serve.ts +3 -1
  153. package/src/channels/github/api.ts +22 -0
  154. package/src/channels/github/defaults.ts +27 -6
  155. package/src/channels/github/github-channel.ts +27 -1
  156. package/src/channels/github/index.ts +1 -0
  157. package/src/channels/github/progress.ts +243 -0
  158. package/src/channels/github/state.ts +3 -0
  159. package/src/channels/github/types.ts +8 -4
  160. package/src/channels/slack/slack-channel.ts +4 -0
  161. package/src/hooks.ts +3 -1
  162. package/src/index.ts +6 -0
  163. package/src/internal/cli-ax.ts +19 -1
  164. package/src/internal/discovery.ts +59 -4
  165. package/src/internal/distribution.ts +1 -0
  166. package/src/internal/init-project.ts +150 -7
  167. package/src/internal/otel/attrs.ts +18 -0
  168. package/src/internal/otel/collector.ts +796 -0
  169. package/src/internal/otel/config.ts +307 -0
  170. package/src/internal/otel/http.ts +126 -0
  171. package/src/internal/otel/runtime.ts +271 -0
  172. package/src/internal/server.ts +38 -1
  173. package/src/internal/session-engine.ts +52 -0
  174. package/src/memory.ts +4 -0
  175. package/src/otel.ts +155 -0
  176. package/src/types.ts +29 -4
  177. package/templates/triage/README.md +48 -0
  178. package/templates/triage/agent/agent.ts +14 -0
  179. package/templates/triage/agent/channels/intake.ts +20 -0
  180. package/templates/triage/agent/channels/slack.ts +3 -0
  181. package/templates/triage/agent/hooks/memory.ts +3 -0
  182. package/templates/triage/agent/instructions.md +27 -0
  183. package/templates/triage/agent/skills/triage-rubric.md +43 -0
  184. package/templates/triage/agent/tools/record_triage.ts +23 -0
  185. package/templates/triage/evals/evals.config.ts +5 -0
  186. package/templates/triage/evals/triage.eval.ts +43 -0
  187. package/templates/triage/package.json +18 -0
  188. package/templates/triage/tsconfig.json +12 -0
  189. package/dist/docs/assets/chunks/@localSearchIndexroot.BA7V8dEJ.js +0 -1
  190. package/dist/docs/assets/reference_hooks.md.BHeG-vjK.js +0 -12
  191. package/dist/playground/assets/index-Bqk9nplh.css +0 -1
  192. /package/dist/docs/assets/{deployment.md.BHVjVqRa.lean.js → deployment.md.Cdp4rTE4.lean.js} +0 -0
  193. /package/dist/docs/assets/{index.md.BKpbkCa6.lean.js → index.md.CMc5FP7E.lean.js} +0 -0
  194. /package/dist/docs/assets/{reference_channels.md.BIabFUAI.lean.js → reference_channels.md.MN8iDy8V.lean.js} +0 -0
  195. /package/dist/docs/assets/{reference_project-layout.md._XdeMahr.lean.js → reference_project-layout.md.D3MdHM2z.lean.js} +0 -0
@@ -0,0 +1,236 @@
1
+ /**
2
+ * Merge authored `defineOtel`, `serve({ otel })`, and standard OTel env.
3
+ */
4
+ var __rest = (this && this.__rest) || function (s, e) {
5
+ var t = {};
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
7
+ t[p] = s[p];
8
+ if (s != null && typeof Object.getOwnPropertySymbols === "function")
9
+ for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
10
+ if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
11
+ t[p[i]] = s[p[i]];
12
+ }
13
+ return t;
14
+ };
15
+ /** True when any standard OTLP endpoint env var is set. */
16
+ export function hasOtelEnv(env = process.env) {
17
+ return (nonEmpty(env.OTEL_EXPORTER_OTLP_ENDPOINT) ||
18
+ nonEmpty(env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) ||
19
+ nonEmpty(env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) ||
20
+ nonEmpty(env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT));
21
+ }
22
+ /**
23
+ * Process-global authored config. OTel SDK is one per serve process — if
24
+ * several mounts ship `agent/otel.ts`, they must be identical.
25
+ */
26
+ export function pickAuthoredOtel(mounts) {
27
+ const found = mounts.filter((m) => m.otel !== undefined);
28
+ if (found.length === 0) {
29
+ return undefined;
30
+ }
31
+ const first = found[0];
32
+ const key = stableConfigKey(first.otel);
33
+ for (const other of found.slice(1)) {
34
+ if (stableConfigKey(other.otel) !== key) {
35
+ const a = first.slug === "" ? first.name : first.slug;
36
+ const b = other.slug === "" ? other.name : other.slug;
37
+ throw new Error(`Conflicting agent/otel.ts on mounts "${a}" and "${b}": OTel is process-global. Use identical defineOtel configs, or configure once via serve({ otel }) / OTEL_EXPORTER_OTLP_*.`);
38
+ }
39
+ }
40
+ return first.otel;
41
+ }
42
+ /**
43
+ * Resolve effective config.
44
+ *
45
+ * Precedence: `serve({ otel: false })` disables; otherwise merge
46
+ * `serve({ otel })` over `defineOtel` over env defaults.
47
+ */
48
+ export function resolveOtelConfig(input) {
49
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l;
50
+ const env = (_a = input.env) !== null && _a !== void 0 ? _a : process.env;
51
+ if (input.serve === false) {
52
+ return disabled();
53
+ }
54
+ const authored = (_b = input.authored) !== null && _b !== void 0 ? _b : {};
55
+ const serve = input.serve === undefined ? {} : input.serve;
56
+ const merged = {
57
+ serviceName: (_c = serve.serviceName) !== null && _c !== void 0 ? _c : authored.serviceName,
58
+ serviceVersion: (_d = serve.serviceVersion) !== null && _d !== void 0 ? _d : authored.serviceVersion,
59
+ resourceAttributes: Object.assign(Object.assign({}, authored.resourceAttributes), serve.resourceAttributes),
60
+ exporters: (_e = serve.exporters) !== null && _e !== void 0 ? _e : authored.exporters,
61
+ traces: (_f = serve.traces) !== null && _f !== void 0 ? _f : authored.traces,
62
+ metrics: (_g = serve.metrics) !== null && _g !== void 0 ? _g : authored.metrics,
63
+ logs: (_h = serve.logs) !== null && _h !== void 0 ? _h : authored.logs,
64
+ };
65
+ const envExporters = exportersFromEnv(env);
66
+ const exporters = merged.exporters !== undefined && merged.exporters.length > 0
67
+ ? merged.exporters.map((e) => withEnvHeaders(e, env))
68
+ : envExporters;
69
+ const optedIn = input.authored !== undefined ||
70
+ input.serve !== undefined ||
71
+ envExporters.length > 0;
72
+ if (!optedIn || exporters.length === 0) {
73
+ return disabled();
74
+ }
75
+ const traces = resolveSignal(merged.traces);
76
+ const metrics = resolveSignal(merged.metrics);
77
+ const logs = resolveLogs(merged.logs, env);
78
+ return {
79
+ enabled: traces !== false || metrics !== false || logs !== false,
80
+ serviceName: (_k = (_j = merged.serviceName) !== null && _j !== void 0 ? _j : env.OTEL_SERVICE_NAME) !== null && _k !== void 0 ? _k : "cursor",
81
+ serviceVersion: merged.serviceVersion,
82
+ resourceAttributes: (_l = merged.resourceAttributes) !== null && _l !== void 0 ? _l : {},
83
+ exporters,
84
+ traces,
85
+ metrics,
86
+ logs,
87
+ };
88
+ }
89
+ export function parseOtelHeaders(raw) {
90
+ if (raw === undefined || raw.length === 0) {
91
+ return {};
92
+ }
93
+ const out = {};
94
+ for (const part of raw.split(",")) {
95
+ const idx = part.indexOf("=");
96
+ if (idx <= 0) {
97
+ continue;
98
+ }
99
+ const key = part.slice(0, idx).trim();
100
+ const value = part.slice(idx + 1).trim();
101
+ if (key.length > 0) {
102
+ out[key] = value;
103
+ }
104
+ }
105
+ return out;
106
+ }
107
+ /** Collapse `…/v1/{traces,metrics,logs}` to the collector base. */
108
+ export function stripSignalPath(url) {
109
+ return url.replace(/\/v1\/(traces|metrics|logs)\/?$/i, "");
110
+ }
111
+ /** Exporters that apply to one signal (honors per-exporter `signals`). */
112
+ export function exportersForSignal(exporters, signal) {
113
+ return exporters.filter((exporter) => exporter.signals === undefined || exporter.signals.includes(signal));
114
+ }
115
+ function disabled() {
116
+ return {
117
+ enabled: false,
118
+ serviceName: "cursor",
119
+ serviceVersion: undefined,
120
+ resourceAttributes: {},
121
+ exporters: [],
122
+ traces: false,
123
+ metrics: false,
124
+ logs: false,
125
+ };
126
+ }
127
+ /**
128
+ * Build exporters from env. A shared `OTEL_EXPORTER_OTLP_ENDPOINT` fans out
129
+ * to every signal. Distinct `*_TRACES_ENDPOINT` / `*_METRICS_ENDPOINT` /
130
+ * `*_LOGS_ENDPOINT` values each become their own exporter scoped to that
131
+ * signal (OTel env spec).
132
+ */
133
+ function exportersFromEnv(env) {
134
+ var _a, _b, _c, _d;
135
+ const base = (_a = env.OTEL_EXPORTER_OTLP_ENDPOINT) === null || _a === void 0 ? void 0 : _a.trim();
136
+ const traces = (_b = env.OTEL_EXPORTER_OTLP_TRACES_ENDPOINT) === null || _b === void 0 ? void 0 : _b.trim();
137
+ const metrics = (_c = env.OTEL_EXPORTER_OTLP_METRICS_ENDPOINT) === null || _c === void 0 ? void 0 : _c.trim();
138
+ const logs = (_d = env.OTEL_EXPORTER_OTLP_LOGS_ENDPOINT) === null || _d === void 0 ? void 0 : _d.trim();
139
+ const protocol = protocolFromEnv(env.OTEL_EXPORTER_OTLP_PROTOCOL);
140
+ const headers = parseOtelHeaders(env.OTEL_EXPORTER_OTLP_HEADERS);
141
+ if (nonEmpty(base)) {
142
+ return [{ url: stripSignalPath(base), headers, protocol }];
143
+ }
144
+ const out = [];
145
+ pushSignalExporter(out, traces, "traces", headers, protocol);
146
+ pushSignalExporter(out, metrics, "metrics", headers, protocol);
147
+ pushSignalExporter(out, logs, "logs", headers, protocol);
148
+ return out;
149
+ }
150
+ function pushSignalExporter(out, raw, signal, headers, protocol) {
151
+ if (!nonEmpty(raw)) {
152
+ return;
153
+ }
154
+ out.push({
155
+ url: stripSignalPath(raw),
156
+ headers,
157
+ protocol,
158
+ signals: [signal],
159
+ });
160
+ }
161
+ function withEnvHeaders(exporter, env) {
162
+ var _a;
163
+ const envHeaders = parseOtelHeaders(env.OTEL_EXPORTER_OTLP_HEADERS);
164
+ return {
165
+ url: stripSignalPath(exporter.url),
166
+ headers: Object.assign(Object.assign({}, envHeaders), exporter.headers),
167
+ protocol: (_a = exporter.protocol) !== null && _a !== void 0 ? _a : protocolFromEnv(env.OTEL_EXPORTER_OTLP_PROTOCOL),
168
+ signals: exporter.signals,
169
+ };
170
+ }
171
+ function protocolFromEnv(raw) {
172
+ const v = raw === null || raw === void 0 ? void 0 : raw.trim().toLowerCase();
173
+ if (v === "http/json" || v === "json") {
174
+ return "http/json";
175
+ }
176
+ // Default protobuf — matches Cursor enterprise OTLP/HTTP. grpc unsupported.
177
+ return "http/protobuf";
178
+ }
179
+ function resolveSignal(value) {
180
+ if (value === false) {
181
+ return false;
182
+ }
183
+ if (value === true || value === undefined) {
184
+ return {};
185
+ }
186
+ return value;
187
+ }
188
+ function resolveLogs(value, env) {
189
+ var _a, _b;
190
+ if (value === false) {
191
+ return false;
192
+ }
193
+ const envPrompts = env.OTEL_LOG_USER_PROMPTS === "1";
194
+ const envTools = env.OTEL_LOG_TOOL_CONTENT === "1";
195
+ if (value === true) {
196
+ return { userPrompts: envPrompts, toolContent: envTools };
197
+ }
198
+ if (value === undefined) {
199
+ // Match OTel: unset / empty / `none` means logs off. Any other
200
+ // `OTEL_LOGS_EXPORTER` value (e.g. `otlp`) opts logs on.
201
+ if (!envPrompts && !envTools && !logsExporterOptIn(env)) {
202
+ return false;
203
+ }
204
+ return { userPrompts: envPrompts, toolContent: envTools };
205
+ }
206
+ return {
207
+ userPrompts: (_a = value.userPrompts) !== null && _a !== void 0 ? _a : envPrompts,
208
+ toolContent: (_b = value.toolContent) !== null && _b !== void 0 ? _b : envTools,
209
+ };
210
+ }
211
+ /** `OTEL_LOGS_EXPORTER=none` (or unset) must not enable log export. */
212
+ function logsExporterOptIn(env) {
213
+ var _a;
214
+ const raw = (_a = env.OTEL_LOGS_EXPORTER) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase();
215
+ return raw !== undefined && raw.length > 0 && raw !== "none";
216
+ }
217
+ function stableConfigKey(def) {
218
+ const { __agentServe: _brand } = def, rest = __rest(def, ["__agentServe"]);
219
+ return stable(rest);
220
+ }
221
+ function stable(value) {
222
+ if (value === null || typeof value !== "object") {
223
+ return JSON.stringify(value);
224
+ }
225
+ if (Array.isArray(value)) {
226
+ return `[${value.map(stable).join(",")}]`;
227
+ }
228
+ const obj = value;
229
+ return `{${Object.keys(obj)
230
+ .sort()
231
+ .map((key) => `${JSON.stringify(key)}:${stable(obj[key])}`)
232
+ .join(",")}}`;
233
+ }
234
+ function nonEmpty(value) {
235
+ return value !== undefined && value.trim().length > 0;
236
+ }
@@ -0,0 +1,11 @@
1
+ /**
2
+ * HTTP SERVER spans + W3C `traceparent` extraction for inbound requests.
3
+ */
4
+ import type { IncomingMessage, ServerResponse } from "node:http";
5
+ import type { OtelRuntime } from "./runtime.js";
6
+ /**
7
+ * Instrument one inbound Node request: SERVER span, W3C extract, auto-end
8
+ * on response finish/close, run `fn` under the span context.
9
+ */
10
+ export declare function instrumentHttp<T>(runtime: OtelRuntime | undefined, req: IncomingMessage, res: ServerResponse, fn: () => Promise<T>): Promise<T>;
11
+ //# sourceMappingURL=http.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"http.d.ts","sourceRoot":"","sources":["../../../src/internal/otel/http.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,WAAW,CAAC;AAUjE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AAiBhD;;;GAGG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAC9B,OAAO,EAAE,WAAW,GAAG,SAAS,EAChC,GAAG,EAAE,eAAe,EACpB,GAAG,EAAE,cAAc,EACnB,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GACnB,OAAO,CAAC,CAAC,CAAC,CAcZ"}
@@ -0,0 +1,97 @@
1
+ /**
2
+ * HTTP SERVER spans + W3C `traceparent` extraction for inbound requests.
3
+ */
4
+ import { context, propagation, SpanKind, SpanStatusCode, trace, } from "@opentelemetry/api";
5
+ import { W3CTraceContextPropagator } from "@opentelemetry/core";
6
+ let propagatorInstalled = false;
7
+ function ensurePropagator() {
8
+ if (propagatorInstalled) {
9
+ return;
10
+ }
11
+ propagation.setGlobalPropagator(new W3CTraceContextPropagator());
12
+ propagatorInstalled = true;
13
+ }
14
+ /**
15
+ * Instrument one inbound Node request: SERVER span, W3C extract, auto-end
16
+ * on response finish/close, run `fn` under the span context.
17
+ */
18
+ export function instrumentHttp(runtime, req, res, fn) {
19
+ const handle = startHttpSpan(runtime, req);
20
+ if (handle === undefined) {
21
+ return fn();
22
+ }
23
+ res.once("finish", () => {
24
+ handle.end(res.statusCode);
25
+ });
26
+ res.once("close", () => {
27
+ if (!res.writableFinished) {
28
+ handle.end(res.statusCode || 499);
29
+ }
30
+ });
31
+ return context.with(handle.context, fn);
32
+ }
33
+ function startHttpSpan(runtime, req) {
34
+ var _a, _b, _c, _d;
35
+ if (runtime === undefined || runtime.config.traces === false) {
36
+ return undefined;
37
+ }
38
+ ensurePropagator();
39
+ const headers = {};
40
+ for (const [key, value] of Object.entries(req.headers)) {
41
+ if (typeof value === "string") {
42
+ headers[key] = value;
43
+ }
44
+ else if (Array.isArray(value) && value[0] !== undefined) {
45
+ headers[key] = value[0];
46
+ }
47
+ }
48
+ const parent = propagation.extract(context.active(), headers);
49
+ const method = (_a = req.method) !== null && _a !== void 0 ? _a : "GET";
50
+ const path = (_c = ((_b = req.url) !== null && _b !== void 0 ? _b : "/").split("?")[0]) !== null && _c !== void 0 ? _c : "/";
51
+ const started = Date.now();
52
+ const span = runtime.tracer.startSpan("agent_sdk.http", {
53
+ kind: SpanKind.SERVER,
54
+ attributes: {
55
+ "http.request.method": method,
56
+ "url.path": path,
57
+ "network.peer.address": (_d = req.socket.remoteAddress) !== null && _d !== void 0 ? _d : "",
58
+ },
59
+ }, parent);
60
+ const ctx = trace.setSpan(parent, span);
61
+ let ended = false;
62
+ return {
63
+ context: ctx,
64
+ end(statusCode, error) {
65
+ var _a;
66
+ if (ended) {
67
+ return;
68
+ }
69
+ ended = true;
70
+ span.setAttribute("http.response.status_code", statusCode);
71
+ if (error !== undefined) {
72
+ span.recordException(error instanceof Error ? error : new Error(String(error)));
73
+ span.setStatus({
74
+ code: SpanStatusCode.ERROR,
75
+ message: error instanceof Error ? error.message : String(error),
76
+ });
77
+ }
78
+ else if (statusCode >= 500) {
79
+ span.setStatus({ code: SpanStatusCode.ERROR });
80
+ }
81
+ else {
82
+ span.setStatus({ code: SpanStatusCode.OK });
83
+ }
84
+ span.end();
85
+ (_a = runtime.httpDuration) === null || _a === void 0 ? void 0 : _a.record(Date.now() - started, {
86
+ "http.request.method": method,
87
+ "http.response.status_code": statusCode,
88
+ "url.path": routeClass(path),
89
+ });
90
+ },
91
+ };
92
+ }
93
+ function routeClass(path) {
94
+ return path
95
+ .replace(/\/sessions\/[0-9a-f-]{8,}/gi, "/sessions/:id")
96
+ .replace(/\/[0-9a-f]{8,}(?:-[0-9a-f]{4,})+/gi, "/:id");
97
+ }
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Process-level OTel SDK (OTLP HTTP exporters for traces / metrics / logs).
3
+ *
4
+ * Refuses to install a second global Tracer/Meter/Logger provider when one
5
+ * already owns the process (CLI, extension host, etc.). Spans still use
6
+ * `trace.getTracer()` so they nest under an existing parent when present.
7
+ */
8
+ import type { Histogram, Meter, Tracer } from "@opentelemetry/api";
9
+ import type { Logger as OtelLogger } from "@opentelemetry/api-logs";
10
+ import { type ResolvedOtelConfig } from "./config.js";
11
+ export interface OtelRuntime {
12
+ config: ResolvedOtelConfig;
13
+ tracer: Tracer;
14
+ meter: Meter | undefined;
15
+ logger: OtelLogger | undefined;
16
+ httpDuration: Histogram | undefined;
17
+ shutdown: () => Promise<void>;
18
+ }
19
+ export declare function createOtelRuntime(config: ResolvedOtelConfig, log: (line: string) => void): OtelRuntime | undefined;
20
+ export declare function shutdownOtelRuntime(runtime: OtelRuntime | undefined): Promise<void>;
21
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../../src/internal/otel/runtime.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,oBAAoB,CAAC;AAEnE,OAAO,KAAK,EAAE,MAAM,IAAI,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAgCpE,OAAO,EAAsB,KAAK,kBAAkB,EAAE,MAAM,aAAa,CAAC;AAI1E,MAAM,WAAW,WAAW;IAC1B,MAAM,EAAE,kBAAkB,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,KAAK,GAAG,SAAS,CAAC;IACzB,MAAM,EAAE,UAAU,GAAG,SAAS,CAAC;IAC/B,YAAY,EAAE,SAAS,GAAG,SAAS,CAAC;IACpC,QAAQ,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;CAC/B;AAED,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,kBAAkB,EAC1B,GAAG,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,GAC1B,WAAW,GAAG,SAAS,CA6BzB;AAED,wBAAsB,mBAAmB,CACvC,OAAO,EAAE,WAAW,GAAG,SAAS,GAC/B,OAAO,CAAC,IAAI,CAAC,CAEf"}
@@ -0,0 +1,188 @@
1
+ /**
2
+ * Process-level OTel SDK (OTLP HTTP exporters for traces / metrics / logs).
3
+ *
4
+ * Refuses to install a second global Tracer/Meter/Logger provider when one
5
+ * already owns the process (CLI, extension host, etc.). Spans still use
6
+ * `trace.getTracer()` so they nest under an existing parent when present.
7
+ */
8
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
9
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
10
+ return new (P || (P = Promise))(function (resolve, reject) {
11
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
12
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
13
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
14
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
15
+ });
16
+ };
17
+ import { DiagLogLevel, diag, metrics, trace } from "@opentelemetry/api";
18
+ import { logs } from "@opentelemetry/api-logs";
19
+ import { OTLPLogExporter as OTLPLogExporterHttp } from "@opentelemetry/exporter-logs-otlp-http";
20
+ import { OTLPLogExporter as OTLPLogExporterProto } from "@opentelemetry/exporter-logs-otlp-proto";
21
+ import { OTLPMetricExporter as OTLPMetricExporterHttp } from "@opentelemetry/exporter-metrics-otlp-http";
22
+ import { OTLPMetricExporter as OTLPMetricExporterProto } from "@opentelemetry/exporter-metrics-otlp-proto";
23
+ import { OTLPTraceExporter as OTLPTraceExporterHttp } from "@opentelemetry/exporter-trace-otlp-http";
24
+ import { OTLPTraceExporter as OTLPTraceExporterProto } from "@opentelemetry/exporter-trace-otlp-proto";
25
+ import { resourceFromAttributes, } from "@opentelemetry/resources";
26
+ import { BatchLogRecordProcessor, LoggerProvider, } from "@opentelemetry/sdk-logs";
27
+ import { AggregationTemporality, MeterProvider, PeriodicExportingMetricReader, } from "@opentelemetry/sdk-metrics";
28
+ import { BatchSpanProcessor, NodeTracerProvider, ParentBasedSampler, TraceIdRatioBasedSampler, } from "@opentelemetry/sdk-trace-node";
29
+ import { ATTR_SERVICE_NAME, ATTR_SERVICE_VERSION, } from "@opentelemetry/semantic-conventions";
30
+ import { exportersForSignal } from "./config.js";
31
+ const INSTRUMENTATION = "agent_sdk";
32
+ export function createOtelRuntime(config, log) {
33
+ var _a;
34
+ if (!config.enabled) {
35
+ return undefined;
36
+ }
37
+ const proto = (_a = process.env.OTEL_EXPORTER_OTLP_PROTOCOL) === null || _a === void 0 ? void 0 : _a.trim().toLowerCase();
38
+ if (proto === "grpc") {
39
+ log("[agent-sdk:otel] OTEL_EXPORTER_OTLP_PROTOCOL=grpc is unsupported; using http/protobuf");
40
+ }
41
+ const sdk = startOtelSdk(config, log);
42
+ const meter = config.metrics === false
43
+ ? undefined
44
+ : metrics.getMeterProvider().getMeter(INSTRUMENTATION);
45
+ return {
46
+ config,
47
+ tracer: trace.getTracer(INSTRUMENTATION),
48
+ meter,
49
+ logger: config.logs === false ? undefined : logs.getLogger(INSTRUMENTATION),
50
+ httpDuration: meter === undefined
51
+ ? undefined
52
+ : meter.createHistogram("agent_sdk.http.duration", {
53
+ description: "HTTP request duration",
54
+ unit: "ms",
55
+ }),
56
+ shutdown: sdk.shutdown,
57
+ };
58
+ }
59
+ export function shutdownOtelRuntime(runtime) {
60
+ return __awaiter(this, void 0, void 0, function* () {
61
+ yield runtime === null || runtime === void 0 ? void 0 : runtime.shutdown();
62
+ });
63
+ }
64
+ function startOtelSdk(config, logger) {
65
+ var _a, _b;
66
+ diag.setLogger({
67
+ verbose: (m) => logger(`[agent-sdk:otel] ${m}`),
68
+ debug: (m) => logger(`[agent-sdk:otel] ${m}`),
69
+ info: (m) => logger(`[agent-sdk:otel] ${m}`),
70
+ warn: (m) => logger(`[agent-sdk:otel] warn: ${m}`),
71
+ error: (m) => logger(`[agent-sdk:otel] error: ${m}`),
72
+ }, DiagLogLevel.ERROR);
73
+ const resource = buildResource(config);
74
+ let tracerProvider;
75
+ let meterProvider;
76
+ let loggerProvider;
77
+ const traceOpts = config.traces;
78
+ if (traceOpts !== false) {
79
+ const exporters = exportersForSignal(config.exporters, "traces");
80
+ if (exporters.length > 0) {
81
+ if (hasRealTracerProvider()) {
82
+ logger("[agent-sdk:otel] TracerProvider already registered; reusing global (Agent SDK OTLP exporters not attached)");
83
+ }
84
+ else {
85
+ tracerProvider = new NodeTracerProvider({
86
+ resource,
87
+ spanProcessors: exporters.map((exporter) => new BatchSpanProcessor(createTraceExporter(exporter, signalUrl(exporter.url, "traces")))),
88
+ sampler: new ParentBasedSampler({
89
+ root: new TraceIdRatioBasedSampler((_a = traceOpts.sampleRatio) !== null && _a !== void 0 ? _a : 1),
90
+ }),
91
+ });
92
+ tracerProvider.register();
93
+ }
94
+ }
95
+ }
96
+ const metricOpts = config.metrics;
97
+ if (metricOpts !== false) {
98
+ const exporters = exportersForSignal(config.exporters, "metrics");
99
+ if (exporters.length > 0) {
100
+ const exportIntervalMillis = (_b = metricOpts.exportIntervalMillis) !== null && _b !== void 0 ? _b : 10000;
101
+ const provider = new MeterProvider({
102
+ resource,
103
+ readers: exporters.map((exporter) => new PeriodicExportingMetricReader({
104
+ exporter: createMetricExporter(exporter, signalUrl(exporter.url, "metrics")),
105
+ exportIntervalMillis,
106
+ })),
107
+ });
108
+ if (metrics.setGlobalMeterProvider(provider)) {
109
+ meterProvider = provider;
110
+ }
111
+ else {
112
+ logger("[agent-sdk:otel] MeterProvider already registered; reusing global (Agent SDK OTLP exporters not attached)");
113
+ void provider.shutdown();
114
+ }
115
+ }
116
+ }
117
+ if (config.logs !== false) {
118
+ const exporters = exportersForSignal(config.exporters, "logs");
119
+ if (exporters.length > 0) {
120
+ const provider = new LoggerProvider({
121
+ resource,
122
+ processors: exporters.map((exporter) => new BatchLogRecordProcessor(createLogExporter(exporter, signalUrl(exporter.url, "logs")))),
123
+ });
124
+ // api-logs returns the active provider (ours on success, existing otherwise).
125
+ if (logs.setGlobalLoggerProvider(provider) === provider) {
126
+ loggerProvider = provider;
127
+ }
128
+ else {
129
+ logger("[agent-sdk:otel] LoggerProvider already registered; reusing global (Agent SDK OTLP exporters not attached)");
130
+ void provider.shutdown();
131
+ }
132
+ }
133
+ }
134
+ logger(`[agent-sdk] otel enabled service=${config.serviceName} exporters=${config.exporters.length} traces=${config.traces !== false} metrics=${config.metrics !== false} logs=${config.logs !== false}`);
135
+ return {
136
+ shutdown: () => __awaiter(this, void 0, void 0, function* () {
137
+ yield Promise.allSettled([
138
+ tracerProvider === null || tracerProvider === void 0 ? void 0 : tracerProvider.shutdown(),
139
+ meterProvider === null || meterProvider === void 0 ? void 0 : meterProvider.shutdown(),
140
+ loggerProvider === null || loggerProvider === void 0 ? void 0 : loggerProvider.shutdown(),
141
+ ]);
142
+ }),
143
+ };
144
+ }
145
+ function buildResource(config) {
146
+ // Align with Cursor enterprise wire resource attrs where they overlap so
147
+ // Agent SDK traces join org metrics/logs in the same collector.
148
+ const resourceAttrs = Object.assign({ [ATTR_SERVICE_NAME]: config.serviceName, "telemetry.sdk.language": "nodejs", "cursor.surface": "unspecified", "cursor.entrypoint": "sdk_ts", "agent_sdk.framework": "@cursor/july" }, config.resourceAttributes);
149
+ if (config.serviceVersion !== undefined) {
150
+ resourceAttrs[ATTR_SERVICE_VERSION] = config.serviceVersion;
151
+ }
152
+ return resourceFromAttributes(resourceAttrs);
153
+ }
154
+ function signalUrl(base, signal) {
155
+ return `${base.replace(/\/$/, "")}/v1/${signal}`;
156
+ }
157
+ /** True when a non-noop TracerProvider already owns the process. */
158
+ function hasRealTracerProvider() {
159
+ var _a;
160
+ const provider = trace.getTracerProvider();
161
+ const delegate = (_a = provider.getDelegate) === null || _a === void 0 ? void 0 : _a.call(provider);
162
+ return (delegate !== undefined && delegate.constructor.name !== "NoopTracerProvider");
163
+ }
164
+ function isProtobuf(exporter) {
165
+ return exporter.protocol !== "http/json";
166
+ }
167
+ function createTraceExporter(exporter, url) {
168
+ const opts = { url, headers: exporter.headers };
169
+ return isProtobuf(exporter)
170
+ ? new OTLPTraceExporterProto(opts)
171
+ : new OTLPTraceExporterHttp(opts);
172
+ }
173
+ function createMetricExporter(exporter, url) {
174
+ const opts = {
175
+ url,
176
+ headers: exporter.headers,
177
+ temporalityPreference: AggregationTemporality.DELTA,
178
+ };
179
+ return isProtobuf(exporter)
180
+ ? new OTLPMetricExporterProto(opts)
181
+ : new OTLPMetricExporterHttp(opts);
182
+ }
183
+ function createLogExporter(exporter, url) {
184
+ const opts = { url, headers: exporter.headers };
185
+ return isProtobuf(exporter)
186
+ ? new OTLPLogExporterProto(opts)
187
+ : new OTLPLogExporterHttp(opts);
188
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAqGrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAiBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAaD,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,CAgtB3B"}
1
+ {"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../src/internal/server.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AA4BH,OAAO,KAAK,EACV,YAAY,EACZ,gBAAgB,EAOhB,YAAY,EACb,MAAM,aAAa,CAAC;AAyGrB,OAAO,EAAE,KAAK,WAAW,EAAmB,MAAM,iBAAiB,CAAC;AAiBpE,8EAA8E;AAC9E,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,YAAY,CAAC;CACvB;AAaD,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,CAivB3B"}
@@ -59,6 +59,10 @@ import { createLocalControlPlane, } from "./local-control-plane.js";
59
59
  import { createLogRing } from "./log-ring.js";
60
60
  import { createAgentMcpEndpoint, createToolMcpEndpoint, MCP_ENDPOINT_PATH, TOOL_MCP_ENDPOINT_PATH, } from "./mcp-endpoint.js";
61
61
  import { isLoopbackAddress } from "./net.js";
62
+ import { createOtelCollector } from "./otel/collector.js";
63
+ import { pickAuthoredOtel, resolveOtelConfig } from "./otel/config.js";
64
+ import { instrumentHttp } from "./otel/http.js";
65
+ import { createOtelRuntime, shutdownOtelRuntime } from "./otel/runtime.js";
62
66
  import { collectPeerConnections } from "./peer-connections.js";
63
67
  import { PLATFORM_SCHEDULE_CATALOG_FILENAME, syncHostedPlatformSchedules, } from "./platform-schedule-sync.js";
64
68
  import { createCursorHostedPlatformTimers } from "./platform-timers.js";
@@ -106,6 +110,20 @@ export function startServer(mounts_1) {
106
110
  // this when building its client-version header) so the internal-only
107
111
  // agentkit_enabled gate applies to every turn.
108
112
  (_j = (_s = process.env).CURSOR_AGENTKIT_VERSION) !== null && _j !== void 0 ? _j : (_s.CURSOR_AGENTKIT_VERSION = packageVersion());
113
+ const authoredOtel = pickAuthoredOtel(mounts.map((m) => ({
114
+ slug: m.slug,
115
+ name: m.project.name,
116
+ otel: m.project.otel,
117
+ })));
118
+ const otelRuntime = createOtelRuntime(resolveOtelConfig({
119
+ authored: authoredOtel,
120
+ serve: options.otel,
121
+ }), logger);
122
+ if (otelRuntime === undefined &&
123
+ options.otel !== false &&
124
+ authoredOtel !== undefined) {
125
+ logger("[agent-sdk] otel: agent/otel.ts present but no OTLP exporters configured (set exporters or OTEL_EXPORTER_OTLP_ENDPOINT)");
126
+ }
109
127
  const cursorGithubTargets = collectCursorGithubTargets(mounts);
110
128
  const cursorGithubConfig = resolveCursorGithubEventConfig({
111
129
  configured: options.cursorEvents,
@@ -239,12 +257,16 @@ export function startServer(mounts_1) {
239
257
  // Each agent gets an isolated state root so their sessions never mix.
240
258
  const baseStateRoot = (_m = options.stateRoot) !== null && _m !== void 0 ? _m : join(project.rootDir, ".agent-serve");
241
259
  const stateRoot = slug === "" ? baseStateRoot : join(baseStateRoot, slug);
260
+ const otelCollector = otelRuntime === undefined
261
+ ? undefined
262
+ : createOtelCollector(otelRuntime, project.name, logger);
242
263
  const engine = new SessionEngine({
243
264
  project,
244
265
  stateRoot,
245
266
  runner,
246
267
  logger,
247
268
  platforms: hostPlatforms,
269
+ otel: otelCollector,
248
270
  });
249
271
  // Rehydrate sessions from the authored storage sink before any
250
272
  // channel or route can address them (continuation tokens must resolve).
@@ -489,7 +511,7 @@ export function startServer(mounts_1) {
489
511
  cursorAccountOnly: options.cursorEvents === undefined && cursorGithubTargets.length > 0,
490
512
  });
491
513
  const server = createServer((req, res) => {
492
- void handleRequest(router, req, res, logger);
514
+ void instrumentHttp(otelRuntime, req, res, () => handleRequest(router, req, res, logger));
493
515
  });
494
516
  const host = (_p = options.host) !== null && _p !== void 0 ? _p : "127.0.0.1";
495
517
  const portWasExplicit = options.port !== undefined;
@@ -508,6 +530,7 @@ export function startServer(mounts_1) {
508
530
  yield cursorEventRelay === null || cursorEventRelay === void 0 ? void 0 : cursorEventRelay.stop();
509
531
  yield cursorSlackRelay === null || cursorSlackRelay === void 0 ? void 0 : cursorSlackRelay.stop();
510
532
  cursorGithubCredentials === null || cursorGithubCredentials === void 0 ? void 0 : cursorGithubCredentials.stop();
533
+ yield shutdownOtelRuntime(otelRuntime);
511
534
  throw error;
512
535
  }
513
536
  const address = server.address();
@@ -681,6 +704,7 @@ export function startServer(mounts_1) {
681
704
  }
682
705
  finally {
683
706
  cursorGithubCredentials === null || cursorGithubCredentials === void 0 ? void 0 : cursorGithubCredentials.stop();
707
+ yield shutdownOtelRuntime(otelRuntime);
684
708
  }
685
709
  }),
686
710
  };