@cursor/july 0.1.2 → 0.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (232) 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 +416 -155
  6. package/dist/channels/slack/log.d.ts +1 -1
  7. package/dist/channels/slack/log.d.ts.map +1 -1
  8. package/dist/channels/slack/log.js +4 -5
  9. package/dist/channels/slack/setup.js +1 -1
  10. package/dist/channels/slack/socket-mode.d.ts.map +1 -1
  11. package/dist/channels/slack/socket-mode.js +10 -9
  12. package/dist/docs/404.html +2 -2
  13. package/dist/docs/ab.html +3 -3
  14. package/dist/docs/assets/{app.Oje4vhlk.js → app.DF-Yx4OP.js} +1 -1
  15. package/dist/docs/assets/chunks/@localSearchIndexroot.0XrheBv2.js +1 -0
  16. package/dist/docs/assets/chunks/{VPLocalSearchBox.H5XZ2zCB.js → VPLocalSearchBox.DSeJSudL.js} +1 -1
  17. package/dist/docs/assets/chunks/{theme.CTR_TuaE.js → theme.DZVLTXOC.js} +2 -2
  18. package/dist/docs/assets/{index.md.m81y7TY7.js → index.md.Cylk70gg.js} +1 -1
  19. package/dist/docs/assets/{quickstart.md.CfU8_uTC.js → quickstart.md.BU6Iwi_9.js} +18 -6
  20. package/dist/docs/assets/{reference_cli.md.DA730zCu.js → reference_cli.md.Bv6pOxcF.js} +11 -6
  21. package/dist/docs/assets/{reference_cli.md.DA730zCu.lean.js → reference_cli.md.Bv6pOxcF.lean.js} +1 -1
  22. package/dist/docs/building-with-agents.html +3 -3
  23. package/dist/docs/concepts.html +3 -3
  24. package/dist/docs/deployment.html +3 -3
  25. package/dist/docs/evals.html +3 -3
  26. package/dist/docs/guides/agent-to-agent.html +3 -3
  27. package/dist/docs/guides/cloud-runtime.html +3 -3
  28. package/dist/docs/guides/github.html +3 -3
  29. package/dist/docs/guides/human-in-the-loop.html +3 -3
  30. package/dist/docs/guides/slack.html +3 -3
  31. package/dist/docs/guides/webhooks.html +3 -3
  32. package/dist/docs/hashmap.json +1 -1
  33. package/dist/docs/hillclimbing.html +3 -3
  34. package/dist/docs/index.html +5 -5
  35. package/dist/docs/quickstart.html +22 -10
  36. package/dist/docs/reference/agent-config.html +3 -3
  37. package/dist/docs/reference/channels.html +3 -3
  38. package/dist/docs/reference/cli.html +14 -9
  39. package/dist/docs/reference/connections.html +3 -3
  40. package/dist/docs/reference/hooks.html +3 -3
  41. package/dist/docs/reference/http-api.html +3 -3
  42. package/dist/docs/reference/instructions.html +3 -3
  43. package/dist/docs/reference/playground.html +3 -3
  44. package/dist/docs/reference/project-layout.html +3 -3
  45. package/dist/docs/reference/schedules.html +3 -3
  46. package/dist/docs/reference/sessions.html +3 -3
  47. package/dist/docs/reference/skills.html +3 -3
  48. package/dist/docs/reference/subagents.html +3 -3
  49. package/dist/docs/reference/tools.html +3 -3
  50. package/dist/docs/scaffolding-agents.html +3 -3
  51. package/dist/docs/storage.html +3 -3
  52. package/dist/docs/troubleshooting.html +3 -3
  53. package/dist/internal/ab-collector.js +3 -3
  54. package/dist/internal/ab-fold.js +1 -1
  55. package/dist/internal/chat-client.d.ts +29 -3
  56. package/dist/internal/chat-client.d.ts.map +1 -1
  57. package/dist/internal/chat-client.js +180 -27
  58. package/dist/internal/cli-ax.d.ts +83 -2
  59. package/dist/internal/cli-ax.d.ts.map +1 -1
  60. package/dist/internal/cli-ax.js +626 -52
  61. package/dist/internal/cli-cursor.d.ts.map +1 -1
  62. package/dist/internal/cli-cursor.js +8 -36
  63. package/dist/internal/cli-deploy.d.ts +59 -3
  64. package/dist/internal/cli-deploy.d.ts.map +1 -1
  65. package/dist/internal/cli-deploy.js +316 -38
  66. package/dist/internal/cli-github.js +13 -13
  67. package/dist/internal/cursor/account-mcp.js +3 -3
  68. package/dist/internal/cursor/backend-client.js +1 -1
  69. package/dist/internal/cursor/credentials.d.ts +14 -3
  70. package/dist/internal/cursor/credentials.d.ts.map +1 -1
  71. package/dist/internal/cursor/credentials.js +21 -6
  72. package/dist/internal/cursor/github-credentials.js +3 -3
  73. package/dist/internal/cursor-event-relay.js +1 -1
  74. package/dist/internal/cursor-relay-core.d.ts +1 -1
  75. package/dist/internal/cursor-relay-core.d.ts.map +1 -1
  76. package/dist/internal/cursor-relay-core.js +2 -1
  77. package/dist/internal/cursor-slack-relay.js +1 -1
  78. package/dist/internal/deploy-client.d.ts +9 -1
  79. package/dist/internal/deploy-client.d.ts.map +1 -1
  80. package/dist/internal/deploy-client.js +23 -3
  81. package/dist/internal/deploy-source.d.ts +35 -0
  82. package/dist/internal/deploy-source.d.ts.map +1 -0
  83. package/dist/internal/deploy-source.js +118 -0
  84. package/dist/internal/discovery.d.ts +11 -0
  85. package/dist/internal/discovery.d.ts.map +1 -1
  86. package/dist/internal/discovery.js +43 -14
  87. package/dist/internal/distribution.d.ts +7 -0
  88. package/dist/internal/distribution.d.ts.map +1 -1
  89. package/dist/internal/distribution.js +7 -0
  90. package/dist/internal/docs-site.js +3 -3
  91. package/dist/internal/eval-run-store.d.ts.map +1 -1
  92. package/dist/internal/eval-run-store.js +10 -9
  93. package/dist/internal/eval-runner.d.ts +2 -0
  94. package/dist/internal/eval-runner.d.ts.map +1 -1
  95. package/dist/internal/eval-runner.js +2 -0
  96. package/dist/internal/event-mapper.d.ts +54 -1
  97. package/dist/internal/event-mapper.d.ts.map +1 -1
  98. package/dist/internal/event-mapper.js +151 -41
  99. package/dist/internal/github-fanout.js +2 -2
  100. package/dist/internal/host-platforms.js +5 -5
  101. package/dist/internal/init-project.d.ts +88 -1
  102. package/dist/internal/init-project.d.ts.map +1 -1
  103. package/dist/internal/init-project.js +221 -31
  104. package/dist/internal/install-cursor-skills.d.ts +64 -0
  105. package/dist/internal/install-cursor-skills.d.ts.map +1 -0
  106. package/dist/internal/install-cursor-skills.js +274 -0
  107. package/dist/internal/logs-client.d.ts +60 -0
  108. package/dist/internal/logs-client.d.ts.map +1 -0
  109. package/dist/internal/logs-client.js +311 -0
  110. package/dist/internal/mcp-endpoint.d.ts.map +1 -1
  111. package/dist/internal/mcp-endpoint.js +1 -1
  112. package/dist/internal/open-browser.d.ts +5 -0
  113. package/dist/internal/open-browser.d.ts.map +1 -0
  114. package/dist/internal/open-browser.js +34 -0
  115. package/dist/internal/playground/toolchain.d.ts.map +1 -1
  116. package/dist/internal/playground/toolchain.js +19 -14
  117. package/dist/internal/playground-proxy.d.ts +69 -0
  118. package/dist/internal/playground-proxy.d.ts.map +1 -0
  119. package/dist/internal/playground-proxy.js +468 -0
  120. package/dist/internal/prompt-context.d.ts +35 -0
  121. package/dist/internal/prompt-context.d.ts.map +1 -0
  122. package/dist/internal/prompt-context.js +71 -0
  123. package/dist/internal/reminder-runner.d.ts.map +1 -1
  124. package/dist/internal/reminder-runner.js +11 -11
  125. package/dist/internal/request-headers.d.ts +11 -0
  126. package/dist/internal/request-headers.d.ts.map +1 -0
  127. package/dist/internal/request-headers.js +14 -0
  128. package/dist/internal/resolve-prod-target.d.ts +44 -0
  129. package/dist/internal/resolve-prod-target.d.ts.map +1 -0
  130. package/dist/internal/resolve-prod-target.js +134 -0
  131. package/dist/internal/resolved-connections.js +5 -5
  132. package/dist/internal/run-client.d.ts +2 -2
  133. package/dist/internal/run-client.d.ts.map +1 -1
  134. package/dist/internal/run-client.js +38 -23
  135. package/dist/internal/schedule-runner.js +1 -1
  136. package/dist/internal/server.d.ts.map +1 -1
  137. package/dist/internal/server.js +23 -17
  138. package/dist/internal/session-engine.d.ts +1 -1
  139. package/dist/internal/session-engine.d.ts.map +1 -1
  140. package/dist/internal/session-engine.js +34 -19
  141. package/dist/internal/sessions-client.d.ts +34 -0
  142. package/dist/internal/sessions-client.d.ts.map +1 -0
  143. package/dist/internal/sessions-client.js +193 -0
  144. package/dist/internal/storage-coordinator.js +6 -6
  145. package/dist/internal/stream-progress.d.ts.map +1 -1
  146. package/dist/internal/stream-progress.js +31 -3
  147. package/dist/internal/terminal-style.d.ts +22 -0
  148. package/dist/internal/terminal-style.d.ts.map +1 -0
  149. package/dist/internal/terminal-style.js +49 -0
  150. package/dist/internal/trajectory.d.ts +10 -5
  151. package/dist/internal/trajectory.d.ts.map +1 -1
  152. package/dist/internal/trajectory.js +82 -10
  153. package/dist/internal/update-check.d.ts +93 -0
  154. package/dist/internal/update-check.d.ts.map +1 -0
  155. package/dist/internal/update-check.js +431 -0
  156. package/dist/internal/workspace.d.ts +11 -0
  157. package/dist/internal/workspace.d.ts.map +1 -1
  158. package/dist/internal/workspace.js +38 -4
  159. package/dist/playground/assets/index-Ct_Usdm8.css +1 -0
  160. package/dist/playground/assets/index-Dsyb-Vaj.js +319 -0
  161. package/dist/playground/index.html +2 -2
  162. package/dist/types.d.ts +29 -2
  163. package/dist/types.d.ts.map +1 -1
  164. package/docs/README.md +0 -1
  165. package/docs/quickstart.md +22 -7
  166. package/docs/reference/cli.md +51 -3
  167. package/package.json +4 -1
  168. package/skills/ab/SKILL.md +8 -8
  169. package/skills/create-agent/SKILL.md +28 -22
  170. package/skills/debug/SKILL.md +11 -11
  171. package/skills/evals/SKILL.md +16 -16
  172. package/skills/framework-map/SKILL.md +6 -6
  173. package/skills/github/SKILL.md +13 -13
  174. package/skills/hillclimb/SKILL.md +10 -10
  175. package/skills/setup-slack/SKILL.md +14 -14
  176. package/src/bin/agent-serve.ts +451 -191
  177. package/src/channels/slack/log.ts +5 -5
  178. package/src/channels/slack/setup.ts +1 -1
  179. package/src/channels/slack/socket-mode.ts +11 -9
  180. package/src/internal/ab-collector.ts +3 -3
  181. package/src/internal/ab-fold.ts +1 -1
  182. package/src/internal/chat-client.ts +252 -37
  183. package/src/internal/cli-ax.ts +761 -72
  184. package/src/internal/cli-cursor.ts +14 -42
  185. package/src/internal/cli-deploy.ts +428 -49
  186. package/src/internal/cli-github.ts +13 -15
  187. package/src/internal/cursor/account-mcp.ts +3 -3
  188. package/src/internal/cursor/backend-client.ts +1 -1
  189. package/src/internal/cursor/credentials.ts +26 -7
  190. package/src/internal/cursor/github-credentials.ts +3 -3
  191. package/src/internal/cursor-event-relay.ts +1 -1
  192. package/src/internal/cursor-relay-core.ts +4 -2
  193. package/src/internal/cursor-slack-relay.ts +1 -1
  194. package/src/internal/deploy-client.ts +45 -4
  195. package/src/internal/deploy-source.ts +133 -0
  196. package/src/internal/discovery.ts +53 -16
  197. package/src/internal/distribution.ts +8 -0
  198. package/src/internal/docs-site.ts +3 -3
  199. package/src/internal/eval-run-store.ts +10 -11
  200. package/src/internal/eval-runner.ts +5 -0
  201. package/src/internal/event-mapper.ts +222 -42
  202. package/src/internal/github-fanout.ts +2 -2
  203. package/src/internal/host-platforms.ts +5 -5
  204. package/src/internal/init-project.ts +333 -51
  205. package/src/internal/install-cursor-skills.ts +327 -0
  206. package/src/internal/logs-client.ts +442 -0
  207. package/src/internal/mcp-endpoint.ts +1 -3
  208. package/src/internal/open-browser.ts +41 -0
  209. package/src/internal/playground/toolchain.ts +18 -16
  210. package/src/internal/playground-proxy.ts +576 -0
  211. package/src/internal/prompt-context.ts +95 -0
  212. package/src/internal/reminder-runner.ts +11 -17
  213. package/src/internal/request-headers.ts +23 -0
  214. package/src/internal/resolve-prod-target.ts +182 -0
  215. package/src/internal/resolved-connections.ts +5 -5
  216. package/src/internal/run-client.ts +39 -36
  217. package/src/internal/schedule-runner.ts +1 -1
  218. package/src/internal/server.ts +25 -16
  219. package/src/internal/session-engine.ts +35 -18
  220. package/src/internal/sessions-client.ts +216 -0
  221. package/src/internal/storage-coordinator.ts +6 -6
  222. package/src/internal/stream-progress.ts +36 -2
  223. package/src/internal/terminal-style.ts +74 -0
  224. package/src/internal/trajectory.ts +91 -13
  225. package/src/internal/update-check.ts +552 -0
  226. package/src/internal/workspace.ts +42 -4
  227. package/src/types.ts +45 -7
  228. package/dist/docs/assets/chunks/@localSearchIndexroot.zwQ9RCQ7.js +0 -1
  229. package/dist/playground/assets/index-B1Qc9h2u.css +0 -1
  230. package/dist/playground/assets/index-CpDYCj8W.js +0 -79
  231. /package/dist/docs/assets/{index.md.m81y7TY7.lean.js → index.md.Cylk70gg.lean.js} +0 -0
  232. /package/dist/docs/assets/{quickstart.md.CfU8_uTC.lean.js → quickstart.md.BU6Iwi_9.lean.js} +0 -0
@@ -0,0 +1,442 @@
1
+ /**
2
+ * `agentkit logs` — follow deploy progress (hosted) then runtime `/v1/logs`.
3
+ *
4
+ * Customer-facing output never includes hosting URLs, tokens, or infra jargon.
5
+ */
6
+
7
+ import {
8
+ DeployApiError,
9
+ type DeploymentDetail,
10
+ type DeploymentProgress,
11
+ } from "./deploy-client.js";
12
+ import { mergeRequestHeaders, type RequestAuth } from "./request-headers.js";
13
+ import { resolveProdTarget } from "./resolve-prod-target.js";
14
+ import { stderrPalette } from "./terminal-style.js";
15
+
16
+ const DEFAULT_POLL_INTERVAL_MS = 1_000;
17
+
18
+ /** Re-read abort state after await (loop narrowing would hide async abort). */
19
+ function isAborted(signal: AbortSignal | undefined): boolean {
20
+ return signal?.aborted === true;
21
+ }
22
+
23
+ export interface LogRingEntry {
24
+ index: number;
25
+ at: string;
26
+ line: string;
27
+ }
28
+
29
+ export interface LogsResponse {
30
+ entries: LogRingEntry[];
31
+ nextAfter: number;
32
+ }
33
+
34
+ export type LogsProgress =
35
+ | DeploymentProgress
36
+ | "queued"
37
+ | "preparing"
38
+ | "building"
39
+ | "finalizing"
40
+ | "running"
41
+ | "failed"
42
+ | "stopping"
43
+ | "stopped"
44
+ | "degraded";
45
+
46
+ const PROGRESS_MESSAGES: Readonly<Record<LogsProgress, string>> = {
47
+ queued: "Waiting to start…",
48
+ preparing: "Preparing runtime…",
49
+ building: "Building and starting agent…",
50
+ finalizing: "Finishing deployment…",
51
+ running: "Deployment running",
52
+ failed: "Deploy failed",
53
+ stopping: "Stopping deployment…",
54
+ stopped: "Deployment stopped",
55
+ degraded: "Deployment degraded",
56
+ };
57
+
58
+ export function progressMessage(
59
+ progress: LogsProgress,
60
+ lastError?: string | null
61
+ ): string {
62
+ if (progress === "failed") {
63
+ const detail =
64
+ lastError === null || lastError === undefined || lastError.trim() === ""
65
+ ? ""
66
+ : `: ${sanitizeCustomerError(lastError)}`;
67
+ return `Deploy failed${detail}`;
68
+ }
69
+ if (progress === "degraded") {
70
+ const detail =
71
+ lastError === null || lastError === undefined || lastError.trim() === ""
72
+ ? ""
73
+ : `: ${sanitizeCustomerError(lastError)}`;
74
+ return `Deployment degraded${detail}`;
75
+ }
76
+ return PROGRESS_MESSAGES[progress];
77
+ }
78
+
79
+ /** Strip obvious hosting internals from error text shown to customers. */
80
+ export function sanitizeCustomerError(message: string): string {
81
+ return message
82
+ .replace(/https?:\/\/\S+/gi, "[url]")
83
+ .replace(/\bpod-[a-z0-9]+\b/gi, "[runtime]")
84
+ .replace(/\banyrun\b/gi, "runtime")
85
+ .replace(/\bcursorvm\.com\b/gi, "host")
86
+ .replace(/\bx-anyrun-[a-z0-9-]+\b/gi, "header")
87
+ .replace(/\bPROVISIONING\b/g, "building")
88
+ .replace(/\bPLANNED\b/g, "preparing");
89
+ }
90
+
91
+ export async function fetchLogs(args: {
92
+ baseUrl: string;
93
+ after?: number;
94
+ auth?: RequestAuth;
95
+ fetchImpl?: typeof fetch;
96
+ signal?: AbortSignal;
97
+ }): Promise<LogsResponse> {
98
+ const fetchImpl = args.fetchImpl ?? fetch;
99
+ const after = args.after ?? -1;
100
+ const url = new URL(`${args.baseUrl.replace(/\/$/, "")}/v1/logs`);
101
+ if (after >= 0) {
102
+ url.searchParams.set("after", String(after));
103
+ }
104
+ const resp = await fetchImpl(url, {
105
+ headers: mergeRequestHeaders(args.auth),
106
+ signal: args.signal,
107
+ });
108
+ if (!resp.ok) {
109
+ throw new Error(`Could not fetch logs (HTTP ${resp.status}).`);
110
+ }
111
+ const body = (await resp.json()) as {
112
+ entries?: LogRingEntry[];
113
+ nextAfter?: number;
114
+ };
115
+ const entries = Array.isArray(body.entries) ? body.entries : [];
116
+ const nextAfter =
117
+ typeof body.nextAfter === "number"
118
+ ? body.nextAfter
119
+ : entries.length === 0
120
+ ? after
121
+ : (entries[entries.length - 1]?.index ?? after);
122
+ return { entries, nextAfter };
123
+ }
124
+
125
+ export interface RunLogsTailOptions {
126
+ /** When true, use hosted deploy progress then runtime logs. */
127
+ prod?: boolean;
128
+ dir: string;
129
+ cwd?: string;
130
+ slug?: string;
131
+ team?: string;
132
+ apiKey?: string;
133
+ url?: string;
134
+ bearerToken?: string;
135
+ once?: boolean;
136
+ json?: boolean;
137
+ fetchImpl?: typeof fetch;
138
+ signal?: AbortSignal;
139
+ intervalMs?: number;
140
+ /** stdout writer (test seam). */
141
+ write?: (text: string) => void;
142
+ /** stderr writer (test seam). */
143
+ err?: (text: string) => void;
144
+ /**
145
+ * Deploy detail fetcher for `--prod` progress (test seam). Defaults to
146
+ * management API via resolveProdTarget's auth path.
147
+ */
148
+ getDeployment?: () => Promise<DeploymentDetail>;
149
+ /** After deploy is running, resolve runtime base URL + headers. */
150
+ resolveRuntime?: () => Promise<{
151
+ agentUrl: string;
152
+ headers?: Record<string, string>;
153
+ }>;
154
+ sleep?: (ms: number, signal?: AbortSignal) => Promise<void>;
155
+ }
156
+
157
+ export async function runLogsTail(options: RunLogsTailOptions): Promise<void> {
158
+ const write =
159
+ options.write ?? ((text: string) => void process.stdout.write(text));
160
+ const err =
161
+ options.err ?? ((text: string) => void process.stderr.write(text));
162
+ const sleep = options.sleep ?? sleepMs;
163
+ const intervalMs = options.intervalMs ?? DEFAULT_POLL_INTERVAL_MS;
164
+ const c = stderrPalette();
165
+
166
+ if (options.prod === true) {
167
+ await followProdLogs({
168
+ ...options,
169
+ write,
170
+ err,
171
+ sleep,
172
+ intervalMs,
173
+ palette: c,
174
+ });
175
+ return;
176
+ }
177
+
178
+ const baseUrl = (options.url ?? "http://127.0.0.1:3000").replace(/\/$/, "");
179
+ if (options.once !== true) {
180
+ err(c.dim("Tailing logs… (Ctrl-C to stop)\n"));
181
+ }
182
+ await followRuntimeLogs({
183
+ baseUrl,
184
+ auth: { bearerToken: options.bearerToken },
185
+ once: options.once === true,
186
+ json: options.json === true,
187
+ fetchImpl: options.fetchImpl,
188
+ signal: options.signal,
189
+ intervalMs,
190
+ write,
191
+ sleep,
192
+ });
193
+ }
194
+
195
+ async function followProdLogs(args: {
196
+ dir: string;
197
+ cwd?: string;
198
+ slug?: string;
199
+ team?: string;
200
+ apiKey?: string;
201
+ bearerToken?: string;
202
+ once?: boolean;
203
+ json?: boolean;
204
+ fetchImpl?: typeof fetch;
205
+ signal?: AbortSignal;
206
+ intervalMs: number;
207
+ write: (text: string) => void;
208
+ err: (text: string) => void;
209
+ getDeployment?: () => Promise<DeploymentDetail>;
210
+ resolveRuntime?: () => Promise<{
211
+ agentUrl: string;
212
+ headers?: Record<string, string>;
213
+ }>;
214
+ sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
215
+ palette: ReturnType<typeof stderrPalette>;
216
+ }): Promise<void> {
217
+ const resolveRuntime =
218
+ args.resolveRuntime ??
219
+ (async () => {
220
+ const target = await resolveProdTarget({
221
+ dir: args.dir,
222
+ cwd: args.cwd,
223
+ slug: args.slug,
224
+ team: args.team,
225
+ apiKey: args.apiKey,
226
+ fetchImpl: args.fetchImpl,
227
+ err: () => {},
228
+ });
229
+ return { agentUrl: target.agentUrl, headers: target.headers };
230
+ });
231
+
232
+ const getDeployment =
233
+ args.getDeployment ??
234
+ (async () => {
235
+ // Lazy import path via resolveProdTarget side: re-fetch through a
236
+ // one-shot resolve that throws if not running is wrong for progress.
237
+ // Callers that omit getDeployment must provide it in production via
238
+ // cmdLogs (which wires deploy auth).
239
+ throw new Error(
240
+ "Internal error: deploy progress requires a deployment lookup."
241
+ );
242
+ });
243
+
244
+ let lastProgress: string | undefined;
245
+ const slugHint = args.slug !== undefined && args.slug !== "" ? args.slug : "";
246
+ if (args.once !== true) {
247
+ const label = slugHint !== "" ? slugHint : "deployment";
248
+ args.err(args.palette.dim(`Tailing logs for ${label}… (Ctrl-C to stop)\n`));
249
+ }
250
+
251
+ while (!isAborted(args.signal)) {
252
+ let detail: DeploymentDetail;
253
+ try {
254
+ detail = await getDeployment();
255
+ } catch (error) {
256
+ if (isAborted(args.signal)) {
257
+ return;
258
+ }
259
+ throw customerDeployLookupError(error);
260
+ }
261
+
262
+ const progress = resolveProgress(detail);
263
+
264
+ if (progress === "failed") {
265
+ const message = progressMessage(progress, detail.lastError);
266
+ if (progress !== lastProgress) {
267
+ lastProgress = progress;
268
+ emitProgress(args.write, args.json === true, progress, message);
269
+ }
270
+ throw new Error(`Deployment "${detail.slug}" failed.`);
271
+ }
272
+ if (progress === "stopped") {
273
+ const message = progressMessage(progress, detail.lastError);
274
+ if (progress !== lastProgress) {
275
+ lastProgress = progress;
276
+ emitProgress(args.write, args.json === true, progress, message);
277
+ }
278
+ throw new Error(`Deployment "${detail.slug}" is stopped.`);
279
+ }
280
+ if (progress === "running" || progress === "degraded") {
281
+ // Hand off to runtime logs. Print degraded once; skip a "running" line.
282
+ if (progress === "degraded" && progress !== lastProgress) {
283
+ lastProgress = progress;
284
+ emitProgress(
285
+ args.write,
286
+ args.json === true,
287
+ progress,
288
+ progressMessage(progress, detail.lastError)
289
+ );
290
+ }
291
+ const runtime = await resolveRuntime();
292
+ await followRuntimeLogs({
293
+ baseUrl: runtime.agentUrl,
294
+ auth: {
295
+ bearerToken: args.bearerToken,
296
+ headers: runtime.headers,
297
+ },
298
+ once: args.once === true,
299
+ json: args.json === true,
300
+ fetchImpl: args.fetchImpl,
301
+ signal: args.signal,
302
+ intervalMs: args.intervalMs,
303
+ write: args.write,
304
+ sleep: args.sleep,
305
+ });
306
+ return;
307
+ }
308
+
309
+ const message = progressMessage(progress, detail.lastError);
310
+ if (progress !== lastProgress) {
311
+ lastProgress = progress;
312
+ emitProgress(args.write, args.json === true, progress, message);
313
+ }
314
+
315
+ if (args.once === true) {
316
+ return;
317
+ }
318
+
319
+ await args.sleep(args.intervalMs, args.signal);
320
+ }
321
+ }
322
+
323
+ function resolveProgress(detail: DeploymentDetail): LogsProgress {
324
+ if (detail.progress !== undefined) {
325
+ return detail.progress;
326
+ }
327
+ switch (detail.status) {
328
+ case "pending":
329
+ return "queued";
330
+ case "deploying":
331
+ return "building";
332
+ case "running":
333
+ return "running";
334
+ case "failed":
335
+ return "failed";
336
+ case "degraded":
337
+ return "degraded";
338
+ case "stopping":
339
+ return "stopping";
340
+ case "stopped":
341
+ return "stopped";
342
+ default:
343
+ return "queued";
344
+ }
345
+ }
346
+
347
+ function emitProgress(
348
+ write: (text: string) => void,
349
+ json: boolean,
350
+ progress: LogsProgress,
351
+ message: string
352
+ ): void {
353
+ if (json) {
354
+ write(`${JSON.stringify({ type: "progress", progress, message })}\n`);
355
+ return;
356
+ }
357
+ write(`${message}\n`);
358
+ }
359
+
360
+ async function followRuntimeLogs(args: {
361
+ baseUrl: string;
362
+ auth?: RequestAuth;
363
+ once: boolean;
364
+ json: boolean;
365
+ fetchImpl?: typeof fetch;
366
+ signal?: AbortSignal;
367
+ intervalMs: number;
368
+ write: (text: string) => void;
369
+ sleep: (ms: number, signal?: AbortSignal) => Promise<void>;
370
+ }): Promise<void> {
371
+ let after = -1;
372
+ for (;;) {
373
+ if (isAborted(args.signal)) {
374
+ return;
375
+ }
376
+ let batch: LogsResponse;
377
+ try {
378
+ batch = await fetchLogs({
379
+ baseUrl: args.baseUrl,
380
+ after,
381
+ auth: args.auth,
382
+ fetchImpl: args.fetchImpl,
383
+ signal: args.signal,
384
+ });
385
+ } catch (error) {
386
+ if (isAborted(args.signal)) {
387
+ return;
388
+ }
389
+ throw error instanceof Error ? error : new Error("Could not fetch logs.");
390
+ }
391
+
392
+ for (const entry of batch.entries) {
393
+ if (args.json) {
394
+ args.write(
395
+ `${JSON.stringify({
396
+ type: "log",
397
+ index: entry.index,
398
+ at: entry.at,
399
+ line: entry.line,
400
+ })}\n`
401
+ );
402
+ } else {
403
+ args.write(`${entry.line}\n`);
404
+ }
405
+ }
406
+ after = batch.nextAfter;
407
+
408
+ if (args.once) {
409
+ return;
410
+ }
411
+ await args.sleep(args.intervalMs, args.signal);
412
+ }
413
+ }
414
+
415
+ function customerDeployLookupError(error: unknown): Error {
416
+ if (error instanceof DeployApiError) {
417
+ return new Error(
418
+ `Could not look up deployment: ${sanitizeCustomerError(error.message)}`
419
+ );
420
+ }
421
+ if (error instanceof Error) {
422
+ return new Error(sanitizeCustomerError(error.message));
423
+ }
424
+ return new Error("Could not look up deployment.");
425
+ }
426
+
427
+ async function sleepMs(ms: number, signal?: AbortSignal): Promise<void> {
428
+ if (isAborted(signal)) {
429
+ return;
430
+ }
431
+ await new Promise<void>((resolve) => {
432
+ const timer = setTimeout(() => {
433
+ signal?.removeEventListener("abort", onAbort);
434
+ resolve();
435
+ }, ms);
436
+ const onAbort = (): void => {
437
+ clearTimeout(timer);
438
+ resolve();
439
+ };
440
+ signal?.addEventListener("abort", onAbort, { once: true });
441
+ });
442
+ }
@@ -106,9 +106,7 @@ export async function handleStatelessMcpRequest(args: {
106
106
  // so closing in `finally` never truncates a streamed response.
107
107
  return await transport.handleRequest(args.request);
108
108
  } catch (error) {
109
- logger(
110
- `[agent-serve] ${args.label} request failed: ${describeError(error)}`
111
- );
109
+ logger(`[agentkit] ${args.label} request failed: ${describeError(error)}`);
112
110
  return new Response(
113
111
  JSON.stringify({
114
112
  jsonrpc: "2.0",
@@ -0,0 +1,41 @@
1
+ /**
2
+ * Best-effort browser open; callers should always print the URL as fallback.
3
+ */
4
+
5
+ import { spawn } from "node:child_process";
6
+ import { join } from "node:path";
7
+
8
+ export function openBrowser(url: string): void {
9
+ const command =
10
+ process.platform === "darwin"
11
+ ? { cmd: "open", args: [url] }
12
+ : process.platform === "win32"
13
+ ? {
14
+ cmd: join(
15
+ process.env.SYSTEMROOT ?? "C:\\Windows",
16
+ "System32",
17
+ "WindowsPowerShell",
18
+ "v1.0",
19
+ "powershell.exe"
20
+ ),
21
+ args: [
22
+ "-NoProfile",
23
+ "-NonInteractive",
24
+ "-WindowStyle",
25
+ "Hidden",
26
+ "-Command",
27
+ `Start-Process '${url.replace(/'/g, "''")}'`,
28
+ ],
29
+ }
30
+ : { cmd: "xdg-open", args: [url] };
31
+ try {
32
+ const child = spawn(command.cmd, command.args, {
33
+ stdio: "ignore",
34
+ detached: true,
35
+ });
36
+ child.on("error", () => {});
37
+ child.unref();
38
+ } catch {
39
+ // Printed URL is the fallback.
40
+ }
41
+ }
@@ -121,7 +121,7 @@ export async function runPlaygroundBuild(
121
121
  "playground vite toolchain unavailable (need playground/ sources and the vite package)"
122
122
  );
123
123
  }
124
- logger("[agent-serve] building playground (vite)...");
124
+ logger("[agentkit] building playground (vite)...");
125
125
  const code = await spawnVite(toolchain, ["build", "--config", VITE_CONFIG], {
126
126
  env: process.env,
127
127
  });
@@ -133,7 +133,7 @@ export async function runPlaygroundBuild(
133
133
  "playground vite build finished but dist/playground/index.html is missing"
134
134
  );
135
135
  }
136
- logger("[agent-serve] playground build complete");
136
+ logger("[agentkit] playground build complete");
137
137
  }
138
138
 
139
139
  /**
@@ -149,7 +149,7 @@ export async function ensurePlaygroundBundle(
149
149
  }
150
150
  if (resolvePlaygroundToolchain() === undefined) {
151
151
  logger(
152
- "[agent-serve] playground bundle missing and vite toolchain unavailable; /playground will show a build hint"
152
+ "[agentkit] playground bundle missing and vite toolchain unavailable; /playground will show a build hint"
153
153
  );
154
154
  return;
155
155
  }
@@ -198,32 +198,34 @@ export function startPlaygroundDevServer(options: {
198
198
  }
199
199
  }
200
200
 
201
- const modeNote = multiAgent
202
- ? " (multi-agent)"
203
- : options.basePath
204
- ? ` (base ${options.basePath})`
205
- : "";
206
- logger(
207
- `[agent-serve] playground HMR starting on http://127.0.0.1:${port}${modeNote}`
208
- );
209
-
201
+ // Quiet + isolated from the TTY: the serve banner owns the terminal.
202
+ // Piped stdio keeps Vite from seeing a TTY (so it cannot clearScreen), and
203
+ // silent logging drops the "VITE ready" / URL spam. Errors still surface via
204
+ // spawn/exit handlers below.
210
205
  const child = spawn(
211
206
  process.execPath,
212
- [toolchain.viteCli, "--config", VITE_CONFIG],
207
+ [toolchain.viteCli, "--config", VITE_CONFIG, "--logLevel", "silent"],
213
208
  {
214
209
  cwd: toolchain.packageRoot,
215
210
  env,
216
- stdio: "inherit",
211
+ stdio: ["ignore", "ignore", "pipe"],
217
212
  }
218
213
  );
219
214
 
215
+ child.stderr?.on("data", (chunk: Buffer) => {
216
+ const text = chunk.toString().trimEnd();
217
+ if (text !== "") {
218
+ logger(`[agentkit] playground: ${text}`);
219
+ }
220
+ });
221
+
220
222
  let stopped = false;
221
223
  child.on("error", (err) => {
222
224
  if (stopped) {
223
225
  return;
224
226
  }
225
227
  logger(
226
- `[agent-serve] playground HMR spawn failed: ${err.message} — static /playground still served when built`
228
+ `[agentkit] playground spawn failed: ${err.message} — static /playground still served when built`
227
229
  );
228
230
  });
229
231
  child.on("exit", (code, signal) => {
@@ -232,7 +234,7 @@ export function startPlaygroundDevServer(options: {
232
234
  }
233
235
  if (code !== 0 && code !== null) {
234
236
  logger(
235
- `[agent-serve] playground HMR exited (code ${code}${
237
+ `[agentkit] playground exited (code ${code}${
236
238
  signal ? `, signal ${signal}` : ""
237
239
  }) — static /playground still served when built`
238
240
  );