@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.
- 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 +389 -152
- package/dist/docs/404.html +2 -2
- package/dist/docs/ab.html +3 -3
- package/dist/docs/assets/{app.Oje4vhlk.js → app.BR0RbIdx.js} +1 -1
- package/dist/docs/assets/chunks/@localSearchIndexroot.DtIOQzGj.js +1 -0
- package/dist/docs/assets/chunks/{VPLocalSearchBox.H5XZ2zCB.js → VPLocalSearchBox.qjsVTneI.js} +1 -1
- package/dist/docs/assets/chunks/{theme.CTR_TuaE.js → theme.2Kg8jIp_.js} +2 -2
- 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 +3 -3
- 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/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 +75 -2
- package/dist/internal/cli-ax.d.ts.map +1 -1
- package/dist/internal/cli-ax.js +600 -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/cursor/credentials.d.ts +9 -0
- package/dist/internal/cursor/credentials.d.ts.map +1 -1
- package/dist/internal/cursor/credentials.js +12 -0
- 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/eval-run-store.d.ts.map +1 -1
- package/dist/internal/eval-run-store.js +2 -1
- 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/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/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 +16 -11
- 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/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 +42 -0
- package/dist/internal/resolve-prod-target.d.ts.map +1 -0
- package/dist/internal/resolve-prod-target.js +111 -0
- 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/server.d.ts.map +1 -1
- package/dist/internal/server.js +10 -4
- 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 +21 -6
- package/dist/internal/sessions-client.d.ts +21 -0
- package/dist/internal/sessions-client.d.ts.map +1 -0
- package/dist/internal/sessions-client.js +168 -0
- 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/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-D-vo2lV_.css +1 -0
- package/dist/playground/assets/index-x60b9q2j.js +312 -0
- package/dist/playground/index.html +2 -2
- package/dist/types.d.ts +26 -1
- package/dist/types.d.ts.map +1 -1
- package/docs/quickstart.md +22 -7
- package/docs/reference/cli.md +51 -3
- package/package.json +3 -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 +13 -13
- package/src/bin/agent-serve.ts +422 -188
- package/src/internal/chat-client.ts +252 -37
- package/src/internal/cli-ax.ts +722 -72
- package/src/internal/cli-cursor.ts +14 -42
- package/src/internal/cli-deploy.ts +428 -49
- package/src/internal/cursor/credentials.ts +14 -0
- 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/eval-run-store.ts +2 -1
- package/src/internal/eval-runner.ts +5 -0
- package/src/internal/event-mapper.ts +222 -42
- 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/open-browser.ts +41 -0
- package/src/internal/playground/toolchain.ts +15 -13
- package/src/internal/playground-proxy.ts +576 -0
- package/src/internal/prompt-context.ts +95 -0
- package/src/internal/request-headers.ts +23 -0
- package/src/internal/resolve-prod-target.ts +150 -0
- package/src/internal/run-client.ts +39 -36
- package/src/internal/server.ts +12 -3
- package/src/internal/session-engine.ts +22 -3
- package/src/internal/sessions-client.ts +182 -0
- 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/workspace.ts +42 -4
- package/src/types.ts +42 -6
- 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/{quickstart.md.CfU8_uTC.lean.js → quickstart.md.BU6Iwi_9.lean.js} +0 -0
|
@@ -0,0 +1,468 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Loopback reverse proxy that injects engine / bearer auth so a normal
|
|
3
|
+
* browser can use the hosted (or remote) playground SPA.
|
|
4
|
+
*
|
|
5
|
+
* Hosted engines sit behind short-lived `engineAccess` headers that a
|
|
6
|
+
* browser cannot set; alias tokens are header-only too. This proxy binds
|
|
7
|
+
* `127.0.0.1` only and forwards every request upstream with those headers.
|
|
8
|
+
*
|
|
9
|
+
* Access is gated by a per-proxy `accessToken` (query on first hit → HttpOnly
|
|
10
|
+
* cookie): other local processes cannot upgrade to injected credentials just
|
|
11
|
+
* by knowing the port. Mutating requests also require Origin/Referer to match
|
|
12
|
+
* this proxy's own origin so another `http://127.0.0.1:<port>` page cannot
|
|
13
|
+
* CSRF the cookie (cookies are host-scoped across ports). Absolute-form
|
|
14
|
+
* request-targets are rejected so injected headers never leave the configured
|
|
15
|
+
* upstream.
|
|
16
|
+
*
|
|
17
|
+
* When `refreshUpstream` is provided (hosted `--prod`), credentials are
|
|
18
|
+
* re-minted shortly before `expiresAt` and once on upstream 401 so a long
|
|
19
|
+
* playground session does not require restarting the CLI.
|
|
20
|
+
*/
|
|
21
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
22
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
23
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
24
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
25
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
26
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
27
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
28
|
+
});
|
|
29
|
+
};
|
|
30
|
+
var __asyncValues = (this && this.__asyncValues) || function (o) {
|
|
31
|
+
if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined.");
|
|
32
|
+
var m = o[Symbol.asyncIterator], i;
|
|
33
|
+
return m ? m.call(o) : (o = typeof __values === "function" ? __values(o) : o[Symbol.iterator](), i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i);
|
|
34
|
+
function verb(n) { i[n] = o[n] && function (v) { return new Promise(function (resolve, reject) { v = o[n](v), settle(resolve, reject, v.done, v.value); }); }; }
|
|
35
|
+
function settle(resolve, reject, d, v) { Promise.resolve(v).then(function(v) { resolve({ value: v, done: d }); }, reject); }
|
|
36
|
+
};
|
|
37
|
+
import { randomBytes } from "node:crypto";
|
|
38
|
+
import { createServer, request as httpRequest, } from "node:http";
|
|
39
|
+
import { request as httpsRequest } from "node:https";
|
|
40
|
+
import { URL } from "node:url";
|
|
41
|
+
import { openBrowser } from "./open-browser.js";
|
|
42
|
+
export { openBrowser };
|
|
43
|
+
const HOP_BY_HOP = new Set([
|
|
44
|
+
"connection",
|
|
45
|
+
"keep-alive",
|
|
46
|
+
"proxy-authenticate",
|
|
47
|
+
"proxy-authorization",
|
|
48
|
+
"te",
|
|
49
|
+
"trailers",
|
|
50
|
+
"transfer-encoding",
|
|
51
|
+
"upgrade",
|
|
52
|
+
"host",
|
|
53
|
+
"content-length",
|
|
54
|
+
]);
|
|
55
|
+
/** Re-mint when the port token is within this window of expiry. */
|
|
56
|
+
const ACCESS_EXPIRY_LEEWAY_MS = 5 * 60 * 1000;
|
|
57
|
+
const PROXY_COOKIE = "agentkit_playground_proxy";
|
|
58
|
+
const PROXY_TOKEN_QUERY = "proxyToken";
|
|
59
|
+
/**
|
|
60
|
+
* Start a loopback proxy. Resolves once listening.
|
|
61
|
+
*/
|
|
62
|
+
export function startPlaygroundProxy(args) {
|
|
63
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
64
|
+
var _a, _b, _c;
|
|
65
|
+
const upstream = parseUpstreamUrl(args.upstreamUrl);
|
|
66
|
+
const state = {
|
|
67
|
+
upstream,
|
|
68
|
+
injectHeaders: buildInjectHeaders(args.headers, args.bearerToken),
|
|
69
|
+
expiresAtMs: parseExpiresAtMs(args.expiresAt),
|
|
70
|
+
};
|
|
71
|
+
const accessToken = (_a = args.accessToken) !== null && _a !== void 0 ? _a : randomBytes(32).toString("base64url");
|
|
72
|
+
const now = (_b = args.now) !== null && _b !== void 0 ? _b : Date.now;
|
|
73
|
+
let refreshInFlight;
|
|
74
|
+
/** Set after listen; used for Origin CSRF checks. */
|
|
75
|
+
let proxyOrigin = "";
|
|
76
|
+
const ensureFreshAccess = (force) => __awaiter(this, void 0, void 0, function* () {
|
|
77
|
+
if (args.refreshUpstream === undefined) {
|
|
78
|
+
return;
|
|
79
|
+
}
|
|
80
|
+
const expired = state.expiresAtMs !== undefined &&
|
|
81
|
+
now() >= state.expiresAtMs - ACCESS_EXPIRY_LEEWAY_MS;
|
|
82
|
+
if (!force && !expired) {
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
if (refreshInFlight !== undefined) {
|
|
86
|
+
yield refreshInFlight;
|
|
87
|
+
return;
|
|
88
|
+
}
|
|
89
|
+
refreshInFlight = (() => __awaiter(this, void 0, void 0, function* () {
|
|
90
|
+
const next = yield args.refreshUpstream();
|
|
91
|
+
state.upstream = parseUpstreamUrl(next.upstreamUrl);
|
|
92
|
+
state.injectHeaders = buildInjectHeaders(next.headers, args.bearerToken);
|
|
93
|
+
state.expiresAtMs = parseExpiresAtMs(next.expiresAt);
|
|
94
|
+
}))().finally(() => {
|
|
95
|
+
refreshInFlight = undefined;
|
|
96
|
+
});
|
|
97
|
+
yield refreshInFlight;
|
|
98
|
+
});
|
|
99
|
+
const create = (_c = args.createServerImpl) !== null && _c !== void 0 ? _c : createServer;
|
|
100
|
+
const server = create((req, res) => {
|
|
101
|
+
void handleProxyRequest({
|
|
102
|
+
req,
|
|
103
|
+
res,
|
|
104
|
+
getState: () => state,
|
|
105
|
+
ensureFreshAccess,
|
|
106
|
+
canRefresh: args.refreshUpstream !== undefined,
|
|
107
|
+
accessToken,
|
|
108
|
+
proxyOrigin: () => proxyOrigin,
|
|
109
|
+
}).catch((error) => {
|
|
110
|
+
if (res.headersSent) {
|
|
111
|
+
if (!res.writableEnded) {
|
|
112
|
+
res.end();
|
|
113
|
+
}
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
117
|
+
res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
|
|
118
|
+
res.end(`Playground proxy error: ${message}`);
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
yield new Promise((resolve, reject) => {
|
|
122
|
+
var _a;
|
|
123
|
+
server.once("error", reject);
|
|
124
|
+
server.listen((_a = args.port) !== null && _a !== void 0 ? _a : 0, "127.0.0.1", () => {
|
|
125
|
+
server.off("error", reject);
|
|
126
|
+
resolve();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
const address = server.address();
|
|
130
|
+
const localUrl = `http://127.0.0.1:${address.port}`;
|
|
131
|
+
proxyOrigin = localUrl;
|
|
132
|
+
return {
|
|
133
|
+
localUrl,
|
|
134
|
+
port: address.port,
|
|
135
|
+
accessToken,
|
|
136
|
+
playgroundUrl: (sessionId) => {
|
|
137
|
+
const url = new URL(`${localUrl}/playground`);
|
|
138
|
+
url.searchParams.set(PROXY_TOKEN_QUERY, accessToken);
|
|
139
|
+
if (sessionId !== undefined && sessionId.trim() !== "") {
|
|
140
|
+
url.searchParams.set("sessionId", sessionId.trim());
|
|
141
|
+
}
|
|
142
|
+
return url.toString();
|
|
143
|
+
},
|
|
144
|
+
close: () => new Promise((resolve, reject) => {
|
|
145
|
+
// Drop keep-alive / streamed playground connections so Ctrl-C
|
|
146
|
+
// does not hang waiting for active sockets.
|
|
147
|
+
server.closeAllConnections();
|
|
148
|
+
server.close((error) => {
|
|
149
|
+
if (error) {
|
|
150
|
+
reject(error);
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
resolve();
|
|
154
|
+
});
|
|
155
|
+
}),
|
|
156
|
+
};
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
function parseUpstreamUrl(raw) {
|
|
160
|
+
const upstream = new URL(raw.replace(/\/$/, ""));
|
|
161
|
+
if (upstream.protocol !== "http:" && upstream.protocol !== "https:") {
|
|
162
|
+
throw new Error(`Unsupported upstream protocol: ${upstream.protocol}`);
|
|
163
|
+
}
|
|
164
|
+
return upstream;
|
|
165
|
+
}
|
|
166
|
+
function parseExpiresAtMs(expiresAt) {
|
|
167
|
+
if (expiresAt === undefined || expiresAt.trim() === "") {
|
|
168
|
+
return undefined;
|
|
169
|
+
}
|
|
170
|
+
const ms = Date.parse(expiresAt);
|
|
171
|
+
return Number.isFinite(ms) ? ms : undefined;
|
|
172
|
+
}
|
|
173
|
+
function buildInjectHeaders(headers, bearerToken) {
|
|
174
|
+
const out = Object.assign({}, (headers !== null && headers !== void 0 ? headers : {}));
|
|
175
|
+
if (bearerToken !== undefined && bearerToken.trim() !== "") {
|
|
176
|
+
out.authorization = `Bearer ${bearerToken.trim()}`;
|
|
177
|
+
}
|
|
178
|
+
return out;
|
|
179
|
+
}
|
|
180
|
+
function readRequestBody(req) {
|
|
181
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
182
|
+
var _a, req_1, req_1_1;
|
|
183
|
+
var _b, e_1, _c, _d;
|
|
184
|
+
const chunks = [];
|
|
185
|
+
try {
|
|
186
|
+
for (_a = true, req_1 = __asyncValues(req); req_1_1 = yield req_1.next(), _b = req_1_1.done, !_b; _a = true) {
|
|
187
|
+
_d = req_1_1.value;
|
|
188
|
+
_a = false;
|
|
189
|
+
const chunk = _d;
|
|
190
|
+
chunks.push(typeof chunk === "string" ? Buffer.from(chunk) : chunk);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
194
|
+
finally {
|
|
195
|
+
try {
|
|
196
|
+
if (!_a && !_b && (_c = req_1.return)) yield _c.call(req_1);
|
|
197
|
+
}
|
|
198
|
+
finally { if (e_1) throw e_1.error; }
|
|
199
|
+
}
|
|
200
|
+
return Buffer.concat(chunks);
|
|
201
|
+
});
|
|
202
|
+
}
|
|
203
|
+
function handleProxyRequest(args) {
|
|
204
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
205
|
+
var _a, _b;
|
|
206
|
+
const { req, res, getState, ensureFreshAccess, canRefresh, accessToken, proxyOrigin, } = args;
|
|
207
|
+
const pathWithQuery = (_a = req.url) !== null && _a !== void 0 ? _a : "/";
|
|
208
|
+
const pathParse = parseProxyPath(pathWithQuery);
|
|
209
|
+
if (!pathParse.ok) {
|
|
210
|
+
res.writeHead(400, { "content-type": "text/plain; charset=utf-8" });
|
|
211
|
+
res.end("Absolute-form request targets are not allowed");
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
const auth = authorizeLocalRequest({
|
|
215
|
+
pathWithQuery: pathParse.path,
|
|
216
|
+
cookieHeader: req.headers.cookie,
|
|
217
|
+
accessToken,
|
|
218
|
+
});
|
|
219
|
+
if (auth.kind === "deny") {
|
|
220
|
+
res.writeHead(401, { "content-type": "text/plain; charset=utf-8" });
|
|
221
|
+
res.end("Playground proxy requires the session access token");
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (auth.kind === "bootstrap") {
|
|
225
|
+
res.writeHead(302, {
|
|
226
|
+
location: auth.redirectPath,
|
|
227
|
+
"set-cookie": auth.setCookie,
|
|
228
|
+
"cache-control": "no-store",
|
|
229
|
+
});
|
|
230
|
+
res.end();
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
const method = (_b = req.method) !== null && _b !== void 0 ? _b : "GET";
|
|
234
|
+
if (!isTrustedBrowserOrigin({
|
|
235
|
+
method,
|
|
236
|
+
origin: headerString(req.headers.origin),
|
|
237
|
+
referer: headerString(req.headers.referer),
|
|
238
|
+
secFetchSite: headerString(req.headers["sec-fetch-site"]),
|
|
239
|
+
proxyOrigin: proxyOrigin(),
|
|
240
|
+
})) {
|
|
241
|
+
res.writeHead(403, { "content-type": "text/plain; charset=utf-8" });
|
|
242
|
+
res.end("Playground proxy rejected cross-origin request");
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
let body;
|
|
246
|
+
try {
|
|
247
|
+
body = yield readRequestBody(req);
|
|
248
|
+
}
|
|
249
|
+
catch (_c) {
|
|
250
|
+
if (!res.headersSent) {
|
|
251
|
+
res.writeHead(400, { "content-type": "text/plain; charset=utf-8" });
|
|
252
|
+
res.end("Playground proxy failed to read request body");
|
|
253
|
+
}
|
|
254
|
+
return;
|
|
255
|
+
}
|
|
256
|
+
const forward = (state, deferWriteOnUnauthorized) => forwardOnce({
|
|
257
|
+
method,
|
|
258
|
+
pathWithQuery: pathParse.path,
|
|
259
|
+
inboundHeaders: req.headers,
|
|
260
|
+
body,
|
|
261
|
+
state,
|
|
262
|
+
res,
|
|
263
|
+
deferWriteOnUnauthorized,
|
|
264
|
+
});
|
|
265
|
+
try {
|
|
266
|
+
yield ensureFreshAccess(false);
|
|
267
|
+
let status = yield forward(getState(), canRefresh);
|
|
268
|
+
if (status === 401 && canRefresh) {
|
|
269
|
+
yield ensureFreshAccess(true);
|
|
270
|
+
// Retry once; always write this response (even if still 401).
|
|
271
|
+
status = yield forward(getState(), false);
|
|
272
|
+
}
|
|
273
|
+
void status;
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
if (!res.headersSent) {
|
|
277
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
278
|
+
res.writeHead(502, { "content-type": "text/plain; charset=utf-8" });
|
|
279
|
+
res.end(`Playground proxy upstream error: ${message}`);
|
|
280
|
+
}
|
|
281
|
+
else if (!res.writableEnded) {
|
|
282
|
+
res.end();
|
|
283
|
+
}
|
|
284
|
+
}
|
|
285
|
+
});
|
|
286
|
+
}
|
|
287
|
+
/**
|
|
288
|
+
* Cookies are host-scoped across ports on 127.0.0.1, so SameSite=Strict alone
|
|
289
|
+
* does not stop CSRF from another loopback origin. Require the browser's
|
|
290
|
+
* Origin (or Referer / Sec-Fetch-Site: same-origin) to match this proxy for
|
|
291
|
+
* mutating methods. Safe methods stay cookie-gated only (no side effects).
|
|
292
|
+
*/
|
|
293
|
+
function isTrustedBrowserOrigin(args) {
|
|
294
|
+
const method = args.method.toUpperCase();
|
|
295
|
+
if (method === "GET" || method === "HEAD" || method === "OPTIONS") {
|
|
296
|
+
return true;
|
|
297
|
+
}
|
|
298
|
+
if (args.proxyOrigin === "") {
|
|
299
|
+
return false;
|
|
300
|
+
}
|
|
301
|
+
if (args.origin === args.proxyOrigin) {
|
|
302
|
+
return true;
|
|
303
|
+
}
|
|
304
|
+
if (args.referer !== undefined &&
|
|
305
|
+
(args.referer === args.proxyOrigin ||
|
|
306
|
+
args.referer.startsWith(`${args.proxyOrigin}/`))) {
|
|
307
|
+
return true;
|
|
308
|
+
}
|
|
309
|
+
// Some same-origin fetches omit Origin; modern browsers still send this.
|
|
310
|
+
if (args.secFetchSite === "same-origin") {
|
|
311
|
+
return true;
|
|
312
|
+
}
|
|
313
|
+
return false;
|
|
314
|
+
}
|
|
315
|
+
function headerString(value) {
|
|
316
|
+
if (value === undefined) {
|
|
317
|
+
return undefined;
|
|
318
|
+
}
|
|
319
|
+
return Array.isArray(value) ? value[0] : value;
|
|
320
|
+
}
|
|
321
|
+
function authorizeLocalRequest(args) {
|
|
322
|
+
const cookieToken = readCookie(args.cookieHeader, PROXY_COOKIE);
|
|
323
|
+
if (cookieToken === args.accessToken) {
|
|
324
|
+
return { kind: "allow" };
|
|
325
|
+
}
|
|
326
|
+
const url = new URL(args.pathWithQuery, "http://127.0.0.1");
|
|
327
|
+
const queryToken = url.searchParams.get(PROXY_TOKEN_QUERY);
|
|
328
|
+
if (queryToken === args.accessToken) {
|
|
329
|
+
url.searchParams.delete(PROXY_TOKEN_QUERY);
|
|
330
|
+
const redirectPath = `${url.pathname}${url.search}`;
|
|
331
|
+
return {
|
|
332
|
+
kind: "bootstrap",
|
|
333
|
+
redirectPath,
|
|
334
|
+
setCookie: `${PROXY_COOKIE}=${args.accessToken}; Path=/; HttpOnly; SameSite=Strict`,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
return { kind: "deny" };
|
|
338
|
+
}
|
|
339
|
+
function readCookie(header, name) {
|
|
340
|
+
if (header === undefined) {
|
|
341
|
+
return undefined;
|
|
342
|
+
}
|
|
343
|
+
const raw = Array.isArray(header) ? header.join("; ") : header;
|
|
344
|
+
for (const part of raw.split(";")) {
|
|
345
|
+
const trimmed = part.trim();
|
|
346
|
+
const eq = trimmed.indexOf("=");
|
|
347
|
+
if (eq <= 0)
|
|
348
|
+
continue;
|
|
349
|
+
if (trimmed.slice(0, eq) === name) {
|
|
350
|
+
return trimmed.slice(eq + 1);
|
|
351
|
+
}
|
|
352
|
+
}
|
|
353
|
+
return undefined;
|
|
354
|
+
}
|
|
355
|
+
function forwardOnce(args) {
|
|
356
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
357
|
+
const { method, pathWithQuery, inboundHeaders, body, state, res } = args;
|
|
358
|
+
const target = buildTargetUrl(pathWithQuery, state.upstream);
|
|
359
|
+
const outboundHeaders = {};
|
|
360
|
+
for (const [name, value] of Object.entries(inboundHeaders)) {
|
|
361
|
+
if (value === undefined)
|
|
362
|
+
continue;
|
|
363
|
+
const lower = name.toLowerCase();
|
|
364
|
+
if (HOP_BY_HOP.has(lower))
|
|
365
|
+
continue;
|
|
366
|
+
if (lower === "authorization")
|
|
367
|
+
continue;
|
|
368
|
+
// Do not forward the loopback session cookie upstream.
|
|
369
|
+
if (lower === "cookie")
|
|
370
|
+
continue;
|
|
371
|
+
outboundHeaders[name] = value;
|
|
372
|
+
}
|
|
373
|
+
for (const [name, value] of Object.entries(state.injectHeaders)) {
|
|
374
|
+
outboundHeaders[name] = value;
|
|
375
|
+
}
|
|
376
|
+
outboundHeaders.host = target.host;
|
|
377
|
+
outboundHeaders["content-length"] = String(body.byteLength);
|
|
378
|
+
const isHttps = target.protocol === "https:";
|
|
379
|
+
const requestFn = isHttps ? httpsRequest : httpRequest;
|
|
380
|
+
const options = {
|
|
381
|
+
protocol: target.protocol,
|
|
382
|
+
hostname: target.hostname,
|
|
383
|
+
port: target.port === "" ? (isHttps ? 443 : 80) : Number(target.port),
|
|
384
|
+
method,
|
|
385
|
+
path: `${target.pathname}${target.search}`,
|
|
386
|
+
headers: outboundHeaders,
|
|
387
|
+
};
|
|
388
|
+
return yield new Promise((resolve, reject) => {
|
|
389
|
+
const upstreamReq = requestFn(options, (upstreamRes) => {
|
|
390
|
+
var _a;
|
|
391
|
+
const status = (_a = upstreamRes.statusCode) !== null && _a !== void 0 ? _a : 502;
|
|
392
|
+
if (status === 401 && args.deferWriteOnUnauthorized) {
|
|
393
|
+
// Drain so the socket can be reused; caller will refresh + retry.
|
|
394
|
+
upstreamRes.resume();
|
|
395
|
+
upstreamRes.on("end", () => resolve(status));
|
|
396
|
+
upstreamRes.on("error", () => resolve(status));
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
const responseHeaders = Object.assign({}, upstreamRes.headers);
|
|
400
|
+
for (const hop of HOP_BY_HOP) {
|
|
401
|
+
delete responseHeaders[hop];
|
|
402
|
+
}
|
|
403
|
+
res.writeHead(status, responseHeaders);
|
|
404
|
+
upstreamRes.pipe(res);
|
|
405
|
+
upstreamRes.on("end", () => resolve(status));
|
|
406
|
+
upstreamRes.on("error", () => {
|
|
407
|
+
if (!res.writableEnded) {
|
|
408
|
+
res.end();
|
|
409
|
+
}
|
|
410
|
+
resolve(status);
|
|
411
|
+
});
|
|
412
|
+
});
|
|
413
|
+
upstreamReq.on("error", (error) => {
|
|
414
|
+
reject(error);
|
|
415
|
+
});
|
|
416
|
+
res.on("close", () => {
|
|
417
|
+
if (!res.writableEnded) {
|
|
418
|
+
upstreamReq.destroy();
|
|
419
|
+
}
|
|
420
|
+
});
|
|
421
|
+
upstreamReq.end(body);
|
|
422
|
+
});
|
|
423
|
+
});
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Build an upstream URL that always keeps the configured host/port.
|
|
427
|
+
* Absolute-form or protocol-relative request-targets must not retarget
|
|
428
|
+
* outbound requests (injected engine/bearer credentials would follow).
|
|
429
|
+
*/
|
|
430
|
+
function buildTargetUrl(pathWithQuery, upstream) {
|
|
431
|
+
const pathParse = parseProxyPath(pathWithQuery);
|
|
432
|
+
const relative = pathParse.ok ? pathParse.path : "/";
|
|
433
|
+
const target = new URL(relative, upstream);
|
|
434
|
+
// Force authority back onto the configured upstream even if `new URL`
|
|
435
|
+
// accepted an absolute/protocol-relative request-target.
|
|
436
|
+
target.protocol = upstream.protocol;
|
|
437
|
+
target.hostname = upstream.hostname;
|
|
438
|
+
target.port = upstream.port;
|
|
439
|
+
target.username = "";
|
|
440
|
+
target.password = "";
|
|
441
|
+
// Preserve upstream pathname prefix when the base URL has one
|
|
442
|
+
// (unusual for engineAccess; kept for `--url` mounts).
|
|
443
|
+
if (upstream.pathname !== "/" && upstream.pathname !== "") {
|
|
444
|
+
const basePath = upstream.pathname.replace(/\/$/, "");
|
|
445
|
+
if (!pathnameHasPrefix(target.pathname, basePath)) {
|
|
446
|
+
target.pathname =
|
|
447
|
+
target.pathname === "/"
|
|
448
|
+
? `${basePath}/`
|
|
449
|
+
: `${basePath}${target.pathname}`;
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
return target;
|
|
453
|
+
}
|
|
454
|
+
/** Reject absolute / scheme-relative request-targets; keep path + query only. */
|
|
455
|
+
function parseProxyPath(pathWithQuery) {
|
|
456
|
+
const raw = pathWithQuery.trim();
|
|
457
|
+
if (raw === "") {
|
|
458
|
+
return { ok: true, path: "/" };
|
|
459
|
+
}
|
|
460
|
+
// Absolute-form ("http://evil/…") or protocol-relative ("//evil/…").
|
|
461
|
+
if (/^[a-zA-Z][a-zA-Z0-9+.-]*:/u.test(raw) || raw.startsWith("//")) {
|
|
462
|
+
return { ok: false };
|
|
463
|
+
}
|
|
464
|
+
return { ok: true, path: raw.startsWith("/") ? raw : `/${raw}` };
|
|
465
|
+
}
|
|
466
|
+
function pathnameHasPrefix(pathname, basePath) {
|
|
467
|
+
return pathname === basePath || pathname.startsWith(`${basePath}/`);
|
|
468
|
+
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-authored prompt context. Two pieces:
|
|
3
|
+
*
|
|
4
|
+
* 1. Identity section — static, appended to the agent's instructions (local
|
|
5
|
+
* AGENTS.md and cloud first-turn preamble) so the model knows its own
|
|
6
|
+
* name and how messages and sessions reach it.
|
|
7
|
+
* 2. Session context block — dynamic, prepended to the first turn's user
|
|
8
|
+
* prompt only, telling the model which session/channel/environment it is
|
|
9
|
+
* in plus a channel-appropriate presence line.
|
|
10
|
+
*/
|
|
11
|
+
import type { ResolvedAgent } from "../types.js";
|
|
12
|
+
export declare const SCHEDULE_CHANNEL_PREFIX = "schedule:";
|
|
13
|
+
export type PromptEnvironment = "hosted deployment" | "local dev server";
|
|
14
|
+
export declare function buildIdentitySection(agent: Pick<ResolvedAgent, "name" | "description">): string;
|
|
15
|
+
export interface SessionContextInput {
|
|
16
|
+
sessionId: string;
|
|
17
|
+
channelId: string;
|
|
18
|
+
/**
|
|
19
|
+
* The channel pack's `meta.kind` (e.g. `"slack"`, `"github"`). Channel ids
|
|
20
|
+
* are file stems, so kind — not id — identifies what the channel is.
|
|
21
|
+
*/
|
|
22
|
+
channelKind?: string;
|
|
23
|
+
environment: PromptEnvironment;
|
|
24
|
+
/** Injectable clock for tests; defaults to now. */
|
|
25
|
+
now?: Date;
|
|
26
|
+
}
|
|
27
|
+
export declare function buildSessionContextBlock(input: SessionContextInput): string;
|
|
28
|
+
/**
|
|
29
|
+
* One line telling the model whether anyone is watching this session and
|
|
30
|
+
* where its output lands. Resolved from the channel pack's declared kind
|
|
31
|
+
* when present, falling back to the built-in channel ids. Unknown channels
|
|
32
|
+
* get no line rather than a guess.
|
|
33
|
+
*/
|
|
34
|
+
export declare function channelPresenceLine(channel: Pick<SessionContextInput, "channelId" | "channelKind">): string | undefined;
|
|
35
|
+
//# sourceMappingURL=prompt-context.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompt-context.d.ts","sourceRoot":"","sources":["../../src/internal/prompt-context.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,eAAO,MAAM,uBAAuB,cAAc,CAAC;AAEnD,MAAM,MAAM,iBAAiB,GAAG,mBAAmB,GAAG,kBAAkB,CAAC;AAEzE,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,IAAI,CAAC,aAAa,EAAE,MAAM,GAAG,aAAa,CAAC,GACjD,MAAM,CAWR;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB;;;OAGG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,iBAAiB,CAAC;IAC/B,mDAAmD;IACnD,GAAG,CAAC,EAAE,IAAI,CAAC;CACZ;AAED,wBAAgB,wBAAwB,CAAC,KAAK,EAAE,mBAAmB,GAAG,MAAM,CAc3E;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,OAAO,EAAE,IAAI,CAAC,mBAAmB,EAAE,WAAW,GAAG,aAAa,CAAC,GAC9D,MAAM,GAAG,SAAS,CAepB"}
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-authored prompt context. Two pieces:
|
|
3
|
+
*
|
|
4
|
+
* 1. Identity section — static, appended to the agent's instructions (local
|
|
5
|
+
* AGENTS.md and cloud first-turn preamble) so the model knows its own
|
|
6
|
+
* name and how messages and sessions reach it.
|
|
7
|
+
* 2. Session context block — dynamic, prepended to the first turn's user
|
|
8
|
+
* prompt only, telling the model which session/channel/environment it is
|
|
9
|
+
* in plus a channel-appropriate presence line.
|
|
10
|
+
*/
|
|
11
|
+
export const SCHEDULE_CHANNEL_PREFIX = "schedule:";
|
|
12
|
+
export function buildIdentitySection(agent) {
|
|
13
|
+
var _a;
|
|
14
|
+
const description = (_a = agent.description) === null || _a === void 0 ? void 0 : _a.trim().replace(/\.$/, "");
|
|
15
|
+
const intro = description === undefined || description === ""
|
|
16
|
+
? `You are "${agent.name}".`
|
|
17
|
+
: `You are "${agent.name}" — ${description}.`;
|
|
18
|
+
return [
|
|
19
|
+
"## About you",
|
|
20
|
+
"",
|
|
21
|
+
`${intro} You run as a persistent service: messages reach you through channels (such as Slack, GitHub, webhooks, or a web playground), and each conversation is a session that can continue across multiple turns.`,
|
|
22
|
+
].join("\n");
|
|
23
|
+
}
|
|
24
|
+
export function buildSessionContextBlock(input) {
|
|
25
|
+
var _a;
|
|
26
|
+
const lines = [
|
|
27
|
+
"<agentkit_context>",
|
|
28
|
+
`session: ${input.sessionId}`,
|
|
29
|
+
`channel: ${input.channelId}`,
|
|
30
|
+
`environment: ${input.environment}`,
|
|
31
|
+
`time: ${((_a = input.now) !== null && _a !== void 0 ? _a : new Date()).toISOString()}`,
|
|
32
|
+
"</agentkit_context>",
|
|
33
|
+
];
|
|
34
|
+
const presence = channelPresenceLine(input);
|
|
35
|
+
if (presence !== undefined) {
|
|
36
|
+
lines.push(presence);
|
|
37
|
+
}
|
|
38
|
+
return lines.join("\n");
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* One line telling the model whether anyone is watching this session and
|
|
42
|
+
* where its output lands. Resolved from the channel pack's declared kind
|
|
43
|
+
* when present, falling back to the built-in channel ids. Unknown channels
|
|
44
|
+
* get no line rather than a guess.
|
|
45
|
+
*/
|
|
46
|
+
export function channelPresenceLine(channel) {
|
|
47
|
+
var _a;
|
|
48
|
+
const kind = (_a = channel.channelKind) !== null && _a !== void 0 ? _a : builtinChannelKind(channel.channelId);
|
|
49
|
+
switch (kind) {
|
|
50
|
+
case "http":
|
|
51
|
+
case "mcp":
|
|
52
|
+
return "A user is interacting with you live and sees your replies as they stream.";
|
|
53
|
+
case "slack":
|
|
54
|
+
return "You are replying in a Slack thread; participants will read your messages.";
|
|
55
|
+
case "github":
|
|
56
|
+
return "You were triggered by a GitHub event. Deliver results through the actions available to you (comments, reviews, PRs); nobody sees your raw output otherwise.";
|
|
57
|
+
case "schedule":
|
|
58
|
+
return "This run was triggered automatically. No user is watching; complete the task autonomously and deliver results through your available tools/channels.";
|
|
59
|
+
default:
|
|
60
|
+
return undefined;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function builtinChannelKind(channelId) {
|
|
64
|
+
if (channelId === "http" || channelId === "mcp") {
|
|
65
|
+
return channelId;
|
|
66
|
+
}
|
|
67
|
+
if (channelId.startsWith(SCHEDULE_CHANNEL_PREFIX)) {
|
|
68
|
+
return "schedule";
|
|
69
|
+
}
|
|
70
|
+
return undefined;
|
|
71
|
+
}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge Authorization bearer + arbitrary request headers for agent HTTP
|
|
3
|
+
* clients (local `--bearer-token`, hosted `engineAccess.headers`, etc.).
|
|
4
|
+
*/
|
|
5
|
+
export interface RequestAuth {
|
|
6
|
+
bearerToken?: string;
|
|
7
|
+
/** Extra headers (e.g. X-Anyrun-Port-Token from engineAccess). */
|
|
8
|
+
headers?: Record<string, string>;
|
|
9
|
+
}
|
|
10
|
+
export declare function mergeRequestHeaders(auth: RequestAuth | undefined): Record<string, string>;
|
|
11
|
+
//# sourceMappingURL=request-headers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"request-headers.d.ts","sourceRoot":"","sources":["../../src/internal/request-headers.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,MAAM,WAAW,WAAW;IAC1B,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,kEAAkE;IAClE,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,WAAW,GAAG,SAAS,GAC5B,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CASxB"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Merge Authorization bearer + arbitrary request headers for agent HTTP
|
|
3
|
+
* clients (local `--bearer-token`, hosted `engineAccess.headers`, etc.).
|
|
4
|
+
*/
|
|
5
|
+
export function mergeRequestHeaders(auth) {
|
|
6
|
+
const out = {};
|
|
7
|
+
if ((auth === null || auth === void 0 ? void 0 : auth.headers) !== undefined) {
|
|
8
|
+
Object.assign(out, auth.headers);
|
|
9
|
+
}
|
|
10
|
+
if ((auth === null || auth === void 0 ? void 0 : auth.bearerToken) !== undefined) {
|
|
11
|
+
out.authorization = `Bearer ${auth.bearerToken}`;
|
|
12
|
+
}
|
|
13
|
+
return out;
|
|
14
|
+
}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Resolve a hosted (managed) agent-serve deployment into a base URL +
|
|
3
|
+
* request headers for chat/run/call/eval `--prod`.
|
|
4
|
+
*
|
|
5
|
+
* Uses short-lived `engineAccess` from the deployment status route
|
|
6
|
+
* (Cursor API key on the management API; `X-Anyrun-Port-Token` on the
|
|
7
|
+
* engine). Alias tokens are out of scope here.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Interactive CLI keep-alive for hosted engines. Without these, a hibernated
|
|
11
|
+
* Anyrun pod returns 417 `pod_hibernated` and never wakes. Matches the
|
|
12
|
+
* cloud-agent interactive keep-alive shape (lower ≤ upper, seconds).
|
|
13
|
+
*/
|
|
14
|
+
export declare const PROD_ENGINE_WAKE_HEADERS: Readonly<Record<string, string>>;
|
|
15
|
+
export interface ResolveProdTargetOptions {
|
|
16
|
+
dir: string;
|
|
17
|
+
cwd?: string;
|
|
18
|
+
/** Explicit deployment slug; otherwise derived from `--dir` basename. */
|
|
19
|
+
slug?: string;
|
|
20
|
+
team?: string;
|
|
21
|
+
apiKey?: string;
|
|
22
|
+
fetchImpl?: typeof fetch;
|
|
23
|
+
err?: (text: string) => void;
|
|
24
|
+
}
|
|
25
|
+
export interface ResolvedProdTarget {
|
|
26
|
+
agentUrl: string;
|
|
27
|
+
headers: Record<string, string>;
|
|
28
|
+
slug: string;
|
|
29
|
+
expiresAt: string;
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Look up a running deployment and return its engineAccess URL/headers.
|
|
33
|
+
* Throws {@link Error} with a CLI-ready message on failure.
|
|
34
|
+
*/
|
|
35
|
+
export declare function resolveProdTarget(options: ResolveProdTargetOptions): Promise<ResolvedProdTarget>;
|
|
36
|
+
/** Resolve the deployment slug the same way `deploy` does for a single dir. */
|
|
37
|
+
export declare function resolveProdSlug(options: {
|
|
38
|
+
dir: string;
|
|
39
|
+
cwd?: string;
|
|
40
|
+
slug?: string;
|
|
41
|
+
}): string;
|
|
42
|
+
//# sourceMappingURL=resolve-prod-target.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"resolve-prod-target.d.ts","sourceRoot":"","sources":["../../src/internal/resolve-prod-target.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAaH;;;;GAIG;AACH,eAAO,MAAM,wBAAwB,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAGrE,CAAC;AAEF,MAAM,WAAW,wBAAwB;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,yEAAyE;IACzE,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,KAAK,CAAC;IACzB,GAAG,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;CAC9B;AAED,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,MAAM,CAAC;IACjB,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,wBAAsB,iBAAiB,CACrC,OAAO,EAAE,wBAAwB,GAChC,OAAO,CAAC,kBAAkB,CAAC,CA+D7B;AAWD,+EAA+E;AAC/E,wBAAgB,eAAe,CAAC,OAAO,EAAE;IACvC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GAAG,MAAM,CAgBT"}
|