@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
@@ -3,10 +3,12 @@
3
3
  * agent-serve CLI.
4
4
  *
5
5
  * agent-serve serve [--dir .] [--port 3000] [--host 127.0.0.1] [--dev]
6
+ * agent-serve dev [path] [--port 3000] [--host 127.0.0.1]
6
7
  * agent-serve chat [--url http://127.0.0.1:3000] [--message "..."] [--json]
8
+ * agent-serve resume <sessionId> [--url | --prod] [--message "..."]
7
9
  * agent-serve run [--dir .] [--message "..."] [--json|--text]
8
10
  * agent-serve trajectory --events <file.ndjson>
9
- * agent-serve init [dir]
11
+ * agent-serve init [dir] [--json]
10
12
  * agent-serve eval [--dir .] [evalId...]
11
13
  * agent-serve validate [--dir .]
12
14
  * agent-serve slack <subcommand>
@@ -25,12 +27,10 @@ import { resolve } from "node:path";
25
27
  import { parseArgs } from "node:util";
26
28
  import { formatDiagnostics, projectInfo, resolveAgentMounts, serve, } from "../index.js";
27
29
  import { registerAuthoredModuleLoaders } from "../internal/authored-loaders.js";
28
- import { runChat } from "../internal/chat-client.js";
29
- import { cmdCall, cmdEval, cmdInit, cmdRun, cmdTrajectory, } from "../internal/cli-ax.js";
30
+ import { cmdCall, cmdChat, cmdEval, cmdInit, cmdLogs, cmdPlayground, cmdResume, cmdRun, cmdSession, cmdSessions, cmdTrajectory, } from "../internal/cli-ax.js";
30
31
  import { cmdDeploy, cmdDeploymentStatus, cmdDeployments, cmdRotatePodCredential, cmdRotateToken, cmdSecretsList, cmdSecretsSet, cmdSecretsUnset, cmdStop, } from "../internal/cli-deploy.js";
31
32
  import { CLI_COMMAND_NAME as CLI } from "../internal/distribution.js";
32
- import { runSession } from "../internal/run-client.js";
33
- import { formatTrajectoryText } from "../internal/trajectory.js";
33
+ import { clearTerminal, stdoutPalette } from "../internal/terminal-style.js";
34
34
  const HELP = `${CLI} — serve a filesystem-defined Cursor agent over channels
35
35
 
36
36
  Usage:
@@ -38,24 +38,42 @@ Usage:
38
38
  [--mode single|multi] [--api-key <key>] [--no-schedules]
39
39
  [--public-url <url>]
40
40
  [--cursor-events --repo <owner/name>]...
41
- ${CLI} chat [--url <baseUrl>] [--message <text>] [--json] [--text]
42
- ${CLI} run [--dir <path>] [--message <text>]... [--url <baseUrl>]
41
+ ${CLI} dev [path] [--port <n>] [--host <host>]
42
+ Same flags as serve; implies --dev. Path defaults to
43
+ the current directory (or pass --dir).
44
+ ${CLI} chat [--url <baseUrl> | --prod] [--message <text>] [--json] [--text]
45
+ [--session <id>] [--continuation-token <t>]
46
+ [--slug <slug>] [--team <id>]
47
+ ${CLI} resume <sessionId> [--url <baseUrl> | --prod] [--message <text>]
48
+ [--json] [--text] [--continuation-token <t>]
49
+ [--slug <slug>] [--team <id>]
50
+ ${CLI} logs [--url <baseUrl> | --prod] [--once] [--json]
51
+ [--slug <slug>] [--team <id>] [--dir <path>]
52
+ ${CLI} sessions [--url <baseUrl> | --prod] [--json]
53
+ [--slug <slug>] [--team <id>] [--dir <path>]
54
+ ${CLI} session <sessionId> [--url <baseUrl> | --prod]
55
+ [--json | --text | --events]
56
+ [--slug <slug>] [--team <id>] [--dir <path>]
57
+ ${CLI} playground [--url <baseUrl> | --prod] [--session <id>] [--print]
58
+ [--slug <slug>] [--team <id>] [--dir <path>]
59
+ ${CLI} run [--dir <path>] [--message <text>]... [--url <baseUrl> | --prod]
43
60
  [--session <id>] [--continuation-token <t>]
44
61
  [--events <file.ndjson>] [--no-events] [--text]
45
- [--timeout-ms <n>] [--no-stream]
62
+ [--timeout-ms <n>] [--no-stream] [--slug <slug>] [--team <id>]
46
63
  ${CLI} trajectory --events <file.ndjson> [--text]
47
- ${CLI} call <tool> [--input <json>] [--dir <path> | --url <baseUrl>]
48
- [--session <id>] [--slug <slug>]
49
- ${CLI} init [dir]
64
+ ${CLI} call <tool> [--input <json>] [--dir <path> | --url <baseUrl> | --prod]
65
+ [--session <id>] [--slug <slug>] [--team <id>]
66
+ ${CLI} init [dir] [--json]
50
67
  ${CLI} eval [--dir <path>] [evalId...] [--list] [--json]
51
68
  [--tag <tag>]... [--verbose] [--timeout-ms <n>]
52
- [--no-stream]
69
+ [--no-stream] [--url <baseUrl> | --prod] [--slug <slug>]
70
+ [--team <id>]
53
71
  ${CLI} info [--dir <path>] [--json]
54
72
  ${CLI} validate [--dir <path>]
55
73
  ${CLI} login [--api-key <key>] [--key-name <name>]
56
74
  ${CLI} logout
57
75
  ${CLI} whoami [--json]
58
- ${CLI} deploy [--dir <path>] [--slug <slug>] [--team <id>] [--json]
76
+ ${CLI} deploy [--dir <path>] [--slug <slug> | --all] [--team <id>] [--json]
59
77
  [--no-wait] [--repo <url>] [--ref <ref>]
60
78
  [--path <agentPath>] [--cursor-events-repo <owner/name>]...
61
79
  [--allow-domain <domain>]...
@@ -72,15 +90,41 @@ Usage:
72
90
  Commands:
73
91
  serve Serve agents under /<slug>/... (index at /). On a TTY, press
74
92
  Enter to restart (reloads agent code + Vite HMR child).
75
- chat Talk to a running server (streams the reply). --json prints a trajectory.
93
+ dev Local development: same as \`${CLI} serve --dev\` (manual
94
+ schedule/reminder dispatch, unsigned GitHub loopback, Vite HMR).
95
+ chat Interactive REPL against a running server (follow-ups keep the
96
+ session + continuation token). Optional --message seeds the first
97
+ turn then stays open on a TTY. --session reattaches (looks up the
98
+ continuation token via /v1/sessions when omitted) and replays the
99
+ transcript. --json is one-shot. Pass --prod to hit the team's
100
+ hosted deployment (slug from --slug or the directory name).
101
+ resume Reattach chat to an existing session id (same as
102
+ \`${CLI} chat --session <id>\`). Looks up the continuation token
103
+ via /v1/sessions when --continuation-token is omitted, then
104
+ replays the transcript. Pass --prod for a hosted deployment.
105
+ logs Tail agent logs. Default follows (Ctrl-C to stop); --once dumps
106
+ the current buffer. --prod shows deploy progress until the
107
+ hosted deployment is running, then tails runtime logs. Without
108
+ --prod, tails the local server (or --url).
109
+ sessions List sessions on a running agent (or --prod hosted deployment).
110
+ session Show one session. Default: text trajectory. --json for trajectory
111
+ JSON; --events for the raw event list. To continue interactively,
112
+ use \`${CLI} resume <id>\`.
113
+ playground Open the web playground. --prod starts a loopback proxy that
114
+ injects hosted engine credentials (browsers cannot set them).
115
+ --print skips opening a browser. Ctrl-C stops the proxy.
76
116
  run One-shot create→test loop: ephemeral server + JSON trajectory.
77
117
  Writes a single events.ndjson trace (visualize in the playground).
78
118
  Streams tool calls and reply text to stderr when stderr is a TTY.
119
+ Pass --prod to hit the hosted deployment instead of a local server.
79
120
  trajectory Summarize an events.ndjson file into a trajectory.
80
121
  call Call an authored server tool deterministically (no model turn)
81
122
  via POST /v1/tools/:toolName. --session runs it inside an
82
123
  existing session and records it on that session's event stream.
83
- init Scaffold a project, or print the coding-agent setup guide (no args).
124
+ init Scaffold a project (skipping existing files), npm install,
125
+ run login when unsigned, then print next steps. --json is
126
+ machine-readable and never blocks on login. No directory:
127
+ print the setup guide.
84
128
  eval Run filesystem evals under evals/**/*.eval.ts (streams on a TTY).
85
129
  Pass evalId args to select: one datapoint (weather/nyc), a whole
86
130
  file (weather → all cases in that file), several of either, or
@@ -93,8 +137,11 @@ Commands:
93
137
  logout Remove the stored Cursor credentials.
94
138
  whoami Show which Cursor account powers this host (and why).
95
139
  deploy Deploy onto Cursor's managed agent-serve hosting, then wait for
96
- the engine to come up. First deploy of a slug prints the alias
97
- token exactly once save it.
140
+ the engine to come up. --repo/--ref/--path stay available;
141
+ inside an agent git checkout they are inferred when omitted
142
+ (flags always win). When --dir is a multi-agent parent,
143
+ pick one interactively, or pass --slug / --all. First deploy
144
+ of a slug prints the alias token exactly once — save it.
98
145
  deployments List the team's deployments (slug, status, generation, kind).
99
146
  deployment Show one deployment in full (status, lastError, engine info).
100
147
  stop Stop a deployment and wait until it reports stopped.
@@ -115,6 +162,7 @@ Agent loop:
115
162
  ${CLI} info --dir . --json
116
163
  ${CLI} run --dir . --message "..."
117
164
  ${CLI} eval --dir .
165
+ ${CLI} dev .
118
166
 
119
167
  Options:
120
168
  --dir Project root (defaults to the current directory).
@@ -135,28 +183,49 @@ Options:
135
183
  send it as the Authorization bearer.
136
184
  --allow-anonymous serve: admit all HTTP callers (allowAll). For demos behind a
137
185
  trusted network only; mutually exclusive with --bearer-token.
186
+ --allow-anonymous-cursor-github
187
+ serve: allow --allow-anonymous together with
188
+ githubChannel({ cursorAccount }). Admitted callers can drive
189
+ sessions holding the account's repo-scoped GitHub credential,
190
+ so use only behind a trusted boundary (e.g. an SSO proxy).
138
191
  --public-url serve: base URL where this host is reachable from outside
139
192
  (e.g. https://agent-serve.example.com). Required for peer
140
193
  connections (defineConnection({ agent })) on cloud-runtime
141
194
  turns; local turns always use loopback.
142
195
  --no-schedules Disable the cron runner outside dev mode.
143
- --team deploy/deployments/deployment/stop/rotate-token: Cursor
144
- team id. Defaults to the account's team when it has one.
196
+ --team deploy/deployments/deployment/stop/rotate-token and
197
+ chat/resume/run/call/eval/logs/sessions/session/playground
198
+ --prod: Cursor team id. Defaults to the account's team when
199
+ it has one.
200
+ --prod chat/resume/run/call/eval/logs/sessions/session/playground:
201
+ use the team's hosted deployment. Slug from --slug or the
202
+ --dir basename. Mutually exclusive with --url. Requires
203
+ \`${CLI} login\`.
204
+ --once logs: print current progress / log buffer once and exit
205
+ (default is to follow).
206
+ --print playground: print the URL only; do not open a browser.
145
207
  --no-wait deploy/stop: return right after the request is accepted
146
208
  instead of polling until a terminal status.
147
209
  --no-playground Disable the bundled web playground at /playground (also skips
148
210
  auto-build / HMR).
149
211
  --no-docs Disable the documentation site at /docs (also skips its
150
212
  auto-build).
151
- --url chat/run/eval: base URL of a running agent (skip local host).
152
- --message chat/run: user message (repeatable for run).
213
+ --url chat/resume/run/call/eval/logs/sessions/session/playground:
214
+ base URL of a running agent (skip local host). Mutually
215
+ exclusive with --prod.
216
+ --message chat/resume/run: user message (repeatable for run).
153
217
  --input call: JSON object of tool arguments (default {}).
154
218
  --messages-file JSON array of strings (run).
155
- --session Existing session id for a follow-up turn.
156
- --continuation-token Token from a prior run/chat response.
219
+ --session Existing session id (run/call follow-up, or chat reattach).
220
+ Prefer \`${CLI} resume <sessionId>\` for interactive
221
+ reattach.
222
+ --continuation-token Token from a prior run/chat/resume response (optional
223
+ for resume / chat --session; looked up via /v1/sessions
224
+ when omitted).
157
225
  --events run: write NDJSON trace to this path (default
158
226
  <dir>/.agent-serve/traces/<sessionId>.ndjson).
159
- trajectory: read this file.
227
+ trajectory: read this file. session: print raw
228
+ { sessionId, events } JSON (boolean; no path).
160
229
  --no-events run: do not write a trace file.
161
230
  --slug Agent slug when --dir mounts multiple agents.
162
231
  --timeout-ms Abort a hung turn after N milliseconds.
@@ -164,7 +233,9 @@ Options:
164
233
  --list eval: print discovered cases without running.
165
234
  --verbose eval: stream t.log lines and reply snippets.
166
235
  --no-stream run/eval: silence live progress on stderr (JSON still prints).
167
- --json JSON output (info/chat/eval/github; run defaults to JSON).
236
+ --json JSON output (init/info/chat/eval/logs/sessions/session/
237
+ github; run defaults to JSON). logs: NDJSON progress/log
238
+ events. session: trajectory JSON (not raw events).
168
239
  --no-color chat: force plain output.
169
240
  --cursor-events serve: pull SCM webhook events from /v0/scm-events. The
170
241
  stream is read as your Cursor user, so serve requires
@@ -174,10 +245,15 @@ Options:
174
245
  --repo serve --cursor-events: repo to subscribe to (repeatable).
175
246
  github forward: owner/repo to forward from (inferred from
176
247
  the git remote when omitted; last wins).
177
- deploy: https git repo URL the control plane builds from.
178
- --ref deploy: git ref to build (defaults to the repo's default
179
- branch server-side).
180
- --path deploy: agent directory relative to the repo root.
248
+ deploy: https git repo URL (optional; inferred from
249
+ git remote origin when omitted).
250
+ --ref deploy: git ref to build (optional; inferred from the
251
+ current branch when omitted).
252
+ --path deploy: agent dir relative to repo root (optional;
253
+ inferred from --dir vs git toplevel when omitted).
254
+ --all deploy: every child agent under a multi-agent --dir
255
+ (skips the interactive picker; mutually exclusive with
256
+ --slug).
181
257
  --cursor-events-repo deploy: repo (owner/name) whose SCM events the
182
258
  deployed engine pulls (repeatable).
183
259
  --allow-domain deploy: egress domain the engine pod may reach
@@ -198,9 +274,9 @@ Options:
198
274
  `;
199
275
  function main(argv) {
200
276
  return __awaiter(this, void 0, void 0, function* () {
201
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
202
- var _k, _l, _m, _o, _p, _q, _r, _s;
203
- const [command, ...rest] = argv;
277
+ var _a, _b, _c, _d, _e, _f, _g;
278
+ var _h, _j, _k, _l, _m, _o, _p, _q, _r, _s;
279
+ const [command, ...restIn] = argv;
204
280
  if (command === undefined ||
205
281
  command === "help" ||
206
282
  command === "--help" ||
@@ -208,6 +284,11 @@ function main(argv) {
208
284
  process.stdout.write(HELP);
209
285
  return command === undefined ? 1 : 0;
210
286
  }
287
+ // `session --events` means "dump raw events" (boolean). Rewrite so it does
288
+ // not collide with run/trajectory's `--events <file.ndjson>` string flag.
289
+ const rest = command === "session"
290
+ ? restIn.map((arg) => (arg === "--events" ? "--raw-events" : arg))
291
+ : restIn;
211
292
  const { values, positionals } = parseArgs({
212
293
  args: rest,
213
294
  allowPositionals: true,
@@ -222,10 +303,12 @@ function main(argv) {
222
303
  "state-root": { type: "string" },
223
304
  "bearer-token": { type: "string" },
224
305
  "allow-anonymous": { type: "boolean", default: false },
306
+ "allow-anonymous-cursor-github": { type: "boolean", default: false },
225
307
  "no-schedules": { type: "boolean", default: false },
226
308
  "no-playground": { type: "boolean", default: false },
227
309
  "no-docs": { type: "boolean", default: false },
228
310
  url: { type: "string" },
311
+ prod: { type: "boolean", default: false },
229
312
  message: { type: "string", multiple: true },
230
313
  input: { type: "string" },
231
314
  "messages-file": { type: "string" },
@@ -242,6 +325,8 @@ function main(argv) {
242
325
  text: { type: "boolean", default: false },
243
326
  "no-color": { type: "boolean", default: false },
244
327
  "no-stream": { type: "boolean", default: false },
328
+ once: { type: "boolean", default: false },
329
+ "raw-events": { type: "boolean", default: false },
245
330
  json: { type: "boolean", default: false },
246
331
  name: { type: "string" },
247
332
  env: { type: "string" },
@@ -269,11 +354,12 @@ function main(argv) {
269
354
  "no-wait": { type: "boolean", default: false },
270
355
  ref: { type: "string" },
271
356
  path: { type: "string" },
357
+ all: { type: "boolean", default: false },
272
358
  "cursor-events-repo": { type: "string", multiple: true },
273
359
  "allow-domain": { type: "string", multiple: true },
274
360
  },
275
361
  });
276
- const dir = (_k = values.dir) !== null && _k !== void 0 ? _k : ".";
362
+ const dir = (_h = values.dir) !== null && _h !== void 0 ? _h : ".";
277
363
  switch (command) {
278
364
  case "slack": {
279
365
  const { cmdSlack } = yield import("../internal/cli-slack.js");
@@ -329,6 +415,7 @@ function main(argv) {
329
415
  return cmdInit({
330
416
  dir,
331
417
  initTarget: positionals[0],
418
+ json: values.json,
332
419
  });
333
420
  }
334
421
  case "login": {
@@ -350,7 +437,7 @@ function main(argv) {
350
437
  // `--repo` is repeatable for `serve --cursor-events`; deploy targets a
351
438
  // single source repo, so the last one wins.
352
439
  const repo = (_b = values.repo) === null || _b === void 0 ? void 0 : _b.at(-1);
353
- return cmdDeploy(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, deployOptionsFromValues(values)), { dir }), (values.slug === undefined ? {} : { slug: values.slug })), (repo === undefined ? {} : { repo })), (values.ref === undefined ? {} : { ref: values.ref })), (values.path === undefined ? {} : { path: values.path })), (values["cursor-events-repo"] === undefined
440
+ return cmdDeploy(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({}, deployOptionsFromValues(values)), { dir }), (values.slug === undefined ? {} : { slug: values.slug })), { all: values.all === true }), (repo === undefined ? {} : { repo })), (values.ref === undefined ? {} : { ref: values.ref })), (values.path === undefined ? {} : { path: values.path })), (values["cursor-events-repo"] === undefined
354
441
  ? {}
355
442
  : { cursorEventsRepos: values["cursor-events-repo"] })), (values["allow-domain"] === undefined
356
443
  ? {}
@@ -390,7 +477,7 @@ function main(argv) {
390
477
  return cmdRun(axFromOptions({
391
478
  dir,
392
479
  messages,
393
- sessionId: (_l = values["session-id"]) !== null && _l !== void 0 ? _l : values.session,
480
+ sessionId: (_j = values["session-id"]) !== null && _j !== void 0 ? _j : values.session,
394
481
  continuationToken: values["continuation-token"],
395
482
  events: values["no-events"]
396
483
  ? false
@@ -399,6 +486,9 @@ function main(argv) {
399
486
  : values.events,
400
487
  text: values.text,
401
488
  url: values.url,
489
+ prod: values.prod,
490
+ team: values.team,
491
+ apiKey: values["api-key"],
402
492
  slug: values.slug,
403
493
  bearerToken: values["bearer-token"],
404
494
  stateRoot: values["state-root"],
@@ -411,8 +501,11 @@ function main(argv) {
411
501
  dir,
412
502
  toolName: positionals[0],
413
503
  toolInput: values.input,
414
- sessionId: (_m = values["session-id"]) !== null && _m !== void 0 ? _m : values.session,
504
+ sessionId: (_k = values["session-id"]) !== null && _k !== void 0 ? _k : values.session,
415
505
  url: values.url,
506
+ prod: values.prod,
507
+ team: values.team,
508
+ apiKey: values["api-key"],
416
509
  slug: values.slug,
417
510
  bearerToken: values["bearer-token"],
418
511
  stateRoot: values["state-root"],
@@ -438,6 +531,9 @@ function main(argv) {
438
531
  json: values.json,
439
532
  tags: values.tag,
440
533
  url: values.url,
534
+ prod: values.prod,
535
+ team: values.team,
536
+ apiKey: values["api-key"],
441
537
  slug: values.slug,
442
538
  bearerToken: values["bearer-token"],
443
539
  stateRoot: values["state-root"],
@@ -446,20 +542,91 @@ function main(argv) {
446
542
  }));
447
543
  }
448
544
  case "chat": {
449
- if (values.json) {
450
- return chatJson({
451
- baseUrl: (_o = values.url) !== null && _o !== void 0 ? _o : "http://127.0.0.1:3000",
452
- message: (_c = values.message) === null || _c === void 0 ? void 0 : _c[0],
453
- bearerToken: values["bearer-token"],
454
- text: values.text,
455
- });
456
- }
457
- yield runChat(Object.assign(Object.assign(Object.assign({ baseUrl: (_p = values.url) !== null && _p !== void 0 ? _p : "http://127.0.0.1:3000" }, (((_d = values.message) === null || _d === void 0 ? void 0 : _d[0]) === undefined
458
- ? {}
459
- : { message: values.message[0] })), (values["bearer-token"] === undefined
460
- ? {}
461
- : { bearerToken: values["bearer-token"] })), (values["no-color"] ? { noColor: true } : {})));
462
- return 0;
545
+ return cmdChat(axFromOptions({
546
+ dir,
547
+ messages: values.message,
548
+ url: values.url,
549
+ prod: values.prod,
550
+ team: values.team,
551
+ apiKey: values["api-key"],
552
+ slug: values.slug,
553
+ sessionId: (_l = values["session-id"]) !== null && _l !== void 0 ? _l : values.session,
554
+ continuationToken: values["continuation-token"],
555
+ bearerToken: values["bearer-token"],
556
+ json: values.json,
557
+ text: values.text,
558
+ noColor: values["no-color"],
559
+ }));
560
+ }
561
+ case "resume": {
562
+ return cmdResume(positionals[0], axFromOptions({
563
+ dir,
564
+ messages: values.message,
565
+ url: values.url,
566
+ prod: values.prod,
567
+ team: values.team,
568
+ apiKey: values["api-key"],
569
+ slug: values.slug,
570
+ // Positional wins; --session is accepted as a redundant alias.
571
+ sessionId: (_o = (_m = positionals[0]) !== null && _m !== void 0 ? _m : values["session-id"]) !== null && _o !== void 0 ? _o : values.session,
572
+ continuationToken: values["continuation-token"],
573
+ bearerToken: values["bearer-token"],
574
+ json: values.json,
575
+ text: values.text,
576
+ noColor: values["no-color"],
577
+ }));
578
+ }
579
+ case "logs": {
580
+ return cmdLogs(axFromOptions({
581
+ dir,
582
+ url: values.url,
583
+ prod: values.prod,
584
+ team: values.team,
585
+ apiKey: values["api-key"],
586
+ slug: values.slug,
587
+ bearerToken: values["bearer-token"],
588
+ json: values.json,
589
+ once: values.once,
590
+ }));
591
+ }
592
+ case "sessions": {
593
+ return cmdSessions(axFromOptions({
594
+ dir,
595
+ url: values.url,
596
+ prod: values.prod,
597
+ team: values.team,
598
+ apiKey: values["api-key"],
599
+ slug: values.slug,
600
+ bearerToken: values["bearer-token"],
601
+ json: values.json,
602
+ }));
603
+ }
604
+ case "session": {
605
+ return cmdSession(positionals[0], axFromOptions({
606
+ dir,
607
+ url: values.url,
608
+ prod: values.prod,
609
+ team: values.team,
610
+ apiKey: values["api-key"],
611
+ slug: values.slug,
612
+ bearerToken: values["bearer-token"],
613
+ json: values.json,
614
+ text: values.text,
615
+ rawEvents: values["raw-events"],
616
+ }));
617
+ }
618
+ case "playground": {
619
+ return cmdPlayground(axFromOptions({
620
+ dir,
621
+ url: values.url,
622
+ prod: values.prod,
623
+ team: values.team,
624
+ apiKey: values["api-key"],
625
+ slug: values.slug,
626
+ bearerToken: values["bearer-token"],
627
+ sessionId: (_p = values["session-id"]) !== null && _p !== void 0 ? _p : values.session,
628
+ print: values.print,
629
+ }));
463
630
  }
464
631
  case "validate": {
465
632
  const mounts = yield loadMounts(dir);
@@ -478,7 +645,7 @@ function main(argv) {
478
645
  case "info": {
479
646
  const mounts = yield loadMounts(dir);
480
647
  if (values.json) {
481
- const payload = mounts.length === 1 && ((_e = mounts[0]) === null || _e === void 0 ? void 0 : _e.slug) === ""
648
+ const payload = mounts.length === 1 && ((_c = mounts[0]) === null || _c === void 0 ? void 0 : _c.slug) === ""
482
649
  ? projectInfo(mounts[0].project)
483
650
  : {
484
651
  agents: mounts.map(({ slug, project }) => (Object.assign({ slug }, projectInfo(project)))),
@@ -486,7 +653,7 @@ function main(argv) {
486
653
  process.stdout.write(`${JSON.stringify(payload, null, 2)}\n`);
487
654
  return 0;
488
655
  }
489
- if (mounts.length > 1 || ((_f = mounts[0]) === null || _f === void 0 ? void 0 : _f.slug) !== "") {
656
+ if (mounts.length > 1 || ((_d = mounts[0]) === null || _d === void 0 ? void 0 : _d.slug) !== "") {
490
657
  process.stdout.write(`${mounts.length} agents under ${dir}:\n\n`);
491
658
  for (const { slug, project } of mounts) {
492
659
  const info = projectInfo(project);
@@ -495,7 +662,7 @@ function main(argv) {
495
662
  const anyError = mounts.some((m) => m.project.diagnostics.some((d) => d.severity === "error"));
496
663
  return anyError ? 1 : 0;
497
664
  }
498
- const project = (_g = mounts[0]) === null || _g === void 0 ? void 0 : _g.project;
665
+ const project = (_e = mounts[0]) === null || _e === void 0 ? void 0 : _e.project;
499
666
  const info = projectInfo(project);
500
667
  const lines = [];
501
668
  lines.push(`agent: ${info.name}`);
@@ -512,15 +679,27 @@ function main(argv) {
512
679
  "(events only)"}`)));
513
680
  lines.push(section("schedules", info.schedules.map((s) => `${s.name} (${s.cron}, ${s.kind})`)));
514
681
  lines.push(section("hooks", info.hooks));
515
- lines.push(section("hosting egress domains", (_q = (_h = info.hosting) === null || _h === void 0 ? void 0 : _h.egressDomains) !== null && _q !== void 0 ? _q : []));
516
- lines.push(section("hosting secret names", (_r = (_j = info.hosting) === null || _j === void 0 ? void 0 : _j.secretNames) !== null && _r !== void 0 ? _r : []));
682
+ lines.push(section("hosting egress domains", (_q = (_f = info.hosting) === null || _f === void 0 ? void 0 : _f.egressDomains) !== null && _q !== void 0 ? _q : []));
683
+ lines.push(section("hosting secret names", (_r = (_g = info.hosting) === null || _g === void 0 ? void 0 : _g.secretNames) !== null && _r !== void 0 ? _r : []));
517
684
  if (info.diagnostics.length > 0) {
518
685
  lines.push(`\ndiagnostics:\n${formatDiagnostics(info.diagnostics)}`);
519
686
  }
520
687
  process.stdout.write(`${lines.filter((line) => line !== "").join("\n")}\n`);
521
688
  return info.diagnostics.some((d) => d.severity === "error") ? 1 : 0;
522
689
  }
690
+ case "dev":
523
691
  case "serve": {
692
+ const serveDirResult = resolveServeDir({
693
+ command,
694
+ dir,
695
+ positionals,
696
+ dirFlagPassed: rest.includes("--dir"),
697
+ });
698
+ if (typeof serveDirResult !== "string") {
699
+ process.stderr.write(serveDirResult.error);
700
+ return 1;
701
+ }
702
+ const serveDir = serveDirResult;
524
703
  const port = values.port === undefined ? 3000 : Number.parseInt(values.port, 10);
525
704
  if (Number.isNaN(port) || port < 0 || port > 65535) {
526
705
  process.stderr.write(`invalid --port: ${values.port}\n`);
@@ -536,29 +715,42 @@ function main(argv) {
536
715
  process.stderr.write(`invalid --mode: ${mode} (expected "single" or "multi")\n`);
537
716
  return 1;
538
717
  }
539
- const serveOptions = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ port }, (values.host === undefined ? {} : { host: values.host })), (mode === undefined ? {} : { mode: mode })), { dev: values.dev }), (values["api-key"] === undefined
540
- ? {}
541
- : { apiKey: values["api-key"] })), (values["state-root"] === undefined
542
- ? {}
543
- : { stateRoot: values["state-root"] })), (values["bearer-token"] === undefined
544
- ? {}
545
- : { authToken: values["bearer-token"] })), (values["allow-anonymous"] ? { allowAnonymous: true } : {})), (values["no-schedules"] ? { schedules: false } : {})), (values["no-playground"] ? { playground: false } : {})), (values["no-docs"] ? { docs: false } : {})), (values["public-url"] === undefined
546
- ? {}
547
- : { publicUrl: values["public-url"] })), (values["cursor-events"]
548
- ? { cursorEvents: { repos: (_s = values.repo) !== null && _s !== void 0 ? _s : [] } }
549
- : {}));
718
+ const dev = command === "dev" || values.dev === true;
719
+ const style = stdoutPalette();
720
+ const serveOptions = {
721
+ port,
722
+ host: values.host,
723
+ mode: mode,
724
+ dev,
725
+ apiKey: values["api-key"],
726
+ stateRoot: values["state-root"],
727
+ authToken: values["bearer-token"],
728
+ allowAnonymous: values["allow-anonymous"] === true ? true : undefined,
729
+ allowAnonymousCursorGithub: values["allow-anonymous-cursor-github"] === true ? true : undefined,
730
+ schedules: values["no-schedules"] === true ? false : undefined,
731
+ playground: values["no-playground"] === true ? false : undefined,
732
+ docs: values["no-docs"] === true ? false : undefined,
733
+ publicUrl: values["public-url"],
734
+ cursorEvents: values["cursor-events"] === true
735
+ ? { repos: (_s = values.repo) !== null && _s !== void 0 ? _s : [] }
736
+ : undefined,
737
+ // Soft boot logs (GitHub auth, etc.) stay secondary to the banner.
738
+ logger: (line) => {
739
+ process.stdout.write(`${style.dim(line)}\n`);
740
+ },
741
+ };
550
742
  const enterToRestart = process.stdin.isTTY === true;
551
743
  const bannerOpts = {
552
744
  noPlayground: values["no-playground"] === true,
553
- dev: values.dev === true,
745
+ dev,
554
746
  bearerToken: values["bearer-token"] !== undefined,
555
747
  noSchedules: values["no-schedules"] === true,
556
748
  };
557
749
  const start = () => __awaiter(this, void 0, void 0, function* () {
558
- const next = yield serve(dir, serveOptions);
750
+ const next = yield serve(serveDir, serveOptions);
559
751
  printServeBanner(next, bannerOpts);
560
752
  if (enterToRestart) {
561
- process.stdout.write(" press Enter to restart\n");
753
+ process.stdout.write(style.dim(" press Enter to restart\n"));
562
754
  }
563
755
  return next;
564
756
  });
@@ -586,10 +778,16 @@ function main(argv) {
586
778
  return;
587
779
  }
588
780
  restarting = true;
589
- process.stdout.write("\nrestarting…\n");
590
- void handle
591
- .close()
592
- .then(start)
781
+ // Close + re-serve reloads authored agent modules and respawns Vite.
782
+ // Hold the "restarting…" frame briefly so a fast close doesn't look
783
+ // like Enter did nothing.
784
+ clearTerminal();
785
+ process.stdout.write(style.dim("restarting…\n"));
786
+ void Promise.all([handle.close(), sleep(450)])
787
+ .then(() => {
788
+ clearTerminal();
789
+ return start();
790
+ })
593
791
  .then((next) => {
594
792
  handle = next;
595
793
  })
@@ -619,21 +817,37 @@ function deployOptionsFromValues(values) {
619
817
  return Object.assign(Object.assign(Object.assign({}, (values.team === undefined ? {} : { team: values.team })), { json: values.json === true, noWait: values["no-wait"] === true }), (values["api-key"] === undefined ? {} : { apiKey: values["api-key"] }));
620
818
  }
621
819
  function axFromOptions(partial) {
622
- return Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ dir: partial.dir }, (partial.cwd === undefined ? {} : { cwd: partial.cwd })), (partial.slug === undefined ? {} : { slug: partial.slug })), (partial.bearerToken === undefined
623
- ? {}
624
- : { bearerToken: partial.bearerToken })), (partial.stateRoot === undefined
625
- ? {}
626
- : { stateRoot: partial.stateRoot })), (partial.messages === undefined ? {} : { messages: partial.messages })), (partial.sessionId === undefined
627
- ? {}
628
- : { sessionId: partial.sessionId })), (partial.continuationToken === undefined
629
- ? {}
630
- : { continuationToken: partial.continuationToken })), (partial.timeoutMs === undefined
631
- ? {}
632
- : { timeoutMs: partial.timeoutMs })), (partial.events === undefined ? {} : { events: partial.events })), (partial.text === undefined ? {} : { text: partial.text })), (partial.json === undefined ? {} : { json: partial.json })), (partial.list === undefined ? {} : { list: partial.list })), (partial.verbose === undefined ? {} : { verbose: partial.verbose })), (partial.tags === undefined ? {} : { tags: partial.tags })), (partial.evalIds === undefined ? {} : { evalIds: partial.evalIds })), (partial.initTarget === undefined
633
- ? {}
634
- : { initTarget: partial.initTarget })), (partial.toolName === undefined ? {} : { toolName: partial.toolName })), (partial.toolInput === undefined
635
- ? {}
636
- : { toolInput: partial.toolInput })), (partial.url === undefined ? {} : { url: partial.url })), (partial.stream === undefined ? {} : { stream: partial.stream }));
820
+ return {
821
+ dir: partial.dir,
822
+ cwd: partial.cwd,
823
+ slug: partial.slug,
824
+ bearerToken: partial.bearerToken,
825
+ stateRoot: partial.stateRoot,
826
+ messages: partial.messages,
827
+ sessionId: partial.sessionId,
828
+ continuationToken: partial.continuationToken,
829
+ timeoutMs: partial.timeoutMs,
830
+ events: partial.events,
831
+ text: partial.text,
832
+ json: partial.json,
833
+ list: partial.list,
834
+ verbose: partial.verbose,
835
+ tags: partial.tags,
836
+ evalIds: partial.evalIds,
837
+ initTarget: partial.initTarget,
838
+ toolName: partial.toolName,
839
+ toolInput: partial.toolInput,
840
+ url: partial.url,
841
+ prod: partial.prod,
842
+ team: partial.team,
843
+ apiKey: partial.apiKey,
844
+ fetchImpl: partial.fetchImpl,
845
+ stream: partial.stream,
846
+ noColor: partial.noColor,
847
+ once: partial.once,
848
+ rawEvents: partial.rawEvents,
849
+ print: partial.print,
850
+ };
637
851
  }
638
852
  function loadMessages(messages, messagesFile) {
639
853
  return __awaiter(this, void 0, void 0, function* () {
@@ -667,30 +881,6 @@ function parseTimeoutMs(value) {
667
881
  }
668
882
  return n;
669
883
  }
670
- function chatJson(args) {
671
- return __awaiter(this, void 0, void 0, function* () {
672
- var _a;
673
- if (args.message === undefined) {
674
- process.stderr.write("chat --json requires --message\n");
675
- return 2;
676
- }
677
- const result = yield runSession(Object.assign({ baseUrl: args.baseUrl, messages: [args.message] }, (args.bearerToken === undefined
678
- ? {}
679
- : { bearerToken: args.bearerToken })));
680
- if (args.text) {
681
- process.stdout.write(formatTrajectoryText(result.trajectory));
682
- }
683
- else {
684
- console.log(JSON.stringify({
685
- ok: result.ok,
686
- sessionId: result.sessionId,
687
- continuationToken: (_a = result.continuationToken) !== null && _a !== void 0 ? _a : null,
688
- trajectory: result.trajectory,
689
- }, null, 2));
690
- }
691
- return result.ok ? 0 : 1;
692
- });
693
- }
694
884
  /**
695
885
  * Load mounts the same way `serve` does (multi-agent layout by default).
696
886
  */
@@ -708,62 +898,109 @@ function section(title, items) {
708
898
  function isEnterOnly(text) {
709
899
  return text.length > 0 && [...text].every((ch) => ch === "\n" || ch === "\r");
710
900
  }
901
+ function sleep(ms) {
902
+ return new Promise((resolve) => {
903
+ setTimeout(resolve, ms);
904
+ });
905
+ }
906
+ /**
907
+ * `dev [path]` takes a positional project root; `serve` keeps `--dir` only.
908
+ * Reject mixing a positional with an explicit `--dir`, and extra args on `dev`.
909
+ */
910
+ function resolveServeDir(args) {
911
+ if (args.command !== "dev") {
912
+ return args.dir;
913
+ }
914
+ if (args.positionals.length > 1) {
915
+ return {
916
+ error: `${CLI} dev: unexpected arguments: ${args.positionals.slice(1).join(" ")}\n`,
917
+ };
918
+ }
919
+ const positionalDir = args.positionals[0];
920
+ if (positionalDir === undefined) {
921
+ return args.dir;
922
+ }
923
+ if (args.dirFlagPassed && args.dir !== positionalDir) {
924
+ return {
925
+ error: `${CLI} dev: pass a path as a positional or --dir, not both\n`,
926
+ };
927
+ }
928
+ return positionalDir;
929
+ }
711
930
  function printServeBanner(handle, opts) {
712
- var _a;
713
- const multi = handle.agents.length > 1 || ((_a = handle.agents[0]) === null || _a === void 0 ? void 0 : _a.slug) !== "";
714
- if (multi) {
715
- process.stdout.write(`${handle.agents.length} agents listening on ${handle.url}\n`);
716
- if (!opts.noPlayground) {
717
- process.stdout.write(` index: ${handle.url}/\n`);
718
- }
719
- for (const agent of handle.agents) {
720
- const info = projectInfo(agent.project);
721
- const suffix = opts.noPlayground
722
- ? `${agent.url}/v1/session`
723
- : `${agent.url}/playground`;
724
- process.stdout.write(` /${agent.slug} ${info.name} — ${suffix}\n`);
725
- }
931
+ var _a, _b;
932
+ var _c;
933
+ const c = stdoutPalette();
934
+ const agents = handle.agents;
935
+ if (agents.length > 1) {
936
+ process.stdout.write(`${agents.length} agents listening\n`);
726
937
  }
727
938
  else {
728
- const info = projectInfo(handle.project);
729
- process.stdout.write(`${info.name} listening on ${handle.url}\n`);
730
- if (!opts.noPlayground) {
731
- process.stdout.write(` playground: ${handle.url}/playground\n`);
732
- }
733
- process.stdout.write(` POST ${handle.url}/v1/session\n`);
734
- process.stdout.write(` GET ${handle.url}/v1/session/:sessionId/stream\n`);
735
- for (const channel of info.channels) {
736
- if (channel.id === "http") {
737
- continue;
738
- }
739
- for (const route of channel.routes) {
740
- process.stdout.write(` ${route.method} ${handle.url}${route.url}\n`);
939
+ const info = projectInfo((_c = (_a = agents[0]) === null || _a === void 0 ? void 0 : _a.project) !== null && _c !== void 0 ? _c : handle.project);
940
+ process.stdout.write(`${info.name} listening\n`);
941
+ }
942
+ const playgroundUrl = resolvePlaygroundBannerUrl(handle, opts.noPlayground);
943
+ if (playgroundUrl !== undefined) {
944
+ process.stdout.write(` playground ${c.cyan(playgroundUrl)}\n`);
945
+ }
946
+ // Dev is playground-first (Vite proxies the API). Keep API/route detail for
947
+ // plain `serve`, where operators often curl the HTTP surface directly.
948
+ if (!opts.dev) {
949
+ process.stdout.write(c.dim(` api ${handle.url}\n`));
950
+ if (agents.length > 1 || ((_b = agents[0]) === null || _b === void 0 ? void 0 : _b.slug) !== "") {
951
+ for (const agent of agents) {
952
+ const info = projectInfo(agent.project);
953
+ process.stdout.write(c.dim(` /${agent.slug} ${info.name}\n`));
741
954
  }
742
955
  }
743
- if (info.schedules.length > 0) {
744
- const scheduleMode = opts.dev
745
- ? "dev mode: dispatch with POST /v1/dev/schedules/:scheduleId"
746
- : opts.noSchedules
956
+ else {
957
+ const info = projectInfo(handle.project);
958
+ process.stdout.write(c.dim(` POST ${handle.url}/v1/session\n`));
959
+ process.stdout.write(c.dim(` GET ${handle.url}/v1/session/:sessionId/stream\n`));
960
+ for (const channel of info.channels) {
961
+ if (channel.id === "http") {
962
+ continue;
963
+ }
964
+ for (const route of channel.routes) {
965
+ process.stdout.write(c.dim(` ${route.method} ${handle.url}${route.url}\n`));
966
+ }
967
+ }
968
+ if (info.schedules.length > 0) {
969
+ const scheduleMode = opts.noSchedules
747
970
  ? "disabled"
748
971
  : "running on cron cadence (UTC)";
749
- process.stdout.write(` schedules: ${info.schedules.map((s) => s.name).join(", ")} — ${scheduleMode}\n`);
972
+ process.stdout.write(c.dim(` schedules: ${info.schedules.map((s) => s.name).join(", ")} — ${scheduleMode}\n`));
973
+ }
974
+ }
975
+ if (handle.docsUrl !== undefined) {
976
+ process.stdout.write(c.dim(` docs ${handle.docsUrl}\n`));
750
977
  }
751
- }
752
- if (handle.playgroundDevUrl !== undefined) {
753
- process.stdout.write(` playground (HMR): ${handle.playgroundDevUrl}\n`);
754
- }
755
- if (handle.docsUrl !== undefined) {
756
- process.stdout.write(` docs: ${handle.docsUrl}\n`);
757
978
  }
758
979
  if (opts.bearerToken) {
759
- process.stdout.write(" auth: bearer token required on API routes (playground has a token field)\n");
980
+ process.stdout.write(c.dim(" auth: bearer token required on API routes (playground has a token field)\n"));
760
981
  }
761
982
  if (opts.dev &&
762
983
  (process.env.GITHUB_WEBHOOK_SECRET === undefined ||
763
984
  process.env.GITHUB_WEBHOOK_SECRET === "") &&
764
985
  handle.agents.some((agent) => projectInfo(agent.project).channels.some((c) => c.kind === "github"))) {
765
- process.stdout.write(` github: dev accepts unsigned loopback deliveries (${CLI} github forward works without a secret; set GITHUB_WEBHOOK_SECRET to verify signatures)\n`);
986
+ process.stdout.write(c.dim(` github: dev accepts unsigned loopback deliveries (${CLI} github forward works without a secret; set GITHUB_WEBHOOK_SECRET to verify signatures)\n`));
987
+ }
988
+ }
989
+ /** Prefer the Vite playground URL in --dev; otherwise the static SPA path. */
990
+ function resolvePlaygroundBannerUrl(handle, noPlayground) {
991
+ if (noPlayground) {
992
+ return undefined;
993
+ }
994
+ if (handle.playgroundDevUrl !== undefined) {
995
+ return handle.playgroundDevUrl.replace(/\/$/, "");
996
+ }
997
+ if (handle.agents.length === 1) {
998
+ return `${handle.agents[0].url}/playground`;
999
+ }
1000
+ if (handle.agents.length > 1) {
1001
+ return handle.url;
766
1002
  }
1003
+ return undefined;
767
1004
  }
768
1005
  function formatModel(model) {
769
1006
  if (model === undefined) {