@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
@@ -1 +1 @@
1
- {"version":3,"file":"cli-cursor.d.ts","sourceRoot":"","sources":["../../src/internal/cli-cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0BH,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CA+FzE;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAWjD;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuC1E"}
1
+ {"version":3,"file":"cli-cursor.d.ts","sourceRoot":"","sources":["../../src/internal/cli-cursor.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AA0BH,MAAM,WAAW,gBAAgB;IAC/B,wEAAwE;IACxE,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2DAA2D;IAC3D,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC;CAChB;AAED,wBAAsB,QAAQ,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuGzE;AAED,wBAAsB,SAAS,IAAI,OAAO,CAAC,MAAM,CAAC,CAWjD;AAED,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAuC1E"}
@@ -16,16 +16,18 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
16
16
  step((generator = generator.apply(thisArg, _arguments || [])).next());
17
17
  });
18
18
  };
19
- import { spawn } from "node:child_process";
20
19
  import { hostname } from "node:os";
21
- import { join } from "node:path";
22
20
  import { CursorBackendClient, CursorBackendError, createUserApiKeyWithSessionToken, revokeMintedUserApiKey, } from "./cursor/backend-client.js";
23
21
  import { clearStoredCredentials, credentialsFilePath, cursorBackendUrl, pollForLoginTokens, readStoredCredentials, resolveApiKey, SIGN_IN_HINT, startBrowserLogin, writeStoredCredentials, } from "./cursor/credentials.js";
24
22
  import { CLI_COMMAND_NAME } from "./distribution.js";
23
+ import { openBrowser } from "./open-browser.js";
24
+ import { stderrPalette, stdoutPalette } from "./terminal-style.js";
25
25
  export function cmdLogin(options) {
26
26
  return __awaiter(this, void 0, void 0, function* () {
27
27
  var _a;
28
28
  const backendUrl = cursorBackendUrl();
29
+ const err = stderrPalette();
30
+ const out = stdoutPalette();
29
31
  let apiKey;
30
32
  // Set only on the browser-mint path; carries what the revoke-on-failure
31
33
  // cleanup needs (the session token that minted the key + its label).
@@ -36,7 +38,7 @@ export function cmdLogin(options) {
36
38
  }
37
39
  else {
38
40
  const { loginUrl, uuid, verifier } = startBrowserLogin();
39
- process.stderr.write(`Opening your browser to sign in to Cursor…\n\n ${loginUrl}\n\n(waiting for the browser sign-in to complete)\n`);
41
+ process.stderr.write(err.dim(`Opening your browser to sign in to Cursor…\n\n ${loginUrl}\n\n(waiting for the browser sign-in to complete)\n`));
40
42
  openBrowser(loginUrl);
41
43
  const login = yield pollForLoginTokens({
42
44
  uuid,
@@ -68,7 +70,7 @@ export function cmdLogin(options) {
68
70
  throw error;
69
71
  }
70
72
  minted = { keyName, sessionToken: login.accessToken };
71
- process.stderr.write(`Minted the "${keyName}" API key.\n`);
73
+ process.stderr.write(err.dim(`Minted the "${keyName}" API key.\n`));
72
74
  }
73
75
  // Revoke the just-minted key when a later step fails, so a botched login
74
76
  // never leaves an orphaned live credential (no-op on the headless path).
@@ -101,9 +103,9 @@ export function cmdLogin(options) {
101
103
  process.stderr.write(`Could not store credentials at ${credentialsFilePath()}: ${describeError(error)}\n`);
102
104
  return 1;
103
105
  }
104
- process.stdout.write(`Signed in as ${formatIdentity(identity)} (${backendUrl})\nCredentials stored at ${credentialsFilePath()}\n`);
106
+ process.stdout.write(`Signed in as ${formatIdentity(identity)} (${backendUrl})\n${out.dim(`Credentials stored at ${credentialsFilePath()}`)}\n`);
105
107
  if (process.env.CURSOR_API_KEY !== undefined) {
106
- process.stderr.write("note: CURSOR_API_KEY is set in this shell and takes precedence over the stored login.\n");
108
+ process.stderr.write(err.dim("note: CURSOR_API_KEY is set in this shell and takes precedence over the stored login.\n"));
107
109
  }
108
110
  return 0;
109
111
  });
@@ -192,36 +194,6 @@ function describeLoginPollFailure(result) {
192
194
  ].join("\n");
193
195
  }
194
196
  }
195
- /** Best-effort browser open; the URL is always printed as the fallback. */
196
- function openBrowser(url) {
197
- var _a;
198
- const command = process.platform === "darwin"
199
- ? { cmd: "open", args: [url] }
200
- : process.platform === "win32"
201
- ? {
202
- cmd: join((_a = process.env.SYSTEMROOT) !== null && _a !== void 0 ? _a : "C:\\Windows", "System32", "WindowsPowerShell", "v1.0", "powershell.exe"),
203
- args: [
204
- "-NoProfile",
205
- "-NonInteractive",
206
- "-WindowStyle",
207
- "Hidden",
208
- "-Command",
209
- `Start-Process '${url.replace(/'/g, "''")}'`,
210
- ],
211
- }
212
- : { cmd: "xdg-open", args: [url] };
213
- try {
214
- const child = spawn(command.cmd, command.args, {
215
- stdio: "ignore",
216
- detached: true,
217
- });
218
- child.on("error", () => { });
219
- child.unref();
220
- }
221
- catch (_b) {
222
- // The printed URL is the fallback.
223
- }
224
- }
225
197
  function describeError(error) {
226
198
  return error instanceof Error ? error.message : String(error);
227
199
  }
@@ -8,19 +8,45 @@
8
8
  * `hosting` manifest block), call the management API through
9
9
  * `deploy-client.ts`, poll status, and render.
10
10
  */
11
+ import { AgentServeDeployClient } from "./deploy-client.js";
12
+ import { type GitRunner } from "./deploy-source.js";
13
+ import { type ChildAgentDir } from "./discovery.js";
14
+ /** One agent directory selected for deploy (single or multi-agent parent). */
15
+ export type DeployTarget = ChildAgentDir;
16
+ /**
17
+ * Interactive / test seam: pick which agents under a multi-agent parent to
18
+ * deploy. Return `null` to cancel.
19
+ */
20
+ export type ChooseDeployTargets = (agents: readonly DeployTarget[]) => Promise<DeployTarget[] | null>;
11
21
  export interface DeployCliOptions {
12
22
  dir?: string;
13
23
  slug?: string;
24
+ /**
25
+ * deploy `--all`: when `--dir` is a multi-agent parent, deploy every
26
+ * child agent (skips the interactive picker).
27
+ */
28
+ all?: boolean;
14
29
  /** `--team <id>`; resolved from the account when omitted. */
15
30
  team?: string;
16
31
  json?: boolean;
17
32
  noWait?: boolean;
18
33
  apiKey?: string;
19
- /** deploy `--repo <url>`: https git repo the control plane builds from. */
34
+ /**
35
+ * deploy `--repo <url>`: https git repo the control plane builds from.
36
+ * Optional — inferred from `git remote origin` when omitted inside an
37
+ * agent project checkout.
38
+ */
20
39
  repo?: string;
21
- /** deploy `--ref <ref>`: git ref (defaults to the default branch server-side). */
40
+ /**
41
+ * deploy `--ref <ref>`: git ref to build. Optional — inferred from the
42
+ * current branch (or HEAD SHA if detached) when omitted; otherwise the
43
+ * server uses the repo's default branch.
44
+ */
22
45
  ref?: string;
23
- /** deploy `--path <agentPath>`: agent directory relative to the repo root. */
46
+ /**
47
+ * deploy `--path <agentPath>`: agent directory relative to the repo root.
48
+ * Optional — inferred from `--dir` vs the git toplevel when omitted.
49
+ */
24
50
  path?: string;
25
51
  /** deploy `--cursor-events-repo <owner/name>` (repeatable). */
26
52
  cursorEventsRepos?: string[];
@@ -28,6 +54,10 @@ export interface DeployCliOptions {
28
54
  allowDomains?: string[];
29
55
  /** Test seams. */
30
56
  fetchImpl?: typeof fetch;
57
+ /** Inject git probing for deploy source inference (tests). */
58
+ git?: GitRunner;
59
+ /** Inject the multi-agent picker (tests / non-interactive hosts). */
60
+ chooseTargets?: ChooseDeployTargets;
31
61
  pollIntervalMs?: number;
32
62
  timeoutMs?: number;
33
63
  out?: (text: string) => void;
@@ -40,7 +70,33 @@ export type SecretInputStream = NodeJS.ReadableStream & {
40
70
  isTTY?: boolean;
41
71
  setRawMode?: (mode: boolean) => void;
42
72
  };
73
+ export interface ResolveDeployAuthOptions {
74
+ team?: string;
75
+ apiKey?: string;
76
+ fetchImpl?: typeof fetch;
77
+ /** Quiet team-resolution chatter (default: write to stderr). */
78
+ err?: (text: string) => void;
79
+ }
80
+ export interface ResolvedDeployAuth {
81
+ client: AgentServeDeployClient;
82
+ teamId: number;
83
+ }
84
+ /**
85
+ * Credentials → deploy client → team id. Shared by deploy commands and
86
+ * `--prod` AX routing. Returns an exit code (error already rendered) on
87
+ * failure.
88
+ */
89
+ export declare function resolveDeployAuth(options: ResolveDeployAuthOptions): Promise<ResolvedDeployAuth | number>;
43
90
  export declare function cmdDeploy(options: DeployCliOptions): Promise<number>;
91
+ /**
92
+ * TTY picker for multi-agent parents. Non-interactive callers get `[]`
93
+ * so {@link resolveDeployTargets} can print the --slug/--all hint.
94
+ */
95
+ export declare function promptChooseDeployTargets(agents: readonly DeployTarget[], options: {
96
+ err: (text: string) => void;
97
+ stdin: SecretInputStream;
98
+ interactive: boolean;
99
+ }): Promise<DeployTarget[] | null>;
44
100
  export declare function cmdDeployments(options: DeployCliOptions): Promise<number>;
45
101
  export declare function cmdDeploymentStatus(slug: string | undefined, options: DeployCliOptions): Promise<number>;
46
102
  export declare function cmdStop(slug: string | undefined, options: DeployCliOptions): Promise<number>;
@@ -1 +1 @@
1
- {"version":3,"file":"cli-deploy.d.ts","sourceRoot":"","sources":["../../src/internal/cli-deploy.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAkCH,MAAM,WAAW,gBAAgB;IAC/B,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,6DAA6D;IAC7D,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,OAAO,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,2EAA2E;IAC3E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,8EAA8E;IAC9E,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC7B,gFAAgF;IAChF,YAAY,CAAC,EAAE,MAAM,EAAE,CAAC;IACxB,kBAAkB;IAClB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IAC7B,2EAA2E;IAC3E,KAAK,CAAC,EAAE,iBAAiB,CAAC;CAC3B;AAED,+EAA+E;AAC/E,MAAM,MAAM,iBAAiB,GAAG,MAAM,CAAC,cAAc,GAAG;IACtD,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,OAAO,KAAK,IAAI,CAAC;CACtC,CAAC;AA8FF,wBAAsB,SAAS,CAAC,OAAO,EAAE,gBAAgB,GAAG,OAAO,CAAC,MAAM,CAAC,CAmI1E;AA6CD,wBAAsB,cAAc,CAClC,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAkCjB;AAMD,wBAAsB,mBAAmB,CACvC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAyEjB;AAMD,wBAAsB,OAAO,CAC3B,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAqCjB;AAMD,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CA4BjB;AAMD,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAMD,wBAAsB,aAAa,CACjC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,KAAK,EAAE,MAAM,EAAE,EACf,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAgEjB;AAED,wBAAsB,cAAc,CAClC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CAkCjB;AAED,wBAAsB,eAAe,CACnC,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,MAAM,CAAC,CA4BjB"}
1
+ {"version":3,"file":"cli-deploy.d.ts","sourceRoot":"","sources":["../../src/internal/cli-deploy.ts"],"names":[],"mappings":"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"}
@@ -19,30 +19,37 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
19
19
  };
20
20
  import { basename, resolve } from "node:path";
21
21
  import { CursorBackendClient } from "./cursor/backend-client.js";
22
- import { cursorBackendUrl, resolveApiKey, SIGN_IN_HINT, } from "./cursor/credentials.js";
22
+ import { cursorExternalApiUrl, resolveApiKey, SIGN_IN_HINT, } from "./cursor/credentials.js";
23
23
  import { AgentServeDeployClient, DeployApiError, slugFromDirectoryName, TERMINAL_DEPLOY_STATUSES, validateDeploymentSlug, } from "./deploy-client.js";
24
- import { isAgentProjectDir, loadAgentProject } from "./discovery.js";
24
+ import { inferDeployGitSource } from "./deploy-source.js";
25
+ import { isAgentProjectDir, listChildAgentDirs, loadAgentProject, } from "./discovery.js";
25
26
  import { CLI_COMMAND_NAME as CLI } from "./distribution.js";
26
27
  import { isValidCursorEventRepo, validateSettableSecretName, } from "./hosting.js";
28
+ import { stderrPalette } from "./terminal-style.js";
27
29
  const DEFAULT_POLL_INTERVAL_MS = 3000;
28
30
  const DEFAULT_DEPLOY_TIMEOUT_MS = 10 * 60 * 1000;
29
31
  /**
30
- * Shared preamble: credentials client → team id. Returns an exit code
31
- * (with the error already rendered) when resolution fails.
32
+ * Credentials deploy client → team id. Shared by deploy commands and
33
+ * `--prod` AX routing. Returns an exit code (error already rendered) on
34
+ * failure.
32
35
  */
33
- function prepare(options) {
36
+ export function resolveDeployAuth(options) {
34
37
  return __awaiter(this, void 0, void 0, function* () {
35
- var _a, _b, _c, _d;
36
- const out = (_a = options.out) !== null && _a !== void 0 ? _a : ((text) => void process.stdout.write(text));
37
- const err = (_b = options.err) !== null && _b !== void 0 ? _b : ((text) => void process.stderr.write(text));
38
+ var _a;
39
+ const err = (_a = options.err) !== null && _a !== void 0 ? _a : ((text) => void process.stderr.write(text));
38
40
  const resolved = yield resolveApiKey(options.apiKey === undefined ? undefined : { apiKey: options.apiKey });
39
41
  if (resolved === undefined) {
40
42
  err(`Not signed in to Cursor. ${SIGN_IN_HINT}\n`);
41
43
  return 1;
42
44
  }
43
- const client = new AgentServeDeployClient(Object.assign({ backendUrl: resolved.backendUrl, apiKey: resolved.apiKey }, (options.fetchImpl === undefined
44
- ? {}
45
- : { fetchImpl: options.fetchImpl })));
45
+ // The deployment management routes live on the external API host
46
+ // (api.cursor.com), not the default backend (api2.cursor.sh) — see
47
+ // cursorExternalApiUrl. GetMe below stays on the resolved backend.
48
+ const client = new AgentServeDeployClient({
49
+ backendUrl: cursorExternalApiUrl(),
50
+ apiKey: resolved.apiKey,
51
+ fetchImpl: options.fetchImpl,
52
+ });
46
53
  let teamId;
47
54
  if (options.team !== undefined) {
48
55
  teamId = Number.parseInt(options.team, 10);
@@ -52,9 +59,11 @@ function prepare(options) {
52
59
  }
53
60
  }
54
61
  else {
55
- const account = new CursorBackendClient(Object.assign({ backendUrl: resolved.backendUrl, apiKey: resolved.apiKey }, (options.fetchImpl === undefined
56
- ? {}
57
- : { fetchImpl: options.fetchImpl })));
62
+ const account = new CursorBackendClient({
63
+ backendUrl: resolved.backendUrl,
64
+ apiKey: resolved.apiKey,
65
+ fetchImpl: options.fetchImpl,
66
+ });
58
67
  let identity;
59
68
  try {
60
69
  identity = yield account.getMe();
@@ -68,11 +77,33 @@ function prepare(options) {
68
77
  return 1;
69
78
  }
70
79
  teamId = identity.teamId;
71
- err(`Using team ${teamId}${identity.teamName === undefined ? "" : ` (${identity.teamName})`} — the account's team; pass --team to override.\n`);
80
+ const dim = stderrPalette().dim;
81
+ err(`${dim(`Using team ${teamId}${identity.teamName === undefined ? "" : ` (${identity.teamName})`} — the account's team; pass --team to override.`)}\n`);
82
+ }
83
+ return { client, teamId };
84
+ });
85
+ }
86
+ /**
87
+ * Shared preamble: credentials → client → team id. Returns an exit code
88
+ * (with the error already rendered) when resolution fails.
89
+ */
90
+ function prepare(options) {
91
+ return __awaiter(this, void 0, void 0, function* () {
92
+ var _a, _b, _c, _d;
93
+ const out = (_a = options.out) !== null && _a !== void 0 ? _a : ((text) => void process.stdout.write(text));
94
+ const err = (_b = options.err) !== null && _b !== void 0 ? _b : ((text) => void process.stderr.write(text));
95
+ const auth = yield resolveDeployAuth({
96
+ team: options.team,
97
+ apiKey: options.apiKey,
98
+ fetchImpl: options.fetchImpl,
99
+ err,
100
+ });
101
+ if (typeof auth === "number") {
102
+ return auth;
72
103
  }
73
104
  return {
74
- client,
75
- teamId,
105
+ client: auth.client,
106
+ teamId: auth.teamId,
76
107
  json: options.json === true,
77
108
  noWait: options.noWait === true,
78
109
  pollIntervalMs: (_c = options.pollIntervalMs) !== null && _c !== void 0 ? _c : DEFAULT_POLL_INTERVAL_MS,
@@ -87,54 +118,293 @@ function prepare(options) {
87
118
  // ============================================================================
88
119
  export function cmdDeploy(options) {
89
120
  return __awaiter(this, void 0, void 0, function* () {
90
- var _a, _b, _c, _d;
91
121
  const ctx = yield prepare(options);
92
122
  if (typeof ctx === "number") {
93
123
  return ctx;
94
124
  }
125
+ const targets = yield resolveDeployTargets(options, ctx);
126
+ if (typeof targets === "number") {
127
+ return targets;
128
+ }
129
+ // --path is per-agent (relative to the repo root). When deploying several
130
+ // agents, ignore a shared --path so each target can infer its own path.
131
+ let deployOptions = options;
132
+ if (targets.length > 1 && options.path !== undefined) {
133
+ if (!ctx.json) {
134
+ ctx.err(`warning: ignoring --path ${JSON.stringify(options.path)} for a multi-agent deploy; each agent infers its own path from git.\n`);
135
+ }
136
+ deployOptions = Object.assign(Object.assign({}, options), { path: undefined });
137
+ }
138
+ if (targets.length === 1) {
139
+ return deployOne(ctx, deployOptions, targets[0]);
140
+ }
141
+ // Multi-agent batch: deploy sequentially; --json emits an array.
142
+ const jsonResults = [];
143
+ let failures = 0;
144
+ for (const [index, target] of targets.entries()) {
145
+ if (!ctx.json) {
146
+ ctx.err(`\n=== [${index + 1}/${targets.length}] Deploying ${target.slug} ===\n`);
147
+ }
148
+ const before = jsonResults.length;
149
+ const code = yield deployOne(ctx, deployOptions, target, {
150
+ jsonCollect: ctx.json ? jsonResults : undefined,
151
+ });
152
+ if (code !== 0) {
153
+ failures += 1;
154
+ if (ctx.json && jsonResults.length === before) {
155
+ jsonResults.push({ slug: target.slug, error: "deploy failed" });
156
+ }
157
+ }
158
+ }
159
+ if (ctx.json) {
160
+ ctx.out(`${JSON.stringify(jsonResults, null, 2)}\n`);
161
+ }
162
+ else if (failures > 0) {
163
+ ctx.err(`\n${failures} of ${targets.length} deploy(s) failed.\n`);
164
+ }
165
+ else {
166
+ ctx.err(`\nDeployed ${targets.length} agents.\n`);
167
+ }
168
+ return failures === 0 ? 0 : 1;
169
+ });
170
+ }
171
+ /**
172
+ * Resolve which agent directory(ies) to deploy from `--dir` / `--slug` /
173
+ * `--all`, with an interactive picker when a multi-agent parent is on a TTY.
174
+ */
175
+ function resolveDeployTargets(options, ctx) {
176
+ return __awaiter(this, void 0, void 0, function* () {
177
+ var _a, _b;
95
178
  const dir = resolve((_a = options.dir) !== null && _a !== void 0 ? _a : ".");
96
- let slug;
97
179
  if (options.slug !== undefined) {
98
180
  const slugError = validateDeploymentSlug(options.slug);
99
181
  if (slugError !== undefined) {
100
182
  ctx.err(`${slugError}\n`);
101
183
  return 1;
102
184
  }
103
- slug = options.slug;
104
185
  }
105
- else {
106
- const derived = slugFromDirectoryName(basename(dir));
107
- if (derived === undefined) {
108
- ctx.err(`Could not derive a deployment slug from the directory name ${JSON.stringify(basename(dir))}; pass --slug.\n`);
186
+ if (options.all === true && options.slug !== undefined) {
187
+ ctx.err("Pass either --slug or --all, not both.\n");
188
+ return 1;
189
+ }
190
+ if (yield isAgentProjectDir(dir)) {
191
+ if (options.all === true) {
192
+ ctx.err(`--all requires a multi-agent parent directory (several child agents under --dir); ${dir} is a single agent project.\n`);
109
193
  return 1;
110
194
  }
111
- slug = derived;
112
- ctx.err(`Deploying as "${slug}" (from the directory name).\n`);
195
+ let slug;
196
+ if (options.slug !== undefined) {
197
+ slug = options.slug;
198
+ }
199
+ else {
200
+ const derived = slugFromDirectoryName(basename(dir));
201
+ if (derived === undefined) {
202
+ ctx.err(`Could not derive a deployment slug from the directory name ${JSON.stringify(basename(dir))}; pass --slug.\n`);
203
+ return 1;
204
+ }
205
+ slug = derived;
206
+ if (!ctx.json) {
207
+ ctx.err(`Deploying as "${slug}" (from the directory name).\n`);
208
+ }
209
+ }
210
+ return [{ slug, dir }];
211
+ }
212
+ let children;
213
+ try {
214
+ children = yield listChildAgentDirs(dir);
215
+ }
216
+ catch (error) {
217
+ ctx.err(`${describeError(error)}\n`);
218
+ return 1;
219
+ }
220
+ // Deploy slugs are lowercase-only; normalize directory names the same way
221
+ // single-agent deploy does so MixedCase child dirs still deploy.
222
+ children = children.flatMap((child) => {
223
+ const slug = slugFromDirectoryName(basename(child.dir));
224
+ if (slug === undefined) {
225
+ return [];
226
+ }
227
+ return [{ slug, dir: child.dir }];
228
+ });
229
+ if (children.length === 0) {
230
+ if (options.all === true) {
231
+ ctx.err(`--all requires child agent projects under --dir; none found in ${dir}.\n`);
232
+ return 1;
233
+ }
234
+ // Static / bare-slug deploy against a non-agent directory.
235
+ let slug;
236
+ if (options.slug !== undefined) {
237
+ slug = options.slug;
238
+ }
239
+ else {
240
+ const derived = slugFromDirectoryName(basename(dir));
241
+ if (derived === undefined) {
242
+ ctx.err(`No agent projects under ${dir}, and could not derive a slug from ${JSON.stringify(basename(dir))}; pass --slug or --dir <agent>.\n`);
243
+ return 1;
244
+ }
245
+ slug = derived;
246
+ if (!ctx.json) {
247
+ ctx.err(`Deploying as "${slug}" (static; no agent project at ${dir}).\n`);
248
+ }
249
+ }
250
+ return [{ slug, dir }];
251
+ }
252
+ if (children.length === 1) {
253
+ const only = children[0];
254
+ if (options.all === true) {
255
+ // One child is fine for --all (degenerate multi-agent parent).
256
+ }
257
+ else if (options.slug !== undefined &&
258
+ options.slug.toLowerCase() !== only.slug) {
259
+ ctx.err(`No agent "${options.slug}" under ${dir}; found "${only.slug}".\n`);
260
+ return 1;
261
+ }
262
+ if (!ctx.json) {
263
+ ctx.err(`Deploying "${only.slug}" (only agent under ${basename(dir)}).\n`);
264
+ }
265
+ return [only];
266
+ }
267
+ // Multiple children.
268
+ if (options.all === true) {
269
+ if (!ctx.json) {
270
+ ctx.err(`Deploying all ${children.length} agents under ${basename(dir)}: ${children.map((c) => c.slug).join(", ")}.\n`);
271
+ }
272
+ return [...children];
273
+ }
274
+ if (options.slug !== undefined) {
275
+ const wanted = options.slug.toLowerCase();
276
+ const match = children.find((child) => child.slug === wanted);
277
+ if (match === undefined) {
278
+ ctx.err(`No agent "${options.slug}" under ${dir}.\n` +
279
+ formatAgentList(children) +
280
+ `Pass --slug <name> or --all.\n`);
281
+ return 1;
282
+ }
283
+ return [match];
284
+ }
285
+ const chooser = (_b = options.chooseTargets) !== null && _b !== void 0 ? _b : ((agents) => { var _a, _b; return promptChooseDeployTargets(agents, {
286
+ err: ctx.err,
287
+ stdin: (_a = options.stdin) !== null && _a !== void 0 ? _a : process.stdin,
288
+ interactive: ctx.json !== true &&
289
+ ((_b = options.stdin) !== null && _b !== void 0 ? _b : process.stdin).isTTY === true &&
290
+ process.stderr.isTTY === true,
291
+ }); });
292
+ const chosen = yield chooser(children);
293
+ if (chosen === null) {
294
+ ctx.err("Deploy cancelled.\n");
295
+ return 1;
296
+ }
297
+ if (chosen.length === 0) {
298
+ ctx.err(`Multiple agents under ${dir}:\n` +
299
+ formatAgentList(children) +
300
+ `Pass --slug <name> or --all (or re-run on a TTY to pick interactively).\n`);
301
+ return 1;
113
302
  }
114
- if (options.repo !== undefined && !options.repo.startsWith("https://")) {
115
- ctx.err(`Invalid --repo: ${options.repo} (expected an https:// git repository URL)\n`);
303
+ return chosen;
304
+ });
305
+ }
306
+ function formatAgentList(agents) {
307
+ return agents.map((agent, i) => ` ${i + 1}) ${agent.slug}\n`).join("");
308
+ }
309
+ /**
310
+ * TTY picker for multi-agent parents. Non-interactive callers get `[]`
311
+ * so {@link resolveDeployTargets} can print the --slug/--all hint.
312
+ */
313
+ export function promptChooseDeployTargets(agents, options) {
314
+ return __awaiter(this, void 0, void 0, function* () {
315
+ var _a, _b, _c;
316
+ options.err(`Multiple agents (${agents.length}):\n` +
317
+ formatAgentList(agents) +
318
+ ` a) all\n`);
319
+ if (!options.interactive) {
320
+ return [];
321
+ }
322
+ options.err('Deploy which? Enter a number, slug, "all", or "q" to cancel: ');
323
+ const readLine = createLineReader(options.stdin);
324
+ // createLineReader pauses until data; ensure stdin is flowing on a TTY.
325
+ (_b = (_a = options.stdin).resume) === null || _b === void 0 ? void 0 : _b.call(_a);
326
+ const answer = (_c = (yield readLine())) === null || _c === void 0 ? void 0 : _c.trim().toLowerCase();
327
+ if (answer === undefined || answer === "q" || answer === "quit") {
328
+ return null;
329
+ }
330
+ if (answer === "a" || answer === "all" || answer === "*") {
331
+ return [...agents];
332
+ }
333
+ const asIndex = Number.parseInt(answer, 10);
334
+ if (!Number.isNaN(asIndex) &&
335
+ String(asIndex) === answer &&
336
+ asIndex >= 1 &&
337
+ asIndex <= agents.length) {
338
+ return [agents[asIndex - 1]];
339
+ }
340
+ const bySlug = agents.find((agent) => agent.slug.toLowerCase() === answer);
341
+ if (bySlug !== undefined) {
342
+ return [bySlug];
343
+ }
344
+ options.err(`Unrecognized choice ${JSON.stringify(answer)} — expected 1–${agents.length}, a slug, "all", or "q". Aborting.\n`);
345
+ return null;
346
+ });
347
+ }
348
+ function deployOne(ctx, options, target, extras) {
349
+ return __awaiter(this, void 0, void 0, function* () {
350
+ var _a, _b, _c, _d, _e, _f;
351
+ const { dir, slug } = target;
352
+ // Fill --repo/--ref/--path from the local git checkout when omitted so
353
+ // `agentkit deploy` inside an agent directory is enough. Only probe git
354
+ // for real agent projects (avoids ambient monorepo remotes when someone
355
+ // deploys a bare --slug). Explicit flags always win.
356
+ const isAgent = yield isAgentProjectDir(dir);
357
+ const needsGitInference = isAgent &&
358
+ (options.repo === undefined ||
359
+ options.ref === undefined ||
360
+ options.path === undefined);
361
+ const inferred = needsGitInference
362
+ ? yield inferDeployGitSource(dir, Object.assign({}, (options.git === undefined ? {} : { git: options.git })))
363
+ : {};
364
+ const gitRepoUrl = (_a = options.repo) !== null && _a !== void 0 ? _a : inferred.gitRepoUrl;
365
+ const gitRef = (_b = options.ref) !== null && _b !== void 0 ? _b : inferred.gitRef;
366
+ const agentPath = (_c = options.path) !== null && _c !== void 0 ? _c : inferred.agentPath;
367
+ if (gitRepoUrl !== undefined && !gitRepoUrl.startsWith("https://")) {
368
+ ctx.err(`Invalid --repo: ${gitRepoUrl} (expected an https:// git repository URL)\n`);
116
369
  return 1;
117
370
  }
118
- for (const repo of (_b = options.cursorEventsRepos) !== null && _b !== void 0 ? _b : []) {
371
+ for (const repo of (_d = options.cursorEventsRepos) !== null && _d !== void 0 ? _d : []) {
119
372
  if (!isValidCursorEventRepo(repo)) {
120
373
  ctx.err(`Invalid --cursor-events-repo: ${repo} (expected owner/name)\n`);
121
374
  return 1;
122
375
  }
123
376
  }
377
+ if (!ctx.json && gitRepoUrl !== undefined) {
378
+ const inferredBits = [];
379
+ if (options.repo === undefined && inferred.gitRepoUrl !== undefined) {
380
+ inferredBits.push("repo");
381
+ }
382
+ if (options.ref === undefined && inferred.gitRef !== undefined) {
383
+ inferredBits.push("ref");
384
+ }
385
+ if (options.path === undefined && inferred.agentPath !== undefined) {
386
+ inferredBits.push("path");
387
+ }
388
+ ctx.err(` source: ${gitRepoUrl}${gitRef === undefined ? "" : ` @ ${gitRef}`}\n` +
389
+ (agentPath === undefined ? "" : ` path: ${agentPath}\n`) +
390
+ (inferredBits.length === 0
391
+ ? ""
392
+ : ` (inferred ${inferredBits.join(", ")} from git; pass --repo/--ref/--path to override)\n`));
393
+ }
124
394
  // The package manifest (`defineAgent({ hosting })`) is the source of
125
395
  // truth for egress domains and expected secret names; flags override or
126
396
  // augment it. Directories without an agent project (static placeholder
127
397
  // deploys) simply have no manifest.
128
- const hosting = yield readHostingManifest(dir);
398
+ const hosting = isAgent ? yield readHostingManifest(dir) : undefined;
129
399
  const egressAllowedDomains = [
130
400
  ...new Set([
131
- ...((_c = hosting === null || hosting === void 0 ? void 0 : hosting.egressDomains) !== null && _c !== void 0 ? _c : []),
132
- ...((_d = options.allowDomains) !== null && _d !== void 0 ? _d : []),
401
+ ...((_e = hosting === null || hosting === void 0 ? void 0 : hosting.egressDomains) !== null && _e !== void 0 ? _e : []),
402
+ ...((_f = options.allowDomains) !== null && _f !== void 0 ? _f : []),
133
403
  ]),
134
404
  ];
135
405
  // Today's only source shape: the control plane builds from a git ref (or
136
406
  // serves the static placeholder). See DeploySource for the artifact seam.
137
- const source = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "git-ref" }, (options.repo === undefined ? {} : { gitRepoUrl: options.repo })), (options.ref === undefined ? {} : { gitRef: options.ref })), (options.path === undefined ? {} : { agentPath: options.path })), (options.cursorEventsRepos === undefined ||
407
+ const source = Object.assign(Object.assign(Object.assign(Object.assign(Object.assign({ kind: "git-ref" }, (gitRepoUrl === undefined ? {} : { gitRepoUrl })), (gitRef === undefined ? {} : { gitRef })), (agentPath === undefined ? {} : { agentPath })), (options.cursorEventsRepos === undefined ||
138
408
  options.cursorEventsRepos.length === 0
139
409
  ? {}
140
410
  : { cursorEventRepos: options.cursorEventsRepos })), (egressAllowedDomains.length === 0 ? {} : { egressAllowedDomains }));
@@ -150,7 +420,10 @@ export function cmdDeploy(options) {
150
420
  ctx.out(aliasTokenBlock(accepted.aliasToken));
151
421
  }
152
422
  if (ctx.noWait) {
153
- if (ctx.json) {
423
+ if ((extras === null || extras === void 0 ? void 0 : extras.jsonCollect) !== undefined) {
424
+ extras.jsonCollect.push(accepted);
425
+ }
426
+ else if (ctx.json) {
154
427
  ctx.out(`${JSON.stringify(accepted, null, 2)}\n`);
155
428
  }
156
429
  else {
@@ -168,10 +441,15 @@ export function cmdDeploy(options) {
168
441
  return renderApiError(error, ctx.err);
169
442
  }
170
443
  warnMissingSecrets(ctx, slug, hosting === null || hosting === void 0 ? void 0 : hosting.secretNames, detail.secretNames);
444
+ const payload = accepted.aliasToken === undefined
445
+ ? detail
446
+ : Object.assign(Object.assign({}, detail), { aliasToken: accepted.aliasToken });
447
+ if ((extras === null || extras === void 0 ? void 0 : extras.jsonCollect) !== undefined) {
448
+ extras.jsonCollect.push(payload);
449
+ return detail.status === "running" ? 0 : 1;
450
+ }
171
451
  if (ctx.json) {
172
- ctx.out(`${JSON.stringify(accepted.aliasToken === undefined
173
- ? detail
174
- : Object.assign(Object.assign({}, detail), { aliasToken: accepted.aliasToken }), null, 2)}\n`);
452
+ ctx.out(`${JSON.stringify(payload, null, 2)}\n`);
175
453
  return detail.status === "running" ? 0 : 1;
176
454
  }
177
455
  if (detail.status !== "running") {
@@ -185,7 +463,7 @@ export function cmdDeploy(options) {
185
463
  ` generation: ${detail.generation}\n` +
186
464
  ` kind: ${detail.deploymentKind}\n` +
187
465
  ` alias: ${aliasUrl}\n` +
188
- ` playground: ${aliasUrl}/playground (send X-Agent-Alias-Token)\n`);
466
+ ` playground: ${CLI} playground --prod --slug ${slug} --team ${ctx.teamId}\n`);
189
467
  return 0;
190
468
  });
191
469
  }