@cursor/july 0.1.2 → 0.1.3

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 (174) hide show
  1. package/AGENTS.md +16 -5
  2. package/README.md +8 -9
  3. package/dist/bin/agent-serve.d.ts +3 -1
  4. package/dist/bin/agent-serve.d.ts.map +1 -1
  5. package/dist/bin/agent-serve.js +389 -152
  6. package/dist/docs/404.html +2 -2
  7. package/dist/docs/ab.html +3 -3
  8. package/dist/docs/assets/{app.Oje4vhlk.js → app.BR0RbIdx.js} +1 -1
  9. package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +1 -0
  10. package/dist/docs/assets/chunks/{VPLocalSearchBox.H5XZ2zCB.js → VPLocalSearchBox.qjsVTneI.js} +1 -1
  11. package/dist/docs/assets/chunks/{theme.CTR_TuaE.js → theme.2Kg8jIp_.js} +2 -2
  12. package/dist/docs/assets/{quickstart.md.CfU8_uTC.js → quickstart.md.BU6Iwi_9.js} +18 -6
  13. package/dist/docs/assets/{reference_cli.md.DA730zCu.js → reference_cli.md.Bv6pOxcF.js} +11 -6
  14. package/dist/docs/assets/{reference_cli.md.DA730zCu.lean.js → reference_cli.md.Bv6pOxcF.lean.js} +1 -1
  15. package/dist/docs/building-with-agents.html +3 -3
  16. package/dist/docs/concepts.html +3 -3
  17. package/dist/docs/deployment.html +3 -3
  18. package/dist/docs/evals.html +3 -3
  19. package/dist/docs/guides/agent-to-agent.html +3 -3
  20. package/dist/docs/guides/cloud-runtime.html +3 -3
  21. package/dist/docs/guides/github.html +3 -3
  22. package/dist/docs/guides/human-in-the-loop.html +3 -3
  23. package/dist/docs/guides/slack.html +3 -3
  24. package/dist/docs/guides/webhooks.html +3 -3
  25. package/dist/docs/hashmap.json +1 -1
  26. package/dist/docs/hillclimbing.html +3 -3
  27. package/dist/docs/index.html +3 -3
  28. package/dist/docs/quickstart.html +22 -10
  29. package/dist/docs/reference/agent-config.html +3 -3
  30. package/dist/docs/reference/channels.html +3 -3
  31. package/dist/docs/reference/cli.html +14 -9
  32. package/dist/docs/reference/connections.html +3 -3
  33. package/dist/docs/reference/hooks.html +3 -3
  34. package/dist/docs/reference/http-api.html +3 -3
  35. package/dist/docs/reference/instructions.html +3 -3
  36. package/dist/docs/reference/playground.html +3 -3
  37. package/dist/docs/reference/project-layout.html +3 -3
  38. package/dist/docs/reference/schedules.html +3 -3
  39. package/dist/docs/reference/sessions.html +3 -3
  40. package/dist/docs/reference/skills.html +3 -3
  41. package/dist/docs/reference/subagents.html +3 -3
  42. package/dist/docs/reference/tools.html +3 -3
  43. package/dist/docs/scaffolding-agents.html +3 -3
  44. package/dist/docs/storage.html +3 -3
  45. package/dist/docs/troubleshooting.html +3 -3
  46. package/dist/internal/chat-client.d.ts +29 -3
  47. package/dist/internal/chat-client.d.ts.map +1 -1
  48. package/dist/internal/chat-client.js +180 -27
  49. package/dist/internal/cli-ax.d.ts +75 -2
  50. package/dist/internal/cli-ax.d.ts.map +1 -1
  51. package/dist/internal/cli-ax.js +600 -52
  52. package/dist/internal/cli-cursor.d.ts.map +1 -1
  53. package/dist/internal/cli-cursor.js +8 -36
  54. package/dist/internal/cli-deploy.d.ts +59 -3
  55. package/dist/internal/cli-deploy.d.ts.map +1 -1
  56. package/dist/internal/cli-deploy.js +316 -38
  57. package/dist/internal/cursor/credentials.d.ts +9 -0
  58. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  59. package/dist/internal/cursor/credentials.js +12 -0
  60. package/dist/internal/deploy-client.d.ts +9 -1
  61. package/dist/internal/deploy-client.d.ts.map +1 -1
  62. package/dist/internal/deploy-client.js +23 -3
  63. package/dist/internal/deploy-source.d.ts +35 -0
  64. package/dist/internal/deploy-source.d.ts.map +1 -0
  65. package/dist/internal/deploy-source.js +118 -0
  66. package/dist/internal/discovery.d.ts +11 -0
  67. package/dist/internal/discovery.d.ts.map +1 -1
  68. package/dist/internal/discovery.js +43 -14
  69. package/dist/internal/eval-run-store.d.ts.map +1 -1
  70. package/dist/internal/eval-run-store.js +2 -1
  71. package/dist/internal/eval-runner.d.ts +2 -0
  72. package/dist/internal/eval-runner.d.ts.map +1 -1
  73. package/dist/internal/eval-runner.js +2 -0
  74. package/dist/internal/event-mapper.d.ts +54 -1
  75. package/dist/internal/event-mapper.d.ts.map +1 -1
  76. package/dist/internal/event-mapper.js +151 -41
  77. package/dist/internal/init-project.d.ts +88 -1
  78. package/dist/internal/init-project.d.ts.map +1 -1
  79. package/dist/internal/init-project.js +221 -31
  80. package/dist/internal/install-cursor-skills.d.ts +64 -0
  81. package/dist/internal/install-cursor-skills.d.ts.map +1 -0
  82. package/dist/internal/install-cursor-skills.js +274 -0
  83. package/dist/internal/logs-client.d.ts +60 -0
  84. package/dist/internal/logs-client.d.ts.map +1 -0
  85. package/dist/internal/logs-client.js +311 -0
  86. package/dist/internal/open-browser.d.ts +5 -0
  87. package/dist/internal/open-browser.d.ts.map +1 -0
  88. package/dist/internal/open-browser.js +34 -0
  89. package/dist/internal/playground/toolchain.d.ts.map +1 -1
  90. package/dist/internal/playground/toolchain.js +16 -11
  91. package/dist/internal/playground-proxy.d.ts +69 -0
  92. package/dist/internal/playground-proxy.d.ts.map +1 -0
  93. package/dist/internal/playground-proxy.js +468 -0
  94. package/dist/internal/prompt-context.d.ts +35 -0
  95. package/dist/internal/prompt-context.d.ts.map +1 -0
  96. package/dist/internal/prompt-context.js +71 -0
  97. package/dist/internal/request-headers.d.ts +11 -0
  98. package/dist/internal/request-headers.d.ts.map +1 -0
  99. package/dist/internal/request-headers.js +14 -0
  100. package/dist/internal/resolve-prod-target.d.ts +42 -0
  101. package/dist/internal/resolve-prod-target.d.ts.map +1 -0
  102. package/dist/internal/resolve-prod-target.js +111 -0
  103. package/dist/internal/run-client.d.ts +2 -2
  104. package/dist/internal/run-client.d.ts.map +1 -1
  105. package/dist/internal/run-client.js +38 -23
  106. package/dist/internal/server.d.ts.map +1 -1
  107. package/dist/internal/server.js +10 -4
  108. package/dist/internal/session-engine.d.ts +1 -1
  109. package/dist/internal/session-engine.d.ts.map +1 -1
  110. package/dist/internal/session-engine.js +21 -6
  111. package/dist/internal/sessions-client.d.ts +21 -0
  112. package/dist/internal/sessions-client.d.ts.map +1 -0
  113. package/dist/internal/sessions-client.js +168 -0
  114. package/dist/internal/stream-progress.d.ts.map +1 -1
  115. package/dist/internal/stream-progress.js +31 -3
  116. package/dist/internal/terminal-style.d.ts +22 -0
  117. package/dist/internal/terminal-style.d.ts.map +1 -0
  118. package/dist/internal/terminal-style.js +49 -0
  119. package/dist/internal/trajectory.d.ts +10 -5
  120. package/dist/internal/trajectory.d.ts.map +1 -1
  121. package/dist/internal/trajectory.js +82 -10
  122. package/dist/internal/workspace.d.ts +11 -0
  123. package/dist/internal/workspace.d.ts.map +1 -1
  124. package/dist/internal/workspace.js +38 -4
  125. package/dist/playground/assets/index-D-vo2lV_.css +1 -0
  126. package/dist/playground/assets/index-x60b9q2j.js +312 -0
  127. package/dist/playground/index.html +2 -2
  128. package/dist/types.d.ts +26 -1
  129. package/dist/types.d.ts.map +1 -1
  130. package/docs/quickstart.md +22 -7
  131. package/docs/reference/cli.md +51 -3
  132. package/package.json +3 -1
  133. package/skills/ab/SKILL.md +8 -8
  134. package/skills/create-agent/SKILL.md +28 -22
  135. package/skills/debug/SKILL.md +11 -11
  136. package/skills/evals/SKILL.md +16 -16
  137. package/skills/framework-map/SKILL.md +6 -6
  138. package/skills/github/SKILL.md +13 -13
  139. package/skills/hillclimb/SKILL.md +10 -10
  140. package/skills/setup-slack/SKILL.md +13 -13
  141. package/src/bin/agent-serve.ts +422 -188
  142. package/src/internal/chat-client.ts +252 -37
  143. package/src/internal/cli-ax.ts +722 -72
  144. package/src/internal/cli-cursor.ts +14 -42
  145. package/src/internal/cli-deploy.ts +428 -49
  146. package/src/internal/cursor/credentials.ts +14 -0
  147. package/src/internal/deploy-client.ts +45 -4
  148. package/src/internal/deploy-source.ts +133 -0
  149. package/src/internal/discovery.ts +53 -16
  150. package/src/internal/eval-run-store.ts +2 -1
  151. package/src/internal/eval-runner.ts +5 -0
  152. package/src/internal/event-mapper.ts +222 -42
  153. package/src/internal/init-project.ts +333 -51
  154. package/src/internal/install-cursor-skills.ts +327 -0
  155. package/src/internal/logs-client.ts +442 -0
  156. package/src/internal/open-browser.ts +41 -0
  157. package/src/internal/playground/toolchain.ts +15 -13
  158. package/src/internal/playground-proxy.ts +576 -0
  159. package/src/internal/prompt-context.ts +95 -0
  160. package/src/internal/request-headers.ts +23 -0
  161. package/src/internal/resolve-prod-target.ts +150 -0
  162. package/src/internal/run-client.ts +39 -36
  163. package/src/internal/server.ts +12 -3
  164. package/src/internal/session-engine.ts +22 -3
  165. package/src/internal/sessions-client.ts +182 -0
  166. package/src/internal/stream-progress.ts +36 -2
  167. package/src/internal/terminal-style.ts +74 -0
  168. package/src/internal/trajectory.ts +91 -13
  169. package/src/internal/workspace.ts +42 -4
  170. package/src/types.ts +42 -6
  171. package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +0 -1
  172. package/dist/playground/assets/index-B1Qc9h2u.css +0 -1
  173. package/dist/playground/assets/index-CpDYCj8W.js +0 -79
  174. /package/dist/docs/assets/{quickstart.md.CfU8_uTC.lean.js → quickstart.md.BU6Iwi_9.lean.js} +0 -0
@@ -19,12 +19,22 @@ import { mkdir, mkdtemp, writeFile } from "node:fs/promises";
19
19
  import { tmpdir } from "node:os";
20
20
  import { join, resolve } from "node:path";
21
21
  import { serve } from "../index.js";
22
+ import { lookupSessionContinuation, runChat } from "./chat-client.js";
23
+ import { cmdLogin } from "./cli-cursor.js";
24
+ import { resolveDeployAuth } from "./cli-deploy.js";
25
+ import { resolveApiKey } from "./cursor/credentials.js";
22
26
  import { CLI_COMMAND_NAME } from "./distribution.js";
23
27
  import { discoverEvals, filterDiscoveredEvals, runDiscoveredEvals, } from "./eval-runner.js";
24
- import { initProject, printInitGuide } from "./init-project.js";
28
+ import { formatInitNextSteps, formatInitScaffoldSummary, initNextCommands, initProject, installScaffoldDependencies, printInitGuide, } from "./init-project.js";
29
+ import { offerInstallCursorSkills } from "./install-cursor-skills.js";
30
+ import { runLogsTail, sanitizeCustomerError } from "./logs-client.js";
31
+ import { openBrowser } from "./open-browser.js";
32
+ import { startPlaygroundProxy } from "./playground-proxy.js";
33
+ import { resolveProdSlug, resolveProdTarget } from "./resolve-prod-target.js";
25
34
  import { runSession } from "./run-client.js";
35
+ import { fetchSessionEvents, formatSessionsTable, listSessions, } from "./sessions-client.js";
26
36
  import { createStreamProgress } from "./stream-progress.js";
27
- import { formatTrajectoryText, loadTrajectoryFromEventsFile, } from "./trajectory.js";
37
+ import { buildTrajectory, formatTrajectoryText, loadTrajectoryFromEventsFile, } from "./trajectory.js";
28
38
  function shouldStreamProgress(options) {
29
39
  if (options.stream === false) {
30
40
  return false;
@@ -78,11 +88,25 @@ function startEphemeral(options) {
78
88
  };
79
89
  });
80
90
  }
81
- function resolveTarget(options) {
91
+ export function resolveTarget(options) {
82
92
  return __awaiter(this, void 0, void 0, function* () {
93
+ if (options.prod === true && options.url !== undefined) {
94
+ die("--prod and --url are mutually exclusive");
95
+ }
83
96
  if (options.url !== undefined) {
84
97
  return { agentUrl: options.url.replace(/\/$/, "") };
85
98
  }
99
+ if (options.prod === true) {
100
+ const prod = yield resolveProdTarget({
101
+ dir: options.dir,
102
+ cwd: options.cwd,
103
+ slug: options.slug,
104
+ team: options.team,
105
+ apiKey: options.apiKey,
106
+ fetchImpl: options.fetchImpl,
107
+ });
108
+ return { agentUrl: prod.agentUrl, headers: prod.headers };
109
+ }
86
110
  return startEphemeral(options);
87
111
  });
88
112
  }
@@ -94,21 +118,166 @@ export function cmdInit(options) {
94
118
  printInitGuide();
95
119
  return 0;
96
120
  }
97
- const dir = resolve((_a = options.cwd) !== null && _a !== void 0 ? _a : process.cwd(), target);
121
+ const cwd = (_a = options.cwd) !== null && _a !== void 0 ? _a : process.cwd();
122
+ const dir = resolve(cwd, target);
98
123
  const result = yield initProject({ dir });
99
- process.stdout.write(`${JSON.stringify({
100
- ok: true,
101
- directory: result.rootDir,
102
- created: result.files,
103
- next: [
104
- `cd ${dir === process.cwd() ? "." : dir}`,
105
- `${CLI_COMMAND_NAME} validate`,
106
- `${CLI_COMMAND_NAME} info --json`,
107
- `${CLI_COMMAND_NAME} run --message "hello"`,
108
- `${CLI_COMMAND_NAME} eval`,
109
- ],
110
- }, null, 2)}\n`);
111
- return 0;
124
+ let signedIn = (yield resolveApiKey()) !== undefined;
125
+ // Machine-readable path: install deps (piped), never block on browser login.
126
+ if (options.json) {
127
+ const install = yield installScaffoldDependencies(result.rootDir, {
128
+ stdio: "pipe",
129
+ });
130
+ process.stdout.write(`${JSON.stringify({
131
+ ok: install.ok,
132
+ directory: result.rootDir,
133
+ created: result.created,
134
+ skipped: result.skipped,
135
+ installed: install.ok,
136
+ installError: install.ok
137
+ ? null
138
+ : install.stderr.trim() || `npm install exited ${install.exitCode}`,
139
+ next: initNextCommands({
140
+ rootDir: result.rootDir,
141
+ cwd,
142
+ signedIn,
143
+ }),
144
+ }, null, 2)}\n`);
145
+ return install.ok ? 0 : 1;
146
+ }
147
+ process.stdout.write(formatInitScaffoldSummary({
148
+ rootDir: result.rootDir,
149
+ files: result.files,
150
+ }));
151
+ process.stdout.write("Installing npm packages\n\n");
152
+ const install = yield installScaffoldDependencies(result.rootDir, {
153
+ stdio: "inherit",
154
+ });
155
+ if (!install.ok) {
156
+ process.stderr.write(`\nnpm install failed (exit ${install.exitCode}). Fix the install, then run ${CLI_COMMAND_NAME} dev.\n`);
157
+ return install.exitCode || 1;
158
+ }
159
+ process.stdout.write("\n");
160
+ // Personal Cursor skills so coding agents can pick up create-agent / debug / …
161
+ try {
162
+ yield offerInstallCursorSkills();
163
+ }
164
+ catch (err) {
165
+ const message = err instanceof Error ? err.message : String(err);
166
+ process.stderr.write(`\nCould not install Cursor skills (${message}). Continuing init.\n\n`);
167
+ }
168
+ let loginExit = 0;
169
+ if (!signedIn) {
170
+ process.stdout.write("Signing you in to Cursor\n\n");
171
+ loginExit = yield cmdLogin({});
172
+ signedIn = loginExit === 0 && (yield resolveApiKey()) !== undefined;
173
+ process.stdout.write("\n");
174
+ }
175
+ process.stdout.write(formatInitNextSteps({
176
+ rootDir: result.rootDir,
177
+ cwd,
178
+ signedIn,
179
+ }));
180
+ return loginExit;
181
+ });
182
+ }
183
+ /**
184
+ * `chat` — talk to a running (or `--prod` hosted) agent. With `--json`,
185
+ * prints a trajectory instead of the interactive UI.
186
+ */
187
+ /**
188
+ * `resume <sessionId>` — reattach the interactive chat REPL to an existing
189
+ * session (looks up the continuation token via `/v1/sessions` when omitted).
190
+ * Same flags as `chat` (`--prod`, `--message`, `--json`, …). `--session`
191
+ * is accepted as a redundant alias for the positional id.
192
+ */
193
+ export function cmdResume(sessionId, options) {
194
+ return __awaiter(this, void 0, void 0, function* () {
195
+ var _a;
196
+ const resolved = (_a = trimNonEmpty(sessionId)) !== null && _a !== void 0 ? _a : trimNonEmpty(options.sessionId);
197
+ if (resolved === undefined) {
198
+ process.stderr.write(`Usage: ${CLI_COMMAND_NAME} resume <sessionId> [--url | --prod] [--message <text>] [--json] [--text]\n` +
199
+ ` [--continuation-token <t>] [--slug <slug>] [--team <id>]\n`);
200
+ return 2;
201
+ }
202
+ return cmdChat(Object.assign(Object.assign({}, options), { sessionId: resolved }));
203
+ });
204
+ }
205
+ function trimNonEmpty(value) {
206
+ if (value === undefined) {
207
+ return undefined;
208
+ }
209
+ const trimmed = value.trim();
210
+ return trimmed === "" ? undefined : trimmed;
211
+ }
212
+ export function cmdChat(options) {
213
+ return __awaiter(this, void 0, void 0, function* () {
214
+ var _a;
215
+ var _b, _c;
216
+ const message = (_a = options.messages) === null || _a === void 0 ? void 0 : _a[0];
217
+ // chat never starts an ephemeral server — default to local serve URL.
218
+ const target = yield resolveTarget(Object.assign(Object.assign({}, options), { url: options.prod === true
219
+ ? undefined
220
+ : ((_b = options.url) !== null && _b !== void 0 ? _b : "http://127.0.0.1:3000") }));
221
+ if (options.json) {
222
+ if (message === undefined) {
223
+ process.stderr.write("chat --json requires --message\n");
224
+ return 2;
225
+ }
226
+ let continuationToken = options.continuationToken;
227
+ if (options.sessionId !== undefined &&
228
+ (continuationToken === undefined || continuationToken === "")) {
229
+ try {
230
+ continuationToken = yield lookupSessionContinuation({
231
+ baseUrl: target.agentUrl,
232
+ sessionId: options.sessionId,
233
+ auth: {
234
+ bearerToken: options.bearerToken,
235
+ headers: target.headers,
236
+ },
237
+ });
238
+ }
239
+ catch (error) {
240
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
241
+ return 1;
242
+ }
243
+ }
244
+ const result = yield runSession({
245
+ baseUrl: target.agentUrl,
246
+ messages: [message],
247
+ sessionId: options.sessionId,
248
+ continuationToken,
249
+ bearerToken: options.bearerToken,
250
+ headers: target.headers,
251
+ });
252
+ if (options.text) {
253
+ process.stdout.write(formatTrajectoryText(result.trajectory));
254
+ }
255
+ else {
256
+ console.log(JSON.stringify({
257
+ ok: result.ok,
258
+ sessionId: result.sessionId,
259
+ continuationToken: (_c = result.continuationToken) !== null && _c !== void 0 ? _c : null,
260
+ trajectory: result.trajectory,
261
+ }, null, 2));
262
+ }
263
+ return result.ok ? 0 : 1;
264
+ }
265
+ try {
266
+ yield runChat({
267
+ baseUrl: target.agentUrl,
268
+ message,
269
+ sessionId: options.sessionId,
270
+ continuationToken: options.continuationToken,
271
+ bearerToken: options.bearerToken,
272
+ headers: target.headers,
273
+ noColor: options.noColor,
274
+ });
275
+ return 0;
276
+ }
277
+ catch (error) {
278
+ process.stderr.write(`${error instanceof Error ? error.message : String(error)}\n`);
279
+ return 1;
280
+ }
112
281
  });
113
282
  }
114
283
  export function cmdRun(options) {
@@ -125,17 +294,16 @@ export function cmdRun(options) {
125
294
  if (stream) {
126
295
  process.stderr.write(`→ ${target.agentUrl}\n`);
127
296
  }
128
- const result = yield runSession(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ baseUrl: target.agentUrl, messages }, (options.sessionId === undefined
129
- ? {}
130
- : { sessionId: options.sessionId })), (options.continuationToken === undefined
131
- ? {}
132
- : { continuationToken: options.continuationToken })), (options.bearerToken === undefined
133
- ? {}
134
- : { bearerToken: options.bearerToken })), (options.timeoutMs === undefined
135
- ? {}
136
- : { timeoutMs: options.timeoutMs })), (progress === undefined
137
- ? {}
138
- : { onEvent: (e) => progress.onEvent(e) })));
297
+ const result = yield runSession({
298
+ baseUrl: target.agentUrl,
299
+ messages,
300
+ sessionId: options.sessionId,
301
+ continuationToken: options.continuationToken,
302
+ bearerToken: options.bearerToken,
303
+ headers: target.headers,
304
+ timeoutMs: options.timeoutMs,
305
+ onEvent: progress === undefined ? undefined : (e) => progress.onEvent(e),
306
+ });
139
307
  let eventsPath;
140
308
  const writeEvents = options.events !== false;
141
309
  if (writeEvents) {
@@ -150,8 +318,25 @@ export function cmdRun(options) {
150
318
  }
151
319
  yield writeFile(eventsPath, `${result.events.map((e) => JSON.stringify(e)).join("\n")}\n`, "utf8");
152
320
  }
153
- const playgroundUrl = options.url !== undefined
154
- ? `${target.agentUrl.replace(/\/$/, "")}/playground?sessionId=${encodeURIComponent(result.sessionId)}`
321
+ const playgroundUrl = options.prod === true
322
+ ? null
323
+ : options.url !== undefined
324
+ ? `${target.agentUrl.replace(/\/$/, "")}/playground?sessionId=${encodeURIComponent(result.sessionId)}`
325
+ : null;
326
+ const playgroundHint = options.prod === true
327
+ ? [
328
+ CLI_COMMAND_NAME,
329
+ "playground",
330
+ "--prod",
331
+ ...(options.slug !== undefined && options.slug.trim() !== ""
332
+ ? ["--slug", options.slug.trim()]
333
+ : []),
334
+ ...(options.team !== undefined && options.team.trim() !== ""
335
+ ? ["--team", options.team.trim()]
336
+ : []),
337
+ "--session",
338
+ result.sessionId,
339
+ ].join(" ")
155
340
  : null;
156
341
  if (options.text) {
157
342
  process.stdout.write(formatTrajectoryText(result.trajectory));
@@ -161,6 +346,9 @@ export function cmdRun(options) {
161
346
  if (playgroundUrl !== null) {
162
347
  process.stderr.write(`playground: ${playgroundUrl}\n`);
163
348
  }
349
+ else if (playgroundHint !== null) {
350
+ process.stderr.write(`playground: ${playgroundHint}\n`);
351
+ }
164
352
  }
165
353
  else {
166
354
  console.log(JSON.stringify({
@@ -169,11 +357,14 @@ export function cmdRun(options) {
169
357
  continuationToken: (_c = result.continuationToken) !== null && _c !== void 0 ? _c : null,
170
358
  trace: eventsPath !== null && eventsPath !== void 0 ? eventsPath : null,
171
359
  playgroundUrl,
172
- visualize: playgroundUrl !== null
173
- ? `Open ${playgroundUrl}`
174
- : eventsPath !== undefined
175
- ? `Start the playground (${CLI_COMMAND_NAME} serve --dir ${options.dir}), then Open trace → ${eventsPath}`
176
- : null,
360
+ playgroundHint,
361
+ visualize: playgroundHint !== null
362
+ ? `Run ${playgroundHint}`
363
+ : playgroundUrl !== null
364
+ ? `Open ${playgroundUrl}`
365
+ : eventsPath !== undefined
366
+ ? `Start the playground (${CLI_COMMAND_NAME} serve --dir ${options.dir}), then Open trace → ${eventsPath}`
367
+ : null,
177
368
  trajectory: result.trajectory,
178
369
  }, null, 2));
179
370
  }
@@ -208,14 +399,23 @@ export function cmdCall(options) {
208
399
  }
209
400
  const target = yield resolveTarget(options);
210
401
  try {
402
+ const headers = {
403
+ "content-type": "application/json",
404
+ };
405
+ if (target.headers !== undefined) {
406
+ Object.assign(headers, target.headers);
407
+ }
408
+ if (options.bearerToken !== undefined) {
409
+ headers.authorization = `Bearer ${options.bearerToken}`;
410
+ }
411
+ const body = { input };
412
+ if (options.sessionId !== undefined) {
413
+ body.sessionId = options.sessionId;
414
+ }
211
415
  const response = yield fetch(`${target.agentUrl}/v1/tools/${encodeURIComponent(toolName)}`, {
212
416
  method: "POST",
213
- headers: Object.assign({ "content-type": "application/json" }, (options.bearerToken === undefined
214
- ? {}
215
- : { authorization: `Bearer ${options.bearerToken}` })),
216
- body: JSON.stringify(Object.assign({ input }, (options.sessionId === undefined
217
- ? {}
218
- : { sessionId: options.sessionId }))),
417
+ headers,
418
+ body: JSON.stringify(body),
219
419
  });
220
420
  const payload = yield response
221
421
  .json()
@@ -291,17 +491,21 @@ export function cmdEval(options) {
291
491
  if (options.verbose || stream) {
292
492
  process.stderr.write(`eval target: ${target.agentUrl}\n`);
293
493
  }
294
- const results = yield runDiscoveredEvals(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ projectRoot, baseUrl: target.agentUrl }, (options.evalIds === undefined || options.evalIds.length === 0
295
- ? {}
296
- : { filterIds: options.evalIds })), (options.tags === undefined || options.tags.length === 0
297
- ? {}
298
- : { tags: options.tags })), (options.timeoutMs === undefined
299
- ? {}
300
- : { timeoutMs: options.timeoutMs })), (options.bearerToken === undefined
301
- ? {}
302
- : { bearerToken: options.bearerToken })), { verbose: Boolean(options.verbose) || stream }), (progress === undefined
303
- ? {}
304
- : { onEvent: (e) => progress.onEvent(e) })));
494
+ const results = yield runDiscoveredEvals({
495
+ projectRoot,
496
+ baseUrl: target.agentUrl,
497
+ filterIds: options.evalIds === undefined || options.evalIds.length === 0
498
+ ? undefined
499
+ : options.evalIds,
500
+ tags: options.tags === undefined || options.tags.length === 0
501
+ ? undefined
502
+ : options.tags,
503
+ timeoutMs: options.timeoutMs,
504
+ bearerToken: options.bearerToken,
505
+ headers: target.headers,
506
+ verbose: Boolean(options.verbose) || stream,
507
+ onEvent: progress === undefined ? undefined : (e) => progress.onEvent(e),
508
+ });
305
509
  if (results.length === 0) {
306
510
  process.stderr.write("No matching evals found.\n");
307
511
  return 2;
@@ -343,3 +547,347 @@ function printEvalResults(results, options) {
343
547
  }
344
548
  return failed === 0 ? 0 : 1;
345
549
  }
550
+ /**
551
+ * `logs` — follow deploy progress (`--prod`) then runtime agent logs.
552
+ * Local / `--url` tails `/v1/logs` only.
553
+ */
554
+ export function cmdLogs(options) {
555
+ return __awaiter(this, void 0, void 0, function* () {
556
+ var _a;
557
+ if (options.prod === true && options.url !== undefined) {
558
+ process.stderr.write("--prod and --url are mutually exclusive\n");
559
+ return 2;
560
+ }
561
+ const controller = new AbortController();
562
+ const onSignal = () => {
563
+ controller.abort();
564
+ };
565
+ process.on("SIGINT", onSignal);
566
+ process.on("SIGTERM", onSignal);
567
+ try {
568
+ if (options.prod === true) {
569
+ const slug = resolveProdSlug({
570
+ dir: options.dir,
571
+ cwd: options.cwd,
572
+ slug: options.slug,
573
+ });
574
+ const auth = yield resolveDeployAuth({
575
+ team: options.team,
576
+ apiKey: options.apiKey,
577
+ fetchImpl: options.fetchImpl,
578
+ });
579
+ if (typeof auth === "number") {
580
+ return auth;
581
+ }
582
+ yield runLogsTail({
583
+ prod: true,
584
+ dir: options.dir,
585
+ cwd: options.cwd,
586
+ slug,
587
+ team: options.team,
588
+ apiKey: options.apiKey,
589
+ bearerToken: options.bearerToken,
590
+ once: options.once,
591
+ json: options.json,
592
+ fetchImpl: options.fetchImpl,
593
+ signal: controller.signal,
594
+ getDeployment: () => auth.client.getDeployment({ teamId: auth.teamId, slug }),
595
+ resolveRuntime: () => __awaiter(this, void 0, void 0, function* () {
596
+ const target = yield resolveProdTarget({
597
+ dir: options.dir,
598
+ cwd: options.cwd,
599
+ slug,
600
+ team: options.team,
601
+ apiKey: options.apiKey,
602
+ fetchImpl: options.fetchImpl,
603
+ err: () => { },
604
+ });
605
+ return { agentUrl: target.agentUrl, headers: target.headers };
606
+ }),
607
+ });
608
+ return 0;
609
+ }
610
+ yield runLogsTail({
611
+ dir: options.dir,
612
+ cwd: options.cwd,
613
+ url: (_a = options.url) !== null && _a !== void 0 ? _a : "http://127.0.0.1:3000",
614
+ bearerToken: options.bearerToken,
615
+ once: options.once,
616
+ json: options.json,
617
+ fetchImpl: options.fetchImpl,
618
+ signal: controller.signal,
619
+ });
620
+ return 0;
621
+ }
622
+ catch (error) {
623
+ if (controller.signal.aborted) {
624
+ return 0;
625
+ }
626
+ const raw = error instanceof Error ? error.message : String(error);
627
+ process.stderr.write(`${sanitizeCustomerError(raw)}\n`);
628
+ return 1;
629
+ }
630
+ finally {
631
+ process.off("SIGINT", onSignal);
632
+ process.off("SIGTERM", onSignal);
633
+ }
634
+ });
635
+ }
636
+ /** Resolve local / `--url` / `--prod` agent base URL + request headers. */
637
+ function resolveSessionTarget(options) {
638
+ return __awaiter(this, void 0, void 0, function* () {
639
+ var _a;
640
+ if (options.prod === true && options.url !== undefined) {
641
+ process.stderr.write("--prod and --url are mutually exclusive\n");
642
+ return 2;
643
+ }
644
+ if (options.prod === true) {
645
+ try {
646
+ const target = yield resolveProdTarget({
647
+ dir: options.dir,
648
+ cwd: options.cwd,
649
+ slug: options.slug,
650
+ team: options.team,
651
+ apiKey: options.apiKey,
652
+ fetchImpl: options.fetchImpl,
653
+ });
654
+ return { agentUrl: target.agentUrl, headers: target.headers };
655
+ }
656
+ catch (error) {
657
+ process.stderr.write(`${sanitizeCustomerError(error instanceof Error ? error.message : String(error))}\n`);
658
+ return 1;
659
+ }
660
+ }
661
+ return {
662
+ agentUrl: ((_a = options.url) !== null && _a !== void 0 ? _a : "http://127.0.0.1:3000").replace(/\/$/, ""),
663
+ };
664
+ });
665
+ }
666
+ /**
667
+ * `sessions` — list sessions on a running (or `--prod` hosted) agent.
668
+ */
669
+ export function cmdSessions(options) {
670
+ return __awaiter(this, void 0, void 0, function* () {
671
+ const target = yield resolveSessionTarget(options);
672
+ if (typeof target === "number") {
673
+ return target;
674
+ }
675
+ try {
676
+ const sessions = yield listSessions({
677
+ baseUrl: target.agentUrl,
678
+ auth: {
679
+ bearerToken: options.bearerToken,
680
+ headers: target.headers,
681
+ },
682
+ fetchImpl: options.fetchImpl,
683
+ });
684
+ if (options.json === true) {
685
+ process.stdout.write(`${JSON.stringify({ sessions }, null, 2)}\n`);
686
+ return 0;
687
+ }
688
+ process.stdout.write(formatSessionsTable(sessions));
689
+ return 0;
690
+ }
691
+ catch (error) {
692
+ process.stderr.write(`${sanitizeCustomerError(error instanceof Error ? error.message : String(error))}\n`);
693
+ return 1;
694
+ }
695
+ });
696
+ }
697
+ /**
698
+ * `session <id>` — view a full session (trajectory text by default).
699
+ * `--json` → trajectory JSON; `--events` (`rawEvents`) → raw event list.
700
+ * Interactive reattach: `resume <id>` (or `chat --session`).
701
+ */
702
+ export function cmdSession(sessionId, options) {
703
+ return __awaiter(this, void 0, void 0, function* () {
704
+ if (sessionId === undefined || sessionId.trim() === "") {
705
+ process.stderr.write(`Usage: ${CLI_COMMAND_NAME} session <sessionId> [--url | --prod] [--json | --text | --events]\n`);
706
+ return 2;
707
+ }
708
+ if (options.rawEvents === true && options.json === true) {
709
+ process.stderr.write("--events and --json are mutually exclusive\n");
710
+ return 2;
711
+ }
712
+ const target = yield resolveSessionTarget(options);
713
+ if (typeof target === "number") {
714
+ return target;
715
+ }
716
+ try {
717
+ const events = yield fetchSessionEvents({
718
+ baseUrl: target.agentUrl,
719
+ sessionId,
720
+ auth: {
721
+ bearerToken: options.bearerToken,
722
+ headers: target.headers,
723
+ },
724
+ fetchImpl: options.fetchImpl,
725
+ });
726
+ if (options.rawEvents === true) {
727
+ process.stdout.write(`${JSON.stringify({ sessionId, events }, null, 2)}\n`);
728
+ return 0;
729
+ }
730
+ const trajectory = buildTrajectory(events);
731
+ if (options.json === true) {
732
+ process.stdout.write(`${JSON.stringify(trajectory, null, 2)}\n`);
733
+ return 0;
734
+ }
735
+ process.stdout.write(formatTrajectoryText(trajectory));
736
+ return 0;
737
+ }
738
+ catch (error) {
739
+ process.stderr.write(`${sanitizeCustomerError(error instanceof Error ? error.message : String(error))}\n`);
740
+ return 1;
741
+ }
742
+ });
743
+ }
744
+ /**
745
+ * `playground` — open the web UI against local / `--url` / `--prod`.
746
+ *
747
+ * Hosted engines need short-lived access headers a browser cannot set, so
748
+ * `--prod` (and `--bearer-token`) run a loopback reverse proxy that injects
749
+ * them. Ctrl-C stops the proxy.
750
+ */
751
+ export function cmdPlayground(options) {
752
+ return __awaiter(this, void 0, void 0, function* () {
753
+ if (options.prod === true && options.url !== undefined) {
754
+ process.stderr.write("--prod and --url are mutually exclusive\n");
755
+ return 2;
756
+ }
757
+ const sessionId = options.sessionId !== undefined && options.sessionId.trim() !== ""
758
+ ? options.sessionId.trim()
759
+ : undefined;
760
+ // Hosted: mint engineAccess and refresh it for the life of the proxy.
761
+ if (options.prod === true) {
762
+ let initial;
763
+ try {
764
+ initial = yield resolveProdTarget({
765
+ dir: options.dir,
766
+ cwd: options.cwd,
767
+ slug: options.slug,
768
+ team: options.team,
769
+ apiKey: options.apiKey,
770
+ fetchImpl: options.fetchImpl,
771
+ });
772
+ }
773
+ catch (error) {
774
+ process.stderr.write(`${sanitizeCustomerError(error instanceof Error ? error.message : String(error))}\n`);
775
+ return 1;
776
+ }
777
+ let proxy;
778
+ try {
779
+ proxy = yield startPlaygroundProxy({
780
+ upstreamUrl: initial.agentUrl,
781
+ headers: initial.headers,
782
+ expiresAt: initial.expiresAt,
783
+ refreshUpstream: () => __awaiter(this, void 0, void 0, function* () {
784
+ var _a;
785
+ const next = yield resolveProdTarget({
786
+ dir: options.dir,
787
+ cwd: options.cwd,
788
+ slug: (_a = options.slug) !== null && _a !== void 0 ? _a : initial.slug,
789
+ team: options.team,
790
+ apiKey: options.apiKey,
791
+ fetchImpl: options.fetchImpl,
792
+ err: () => { },
793
+ });
794
+ return {
795
+ upstreamUrl: next.agentUrl,
796
+ headers: next.headers,
797
+ expiresAt: next.expiresAt,
798
+ };
799
+ }),
800
+ });
801
+ }
802
+ catch (error) {
803
+ process.stderr.write(`${sanitizeCustomerError(error instanceof Error ? error.message : String(error))}\n`);
804
+ return 1;
805
+ }
806
+ return yield runPlaygroundProxySession({
807
+ proxy,
808
+ sessionId,
809
+ print: options.print === true,
810
+ signal: options.signal,
811
+ });
812
+ }
813
+ const target = yield resolveSessionTarget(options);
814
+ if (typeof target === "number") {
815
+ return target;
816
+ }
817
+ const needsProxy = (target.headers !== undefined && Object.keys(target.headers).length > 0) ||
818
+ (options.bearerToken !== undefined && options.bearerToken.trim() !== "");
819
+ if (!needsProxy) {
820
+ const base = `${target.agentUrl.replace(/\/$/, "")}/playground`;
821
+ const playgroundUrl = sessionId === undefined
822
+ ? base
823
+ : `${base}?sessionId=${encodeURIComponent(sessionId)}`;
824
+ process.stdout.write(`${playgroundUrl}\n`);
825
+ if (options.print !== true) {
826
+ openBrowser(playgroundUrl);
827
+ }
828
+ return 0;
829
+ }
830
+ let proxy;
831
+ try {
832
+ proxy = yield startPlaygroundProxy({
833
+ upstreamUrl: target.agentUrl,
834
+ headers: target.headers,
835
+ bearerToken: options.bearerToken,
836
+ });
837
+ }
838
+ catch (error) {
839
+ process.stderr.write(`${sanitizeCustomerError(error instanceof Error ? error.message : String(error))}\n`);
840
+ return 1;
841
+ }
842
+ return yield runPlaygroundProxySession({
843
+ proxy,
844
+ sessionId,
845
+ print: options.print === true,
846
+ signal: options.signal,
847
+ });
848
+ });
849
+ }
850
+ function runPlaygroundProxySession(args) {
851
+ return __awaiter(this, void 0, void 0, function* () {
852
+ const { proxy } = args;
853
+ const playgroundUrl = proxy.playgroundUrl(args.sessionId);
854
+ process.stdout.write(`${playgroundUrl}\n`);
855
+ process.stderr.write(`Playground proxy on loopback (Ctrl-C to stop).\n`);
856
+ if (args.print !== true) {
857
+ openBrowser(playgroundUrl);
858
+ }
859
+ const controller = new AbortController();
860
+ const onSignal = () => {
861
+ controller.abort();
862
+ };
863
+ process.on("SIGINT", onSignal);
864
+ process.on("SIGTERM", onSignal);
865
+ const external = args.signal;
866
+ if (external !== undefined) {
867
+ if (external.aborted) {
868
+ controller.abort();
869
+ }
870
+ else {
871
+ external.addEventListener("abort", onSignal, { once: true });
872
+ }
873
+ }
874
+ try {
875
+ yield new Promise((resolve) => {
876
+ if (controller.signal.aborted) {
877
+ resolve();
878
+ return;
879
+ }
880
+ controller.signal.addEventListener("abort", () => resolve(), {
881
+ once: true,
882
+ });
883
+ });
884
+ return 0;
885
+ }
886
+ finally {
887
+ process.off("SIGINT", onSignal);
888
+ process.off("SIGTERM", onSignal);
889
+ external === null || external === void 0 ? void 0 : external.removeEventListener("abort", onSignal);
890
+ yield proxy.close().catch(() => { });
891
+ }
892
+ });
893
+ }