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