@pantheon.ai/agents 0.0.1
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/dist/index.js +2029 -0
- package/package.json +38 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,2029 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from "node:module";
|
|
3
|
+
import { createCommand } from "commander";
|
|
4
|
+
import expandTilde from "expand-tilde";
|
|
5
|
+
import path from "node:path";
|
|
6
|
+
import * as process$1 from "node:process";
|
|
7
|
+
import { multistream, pino, transport } from "pino";
|
|
8
|
+
import * as fs$1 from "node:fs";
|
|
9
|
+
import { Kysely, MysqlDialect } from "kysely";
|
|
10
|
+
import { createPool } from "mysql2";
|
|
11
|
+
import z$1, { z } from "zod";
|
|
12
|
+
|
|
13
|
+
//#region \0rolldown/runtime.js
|
|
14
|
+
var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
|
|
15
|
+
var __require = /* @__PURE__ */ createRequire(import.meta.url);
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
//#region schemas/task-list.ts
|
|
19
|
+
const taskItemSchema = z.discriminatedUnion("status", [
|
|
20
|
+
z.object({
|
|
21
|
+
status: z.literal("pending"),
|
|
22
|
+
id: z.string(),
|
|
23
|
+
task: z.string(),
|
|
24
|
+
project_id: z.uuid(),
|
|
25
|
+
base_branch_id: z.uuid(),
|
|
26
|
+
queued_at: z.coerce.date()
|
|
27
|
+
}),
|
|
28
|
+
z.object({
|
|
29
|
+
status: z.literal("running"),
|
|
30
|
+
id: z.string(),
|
|
31
|
+
task: z.string(),
|
|
32
|
+
project_id: z.uuid(),
|
|
33
|
+
base_branch_id: z.uuid(),
|
|
34
|
+
branch_id: z.uuid(),
|
|
35
|
+
queued_at: z.coerce.date(),
|
|
36
|
+
started_at: z.coerce.date()
|
|
37
|
+
}),
|
|
38
|
+
z.object({
|
|
39
|
+
status: z.literal("completed"),
|
|
40
|
+
id: z.string(),
|
|
41
|
+
task: z.string(),
|
|
42
|
+
project_id: z.uuid(),
|
|
43
|
+
base_branch_id: z.uuid(),
|
|
44
|
+
branch_id: z.uuid(),
|
|
45
|
+
queued_at: z.coerce.date(),
|
|
46
|
+
started_at: z.coerce.date(),
|
|
47
|
+
ended_at: z.coerce.date(),
|
|
48
|
+
output: z.string()
|
|
49
|
+
}),
|
|
50
|
+
z.object({
|
|
51
|
+
status: z.literal("failed"),
|
|
52
|
+
id: z.string(),
|
|
53
|
+
task: z.string(),
|
|
54
|
+
project_id: z.uuid(),
|
|
55
|
+
base_branch_id: z.uuid(),
|
|
56
|
+
branch_id: z.uuid().optional(),
|
|
57
|
+
queued_at: z.coerce.date(),
|
|
58
|
+
started_at: z.coerce.date().optional(),
|
|
59
|
+
ended_at: z.coerce.date().optional(),
|
|
60
|
+
error: z.string()
|
|
61
|
+
}),
|
|
62
|
+
z.object({
|
|
63
|
+
status: z.literal("cancelled"),
|
|
64
|
+
id: z.string(),
|
|
65
|
+
task: z.string(),
|
|
66
|
+
project_id: z.uuid(),
|
|
67
|
+
queued_at: z.coerce.date(),
|
|
68
|
+
cancelled_at: z.coerce.date()
|
|
69
|
+
})
|
|
70
|
+
]);
|
|
71
|
+
|
|
72
|
+
//#endregion
|
|
73
|
+
//#region utils/get-error-message.ts
|
|
74
|
+
function getErrorMessage(error) {
|
|
75
|
+
return String(error?.message ?? error);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
//#endregion
|
|
79
|
+
//#region task-list/task-list-provider.ts
|
|
80
|
+
var TaskListProvider = class {
|
|
81
|
+
logger;
|
|
82
|
+
agentName;
|
|
83
|
+
constructor(agentName, logger) {
|
|
84
|
+
this.agentName = agentName;
|
|
85
|
+
this.logger = logger;
|
|
86
|
+
}
|
|
87
|
+
async createTask(params) {
|
|
88
|
+
return await this.insertTask({
|
|
89
|
+
status: "pending",
|
|
90
|
+
...params,
|
|
91
|
+
queued_at: /* @__PURE__ */ new Date()
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
async startTask({ status, id, ...task }, startTask) {
|
|
95
|
+
const now = /* @__PURE__ */ new Date();
|
|
96
|
+
let updatePromise;
|
|
97
|
+
try {
|
|
98
|
+
this.logger.info(`Starting task ${id}`);
|
|
99
|
+
const branchId = await startTask(task);
|
|
100
|
+
this.logger.info(`Started task ${id} at branch ${branchId}`);
|
|
101
|
+
updatePromise = this.updateTask({
|
|
102
|
+
status: "running",
|
|
103
|
+
id,
|
|
104
|
+
...task,
|
|
105
|
+
branch_id: branchId,
|
|
106
|
+
started_at: now
|
|
107
|
+
});
|
|
108
|
+
} catch (e) {
|
|
109
|
+
this.logger.error("Failed to start task: %s", getErrorMessage(e));
|
|
110
|
+
updatePromise = this.updateTask({
|
|
111
|
+
status: "failed",
|
|
112
|
+
id,
|
|
113
|
+
...task,
|
|
114
|
+
started_at: now,
|
|
115
|
+
ended_at: /* @__PURE__ */ new Date(),
|
|
116
|
+
error: getErrorMessage(e)
|
|
117
|
+
}).then(() => Promise.reject(e));
|
|
118
|
+
}
|
|
119
|
+
await updatePromise;
|
|
120
|
+
}
|
|
121
|
+
async failTask(task, error) {
|
|
122
|
+
if (task.status !== "running") {
|
|
123
|
+
this.logger.error(`Can't fail a task that is not running. [task = ${task.id}, status = ${task.status}]`);
|
|
124
|
+
throw new Error("Can't fail a task that is not running");
|
|
125
|
+
}
|
|
126
|
+
await this.updateTask({
|
|
127
|
+
...task,
|
|
128
|
+
status: "failed",
|
|
129
|
+
ended_at: /* @__PURE__ */ new Date(),
|
|
130
|
+
error
|
|
131
|
+
});
|
|
132
|
+
}
|
|
133
|
+
async completeTask(task, output) {
|
|
134
|
+
if (task.status !== "running") {
|
|
135
|
+
this.logger.error(`Can't complete a task that is not running. [task = ${task.id}, status = ${task.status}]`);
|
|
136
|
+
throw new Error("Can't complete a task that is not running");
|
|
137
|
+
}
|
|
138
|
+
await this.updateTask({
|
|
139
|
+
...task,
|
|
140
|
+
status: "completed",
|
|
141
|
+
ended_at: /* @__PURE__ */ new Date(),
|
|
142
|
+
output
|
|
143
|
+
});
|
|
144
|
+
}
|
|
145
|
+
async cancelTask(task) {
|
|
146
|
+
if (task.status !== "pending") {
|
|
147
|
+
this.logger.error(`Can't cancel a task that is not pending. [task = ${task.id}, status = ${task.status}]`);
|
|
148
|
+
throw new Error("Can't cancel a task that is not pending");
|
|
149
|
+
}
|
|
150
|
+
await this.updateTask({
|
|
151
|
+
...task,
|
|
152
|
+
status: "cancelled",
|
|
153
|
+
cancelled_at: /* @__PURE__ */ new Date()
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
|
|
158
|
+
//#endregion
|
|
159
|
+
//#region task-list/task-list-tidb-provider.ts
|
|
160
|
+
var TaskListTidbProvider = class extends TaskListProvider {
|
|
161
|
+
db;
|
|
162
|
+
constructor(agentName, logger) {
|
|
163
|
+
super(agentName, logger);
|
|
164
|
+
this.db = new Kysely({ dialect: new MysqlDialect({ pool: createPool({
|
|
165
|
+
uri: process.env.DATABASE_URL,
|
|
166
|
+
supportBigNumbers: true,
|
|
167
|
+
bigNumberStrings: true
|
|
168
|
+
}) }) });
|
|
169
|
+
}
|
|
170
|
+
async close() {
|
|
171
|
+
await this.db.destroy();
|
|
172
|
+
}
|
|
173
|
+
selectTask() {
|
|
174
|
+
return this.db.selectFrom("task").selectAll().where("agent", "=", this.agentName);
|
|
175
|
+
}
|
|
176
|
+
async getAgentConfig(projectId) {
|
|
177
|
+
const config = await this.db.selectFrom("agent_project_config").selectAll().where("project_id", "=", projectId).where("agent", "=", this.agentName).executeTakeFirst();
|
|
178
|
+
if (config == null) return null;
|
|
179
|
+
return config;
|
|
180
|
+
}
|
|
181
|
+
async setAgentConfig(config) {
|
|
182
|
+
await this.db.insertInto("agent_project_config").values({
|
|
183
|
+
agent: this.agentName,
|
|
184
|
+
...config
|
|
185
|
+
}).execute();
|
|
186
|
+
}
|
|
187
|
+
async getTask(taskId) {
|
|
188
|
+
const taskItem = await this.selectTask().where("id", "=", taskId).executeTakeFirst();
|
|
189
|
+
if (taskItem == null) return null;
|
|
190
|
+
return taskItemSchema.parse(taskItem);
|
|
191
|
+
}
|
|
192
|
+
async getTasks({ status, order_by, order_direction = "asc" } = {}) {
|
|
193
|
+
let builder = this.selectTask();
|
|
194
|
+
if (status && status.length > 0) builder = builder.where("status", "in", status);
|
|
195
|
+
if (order_by) builder = builder.orderBy(order_by, order_direction);
|
|
196
|
+
return (await builder.execute()).map((item) => taskItemSchema.parse(item));
|
|
197
|
+
}
|
|
198
|
+
async updateTask(taskItem) {
|
|
199
|
+
const { id, started_at, ended_at, queued_at, ...rest } = taskItem;
|
|
200
|
+
await this.db.updateTable("task").set({
|
|
201
|
+
started_at,
|
|
202
|
+
ended_at,
|
|
203
|
+
queued_at,
|
|
204
|
+
...rest
|
|
205
|
+
}).where("id", "=", id).where("agent", "=", this.agentName).execute();
|
|
206
|
+
}
|
|
207
|
+
async insertTask(taskItem) {
|
|
208
|
+
const { started_at, ended_at, queued_at, ...rest } = taskItem;
|
|
209
|
+
const { insertId } = await this.db.insertInto("task").values({
|
|
210
|
+
agent: this.agentName,
|
|
211
|
+
started_at,
|
|
212
|
+
ended_at,
|
|
213
|
+
queued_at,
|
|
214
|
+
...rest
|
|
215
|
+
}).executeTakeFirstOrThrow();
|
|
216
|
+
return {
|
|
217
|
+
...taskItem,
|
|
218
|
+
id: String(insertId)
|
|
219
|
+
};
|
|
220
|
+
}
|
|
221
|
+
};
|
|
222
|
+
|
|
223
|
+
//#endregion
|
|
224
|
+
//#region ../sdk/src/lib/stream-parser.ts
|
|
225
|
+
var StreamResponseParser = class {
|
|
226
|
+
options;
|
|
227
|
+
constructor(options) {
|
|
228
|
+
this.options = options;
|
|
229
|
+
}
|
|
230
|
+
async handleResponse(response, context) {
|
|
231
|
+
this.options.validateResponse?.(response);
|
|
232
|
+
if (!response.body) throw new Error("Response body is missing");
|
|
233
|
+
return this.options.pipe(response.body, Object.freeze({
|
|
234
|
+
...context,
|
|
235
|
+
response
|
|
236
|
+
}));
|
|
237
|
+
}
|
|
238
|
+
};
|
|
239
|
+
|
|
240
|
+
//#endregion
|
|
241
|
+
//#region ../sdk/src/lib/validator.ts
|
|
242
|
+
const VALIDATOR_SYMBOL = Symbol("validator");
|
|
243
|
+
function isValidator(object) {
|
|
244
|
+
return typeof object === "object" && object !== null && object[VALIDATOR_SYMBOL] === true && typeof object.parse === "function";
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
//#endregion
|
|
248
|
+
//#region ../../node_modules/url-template/lib/url-template.js
|
|
249
|
+
function encodeReserved(str) {
|
|
250
|
+
return str.split(/(%[0-9A-Fa-f]{2})/g).map(function(part) {
|
|
251
|
+
if (!/%[0-9A-Fa-f]/.test(part)) part = encodeURI(part).replace(/%5B/g, "[").replace(/%5D/g, "]");
|
|
252
|
+
return part;
|
|
253
|
+
}).join("");
|
|
254
|
+
}
|
|
255
|
+
function encodeUnreserved(str) {
|
|
256
|
+
return encodeURIComponent(str).replace(/[!'()*]/g, function(c) {
|
|
257
|
+
return "%" + c.charCodeAt(0).toString(16).toUpperCase();
|
|
258
|
+
});
|
|
259
|
+
}
|
|
260
|
+
function encodeValue(operator, value, key) {
|
|
261
|
+
value = operator === "+" || operator === "#" ? encodeReserved(value) : encodeUnreserved(value);
|
|
262
|
+
if (key) return encodeUnreserved(key) + "=" + value;
|
|
263
|
+
else return value;
|
|
264
|
+
}
|
|
265
|
+
function isDefined(value) {
|
|
266
|
+
return value !== void 0 && value !== null;
|
|
267
|
+
}
|
|
268
|
+
function isKeyOperator(operator) {
|
|
269
|
+
return operator === ";" || operator === "&" || operator === "?";
|
|
270
|
+
}
|
|
271
|
+
function getValues(context, operator, key, modifier) {
|
|
272
|
+
var value = context[key], result = [];
|
|
273
|
+
if (isDefined(value) && value !== "") if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
|
|
274
|
+
value = value.toString();
|
|
275
|
+
if (modifier && modifier !== "*") value = value.substring(0, parseInt(modifier, 10));
|
|
276
|
+
result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
|
|
277
|
+
} else if (modifier === "*") if (Array.isArray(value)) value.filter(isDefined).forEach(function(value) {
|
|
278
|
+
result.push(encodeValue(operator, value, isKeyOperator(operator) ? key : null));
|
|
279
|
+
});
|
|
280
|
+
else Object.keys(value).forEach(function(k) {
|
|
281
|
+
if (isDefined(value[k])) result.push(encodeValue(operator, value[k], k));
|
|
282
|
+
});
|
|
283
|
+
else {
|
|
284
|
+
var tmp = [];
|
|
285
|
+
if (Array.isArray(value)) value.filter(isDefined).forEach(function(value) {
|
|
286
|
+
tmp.push(encodeValue(operator, value));
|
|
287
|
+
});
|
|
288
|
+
else Object.keys(value).forEach(function(k) {
|
|
289
|
+
if (isDefined(value[k])) {
|
|
290
|
+
tmp.push(encodeUnreserved(k));
|
|
291
|
+
tmp.push(encodeValue(operator, value[k].toString()));
|
|
292
|
+
}
|
|
293
|
+
});
|
|
294
|
+
if (isKeyOperator(operator)) result.push(encodeUnreserved(key) + "=" + tmp.join(","));
|
|
295
|
+
else if (tmp.length !== 0) result.push(tmp.join(","));
|
|
296
|
+
}
|
|
297
|
+
else if (operator === ";") {
|
|
298
|
+
if (isDefined(value)) result.push(encodeUnreserved(key));
|
|
299
|
+
} else if (value === "" && (operator === "&" || operator === "?")) result.push(encodeUnreserved(key) + "=");
|
|
300
|
+
else if (value === "") result.push("");
|
|
301
|
+
return result;
|
|
302
|
+
}
|
|
303
|
+
function parseTemplate(template) {
|
|
304
|
+
var operators = [
|
|
305
|
+
"+",
|
|
306
|
+
"#",
|
|
307
|
+
".",
|
|
308
|
+
"/",
|
|
309
|
+
";",
|
|
310
|
+
"?",
|
|
311
|
+
"&"
|
|
312
|
+
];
|
|
313
|
+
return { expand: function(context) {
|
|
314
|
+
return template.replace(/\{([^\{\}]+)\}|([^\{\}]+)/g, function(_, expression, literal) {
|
|
315
|
+
if (expression) {
|
|
316
|
+
var operator = null, values = [];
|
|
317
|
+
if (operators.indexOf(expression.charAt(0)) !== -1) {
|
|
318
|
+
operator = expression.charAt(0);
|
|
319
|
+
expression = expression.substr(1);
|
|
320
|
+
}
|
|
321
|
+
expression.split(/,/g).forEach(function(variable) {
|
|
322
|
+
var tmp = /([^:\*]*)(?::(\d+)|(\*))?/.exec(variable);
|
|
323
|
+
values.push.apply(values, getValues(context, operator, tmp[1], tmp[2] || tmp[3]));
|
|
324
|
+
});
|
|
325
|
+
if (operator && operator !== "+") {
|
|
326
|
+
var separator = ",";
|
|
327
|
+
if (operator === "?") separator = "&";
|
|
328
|
+
else if (operator !== "#") separator = operator;
|
|
329
|
+
return (values.length !== 0 ? operator : "") + values.join(separator);
|
|
330
|
+
} else return values.join(",");
|
|
331
|
+
} else return encodeReserved(literal);
|
|
332
|
+
});
|
|
333
|
+
} };
|
|
334
|
+
}
|
|
335
|
+
|
|
336
|
+
//#endregion
|
|
337
|
+
//#region ../sdk/src/lib/api.ts
|
|
338
|
+
function typeOf() {
|
|
339
|
+
return null;
|
|
340
|
+
}
|
|
341
|
+
function createUrlTemplate(method) {
|
|
342
|
+
return function(arr, ...params) {
|
|
343
|
+
let url = arr[0];
|
|
344
|
+
let expandedPaths = false;
|
|
345
|
+
for (let i = 1; i < arr.length; i++) if (params[i - 1] === "path*") {
|
|
346
|
+
url += "<path*>";
|
|
347
|
+
expandedPaths = true;
|
|
348
|
+
} else url += "{" + params[i - 1].replace(/\?$/, "") + "}" + arr[i];
|
|
349
|
+
const [pathPart, searchPart] = url.split("?");
|
|
350
|
+
const pathPartTemplate = expandedPaths ? { expand: (context) => {
|
|
351
|
+
return parseTemplate(pathPart.replace(/<path\*>/, String(context["path*"]).replace(/^\//, ""))).expand(context);
|
|
352
|
+
} } : parseTemplate(pathPart);
|
|
353
|
+
const searchParamsBuilders = [];
|
|
354
|
+
if (searchPart) searchPart.split("&").forEach((entry) => {
|
|
355
|
+
const [key, value = ""] = entry.split("=").map(decodeURIComponent);
|
|
356
|
+
if (/^\{[^}]+}$/.test(value)) {
|
|
357
|
+
const templateValue = value.slice(1, -1);
|
|
358
|
+
searchParamsBuilders.push((usp, context) => {
|
|
359
|
+
if (templateValue in context) {
|
|
360
|
+
const value = context[templateValue];
|
|
361
|
+
if (value === void 0) return;
|
|
362
|
+
if (Array.isArray(value)) value.forEach((v) => usp.append(key, String(v)));
|
|
363
|
+
else usp.append(key, String(value));
|
|
364
|
+
}
|
|
365
|
+
});
|
|
366
|
+
} else if (value !== "") {
|
|
367
|
+
const template = parseTemplate(value);
|
|
368
|
+
searchParamsBuilders.push((usp, context) => {
|
|
369
|
+
usp.append(key, template.expand(context));
|
|
370
|
+
});
|
|
371
|
+
} else searchParamsBuilders.push((usp) => {
|
|
372
|
+
usp.append(key, "");
|
|
373
|
+
});
|
|
374
|
+
});
|
|
375
|
+
return {
|
|
376
|
+
method,
|
|
377
|
+
signature: `${method} ${url}`,
|
|
378
|
+
templateUrl: url,
|
|
379
|
+
template: { expand: (context) => {
|
|
380
|
+
const pathPart = pathPartTemplate.expand(context);
|
|
381
|
+
const usp = new URLSearchParams();
|
|
382
|
+
searchParamsBuilders.forEach((template) => {
|
|
383
|
+
template(usp, context);
|
|
384
|
+
});
|
|
385
|
+
if (Array.from(usp).length > 0) return pathPart + "?" + usp.toString();
|
|
386
|
+
else return pathPart;
|
|
387
|
+
} },
|
|
388
|
+
__params__: typeOf()
|
|
389
|
+
};
|
|
390
|
+
};
|
|
391
|
+
}
|
|
392
|
+
const get = createUrlTemplate("get");
|
|
393
|
+
const post = createUrlTemplate("post");
|
|
394
|
+
const put = createUrlTemplate("put");
|
|
395
|
+
const del = createUrlTemplate("delete");
|
|
396
|
+
const patch = createUrlTemplate("patch");
|
|
397
|
+
function defineApi(urlTemplate, _type, responseSchema) {
|
|
398
|
+
const method = urlTemplate.method;
|
|
399
|
+
return {
|
|
400
|
+
method: urlTemplate.method,
|
|
401
|
+
signature: urlTemplate.signature,
|
|
402
|
+
url: ((params) => urlTemplate.template.expand(params ?? {})),
|
|
403
|
+
requestInit: (body) => {
|
|
404
|
+
if (method === "get" || method === "delete") return { method };
|
|
405
|
+
if (body instanceof ReadableStream) return {
|
|
406
|
+
method,
|
|
407
|
+
body,
|
|
408
|
+
duplex: "half"
|
|
409
|
+
};
|
|
410
|
+
else if (body instanceof FormData) return {
|
|
411
|
+
method,
|
|
412
|
+
body
|
|
413
|
+
};
|
|
414
|
+
else return {
|
|
415
|
+
method,
|
|
416
|
+
body: JSON.stringify(body),
|
|
417
|
+
headers: { "Content-Type": "application/json" }
|
|
418
|
+
};
|
|
419
|
+
},
|
|
420
|
+
handleResponse: async (response, context) => {
|
|
421
|
+
if (responseSchema instanceof StreamResponseParser) return responseSchema.handleResponse(response, context);
|
|
422
|
+
else if (responseSchema === "text") return await response.text();
|
|
423
|
+
else if (responseSchema === "raw") return response;
|
|
424
|
+
else if (isValidator(responseSchema)) return responseSchema.parse(response);
|
|
425
|
+
else return responseSchema.parse(await response.json());
|
|
426
|
+
}
|
|
427
|
+
};
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
//#endregion
|
|
431
|
+
//#region ../sdk/src/lib/zod.ts
|
|
432
|
+
var ZodStream = class extends TransformStream {
|
|
433
|
+
constructor({ schema, onParseFailed }) {
|
|
434
|
+
super({ async transform(chunk, controller) {
|
|
435
|
+
const result = await schema.safeParseAsync(chunk);
|
|
436
|
+
if (result.success) controller.enqueue(result.data);
|
|
437
|
+
else if (onParseFailed) onParseFailed(result.error, chunk, controller);
|
|
438
|
+
else controller.error(result.error);
|
|
439
|
+
} });
|
|
440
|
+
}
|
|
441
|
+
};
|
|
442
|
+
const zodJsonDate = z.coerce.date();
|
|
443
|
+
|
|
444
|
+
//#endregion
|
|
445
|
+
//#region ../sdk/src/schemas/branch.ts
|
|
446
|
+
const branchManifestArtifactSchema = z.object({
|
|
447
|
+
type: z.string(),
|
|
448
|
+
path: z.string(),
|
|
449
|
+
description: z.string()
|
|
450
|
+
});
|
|
451
|
+
const branchManifestSchema = z.object({
|
|
452
|
+
summary: z.string().optional(),
|
|
453
|
+
export: z.object({
|
|
454
|
+
include_patterns: z.string().array(),
|
|
455
|
+
exclude_patterns: z.string().array()
|
|
456
|
+
}).optional(),
|
|
457
|
+
artifacts: branchManifestArtifactSchema.array().optional()
|
|
458
|
+
});
|
|
459
|
+
const snapSchema = z.object({
|
|
460
|
+
snap_id: z.string(),
|
|
461
|
+
snap_status: z.string(),
|
|
462
|
+
snap_type: z.string(),
|
|
463
|
+
started_at: zodJsonDate,
|
|
464
|
+
finished_at: zodJsonDate,
|
|
465
|
+
exit_code: z.number().nullable(),
|
|
466
|
+
error: z.string().nullable(),
|
|
467
|
+
step_index: z.number(),
|
|
468
|
+
event_stream_id: z.string().nullable(),
|
|
469
|
+
tool_use_id: z.string().nullable(),
|
|
470
|
+
manifest_status: z.string().nullable(),
|
|
471
|
+
manifest_task_id: z.string().nullable(),
|
|
472
|
+
manifest_snap_id: z.string().nullable()
|
|
473
|
+
});
|
|
474
|
+
const snapDetailsSchema = snapSchema.extend({
|
|
475
|
+
output: z.string().nullable(),
|
|
476
|
+
command: z.string().array().nullable().optional()
|
|
477
|
+
});
|
|
478
|
+
const branchStatusSchema = z.enum([
|
|
479
|
+
"created",
|
|
480
|
+
"pending",
|
|
481
|
+
"running",
|
|
482
|
+
"ready_for_manifest",
|
|
483
|
+
"manifesting",
|
|
484
|
+
"succeed",
|
|
485
|
+
"failed"
|
|
486
|
+
]);
|
|
487
|
+
const branchSchema = z.object({
|
|
488
|
+
id: z.string(),
|
|
489
|
+
name: z.string(),
|
|
490
|
+
display_name: z.string(),
|
|
491
|
+
status: branchStatusSchema,
|
|
492
|
+
status_text: z.string().nullable(),
|
|
493
|
+
level: z.number(),
|
|
494
|
+
project_id: z.string(),
|
|
495
|
+
parent_id: z.string().nullable(),
|
|
496
|
+
created_at: zodJsonDate,
|
|
497
|
+
updated_at: zodJsonDate,
|
|
498
|
+
latest_snap_id: z.string().nullable(),
|
|
499
|
+
latest_snap: snapSchema.nullable(),
|
|
500
|
+
manifest: branchManifestSchema.nullable()
|
|
501
|
+
});
|
|
502
|
+
const branchSnapsSchema = z.object({
|
|
503
|
+
branch_id: z.string(),
|
|
504
|
+
branch_name: z.string(),
|
|
505
|
+
branch_status: branchStatusSchema,
|
|
506
|
+
branch_status_text: z.string().nullable(),
|
|
507
|
+
steps: z.array(snapDetailsSchema),
|
|
508
|
+
steps_total: z.number()
|
|
509
|
+
});
|
|
510
|
+
const branchExecutionResultSchema = z.object({
|
|
511
|
+
execution_id: z.string(),
|
|
512
|
+
status: z.string(),
|
|
513
|
+
status_text: z.string(),
|
|
514
|
+
branch_id: z.string(),
|
|
515
|
+
snap_id: z.string(),
|
|
516
|
+
background_task_id: z.string().nullable(),
|
|
517
|
+
started_at: zodJsonDate,
|
|
518
|
+
last_polled_at: zodJsonDate,
|
|
519
|
+
ended_at: zodJsonDate.nullable(),
|
|
520
|
+
exit_code: z.number().nullable()
|
|
521
|
+
});
|
|
522
|
+
|
|
523
|
+
//#endregion
|
|
524
|
+
//#region ../sdk/src/schemas/common.ts
|
|
525
|
+
function paged(schema) {
|
|
526
|
+
return z.object({
|
|
527
|
+
items: z.array(schema),
|
|
528
|
+
total: z.number(),
|
|
529
|
+
page: z.number(),
|
|
530
|
+
size: z.number(),
|
|
531
|
+
pages: z.number()
|
|
532
|
+
});
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region ../sdk/src/schemas/exploration.ts
|
|
537
|
+
const createExplorationResultSchema = z.object({
|
|
538
|
+
id: z.string(),
|
|
539
|
+
project_id: z.string(),
|
|
540
|
+
parent_branch_id: z.string(),
|
|
541
|
+
baseline_branch_id: z.string().nullable(),
|
|
542
|
+
background_task_id: z.string().nullable(),
|
|
543
|
+
status: z.string(),
|
|
544
|
+
status_text: z.string().nullable(),
|
|
545
|
+
started_at: zodJsonDate.nullable(),
|
|
546
|
+
ended_at: zodJsonDate.nullable(),
|
|
547
|
+
branches: z.object({
|
|
548
|
+
branch_id: z.string(),
|
|
549
|
+
branch_name: z.string(),
|
|
550
|
+
branch_display_name: z.string(),
|
|
551
|
+
latest_snap_id: z.string(),
|
|
552
|
+
execution_results: branchExecutionResultSchema.array()
|
|
553
|
+
}).array()
|
|
554
|
+
});
|
|
555
|
+
const explorationSchema = z.object({
|
|
556
|
+
id: z.string(),
|
|
557
|
+
project_id: z.string(),
|
|
558
|
+
parent_branch_id: z.string(),
|
|
559
|
+
tdd_baseline_branch_id: z.string().nullable(),
|
|
560
|
+
background_task_id: z.string().nullable(),
|
|
561
|
+
num_branches: z.number().int(),
|
|
562
|
+
shared_prompt_sequence: z.string().array(),
|
|
563
|
+
status_text: z.string(),
|
|
564
|
+
call_agent: z.string().nullable(),
|
|
565
|
+
started_at: zodJsonDate.nullable(),
|
|
566
|
+
ended_at: zodJsonDate.nullable(),
|
|
567
|
+
created_at: zodJsonDate,
|
|
568
|
+
updated_at: zodJsonDate,
|
|
569
|
+
agent: z.string(),
|
|
570
|
+
status: z.string()
|
|
571
|
+
});
|
|
572
|
+
const explorationResultSchema = z.object({
|
|
573
|
+
id: z.string(),
|
|
574
|
+
project_id: z.string(),
|
|
575
|
+
parent_branch_id: z.string(),
|
|
576
|
+
baseline_branch_id: z.string().nullable(),
|
|
577
|
+
background_task_id: z.string().nullable(),
|
|
578
|
+
status: z.string(),
|
|
579
|
+
status_text: z.string(),
|
|
580
|
+
started_at: zodJsonDate,
|
|
581
|
+
ended_at: zodJsonDate.nullable(),
|
|
582
|
+
branches: z.object({
|
|
583
|
+
branch_id: z.string(),
|
|
584
|
+
branch_name: z.string(),
|
|
585
|
+
branch_display_name: z.string(),
|
|
586
|
+
latest_snap_id: z.string(),
|
|
587
|
+
execution_results: z.object({
|
|
588
|
+
execution_id: z.string(),
|
|
589
|
+
status: z.string(),
|
|
590
|
+
status_text: z.string(),
|
|
591
|
+
branch_id: z.string(),
|
|
592
|
+
snap_id: z.string(),
|
|
593
|
+
background_task_id: z.string().nullable(),
|
|
594
|
+
started_at: zodJsonDate,
|
|
595
|
+
last_polled_at: zodJsonDate,
|
|
596
|
+
ended_at: zodJsonDate.nullable(),
|
|
597
|
+
exit_code: z.number().nullable()
|
|
598
|
+
}).array()
|
|
599
|
+
}).array()
|
|
600
|
+
});
|
|
601
|
+
|
|
602
|
+
//#endregion
|
|
603
|
+
//#region ../sdk/src/schemas/fs.ts
|
|
604
|
+
const fsEntrySchema = z.object({
|
|
605
|
+
name: z.string(),
|
|
606
|
+
is_dir: z.boolean(),
|
|
607
|
+
size: z.number(),
|
|
608
|
+
mode: z.string(),
|
|
609
|
+
mod_time: zodJsonDate
|
|
610
|
+
});
|
|
611
|
+
const FSResponseValidator = Object.freeze({
|
|
612
|
+
[VALIDATOR_SYMBOL]: true,
|
|
613
|
+
__phantom__: typeOf(),
|
|
614
|
+
async parse(response) {
|
|
615
|
+
if (response.headers.get("Content-Type") === "application/json+directory") {
|
|
616
|
+
const data = await response.json();
|
|
617
|
+
return fsEntrySchema.array().parse(data);
|
|
618
|
+
} else {
|
|
619
|
+
const blob = await response.blob();
|
|
620
|
+
return new File([blob], response.url.split("/").pop(), { type: response.headers.get("content-type") ?? "application/octet-stream" });
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
});
|
|
624
|
+
|
|
625
|
+
//#endregion
|
|
626
|
+
//#region ../sdk/src/schemas/ai.ts
|
|
627
|
+
const providerMetadataSchema = z$1.record(z$1.string(), z$1.record(z$1.string(), z$1.any()));
|
|
628
|
+
const messageMetadataSchema = z$1.object().loose();
|
|
629
|
+
const toolsShapeMap = { fake: {
|
|
630
|
+
input: z$1.object({ fakeIn: z$1.string() }).loose(),
|
|
631
|
+
output: z$1.object({ fakeOut: z$1.string() }).loose()
|
|
632
|
+
} };
|
|
633
|
+
const dataTypes = {
|
|
634
|
+
delta: z$1.object().loose(),
|
|
635
|
+
"message-metadata": z$1.object().loose(),
|
|
636
|
+
"ui-collapsed": z$1.object({
|
|
637
|
+
toolParts: z$1.number(),
|
|
638
|
+
reasoningParts: z$1.number(),
|
|
639
|
+
collapsed: z$1.boolean(),
|
|
640
|
+
parts: z$1.object().loose().array()
|
|
641
|
+
}),
|
|
642
|
+
"ui-running-tools": z$1.object({
|
|
643
|
+
toolParts: z$1.object().loose().array(),
|
|
644
|
+
textParts: z$1.object().loose().array(),
|
|
645
|
+
reasoningParts: z$1.object().loose().array()
|
|
646
|
+
})
|
|
647
|
+
};
|
|
648
|
+
const chunksShapeMap = {
|
|
649
|
+
"text-start": {
|
|
650
|
+
id: z$1.string(),
|
|
651
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
652
|
+
},
|
|
653
|
+
"text-delta": {
|
|
654
|
+
delta: z$1.string(),
|
|
655
|
+
id: z$1.string(),
|
|
656
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
657
|
+
},
|
|
658
|
+
"text-end": {
|
|
659
|
+
id: z$1.string(),
|
|
660
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
661
|
+
},
|
|
662
|
+
"reasoning-start": {
|
|
663
|
+
id: z$1.string(),
|
|
664
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
665
|
+
},
|
|
666
|
+
"reasoning-delta": {
|
|
667
|
+
delta: z$1.string(),
|
|
668
|
+
id: z$1.string(),
|
|
669
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
670
|
+
},
|
|
671
|
+
"reasoning-end": {
|
|
672
|
+
id: z$1.string(),
|
|
673
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
674
|
+
},
|
|
675
|
+
error: { errorText: z$1.string() },
|
|
676
|
+
"tool-input-available": {
|
|
677
|
+
toolCallId: z$1.string(),
|
|
678
|
+
toolName: z$1.string(),
|
|
679
|
+
input: z$1.unknown(),
|
|
680
|
+
providerExecuted: z$1.boolean().optional(),
|
|
681
|
+
providerMetadata: providerMetadataSchema.optional(),
|
|
682
|
+
dynamic: z$1.boolean().optional()
|
|
683
|
+
},
|
|
684
|
+
"tool-input-error": {
|
|
685
|
+
toolCallId: z$1.string(),
|
|
686
|
+
toolName: z$1.string(),
|
|
687
|
+
input: z$1.unknown(),
|
|
688
|
+
providerExecuted: z$1.boolean().optional(),
|
|
689
|
+
providerMetadata: providerMetadataSchema.optional(),
|
|
690
|
+
dynamic: z$1.boolean().optional(),
|
|
691
|
+
errorText: z$1.string()
|
|
692
|
+
},
|
|
693
|
+
"tool-output-available": {
|
|
694
|
+
toolCallId: z$1.string(),
|
|
695
|
+
output: z$1.unknown(),
|
|
696
|
+
providerExecuted: z$1.boolean().optional(),
|
|
697
|
+
dynamic: z$1.boolean().optional(),
|
|
698
|
+
preliminary: z$1.boolean().optional()
|
|
699
|
+
},
|
|
700
|
+
"tool-output-error": {
|
|
701
|
+
toolCallId: z$1.string(),
|
|
702
|
+
providerExecuted: z$1.boolean().optional(),
|
|
703
|
+
dynamic: z$1.boolean().optional(),
|
|
704
|
+
errorText: z$1.string()
|
|
705
|
+
},
|
|
706
|
+
"tool-input-start": {
|
|
707
|
+
toolCallId: z$1.string(),
|
|
708
|
+
toolName: z$1.string(),
|
|
709
|
+
providerExecuted: z$1.boolean().optional(),
|
|
710
|
+
dynamic: z$1.boolean().optional()
|
|
711
|
+
},
|
|
712
|
+
"tool-input-delta": {
|
|
713
|
+
toolCallId: z$1.string(),
|
|
714
|
+
inputTextDelta: z$1.string()
|
|
715
|
+
},
|
|
716
|
+
"source-url": {
|
|
717
|
+
sourceId: z$1.string(),
|
|
718
|
+
url: z$1.string(),
|
|
719
|
+
title: z$1.string().optional(),
|
|
720
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
721
|
+
},
|
|
722
|
+
"source-document": {
|
|
723
|
+
sourceId: z$1.string(),
|
|
724
|
+
mediaType: z$1.string(),
|
|
725
|
+
title: z$1.string(),
|
|
726
|
+
filename: z$1.string().optional(),
|
|
727
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
728
|
+
},
|
|
729
|
+
file: {
|
|
730
|
+
url: z$1.string(),
|
|
731
|
+
mediaType: z$1.string()
|
|
732
|
+
},
|
|
733
|
+
"start-step": {},
|
|
734
|
+
"finish-step": {},
|
|
735
|
+
start: {
|
|
736
|
+
messageId: z$1.string().optional(),
|
|
737
|
+
messageMetadata: messageMetadataSchema.optional()
|
|
738
|
+
},
|
|
739
|
+
finish: { messageMetadata: messageMetadataSchema.optional() },
|
|
740
|
+
abort: {},
|
|
741
|
+
"message-metadata": { messageMetadata: messageMetadataSchema }
|
|
742
|
+
};
|
|
743
|
+
const unknownDataChunkSchema = z$1.object({
|
|
744
|
+
type: z$1.string().regex(/^data-/),
|
|
745
|
+
id: z$1.string().optional(),
|
|
746
|
+
data: z$1.unknown(),
|
|
747
|
+
transient: z$1.boolean().optional()
|
|
748
|
+
});
|
|
749
|
+
const dataChunkSchema = Object.entries(dataTypes).map(([name, schema]) => z$1.object({
|
|
750
|
+
type: z$1.literal(`data-${name}`),
|
|
751
|
+
id: z$1.string().optional(),
|
|
752
|
+
data: schema,
|
|
753
|
+
transient: z$1.boolean().optional()
|
|
754
|
+
}));
|
|
755
|
+
const chunkSchema = Object.entries(chunksShapeMap).map(([type, schema]) => z$1.object({
|
|
756
|
+
type: z$1.literal(type),
|
|
757
|
+
...schema
|
|
758
|
+
}));
|
|
759
|
+
const uiMessageChunkSchema = z$1.discriminatedUnion("type", [...chunkSchema, ...dataChunkSchema]);
|
|
760
|
+
const partsShapeMap = {
|
|
761
|
+
text: {
|
|
762
|
+
text: z$1.string(),
|
|
763
|
+
state: z$1.enum(["streaming", "done"]).optional(),
|
|
764
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
765
|
+
},
|
|
766
|
+
reasoning: {
|
|
767
|
+
text: z$1.string(),
|
|
768
|
+
state: z$1.enum(["streaming", "done"]).optional(),
|
|
769
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
770
|
+
},
|
|
771
|
+
"source-url": {
|
|
772
|
+
sourceId: z$1.string(),
|
|
773
|
+
url: z$1.string(),
|
|
774
|
+
title: z$1.string().optional(),
|
|
775
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
776
|
+
},
|
|
777
|
+
"source-document": {
|
|
778
|
+
sourceId: z$1.string(),
|
|
779
|
+
mediaType: z$1.string(),
|
|
780
|
+
title: z$1.string(),
|
|
781
|
+
filename: z$1.string().optional(),
|
|
782
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
783
|
+
},
|
|
784
|
+
file: {
|
|
785
|
+
url: z$1.string(),
|
|
786
|
+
mediaType: z$1.string(),
|
|
787
|
+
filename: z$1.string().optional(),
|
|
788
|
+
providerMetadata: providerMetadataSchema.optional()
|
|
789
|
+
},
|
|
790
|
+
"step-start": {}
|
|
791
|
+
};
|
|
792
|
+
const dynamicToolSchema = z$1.discriminatedUnion("state", [
|
|
793
|
+
z$1.object({
|
|
794
|
+
type: z$1.literal("dynamic-tool"),
|
|
795
|
+
toolName: z$1.string(),
|
|
796
|
+
toolCallId: z$1.string(),
|
|
797
|
+
state: z$1.literal("input-streaming"),
|
|
798
|
+
input: z$1.unknown().optional(),
|
|
799
|
+
output: z$1.never().optional(),
|
|
800
|
+
errorText: z$1.never().optional()
|
|
801
|
+
}),
|
|
802
|
+
z$1.object({
|
|
803
|
+
type: z$1.literal("dynamic-tool"),
|
|
804
|
+
toolName: z$1.string(),
|
|
805
|
+
toolCallId: z$1.string(),
|
|
806
|
+
state: z$1.literal("input-available"),
|
|
807
|
+
input: z$1.unknown(),
|
|
808
|
+
output: z$1.never().optional(),
|
|
809
|
+
errorText: z$1.never().optional(),
|
|
810
|
+
callProviderMetadata: providerMetadataSchema.optional()
|
|
811
|
+
}),
|
|
812
|
+
z$1.object({
|
|
813
|
+
type: z$1.literal("dynamic-tool"),
|
|
814
|
+
toolName: z$1.string(),
|
|
815
|
+
toolCallId: z$1.string(),
|
|
816
|
+
state: z$1.literal("output-available"),
|
|
817
|
+
input: z$1.unknown(),
|
|
818
|
+
output: z$1.unknown(),
|
|
819
|
+
errorText: z$1.never().optional(),
|
|
820
|
+
callProviderMetadata: providerMetadataSchema.optional(),
|
|
821
|
+
preliminary: z$1.boolean().optional()
|
|
822
|
+
}),
|
|
823
|
+
z$1.object({
|
|
824
|
+
type: z$1.literal("dynamic-tool"),
|
|
825
|
+
toolName: z$1.string(),
|
|
826
|
+
toolCallId: z$1.string(),
|
|
827
|
+
state: z$1.literal("output-error"),
|
|
828
|
+
input: z$1.unknown(),
|
|
829
|
+
output: z$1.never().optional(),
|
|
830
|
+
errorText: z$1.string(),
|
|
831
|
+
callProviderMetadata: providerMetadataSchema.optional()
|
|
832
|
+
})
|
|
833
|
+
]);
|
|
834
|
+
const dataPartSchema = Object.entries(dataTypes).map(([name, schema]) => z$1.object({
|
|
835
|
+
type: z$1.literal(`data-${name}`),
|
|
836
|
+
id: z$1.string().optional(),
|
|
837
|
+
data: schema
|
|
838
|
+
}));
|
|
839
|
+
const notDefinedDataType = z$1.string().regex(/data-/).refine((type) => !Object.keys(dataTypes).includes(type.slice(5)));
|
|
840
|
+
const unknownDataPartSchema = z$1.object({
|
|
841
|
+
type: notDefinedDataType,
|
|
842
|
+
id: z$1.string().optional(),
|
|
843
|
+
data: z$1.unknown()
|
|
844
|
+
});
|
|
845
|
+
const notDefinedToolType = z$1.string().regex(/tool-/).refine((type) => !Object.keys(toolsShapeMap).includes(type.slice(5)));
|
|
846
|
+
const unknownToolPartSchema = z$1.discriminatedUnion("state", [
|
|
847
|
+
z$1.object({
|
|
848
|
+
type: notDefinedToolType,
|
|
849
|
+
toolCallId: z$1.string(),
|
|
850
|
+
state: z$1.literal("input-streaming"),
|
|
851
|
+
input: z$1.unknown().optional(),
|
|
852
|
+
output: z$1.never().optional(),
|
|
853
|
+
providerExecuted: z$1.boolean().optional(),
|
|
854
|
+
errorText: z$1.never().optional()
|
|
855
|
+
}),
|
|
856
|
+
z$1.object({
|
|
857
|
+
type: notDefinedToolType,
|
|
858
|
+
toolCallId: z$1.string(),
|
|
859
|
+
state: z$1.literal("input-available"),
|
|
860
|
+
input: z$1.unknown(),
|
|
861
|
+
output: z$1.never().optional(),
|
|
862
|
+
providerExecuted: z$1.boolean().optional(),
|
|
863
|
+
errorText: z$1.never().optional(),
|
|
864
|
+
callProviderMetadata: providerMetadataSchema.optional()
|
|
865
|
+
}),
|
|
866
|
+
z$1.object({
|
|
867
|
+
type: notDefinedToolType,
|
|
868
|
+
toolCallId: z$1.string(),
|
|
869
|
+
state: z$1.literal("output-available"),
|
|
870
|
+
input: z$1.unknown(),
|
|
871
|
+
output: z$1.unknown(),
|
|
872
|
+
errorText: z$1.never().optional(),
|
|
873
|
+
providerExecuted: z$1.boolean().optional(),
|
|
874
|
+
callProviderMetadata: providerMetadataSchema.optional(),
|
|
875
|
+
preliminary: z$1.boolean().optional()
|
|
876
|
+
}),
|
|
877
|
+
z$1.object({
|
|
878
|
+
type: notDefinedToolType,
|
|
879
|
+
toolCallId: z$1.string(),
|
|
880
|
+
state: z$1.literal("output-error"),
|
|
881
|
+
input: z$1.unknown().optional(),
|
|
882
|
+
rawInput: z$1.unknown().optional(),
|
|
883
|
+
output: z$1.never().optional(),
|
|
884
|
+
errorText: z$1.string(),
|
|
885
|
+
providerExecuted: z$1.boolean().optional(),
|
|
886
|
+
callProviderMetadata: providerMetadataSchema.optional()
|
|
887
|
+
})
|
|
888
|
+
]);
|
|
889
|
+
const partSchema = Object.entries(partsShapeMap).map(([type, schema]) => z$1.object({
|
|
890
|
+
type: z$1.literal(type),
|
|
891
|
+
...schema
|
|
892
|
+
}));
|
|
893
|
+
const toolsPartSchema = Object.entries(toolsShapeMap).map(([type, schema]) => z$1.discriminatedUnion("state", [
|
|
894
|
+
z$1.object({
|
|
895
|
+
type: z$1.literal(`tool-${type}`),
|
|
896
|
+
toolCallId: z$1.string(),
|
|
897
|
+
state: z$1.literal("input-streaming"),
|
|
898
|
+
input: schema.input.partial().optional(),
|
|
899
|
+
output: z$1.never().optional(),
|
|
900
|
+
providerExecuted: z$1.boolean().optional(),
|
|
901
|
+
errorText: z$1.never().optional()
|
|
902
|
+
}),
|
|
903
|
+
z$1.object({
|
|
904
|
+
type: z$1.literal(`tool-${type}`),
|
|
905
|
+
toolCallId: z$1.string(),
|
|
906
|
+
state: z$1.literal("input-available"),
|
|
907
|
+
input: schema.input,
|
|
908
|
+
output: z$1.never().optional(),
|
|
909
|
+
providerExecuted: z$1.boolean().optional(),
|
|
910
|
+
errorText: z$1.never().optional(),
|
|
911
|
+
callProviderMetadata: providerMetadataSchema.optional()
|
|
912
|
+
}),
|
|
913
|
+
z$1.object({
|
|
914
|
+
type: z$1.literal(`tool-${type}`),
|
|
915
|
+
toolCallId: z$1.string(),
|
|
916
|
+
state: z$1.literal("output-available"),
|
|
917
|
+
input: schema.input,
|
|
918
|
+
output: schema.output,
|
|
919
|
+
errorText: z$1.never().optional(),
|
|
920
|
+
providerExecuted: z$1.boolean().optional(),
|
|
921
|
+
callProviderMetadata: providerMetadataSchema.optional(),
|
|
922
|
+
preliminary: z$1.boolean().optional()
|
|
923
|
+
}),
|
|
924
|
+
z$1.object({
|
|
925
|
+
type: z$1.literal(`tool-${type}`),
|
|
926
|
+
toolCallId: z$1.string(),
|
|
927
|
+
state: z$1.literal("output-error"),
|
|
928
|
+
input: schema.input.optional(),
|
|
929
|
+
rawInput: z$1.unknown().optional(),
|
|
930
|
+
output: z$1.never().optional(),
|
|
931
|
+
errorText: z$1.string(),
|
|
932
|
+
providerExecuted: z$1.boolean().optional(),
|
|
933
|
+
callProviderMetadata: providerMetadataSchema.optional()
|
|
934
|
+
})
|
|
935
|
+
]));
|
|
936
|
+
const uiMessagePartSchema = z$1.discriminatedUnion("type", [
|
|
937
|
+
...partSchema,
|
|
938
|
+
...toolsPartSchema,
|
|
939
|
+
...dataPartSchema,
|
|
940
|
+
dynamicToolSchema
|
|
941
|
+
]);
|
|
942
|
+
|
|
943
|
+
//#endregion
|
|
944
|
+
//#region ../sdk/src/schemas/project.ts
|
|
945
|
+
const projectMetaGitHubSchema = z.object({
|
|
946
|
+
repo_owner_login: z.string().optional(),
|
|
947
|
+
repo_name: z.string().optional(),
|
|
948
|
+
issue_type: z.string().optional(),
|
|
949
|
+
issue_number: z.number().optional()
|
|
950
|
+
}).optional();
|
|
951
|
+
const projectMetaSchema = z.object({ github: projectMetaGitHubSchema }).optional().nullable();
|
|
952
|
+
const projectSchema = z.object({
|
|
953
|
+
id: z.string(),
|
|
954
|
+
name: z.string(),
|
|
955
|
+
display_name: z.string(),
|
|
956
|
+
category: z.string(),
|
|
957
|
+
description: z.string(),
|
|
958
|
+
user_id: z.string().nullable(),
|
|
959
|
+
owner_email: z.string().nullable().optional(),
|
|
960
|
+
root_branch_id: z.string().nullable(),
|
|
961
|
+
ongoing_stream_id: z.string().nullable(),
|
|
962
|
+
status: z.enum([
|
|
963
|
+
"CREATED",
|
|
964
|
+
"PROVISIONING",
|
|
965
|
+
"READY",
|
|
966
|
+
"RUNNING",
|
|
967
|
+
"PAUSED",
|
|
968
|
+
"FAILED",
|
|
969
|
+
"ARCHIVED"
|
|
970
|
+
]).nullable().optional(),
|
|
971
|
+
error_message: z.string().nullable().optional(),
|
|
972
|
+
meta: projectMetaSchema,
|
|
973
|
+
github_source_owner_id: z.number().nullable().optional(),
|
|
974
|
+
github_source_repo_id: z.number().nullable().optional(),
|
|
975
|
+
github_source_number: z.number().nullable().optional(),
|
|
976
|
+
created_at: zodJsonDate,
|
|
977
|
+
updated_at: zodJsonDate,
|
|
978
|
+
branches_total: z.number().int().nullable().optional(),
|
|
979
|
+
background_tasks_total: z.number().int().nullable().optional()
|
|
980
|
+
});
|
|
981
|
+
const projectMessageSchema = z.object({
|
|
982
|
+
id: z.string(),
|
|
983
|
+
role: z.enum([
|
|
984
|
+
"system",
|
|
985
|
+
"user",
|
|
986
|
+
"assistant"
|
|
987
|
+
]),
|
|
988
|
+
metadata: messageMetadataSchema.nullable().optional(),
|
|
989
|
+
parts: z.array(z.object().loose()),
|
|
990
|
+
ordinal: z.number(),
|
|
991
|
+
project_id: z.string(),
|
|
992
|
+
user_id: z.string().nullable(),
|
|
993
|
+
source_request_id: z.string().nullable().optional(),
|
|
994
|
+
event_stream_id: z.string().nullable(),
|
|
995
|
+
status: z.string().nullable(),
|
|
996
|
+
is_finished: z.boolean(),
|
|
997
|
+
created_at: zodJsonDate,
|
|
998
|
+
updated_at: zodJsonDate
|
|
999
|
+
});
|
|
1000
|
+
const projectMessageStreamParser = new StreamResponseParser({ pipe: (input) => {
|
|
1001
|
+
return input.pipeThrough(new TextDecoderStream()).pipeThrough(new BufferedLinesStream("\n\n")).pipeThrough(new SSEDataDecoderStream()).pipeThrough(new ZodStream({ schema: z.object().loose() }));
|
|
1002
|
+
} });
|
|
1003
|
+
const projectRawMessageStreamParser = new StreamResponseParser({ pipe: (input) => {
|
|
1004
|
+
return input.pipeThrough(new TextDecoderStream()).pipeThrough(new BufferedLinesStream("\n\n")).pipeThrough(new SSEDataDecoderStream()).pipeThrough(new ZodStream({ schema: z.object().loose() }));
|
|
1005
|
+
} });
|
|
1006
|
+
const projectQueuedRequestSchema = z.object({
|
|
1007
|
+
id: z.string(),
|
|
1008
|
+
type: z.string(),
|
|
1009
|
+
payload: z.unknown(),
|
|
1010
|
+
requested_at: zodJsonDate,
|
|
1011
|
+
summary: z.string()
|
|
1012
|
+
});
|
|
1013
|
+
const projectBackgroundTaskSchema = z.object({
|
|
1014
|
+
task_id: z.string(),
|
|
1015
|
+
name: z.string().nullable(),
|
|
1016
|
+
action_type: z.enum(["execution", "exploration"]),
|
|
1017
|
+
action_id: z.string(),
|
|
1018
|
+
status: z.enum([
|
|
1019
|
+
"SUCCESS",
|
|
1020
|
+
"FAILURE",
|
|
1021
|
+
"PENDING",
|
|
1022
|
+
"STARTED"
|
|
1023
|
+
]).nullable(),
|
|
1024
|
+
result: z.object().loose().nullable(),
|
|
1025
|
+
retries: z.number().nullable(),
|
|
1026
|
+
started_at: zodJsonDate.nullable(),
|
|
1027
|
+
last_polled_at: zodJsonDate.nullable(),
|
|
1028
|
+
ended_at: zodJsonDate.nullable()
|
|
1029
|
+
});
|
|
1030
|
+
var BufferedLinesStream = class extends TransformStream {
|
|
1031
|
+
constructor(sep = "\n") {
|
|
1032
|
+
let buffer = "";
|
|
1033
|
+
super({
|
|
1034
|
+
transform(chunk, controller) {
|
|
1035
|
+
chunk = buffer += chunk;
|
|
1036
|
+
while (true) {
|
|
1037
|
+
const index = chunk.indexOf(sep);
|
|
1038
|
+
if (index === -1) {
|
|
1039
|
+
buffer = chunk;
|
|
1040
|
+
break;
|
|
1041
|
+
}
|
|
1042
|
+
const line = chunk.slice(0, index).trim();
|
|
1043
|
+
if (line) controller.enqueue(line);
|
|
1044
|
+
chunk = chunk.slice(index + sep.length);
|
|
1045
|
+
}
|
|
1046
|
+
},
|
|
1047
|
+
flush() {
|
|
1048
|
+
if (buffer) console.warn("buffered lines stream has unprocessed lines:", buffer);
|
|
1049
|
+
}
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
};
|
|
1053
|
+
var SSEDataDecoderStream = class extends TransformStream {
|
|
1054
|
+
constructor() {
|
|
1055
|
+
let handle = void 0;
|
|
1056
|
+
super({ transform: (chunk, controller) => {
|
|
1057
|
+
clearTimeout(handle);
|
|
1058
|
+
handle = setTimeout(() => {
|
|
1059
|
+
controller.error(/* @__PURE__ */ new Error("Read timeout, please retry."));
|
|
1060
|
+
}, 15e3);
|
|
1061
|
+
if (/^data:/.test(chunk)) {
|
|
1062
|
+
const part = chunk.replace(/^data: /, "").trim();
|
|
1063
|
+
if (part === "[DONE]") {} else try {
|
|
1064
|
+
controller.enqueue(JSON.parse(part));
|
|
1065
|
+
} catch (e) {
|
|
1066
|
+
console.error("invalid sse chunk", chunk, e);
|
|
1067
|
+
controller.error(e);
|
|
1068
|
+
}
|
|
1069
|
+
}
|
|
1070
|
+
} });
|
|
1071
|
+
}
|
|
1072
|
+
};
|
|
1073
|
+
|
|
1074
|
+
//#endregion
|
|
1075
|
+
//#region ../sdk/src/api/projects.ts
|
|
1076
|
+
const listProjects = defineApi(get`/api/v1/projects?page=${"page"}&size=${"size"}&user_id=${"user_id?"}&category=${"category?"}&github_source_owner_id=${"github_source_owner_id?"}&github_source_repo_id=${"github_source_repo_id?"}`, null, paged(projectSchema));
|
|
1077
|
+
const listAdminProjects = defineApi(get`/api/v1/admin/projects?page=${"page"}&size=${"size"}&org_id=${"org_id?"}&user_id=${"user_id?"}&category=${"category?"}&github_source_owner_id=${"github_source_owner_id?"}&github_source_repo_id=${"github_source_repo_id?"}`, null, paged(projectSchema));
|
|
1078
|
+
const getProject = defineApi(get`/api/v1/projects/${"projectId"}`, null, projectSchema);
|
|
1079
|
+
const transferProject = defineApi(post`/api/v1/projects/${"projectId"}/transfer`, typeOf(), projectSchema);
|
|
1080
|
+
const createProject = defineApi(post`/api/v1/projects`, typeOf(), projectSchema);
|
|
1081
|
+
const listProjectMessages = defineApi(get`/api/v1/projects/${"projectId"}/messages`, null, z.object({
|
|
1082
|
+
messages: projectMessageSchema.array(),
|
|
1083
|
+
ongoing_stream_id: z.string().nullable()
|
|
1084
|
+
}));
|
|
1085
|
+
const deleteProjectMessage = defineApi(del`/api/v1/projects/${"projectId"}/messages/${"messageId"}`, null, "raw");
|
|
1086
|
+
const postProjectMessage = defineApi(post`/api/v1/projects/${"projectId"}`, typeOf(), z.object({
|
|
1087
|
+
messages: projectMessageSchema.array(),
|
|
1088
|
+
ongoing_stream_id: z.string().nullable()
|
|
1089
|
+
}));
|
|
1090
|
+
const continueProject = defineApi(post`/api/v1/projects/${"projectId"}/continue`, typeOf(), "raw");
|
|
1091
|
+
const stopProject = defineApi(post`/api/v1/projects/${"projectId"}/stop`, typeOf(), "raw");
|
|
1092
|
+
const getProjectBranch = defineApi(get`/api/v1/projects/${"projectId"}/branches/${"branchId"}`, null, branchSchema);
|
|
1093
|
+
const getProjectBranchOutput = defineApi(get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/output?full_output=${"fullOutput?"}`, null, "text");
|
|
1094
|
+
const listProjectBranches = defineApi(get`/api/v1/projects/${"projectId"}/branches?page=${"page"}&size=${"size"}`, null, paged(branchSchema));
|
|
1095
|
+
const listProjectBranchSnaps = defineApi(get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/snaps`, null, branchSnapsSchema);
|
|
1096
|
+
const listProjectBackgroundTasks = defineApi(get`/api/v1/projects/${"projectId"}/background_tasks?statuses=${"statuses?"}`, null, z.array(projectBackgroundTaskSchema));
|
|
1097
|
+
const createProjectExploration = defineApi(post`/api/v1/projects/${"projectId"}/explorations`, typeOf(), createExplorationResultSchema);
|
|
1098
|
+
const listProjectExplorations = defineApi(get`/api/v1/projects/${"projectId"}/explorations`, null, explorationSchema.array());
|
|
1099
|
+
const getProjectExplorationResult = defineApi(get`/api/v1/projects/${"projectId"}/explorations/${"explorationId"}/result`, null, explorationResultSchema);
|
|
1100
|
+
const getProjectBranchFs = defineApi(get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/fs/${"path*"}`, null, FSResponseValidator);
|
|
1101
|
+
const getProjectBranchFsPreview = defineApi(get`/api/v1/projects/${"projectId"}/branches/${"branchId"}/preview/${"path*"}`, null, FSResponseValidator);
|
|
1102
|
+
|
|
1103
|
+
//#endregion
|
|
1104
|
+
//#region ../sdk/src/api/connectors.ts
|
|
1105
|
+
const getGithubUser = defineApi(get`/api/v1/connectors/github/user`, null, z.object({ github_username: z.string() }).nullable());
|
|
1106
|
+
const disconnectGithub = defineApi(post`/api/v1/connectors/github/disconnect`, null, z.object({ success: z.boolean() }));
|
|
1107
|
+
const listGithubRepositories = defineApi(get`/api/v1/user/github/repositories?page=${"page"}&size=${"size"}`, null, paged(z.object({
|
|
1108
|
+
repo_id: z.number(),
|
|
1109
|
+
repo_name: z.string(),
|
|
1110
|
+
public: z.boolean(),
|
|
1111
|
+
installation_id: z.number()
|
|
1112
|
+
})));
|
|
1113
|
+
|
|
1114
|
+
//#endregion
|
|
1115
|
+
//#region ../sdk/src/schemas/organizations.ts
|
|
1116
|
+
const organizationItemSchema = z.object({
|
|
1117
|
+
id: z.string(),
|
|
1118
|
+
name: z.string(),
|
|
1119
|
+
is_personal: z.boolean(),
|
|
1120
|
+
created_at: z.string().nullable(),
|
|
1121
|
+
updated_at: z.string().nullable()
|
|
1122
|
+
});
|
|
1123
|
+
const organizationSchema = organizationItemSchema;
|
|
1124
|
+
const organizationDeleteSchema = z.object({ success: z.boolean() });
|
|
1125
|
+
const organizationRoleSchema = z.enum(["owner", "member"]);
|
|
1126
|
+
const organizationMemberSchema = z.object({
|
|
1127
|
+
org_id: z.string(),
|
|
1128
|
+
user_id: z.string(),
|
|
1129
|
+
email: z.string().nullable().optional(),
|
|
1130
|
+
github_username: z.string().nullable().optional(),
|
|
1131
|
+
role: organizationRoleSchema,
|
|
1132
|
+
created_at: z.string().nullable(),
|
|
1133
|
+
updated_at: z.string().nullable()
|
|
1134
|
+
});
|
|
1135
|
+
const addOrgMemberResponseSchema = z.object({
|
|
1136
|
+
member: organizationMemberSchema.nullable().optional(),
|
|
1137
|
+
email_sent: z.boolean().nullable().optional(),
|
|
1138
|
+
invite_link: z.string().nullable().optional()
|
|
1139
|
+
});
|
|
1140
|
+
const invitationStatusSchema = z.enum(["pending", "accepted"]);
|
|
1141
|
+
const organizationInvitationSchema = z.object({
|
|
1142
|
+
id: z.string(),
|
|
1143
|
+
org_id: z.string(),
|
|
1144
|
+
org_role: organizationRoleSchema,
|
|
1145
|
+
email: z.string().nullable(),
|
|
1146
|
+
github_username: z.string().nullable(),
|
|
1147
|
+
invited_by: z.string(),
|
|
1148
|
+
status: invitationStatusSchema,
|
|
1149
|
+
created_at: z.string().nullable(),
|
|
1150
|
+
updated_at: z.string().nullable()
|
|
1151
|
+
});
|
|
1152
|
+
|
|
1153
|
+
//#endregion
|
|
1154
|
+
//#region ../sdk/src/schemas/github.ts
|
|
1155
|
+
const githubAppInstallationSchema = z.object({
|
|
1156
|
+
installation_id: z.number(),
|
|
1157
|
+
github_account_id: z.number(),
|
|
1158
|
+
github_account_login: z.string(),
|
|
1159
|
+
github_account_type: z.string(),
|
|
1160
|
+
org_id: z.string().nullable()
|
|
1161
|
+
});
|
|
1162
|
+
const githubAppInstallationAdminItemSchema = z.object({
|
|
1163
|
+
installation_id: z.number(),
|
|
1164
|
+
github_account_id: z.number(),
|
|
1165
|
+
github_account_login: z.string(),
|
|
1166
|
+
github_account_type: z.string(),
|
|
1167
|
+
org_id: z.string().nullable(),
|
|
1168
|
+
org_name: z.string().nullable(),
|
|
1169
|
+
installer_user_id: z.string().nullable(),
|
|
1170
|
+
installer_email: z.string().nullable(),
|
|
1171
|
+
created_at: z.string().nullable(),
|
|
1172
|
+
updated_at: z.string().nullable()
|
|
1173
|
+
});
|
|
1174
|
+
const githubRepositorySchema = z.object({
|
|
1175
|
+
repo_id: z.number(),
|
|
1176
|
+
repo_name: z.string(),
|
|
1177
|
+
public: z.boolean(),
|
|
1178
|
+
installation_id: z.number(),
|
|
1179
|
+
enabled: z.boolean().default(false)
|
|
1180
|
+
});
|
|
1181
|
+
const githubAutoReviewConfigSchema = z.object({
|
|
1182
|
+
enabled: z.boolean(),
|
|
1183
|
+
enable_for_non_linked_users: z.boolean().default(false),
|
|
1184
|
+
auto_incremental_review: z.boolean(),
|
|
1185
|
+
labels: z.array(z.string()),
|
|
1186
|
+
drafts: z.boolean(),
|
|
1187
|
+
base_branches: z.array(z.string()),
|
|
1188
|
+
ignore_usernames: z.array(z.string())
|
|
1189
|
+
});
|
|
1190
|
+
const githubRepoSettingsConfigSchema = z.object({
|
|
1191
|
+
allow_usernames: z.array(z.string()),
|
|
1192
|
+
auto_review: githubAutoReviewConfigSchema
|
|
1193
|
+
});
|
|
1194
|
+
const githubRepoSettingsPublicSchema = z.object({
|
|
1195
|
+
enabled: z.boolean(),
|
|
1196
|
+
config: githubRepoSettingsConfigSchema
|
|
1197
|
+
});
|
|
1198
|
+
const githubRepoSettingsUpdateSchema = z.object({
|
|
1199
|
+
enabled: z.boolean().optional(),
|
|
1200
|
+
config: githubRepoSettingsConfigSchema.optional()
|
|
1201
|
+
});
|
|
1202
|
+
|
|
1203
|
+
//#endregion
|
|
1204
|
+
//#region ../sdk/src/api/organizations.ts
|
|
1205
|
+
const listOrganizations = defineApi(get`/api/v1/orgs?page=${"page"}&size=${"size"}`, null, paged(organizationItemSchema));
|
|
1206
|
+
const getOrganization = defineApi(get`/api/v1/orgs/${"orgId"}`, null, organizationSchema);
|
|
1207
|
+
const createOrganization = defineApi(post`/api/v1/orgs`, typeOf(), organizationSchema);
|
|
1208
|
+
const updateOrganization = defineApi(put`/api/v1/orgs/${"orgId"}`, typeOf(), organizationSchema);
|
|
1209
|
+
const deleteOrganization = defineApi(del`/api/v1/orgs/${"orgId"}`, null, organizationDeleteSchema);
|
|
1210
|
+
const listOrganizationMembers = defineApi(get`/api/v1/orgs/${"orgId"}/members?page=${"page"}&size=${"size"}`, null, paged(organizationMemberSchema));
|
|
1211
|
+
const listOrganizationInvitations = defineApi(get`/api/v1/orgs/${"orgId"}/invitations?page=${"page"}&size=${"size"}&status=${"status?"}`, null, paged(organizationInvitationSchema));
|
|
1212
|
+
const revokeOrganizationInvitation = defineApi(del`/api/v1/orgs/${"orgId"}/invitations/${"invitationId"}`, null, z.object({ success: z.boolean() }));
|
|
1213
|
+
const addOrganizationMember = defineApi(post`/api/v1/orgs/${"orgId"}/members`, typeOf(), addOrgMemberResponseSchema);
|
|
1214
|
+
const updateOrganizationMemberRole = defineApi(put`/api/v1/orgs/${"orgId"}/members/${"memberId"}`, typeOf(), organizationMemberSchema);
|
|
1215
|
+
const removeOrganizationMember = defineApi(del`/api/v1/orgs/${"orgId"}/members/${"memberId"}`, null, z.object({ success: z.boolean() }));
|
|
1216
|
+
const listOrganizationGithubInstallations = defineApi(get`/api/v1/orgs/${"orgId"}/github/installations`, null, z.array(githubAppInstallationSchema));
|
|
1217
|
+
const listOrgLinkedAccounts = defineApi(get`/api/v1/orgs/${"orgId"}/github/linked_accounts`, null, z.array(githubAppInstallationSchema));
|
|
1218
|
+
const listOrgLinkedRepositories = defineApi(get`/api/v1/orgs/${"orgId"}/github/linked_repositories`, null, z.array(githubRepositorySchema));
|
|
1219
|
+
const listOrganizationGithubRepositories = defineApi(get`/api/v1/orgs/${"orgId"}/github/installations/${"installationId"}/repos`, null, z.array(githubRepositorySchema));
|
|
1220
|
+
const listOrganizationProjects = defineApi(get`/api/v1/orgs/${"orgId"}/projects?page=${"page"}&size=${"size"}&query=${"query?"}&category=${"category?"}&github_source_owner_id=${"github_source_owner_id?"}&github_source_repo_id=${"github_source_repo_id?"}`, null, paged(projectSchema));
|
|
1221
|
+
const createOrganizationProject = defineApi(post`/api/v1/orgs/${"orgId"}/projects`, typeOf(), projectSchema);
|
|
1222
|
+
const getOrganizationGithubRepoSettings = defineApi(get`/api/v1/orgs/${"orgId"}/github/installations/${"installationId"}/repos/${"repoId"}/settings`, null, githubRepoSettingsPublicSchema);
|
|
1223
|
+
const updateOrganizationGithubRepoSettings = defineApi(put`/api/v1/orgs/${"orgId"}/github/installations/${"installationId"}/repos/${"repoId"}/settings`, typeOf(), githubRepoSettingsPublicSchema);
|
|
1224
|
+
|
|
1225
|
+
//#endregion
|
|
1226
|
+
//#region ../sdk/src/api/stream-proxy.ts
|
|
1227
|
+
const readMessageStream = defineApi(get`/ai_stream_proxy/v2/streams/${"streamId"}/stream?format=vercel-ai-ui-message-stream-v1&skip=${"skip?"}`, null, projectMessageStreamParser);
|
|
1228
|
+
const readRawMessageStream = defineApi(get`/ai_stream_proxy/v2/streams/${"streamId"}/stream?format=opaque-stream-json`, null, projectRawMessageStreamParser);
|
|
1229
|
+
|
|
1230
|
+
//#endregion
|
|
1231
|
+
//#region ../sdk/src/schemas/api-key.ts
|
|
1232
|
+
const publicApiKeySchema = z.object({
|
|
1233
|
+
id: z.union([z.string(), z.number()]).transform(String),
|
|
1234
|
+
description: z.string().nullable().optional(),
|
|
1235
|
+
api_key_display: z.string(),
|
|
1236
|
+
created_at: zodJsonDate,
|
|
1237
|
+
updated_at: zodJsonDate.optional(),
|
|
1238
|
+
is_active: z.boolean(),
|
|
1239
|
+
user_id: z.string()
|
|
1240
|
+
});
|
|
1241
|
+
const apiKeyCreateRequestSchema = z.object({ description: z.string() });
|
|
1242
|
+
const apiKeyCreateResponseSchema = publicApiKeySchema.extend({ api_key: z.string() });
|
|
1243
|
+
|
|
1244
|
+
//#endregion
|
|
1245
|
+
//#region ../sdk/src/api/user-api-keys.ts
|
|
1246
|
+
const listUserApiKeys = defineApi(get`/api/v1/user/api-keys?page=${"page"}&size=${"size"}`, null, paged(publicApiKeySchema));
|
|
1247
|
+
const createUserApiKey = defineApi(post`/api/v1/user/api-keys`, typeOf(), apiKeyCreateResponseSchema);
|
|
1248
|
+
const deleteUserApiKey = defineApi(del`/api/v1/user/api-keys/${"apiKeyId"}`, null, "raw");
|
|
1249
|
+
|
|
1250
|
+
//#endregion
|
|
1251
|
+
//#region ../sdk/src/lib/api-executor.ts
|
|
1252
|
+
var ApiError = class extends Error {
|
|
1253
|
+
response;
|
|
1254
|
+
context;
|
|
1255
|
+
responseBody;
|
|
1256
|
+
constructor(response, context, responseBody) {
|
|
1257
|
+
super(`${context.request.method} ${context.url}: ${response.status} ${response.statusText} ${getServerErrorMessage(responseBody)}`);
|
|
1258
|
+
this.response = response;
|
|
1259
|
+
this.context = context;
|
|
1260
|
+
this.responseBody = responseBody;
|
|
1261
|
+
}
|
|
1262
|
+
};
|
|
1263
|
+
function createApiExecutor({ baseUrl, headers, validateResponse }) {
|
|
1264
|
+
const errorCallbacks = [];
|
|
1265
|
+
function onError(callback) {
|
|
1266
|
+
errorCallbacks.push(callback);
|
|
1267
|
+
return () => {
|
|
1268
|
+
const index = errorCallbacks.indexOf(callback);
|
|
1269
|
+
if (index !== -1) errorCallbacks.splice(index, 1);
|
|
1270
|
+
};
|
|
1271
|
+
}
|
|
1272
|
+
async function execute(api, params, requestBody, requestInit) {
|
|
1273
|
+
const url = baseUrl ? new URL(api.url(params), baseUrl).toString() : api.url(params);
|
|
1274
|
+
const { headers: initHeaders, ...init } = api.requestInit(requestBody);
|
|
1275
|
+
const executorHeaders = new Headers(headers);
|
|
1276
|
+
if (initHeaders) new Headers(initHeaders).forEach((value, key) => {
|
|
1277
|
+
executorHeaders.set(key, value);
|
|
1278
|
+
});
|
|
1279
|
+
const request = new Request(url, {
|
|
1280
|
+
...requestInit,
|
|
1281
|
+
...init,
|
|
1282
|
+
headers: executorHeaders,
|
|
1283
|
+
credentials: "include"
|
|
1284
|
+
});
|
|
1285
|
+
const context = Object.freeze({
|
|
1286
|
+
api,
|
|
1287
|
+
params,
|
|
1288
|
+
requestBody,
|
|
1289
|
+
url,
|
|
1290
|
+
request
|
|
1291
|
+
});
|
|
1292
|
+
try {
|
|
1293
|
+
const response = await fetch(request);
|
|
1294
|
+
await validateResponse(response, context);
|
|
1295
|
+
return await api.handleResponse(response, context);
|
|
1296
|
+
} catch (error) {
|
|
1297
|
+
for (const callback of errorCallbacks) callback(error, context);
|
|
1298
|
+
return Promise.reject(error);
|
|
1299
|
+
}
|
|
1300
|
+
}
|
|
1301
|
+
return Object.freeze({
|
|
1302
|
+
execute,
|
|
1303
|
+
onError
|
|
1304
|
+
});
|
|
1305
|
+
}
|
|
1306
|
+
async function validateResponse(response, context) {
|
|
1307
|
+
if (!response.ok) throw new ApiError(response, context, await response.clone().json().catch(() => response.clone().text()).catch(() => void 0));
|
|
1308
|
+
}
|
|
1309
|
+
function getServerErrorMessage(error) {
|
|
1310
|
+
if (error == null) return "No error message.";
|
|
1311
|
+
if (typeof error === "string") return error;
|
|
1312
|
+
if (typeof error === "object") {
|
|
1313
|
+
for (const key of [
|
|
1314
|
+
"message",
|
|
1315
|
+
"error",
|
|
1316
|
+
"errMsg",
|
|
1317
|
+
"errorMsg",
|
|
1318
|
+
"detail",
|
|
1319
|
+
"details"
|
|
1320
|
+
]) if (key in error) if (typeof error[key] === "string") return error[key];
|
|
1321
|
+
else return JSON.stringify(error[key], void 0, 2);
|
|
1322
|
+
return JSON.stringify(error, void 0, 2);
|
|
1323
|
+
}
|
|
1324
|
+
return String(error);
|
|
1325
|
+
}
|
|
1326
|
+
|
|
1327
|
+
//#endregion
|
|
1328
|
+
//#region core/pantheon.ts
|
|
1329
|
+
const executor = createApiExecutor({
|
|
1330
|
+
baseUrl: "https://pantheon-ai.tidb.ai",
|
|
1331
|
+
headers: { Authorization: `Bearer ${process.env.PANTHEON_API_KEY}` },
|
|
1332
|
+
validateResponse
|
|
1333
|
+
});
|
|
1334
|
+
async function getPantheonProjectInfo({ projectId }) {
|
|
1335
|
+
return await executor.execute(getProject, { projectId }, null);
|
|
1336
|
+
}
|
|
1337
|
+
async function getPantheonBranch({ projectId, branchId, getOutputIfFinished = false, manifestingAsSucceed = false }) {
|
|
1338
|
+
const branch = await executor.execute(getProjectBranch, {
|
|
1339
|
+
projectId,
|
|
1340
|
+
branchId
|
|
1341
|
+
}, null);
|
|
1342
|
+
if (branch.status === "succeed" || manifestingAsSucceed && (branch.status === "manifesting" || branch.status === "ready_for_manifest")) if (getOutputIfFinished) return {
|
|
1343
|
+
state: "succeed",
|
|
1344
|
+
output: await executor.execute(getProjectBranchOutput, {
|
|
1345
|
+
projectId,
|
|
1346
|
+
branchId,
|
|
1347
|
+
fullOutput: true
|
|
1348
|
+
}, null)
|
|
1349
|
+
};
|
|
1350
|
+
else return { state: "succeed" };
|
|
1351
|
+
else if (branch.status === "failed") {
|
|
1352
|
+
let error = branch.latest_snap?.error;
|
|
1353
|
+
if (!error) {
|
|
1354
|
+
error = await executor.execute(getProjectBranchOutput, {
|
|
1355
|
+
projectId,
|
|
1356
|
+
branchId,
|
|
1357
|
+
fullOutput: true
|
|
1358
|
+
}, null);
|
|
1359
|
+
error = `No error message, the latest output:\n\n${error}`;
|
|
1360
|
+
}
|
|
1361
|
+
return {
|
|
1362
|
+
state: "failed",
|
|
1363
|
+
error
|
|
1364
|
+
};
|
|
1365
|
+
}
|
|
1366
|
+
return { state: "others" };
|
|
1367
|
+
}
|
|
1368
|
+
async function executeOnPantheon({ projectId, branchId, prompt, agent }) {
|
|
1369
|
+
return (await executor.execute(createProjectExploration, { projectId }, {
|
|
1370
|
+
shared_prompt_sequence: [prompt],
|
|
1371
|
+
num_branches: 1,
|
|
1372
|
+
agent,
|
|
1373
|
+
parent_branch_id: branchId
|
|
1374
|
+
})).branches[0].branch_id;
|
|
1375
|
+
}
|
|
1376
|
+
|
|
1377
|
+
//#endregion
|
|
1378
|
+
//#region core/task-list.ts
|
|
1379
|
+
async function startTaskListLoop(agentName, { loopInterval = 5 }, logger) {
|
|
1380
|
+
logger.info("Starting task list loop...");
|
|
1381
|
+
let i = 0;
|
|
1382
|
+
const abortController = new AbortController();
|
|
1383
|
+
let sleepTimeout;
|
|
1384
|
+
process.on("SIGINT", (signal) => {
|
|
1385
|
+
logger.info(`Received ${signal}, shutting down gracefully...`);
|
|
1386
|
+
clearTimeout(sleepTimeout);
|
|
1387
|
+
abortController.abort(signal);
|
|
1388
|
+
});
|
|
1389
|
+
process.on("SIGTERM", (signal) => {
|
|
1390
|
+
logger.info(`Received ${signal}, force shutting down...`);
|
|
1391
|
+
clearTimeout(sleepTimeout);
|
|
1392
|
+
abortController.abort(signal);
|
|
1393
|
+
process.exit(1);
|
|
1394
|
+
});
|
|
1395
|
+
const provider = new TaskListTidbProvider(agentName, logger);
|
|
1396
|
+
while (!abortController.signal.aborted) {
|
|
1397
|
+
await loopOnce(provider, logger.child({ name: `loop:${i++}` }));
|
|
1398
|
+
await new Promise((resolve) => {
|
|
1399
|
+
abortController.signal.addEventListener("abort", resolve);
|
|
1400
|
+
sleepTimeout = setTimeout(() => {
|
|
1401
|
+
abortController.signal.removeEventListener("abort", resolve);
|
|
1402
|
+
resolve(false);
|
|
1403
|
+
}, loopInterval * 1e3);
|
|
1404
|
+
});
|
|
1405
|
+
}
|
|
1406
|
+
await provider.close();
|
|
1407
|
+
process.exit(0);
|
|
1408
|
+
}
|
|
1409
|
+
async function loopOnce(provider, logger) {
|
|
1410
|
+
logger.info("Loop start.");
|
|
1411
|
+
const tasks = await provider.getTasks({ status: ["pending", "running"] });
|
|
1412
|
+
const runningTasks = tasks.filter((task) => task.status === "running");
|
|
1413
|
+
const pendingTasks = tasks.filter((task) => task.status === "pending");
|
|
1414
|
+
logger.info(`Found ${tasks.length} tasks, ${runningTasks.length} running, ${pendingTasks.length} pending.`);
|
|
1415
|
+
if (runningTasks.length > 1) logger.warn("More than one task is running, this is not expected. %o", runningTasks.map((task) => task.id));
|
|
1416
|
+
const nextTask = pendingTasks[0];
|
|
1417
|
+
if (runningTasks.length > 0) {
|
|
1418
|
+
if ((await Promise.allSettled(runningTasks.map(async (task) => {
|
|
1419
|
+
await pollRunningTaskState(provider, task, logger.child({ name: `task:${task.id}:poll` }));
|
|
1420
|
+
}))).some((result) => result.status === "rejected")) logger.warn("Failed to poll state for one or more running tasks");
|
|
1421
|
+
} else if (nextTask) try {
|
|
1422
|
+
await startPendingTask(provider, pendingTasks[0], logger.child({ name: `task:${nextTask.id}:start` }));
|
|
1423
|
+
} catch (e) {
|
|
1424
|
+
logger.error(`Failed to start task ${nextTask.id}: ${getErrorMessage(e)}`);
|
|
1425
|
+
}
|
|
1426
|
+
else logger.info("No tasks to process.");
|
|
1427
|
+
}
|
|
1428
|
+
async function pollRunningTaskState(provider, state, logger) {
|
|
1429
|
+
const newStatus = await getPantheonBranch({
|
|
1430
|
+
projectId: state.project_id,
|
|
1431
|
+
branchId: state.branch_id,
|
|
1432
|
+
getOutputIfFinished: true
|
|
1433
|
+
});
|
|
1434
|
+
if (newStatus.state === "succeed") {
|
|
1435
|
+
logger.info("Task completed with output: %s", newStatus.output);
|
|
1436
|
+
await provider.completeTask(state, newStatus.output || "(no output)");
|
|
1437
|
+
} else if (newStatus.state === "failed") {
|
|
1438
|
+
logger.info("Task failed with error: %s", newStatus.error);
|
|
1439
|
+
await provider.failTask(state, newStatus.error);
|
|
1440
|
+
} else logger.info("Task is still pending");
|
|
1441
|
+
}
|
|
1442
|
+
async function startPendingTask(provider, task, logger) {
|
|
1443
|
+
const config = await provider.getAgentConfig(task.project_id);
|
|
1444
|
+
if (!config) {
|
|
1445
|
+
logger.warn("Agent configuration not found for project %s. Skip starting tasks.", task.project_id);
|
|
1446
|
+
return;
|
|
1447
|
+
}
|
|
1448
|
+
await provider.startTask(task, async () => {
|
|
1449
|
+
return await executeOnPantheon({
|
|
1450
|
+
projectId: task.project_id,
|
|
1451
|
+
branchId: task.base_branch_id,
|
|
1452
|
+
prompt: task.task,
|
|
1453
|
+
agent: config.execute_agent
|
|
1454
|
+
});
|
|
1455
|
+
});
|
|
1456
|
+
logger.info(`Task ${task.id} started successfully.`);
|
|
1457
|
+
}
|
|
1458
|
+
|
|
1459
|
+
//#endregion
|
|
1460
|
+
//#region core/index.ts
|
|
1461
|
+
async function runAgent(name, options, logger) {
|
|
1462
|
+
const agentDir = path.join(options.dataDir, "agents", name);
|
|
1463
|
+
const pidFile = path.join(agentDir, "pid");
|
|
1464
|
+
await fs$1.promises.mkdir(agentDir, { recursive: true });
|
|
1465
|
+
await assertsSingleton(logger, pidFile);
|
|
1466
|
+
await startTaskListLoop(name, { loopInterval: options.loopInterval }, logger);
|
|
1467
|
+
}
|
|
1468
|
+
async function configAgent(name, options) {
|
|
1469
|
+
const provider = new TaskListTidbProvider(name, pino());
|
|
1470
|
+
const previousConfig = await provider.getAgentConfig(options.projectId);
|
|
1471
|
+
if (previousConfig) if (previousConfig.role === options.role) {
|
|
1472
|
+
console.log(`Agent ${name} already configured as ${options.role} for project ${options.projectId}.`);
|
|
1473
|
+
console.log(`Base branch id: ${previousConfig.base_branch_id}`);
|
|
1474
|
+
return;
|
|
1475
|
+
} else {
|
|
1476
|
+
console.error(`Agent ${name} already configured as ${previousConfig.role} for project ${options.projectId}.`);
|
|
1477
|
+
console.error(`Base branch id: ${previousConfig.base_branch_id}`);
|
|
1478
|
+
console.error(`Cannot change role to ${options.role}`);
|
|
1479
|
+
await provider.close();
|
|
1480
|
+
process.exitCode = 1;
|
|
1481
|
+
return;
|
|
1482
|
+
}
|
|
1483
|
+
console.log(`Configuring agent ${name} as ${options.role} for project ${options.projectId}.`);
|
|
1484
|
+
if (!options.rootBranchId) {
|
|
1485
|
+
console.log("No root branch id specified, using project root branch.");
|
|
1486
|
+
const project = await getPantheonProjectInfo({ projectId: options.projectId });
|
|
1487
|
+
if (!project.root_branch_id) {
|
|
1488
|
+
console.error(`Project ${options.projectId} has no root branch. Project status is ${project.status}`);
|
|
1489
|
+
await provider.close();
|
|
1490
|
+
process.exitCode = 1;
|
|
1491
|
+
return;
|
|
1492
|
+
}
|
|
1493
|
+
options.rootBranchId = project.root_branch_id;
|
|
1494
|
+
}
|
|
1495
|
+
if (options.bootstrap) {
|
|
1496
|
+
const branchId = await executeOnPantheon({
|
|
1497
|
+
projectId: options.projectId,
|
|
1498
|
+
branchId: options.rootBranchId,
|
|
1499
|
+
agent: "codex",
|
|
1500
|
+
prompt: `You must follow these instructions to setup base branch for role "${options.role}":
|
|
1501
|
+
1. Clone the main branch from https://github.com/pingcap-inc/pantheon-agents to a temporary directory.
|
|
1502
|
+
2. Copy the pantheon-agents/roles/${options.role}/AGENTS.md to \`<workspace>/AGENTS.md\`.
|
|
1503
|
+
3. Copy the pantheon-agents/skills directory to \`<workspace>/.codex/\`
|
|
1504
|
+
|
|
1505
|
+
Validate <workspace>: check if files and directorys exists:
|
|
1506
|
+
- AGENTS.md
|
|
1507
|
+
- .codex/skills
|
|
1508
|
+
`
|
|
1509
|
+
});
|
|
1510
|
+
let retried = 0;
|
|
1511
|
+
const maxRetries = 3;
|
|
1512
|
+
let i = 0;
|
|
1513
|
+
console.log(`Bootstrap branch created: ${branchId}. Waiting for ready... [poll interval = 10s]`);
|
|
1514
|
+
while (true) {
|
|
1515
|
+
await new Promise((resolve) => {
|
|
1516
|
+
setTimeout(resolve, 1e4);
|
|
1517
|
+
});
|
|
1518
|
+
const result = await getPantheonBranch({
|
|
1519
|
+
branchId,
|
|
1520
|
+
projectId: options.projectId,
|
|
1521
|
+
getOutputIfFinished: true
|
|
1522
|
+
}).then((result) => {
|
|
1523
|
+
retried = 0;
|
|
1524
|
+
return result;
|
|
1525
|
+
}).catch((reason) => {
|
|
1526
|
+
if (retried < maxRetries) {
|
|
1527
|
+
retried++;
|
|
1528
|
+
return { state: "others" };
|
|
1529
|
+
} else throw new Error(`Failed to get bootstrap branch status. Retry ${retried} times. Last error: ${getErrorMessage(reason)}`);
|
|
1530
|
+
});
|
|
1531
|
+
if (result.state === "failed") {
|
|
1532
|
+
console.error("Bootstrap failed: " + result.error);
|
|
1533
|
+
await provider.close();
|
|
1534
|
+
process.exit(1);
|
|
1535
|
+
}
|
|
1536
|
+
if (result.state === "succeed") {
|
|
1537
|
+
console.log("Bootstrap succeeded. Output is:");
|
|
1538
|
+
console.log(result.output);
|
|
1539
|
+
break;
|
|
1540
|
+
}
|
|
1541
|
+
console.log(`Bootstrap in progress... [${++i}]`);
|
|
1542
|
+
}
|
|
1543
|
+
await provider.setAgentConfig({
|
|
1544
|
+
project_id: options.projectId,
|
|
1545
|
+
base_branch_id: branchId,
|
|
1546
|
+
execute_agent: options.executeAgent,
|
|
1547
|
+
role: options.role,
|
|
1548
|
+
prototype_url: "https://github.com/pingcap-inc/pantheon-agents"
|
|
1549
|
+
});
|
|
1550
|
+
} else await provider.setAgentConfig({
|
|
1551
|
+
project_id: options.projectId,
|
|
1552
|
+
base_branch_id: options.rootBranchId,
|
|
1553
|
+
execute_agent: options.executeAgent,
|
|
1554
|
+
role: options.role,
|
|
1555
|
+
prototype_url: "https://github.com/pingcap-inc/pantheon-agents"
|
|
1556
|
+
});
|
|
1557
|
+
console.log(`Agent ${name} configured successfully.`);
|
|
1558
|
+
await provider.close();
|
|
1559
|
+
}
|
|
1560
|
+
async function addTask(name, options) {
|
|
1561
|
+
const provider = new TaskListTidbProvider(name, pino());
|
|
1562
|
+
const config = await provider.getAgentConfig(options.projectId);
|
|
1563
|
+
if (!config) throw new Error(`Agent ${name} not configured for project ${options.projectId}`);
|
|
1564
|
+
const task = await provider.createTask({
|
|
1565
|
+
task: options.prompt,
|
|
1566
|
+
project_id: options.projectId,
|
|
1567
|
+
base_branch_id: config.base_branch_id
|
|
1568
|
+
});
|
|
1569
|
+
console.log(`Task ${task.task} queued successfully.`);
|
|
1570
|
+
await provider.close();
|
|
1571
|
+
}
|
|
1572
|
+
async function assertsSingleton(logger, pidFile) {
|
|
1573
|
+
try {
|
|
1574
|
+
const pid = await fs$1.promises.readFile(pidFile, "utf-8");
|
|
1575
|
+
process.kill(parseInt(pid), 0);
|
|
1576
|
+
console.error("Failed to assert singleton agent process:");
|
|
1577
|
+
process.exit(1);
|
|
1578
|
+
} catch (e) {
|
|
1579
|
+
await fs$1.promises.writeFile(pidFile, process.pid.toString());
|
|
1580
|
+
process.on("exit", () => {
|
|
1581
|
+
fs$1.promises.rm(pidFile);
|
|
1582
|
+
});
|
|
1583
|
+
}
|
|
1584
|
+
}
|
|
1585
|
+
|
|
1586
|
+
//#endregion
|
|
1587
|
+
//#region ../../node_modules/dotenv/package.json
|
|
1588
|
+
var require_package = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1589
|
+
module.exports = {
|
|
1590
|
+
"name": "dotenv",
|
|
1591
|
+
"version": "17.2.4",
|
|
1592
|
+
"description": "Loads environment variables from .env file",
|
|
1593
|
+
"main": "lib/main.js",
|
|
1594
|
+
"types": "lib/main.d.ts",
|
|
1595
|
+
"exports": {
|
|
1596
|
+
".": {
|
|
1597
|
+
"types": "./lib/main.d.ts",
|
|
1598
|
+
"require": "./lib/main.js",
|
|
1599
|
+
"default": "./lib/main.js"
|
|
1600
|
+
},
|
|
1601
|
+
"./config": "./config.js",
|
|
1602
|
+
"./config.js": "./config.js",
|
|
1603
|
+
"./lib/env-options": "./lib/env-options.js",
|
|
1604
|
+
"./lib/env-options.js": "./lib/env-options.js",
|
|
1605
|
+
"./lib/cli-options": "./lib/cli-options.js",
|
|
1606
|
+
"./lib/cli-options.js": "./lib/cli-options.js",
|
|
1607
|
+
"./package.json": "./package.json"
|
|
1608
|
+
},
|
|
1609
|
+
"scripts": {
|
|
1610
|
+
"dts-check": "tsc --project tests/types/tsconfig.json",
|
|
1611
|
+
"lint": "standard",
|
|
1612
|
+
"pretest": "npm run lint && npm run dts-check",
|
|
1613
|
+
"test": "tap run tests/**/*.js --allow-empty-coverage --disable-coverage --timeout=60000",
|
|
1614
|
+
"test:coverage": "tap run tests/**/*.js --show-full-coverage --timeout=60000 --coverage-report=text --coverage-report=lcov",
|
|
1615
|
+
"prerelease": "npm test",
|
|
1616
|
+
"release": "standard-version"
|
|
1617
|
+
},
|
|
1618
|
+
"repository": {
|
|
1619
|
+
"type": "git",
|
|
1620
|
+
"url": "git://github.com/motdotla/dotenv.git"
|
|
1621
|
+
},
|
|
1622
|
+
"homepage": "https://github.com/motdotla/dotenv#readme",
|
|
1623
|
+
"funding": "https://dotenvx.com",
|
|
1624
|
+
"keywords": [
|
|
1625
|
+
"dotenv",
|
|
1626
|
+
"env",
|
|
1627
|
+
".env",
|
|
1628
|
+
"environment",
|
|
1629
|
+
"variables",
|
|
1630
|
+
"config",
|
|
1631
|
+
"settings"
|
|
1632
|
+
],
|
|
1633
|
+
"readmeFilename": "README.md",
|
|
1634
|
+
"license": "BSD-2-Clause",
|
|
1635
|
+
"devDependencies": {
|
|
1636
|
+
"@types/node": "^18.11.3",
|
|
1637
|
+
"decache": "^4.6.2",
|
|
1638
|
+
"sinon": "^14.0.1",
|
|
1639
|
+
"standard": "^17.0.0",
|
|
1640
|
+
"standard-version": "^9.5.0",
|
|
1641
|
+
"tap": "^19.2.0",
|
|
1642
|
+
"typescript": "^4.8.4"
|
|
1643
|
+
},
|
|
1644
|
+
"engines": { "node": ">=12" },
|
|
1645
|
+
"browser": { "fs": false }
|
|
1646
|
+
};
|
|
1647
|
+
}));
|
|
1648
|
+
|
|
1649
|
+
//#endregion
|
|
1650
|
+
//#region ../../node_modules/dotenv/lib/main.js
|
|
1651
|
+
var require_main = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1652
|
+
const fs = __require("fs");
|
|
1653
|
+
const path$1 = __require("path");
|
|
1654
|
+
const os = __require("os");
|
|
1655
|
+
const crypto = __require("crypto");
|
|
1656
|
+
const version = require_package().version;
|
|
1657
|
+
const TIPS = [
|
|
1658
|
+
"🔐 encrypt with Dotenvx: https://dotenvx.com",
|
|
1659
|
+
"🔐 prevent committing .env to code: https://dotenvx.com/precommit",
|
|
1660
|
+
"🔐 prevent building .env in docker: https://dotenvx.com/prebuild",
|
|
1661
|
+
"📡 add observability to secrets: https://dotenvx.com/ops",
|
|
1662
|
+
"👥 sync secrets across teammates & machines: https://dotenvx.com/ops",
|
|
1663
|
+
"🗂️ backup and recover secrets: https://dotenvx.com/ops",
|
|
1664
|
+
"✅ audit secrets and track compliance: https://dotenvx.com/ops",
|
|
1665
|
+
"🔄 add secrets lifecycle management: https://dotenvx.com/ops",
|
|
1666
|
+
"🔑 add access controls to secrets: https://dotenvx.com/ops",
|
|
1667
|
+
"🛠️ run anywhere with `dotenvx run -- yourcommand`",
|
|
1668
|
+
"⚙️ specify custom .env file path with { path: '/custom/path/.env' }",
|
|
1669
|
+
"⚙️ enable debug logging with { debug: true }",
|
|
1670
|
+
"⚙️ override existing env vars with { override: true }",
|
|
1671
|
+
"⚙️ suppress all logs with { quiet: true }",
|
|
1672
|
+
"⚙️ write to custom object with { processEnv: myObject }",
|
|
1673
|
+
"⚙️ load multiple .env files with { path: ['.env.local', '.env'] }"
|
|
1674
|
+
];
|
|
1675
|
+
function _getRandomTip() {
|
|
1676
|
+
return TIPS[Math.floor(Math.random() * TIPS.length)];
|
|
1677
|
+
}
|
|
1678
|
+
function parseBoolean(value) {
|
|
1679
|
+
if (typeof value === "string") return ![
|
|
1680
|
+
"false",
|
|
1681
|
+
"0",
|
|
1682
|
+
"no",
|
|
1683
|
+
"off",
|
|
1684
|
+
""
|
|
1685
|
+
].includes(value.toLowerCase());
|
|
1686
|
+
return Boolean(value);
|
|
1687
|
+
}
|
|
1688
|
+
function supportsAnsi() {
|
|
1689
|
+
return process.stdout.isTTY;
|
|
1690
|
+
}
|
|
1691
|
+
function dim(text) {
|
|
1692
|
+
return supportsAnsi() ? `\x1b[2m${text}\x1b[0m` : text;
|
|
1693
|
+
}
|
|
1694
|
+
const LINE = /(?:^|^)\s*(?:export\s+)?([\w.-]+)(?:\s*=\s*?|:\s+?)(\s*'(?:\\'|[^'])*'|\s*"(?:\\"|[^"])*"|\s*`(?:\\`|[^`])*`|[^#\r\n]+)?\s*(?:#.*)?(?:$|$)/gm;
|
|
1695
|
+
function parse(src) {
|
|
1696
|
+
const obj = {};
|
|
1697
|
+
let lines = src.toString();
|
|
1698
|
+
lines = lines.replace(/\r\n?/gm, "\n");
|
|
1699
|
+
let match;
|
|
1700
|
+
while ((match = LINE.exec(lines)) != null) {
|
|
1701
|
+
const key = match[1];
|
|
1702
|
+
let value = match[2] || "";
|
|
1703
|
+
value = value.trim();
|
|
1704
|
+
const maybeQuote = value[0];
|
|
1705
|
+
value = value.replace(/^(['"`])([\s\S]*)\1$/gm, "$2");
|
|
1706
|
+
if (maybeQuote === "\"") {
|
|
1707
|
+
value = value.replace(/\\n/g, "\n");
|
|
1708
|
+
value = value.replace(/\\r/g, "\r");
|
|
1709
|
+
}
|
|
1710
|
+
obj[key] = value;
|
|
1711
|
+
}
|
|
1712
|
+
return obj;
|
|
1713
|
+
}
|
|
1714
|
+
function _parseVault(options) {
|
|
1715
|
+
options = options || {};
|
|
1716
|
+
const vaultPath = _vaultPath(options);
|
|
1717
|
+
options.path = vaultPath;
|
|
1718
|
+
const result = DotenvModule.configDotenv(options);
|
|
1719
|
+
if (!result.parsed) {
|
|
1720
|
+
const err = /* @__PURE__ */ new Error(`MISSING_DATA: Cannot parse ${vaultPath} for an unknown reason`);
|
|
1721
|
+
err.code = "MISSING_DATA";
|
|
1722
|
+
throw err;
|
|
1723
|
+
}
|
|
1724
|
+
const keys = _dotenvKey(options).split(",");
|
|
1725
|
+
const length = keys.length;
|
|
1726
|
+
let decrypted;
|
|
1727
|
+
for (let i = 0; i < length; i++) try {
|
|
1728
|
+
const attrs = _instructions(result, keys[i].trim());
|
|
1729
|
+
decrypted = DotenvModule.decrypt(attrs.ciphertext, attrs.key);
|
|
1730
|
+
break;
|
|
1731
|
+
} catch (error) {
|
|
1732
|
+
if (i + 1 >= length) throw error;
|
|
1733
|
+
}
|
|
1734
|
+
return DotenvModule.parse(decrypted);
|
|
1735
|
+
}
|
|
1736
|
+
function _warn(message) {
|
|
1737
|
+
console.error(`[dotenv@${version}][WARN] ${message}`);
|
|
1738
|
+
}
|
|
1739
|
+
function _debug(message) {
|
|
1740
|
+
console.log(`[dotenv@${version}][DEBUG] ${message}`);
|
|
1741
|
+
}
|
|
1742
|
+
function _log(message) {
|
|
1743
|
+
console.log(`[dotenv@${version}] ${message}`);
|
|
1744
|
+
}
|
|
1745
|
+
function _dotenvKey(options) {
|
|
1746
|
+
if (options && options.DOTENV_KEY && options.DOTENV_KEY.length > 0) return options.DOTENV_KEY;
|
|
1747
|
+
if (process.env.DOTENV_KEY && process.env.DOTENV_KEY.length > 0) return process.env.DOTENV_KEY;
|
|
1748
|
+
return "";
|
|
1749
|
+
}
|
|
1750
|
+
function _instructions(result, dotenvKey) {
|
|
1751
|
+
let uri;
|
|
1752
|
+
try {
|
|
1753
|
+
uri = new URL(dotenvKey);
|
|
1754
|
+
} catch (error) {
|
|
1755
|
+
if (error.code === "ERR_INVALID_URL") {
|
|
1756
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Wrong format. Must be in valid uri format like dotenv://:key_1234@dotenvx.com/vault/.env.vault?environment=development");
|
|
1757
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
1758
|
+
throw err;
|
|
1759
|
+
}
|
|
1760
|
+
throw error;
|
|
1761
|
+
}
|
|
1762
|
+
const key = uri.password;
|
|
1763
|
+
if (!key) {
|
|
1764
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Missing key part");
|
|
1765
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
1766
|
+
throw err;
|
|
1767
|
+
}
|
|
1768
|
+
const environment = uri.searchParams.get("environment");
|
|
1769
|
+
if (!environment) {
|
|
1770
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: Missing environment part");
|
|
1771
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
1772
|
+
throw err;
|
|
1773
|
+
}
|
|
1774
|
+
const environmentKey = `DOTENV_VAULT_${environment.toUpperCase()}`;
|
|
1775
|
+
const ciphertext = result.parsed[environmentKey];
|
|
1776
|
+
if (!ciphertext) {
|
|
1777
|
+
const err = /* @__PURE__ */ new Error(`NOT_FOUND_DOTENV_ENVIRONMENT: Cannot locate environment ${environmentKey} in your .env.vault file.`);
|
|
1778
|
+
err.code = "NOT_FOUND_DOTENV_ENVIRONMENT";
|
|
1779
|
+
throw err;
|
|
1780
|
+
}
|
|
1781
|
+
return {
|
|
1782
|
+
ciphertext,
|
|
1783
|
+
key
|
|
1784
|
+
};
|
|
1785
|
+
}
|
|
1786
|
+
function _vaultPath(options) {
|
|
1787
|
+
let possibleVaultPath = null;
|
|
1788
|
+
if (options && options.path && options.path.length > 0) if (Array.isArray(options.path)) {
|
|
1789
|
+
for (const filepath of options.path) if (fs.existsSync(filepath)) possibleVaultPath = filepath.endsWith(".vault") ? filepath : `${filepath}.vault`;
|
|
1790
|
+
} else possibleVaultPath = options.path.endsWith(".vault") ? options.path : `${options.path}.vault`;
|
|
1791
|
+
else possibleVaultPath = path$1.resolve(process.cwd(), ".env.vault");
|
|
1792
|
+
if (fs.existsSync(possibleVaultPath)) return possibleVaultPath;
|
|
1793
|
+
return null;
|
|
1794
|
+
}
|
|
1795
|
+
function _resolveHome(envPath) {
|
|
1796
|
+
return envPath[0] === "~" ? path$1.join(os.homedir(), envPath.slice(1)) : envPath;
|
|
1797
|
+
}
|
|
1798
|
+
function _configVault(options) {
|
|
1799
|
+
const debug = parseBoolean(process.env.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
1800
|
+
const quiet = parseBoolean(process.env.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
1801
|
+
if (debug || !quiet) _log("Loading env from encrypted .env.vault");
|
|
1802
|
+
const parsed = DotenvModule._parseVault(options);
|
|
1803
|
+
let processEnv = process.env;
|
|
1804
|
+
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
1805
|
+
DotenvModule.populate(processEnv, parsed, options);
|
|
1806
|
+
return { parsed };
|
|
1807
|
+
}
|
|
1808
|
+
function configDotenv(options) {
|
|
1809
|
+
const dotenvPath = path$1.resolve(process.cwd(), ".env");
|
|
1810
|
+
let encoding = "utf8";
|
|
1811
|
+
let processEnv = process.env;
|
|
1812
|
+
if (options && options.processEnv != null) processEnv = options.processEnv;
|
|
1813
|
+
let debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || options && options.debug);
|
|
1814
|
+
let quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || options && options.quiet);
|
|
1815
|
+
if (options && options.encoding) encoding = options.encoding;
|
|
1816
|
+
else if (debug) _debug("No encoding is specified. UTF-8 is used by default");
|
|
1817
|
+
let optionPaths = [dotenvPath];
|
|
1818
|
+
if (options && options.path) if (!Array.isArray(options.path)) optionPaths = [_resolveHome(options.path)];
|
|
1819
|
+
else {
|
|
1820
|
+
optionPaths = [];
|
|
1821
|
+
for (const filepath of options.path) optionPaths.push(_resolveHome(filepath));
|
|
1822
|
+
}
|
|
1823
|
+
let lastError;
|
|
1824
|
+
const parsedAll = {};
|
|
1825
|
+
for (const path of optionPaths) try {
|
|
1826
|
+
const parsed = DotenvModule.parse(fs.readFileSync(path, { encoding }));
|
|
1827
|
+
DotenvModule.populate(parsedAll, parsed, options);
|
|
1828
|
+
} catch (e) {
|
|
1829
|
+
if (debug) _debug(`Failed to load ${path} ${e.message}`);
|
|
1830
|
+
lastError = e;
|
|
1831
|
+
}
|
|
1832
|
+
const populated = DotenvModule.populate(processEnv, parsedAll, options);
|
|
1833
|
+
debug = parseBoolean(processEnv.DOTENV_CONFIG_DEBUG || debug);
|
|
1834
|
+
quiet = parseBoolean(processEnv.DOTENV_CONFIG_QUIET || quiet);
|
|
1835
|
+
if (debug || !quiet) {
|
|
1836
|
+
const keysCount = Object.keys(populated).length;
|
|
1837
|
+
const shortPaths = [];
|
|
1838
|
+
for (const filePath of optionPaths) try {
|
|
1839
|
+
const relative = path$1.relative(process.cwd(), filePath);
|
|
1840
|
+
shortPaths.push(relative);
|
|
1841
|
+
} catch (e) {
|
|
1842
|
+
if (debug) _debug(`Failed to load ${filePath} ${e.message}`);
|
|
1843
|
+
lastError = e;
|
|
1844
|
+
}
|
|
1845
|
+
_log(`injecting env (${keysCount}) from ${shortPaths.join(",")} ${dim(`-- tip: ${_getRandomTip()}`)}`);
|
|
1846
|
+
}
|
|
1847
|
+
if (lastError) return {
|
|
1848
|
+
parsed: parsedAll,
|
|
1849
|
+
error: lastError
|
|
1850
|
+
};
|
|
1851
|
+
else return { parsed: parsedAll };
|
|
1852
|
+
}
|
|
1853
|
+
function config(options) {
|
|
1854
|
+
if (_dotenvKey(options).length === 0) return DotenvModule.configDotenv(options);
|
|
1855
|
+
const vaultPath = _vaultPath(options);
|
|
1856
|
+
if (!vaultPath) {
|
|
1857
|
+
_warn(`You set DOTENV_KEY but you are missing a .env.vault file at ${vaultPath}. Did you forget to build it?`);
|
|
1858
|
+
return DotenvModule.configDotenv(options);
|
|
1859
|
+
}
|
|
1860
|
+
return DotenvModule._configVault(options);
|
|
1861
|
+
}
|
|
1862
|
+
function decrypt(encrypted, keyStr) {
|
|
1863
|
+
const key = Buffer.from(keyStr.slice(-64), "hex");
|
|
1864
|
+
let ciphertext = Buffer.from(encrypted, "base64");
|
|
1865
|
+
const nonce = ciphertext.subarray(0, 12);
|
|
1866
|
+
const authTag = ciphertext.subarray(-16);
|
|
1867
|
+
ciphertext = ciphertext.subarray(12, -16);
|
|
1868
|
+
try {
|
|
1869
|
+
const aesgcm = crypto.createDecipheriv("aes-256-gcm", key, nonce);
|
|
1870
|
+
aesgcm.setAuthTag(authTag);
|
|
1871
|
+
return `${aesgcm.update(ciphertext)}${aesgcm.final()}`;
|
|
1872
|
+
} catch (error) {
|
|
1873
|
+
const isRange = error instanceof RangeError;
|
|
1874
|
+
const invalidKeyLength = error.message === "Invalid key length";
|
|
1875
|
+
const decryptionFailed = error.message === "Unsupported state or unable to authenticate data";
|
|
1876
|
+
if (isRange || invalidKeyLength) {
|
|
1877
|
+
const err = /* @__PURE__ */ new Error("INVALID_DOTENV_KEY: It must be 64 characters long (or more)");
|
|
1878
|
+
err.code = "INVALID_DOTENV_KEY";
|
|
1879
|
+
throw err;
|
|
1880
|
+
} else if (decryptionFailed) {
|
|
1881
|
+
const err = /* @__PURE__ */ new Error("DECRYPTION_FAILED: Please check your DOTENV_KEY");
|
|
1882
|
+
err.code = "DECRYPTION_FAILED";
|
|
1883
|
+
throw err;
|
|
1884
|
+
} else throw error;
|
|
1885
|
+
}
|
|
1886
|
+
}
|
|
1887
|
+
function populate(processEnv, parsed, options = {}) {
|
|
1888
|
+
const debug = Boolean(options && options.debug);
|
|
1889
|
+
const override = Boolean(options && options.override);
|
|
1890
|
+
const populated = {};
|
|
1891
|
+
if (typeof parsed !== "object") {
|
|
1892
|
+
const err = /* @__PURE__ */ new Error("OBJECT_REQUIRED: Please check the processEnv argument being passed to populate");
|
|
1893
|
+
err.code = "OBJECT_REQUIRED";
|
|
1894
|
+
throw err;
|
|
1895
|
+
}
|
|
1896
|
+
for (const key of Object.keys(parsed)) if (Object.prototype.hasOwnProperty.call(processEnv, key)) {
|
|
1897
|
+
if (override === true) {
|
|
1898
|
+
processEnv[key] = parsed[key];
|
|
1899
|
+
populated[key] = parsed[key];
|
|
1900
|
+
}
|
|
1901
|
+
if (debug) if (override === true) _debug(`"${key}" is already defined and WAS overwritten`);
|
|
1902
|
+
else _debug(`"${key}" is already defined and was NOT overwritten`);
|
|
1903
|
+
} else {
|
|
1904
|
+
processEnv[key] = parsed[key];
|
|
1905
|
+
populated[key] = parsed[key];
|
|
1906
|
+
}
|
|
1907
|
+
return populated;
|
|
1908
|
+
}
|
|
1909
|
+
const DotenvModule = {
|
|
1910
|
+
configDotenv,
|
|
1911
|
+
_configVault,
|
|
1912
|
+
_parseVault,
|
|
1913
|
+
config,
|
|
1914
|
+
decrypt,
|
|
1915
|
+
parse,
|
|
1916
|
+
populate
|
|
1917
|
+
};
|
|
1918
|
+
module.exports.configDotenv = DotenvModule.configDotenv;
|
|
1919
|
+
module.exports._configVault = DotenvModule._configVault;
|
|
1920
|
+
module.exports._parseVault = DotenvModule._parseVault;
|
|
1921
|
+
module.exports.config = DotenvModule.config;
|
|
1922
|
+
module.exports.decrypt = DotenvModule.decrypt;
|
|
1923
|
+
module.exports.parse = DotenvModule.parse;
|
|
1924
|
+
module.exports.populate = DotenvModule.populate;
|
|
1925
|
+
module.exports = DotenvModule;
|
|
1926
|
+
}));
|
|
1927
|
+
|
|
1928
|
+
//#endregion
|
|
1929
|
+
//#region ../../node_modules/dotenv/lib/env-options.js
|
|
1930
|
+
var require_env_options = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1931
|
+
const options = {};
|
|
1932
|
+
if (process.env.DOTENV_CONFIG_ENCODING != null) options.encoding = process.env.DOTENV_CONFIG_ENCODING;
|
|
1933
|
+
if (process.env.DOTENV_CONFIG_PATH != null) options.path = process.env.DOTENV_CONFIG_PATH;
|
|
1934
|
+
if (process.env.DOTENV_CONFIG_QUIET != null) options.quiet = process.env.DOTENV_CONFIG_QUIET;
|
|
1935
|
+
if (process.env.DOTENV_CONFIG_DEBUG != null) options.debug = process.env.DOTENV_CONFIG_DEBUG;
|
|
1936
|
+
if (process.env.DOTENV_CONFIG_OVERRIDE != null) options.override = process.env.DOTENV_CONFIG_OVERRIDE;
|
|
1937
|
+
if (process.env.DOTENV_CONFIG_DOTENV_KEY != null) options.DOTENV_KEY = process.env.DOTENV_CONFIG_DOTENV_KEY;
|
|
1938
|
+
module.exports = options;
|
|
1939
|
+
}));
|
|
1940
|
+
|
|
1941
|
+
//#endregion
|
|
1942
|
+
//#region ../../node_modules/dotenv/lib/cli-options.js
|
|
1943
|
+
var require_cli_options = /* @__PURE__ */ __commonJSMin(((exports, module) => {
|
|
1944
|
+
const re = /^dotenv_config_(encoding|path|quiet|debug|override|DOTENV_KEY)=(.+)$/;
|
|
1945
|
+
module.exports = function optionMatcher(args) {
|
|
1946
|
+
const options = args.reduce(function(acc, cur) {
|
|
1947
|
+
const matches = cur.match(re);
|
|
1948
|
+
if (matches) acc[matches[1]] = matches[2];
|
|
1949
|
+
return acc;
|
|
1950
|
+
}, {});
|
|
1951
|
+
if (!("quiet" in options)) options.quiet = "true";
|
|
1952
|
+
return options;
|
|
1953
|
+
};
|
|
1954
|
+
}));
|
|
1955
|
+
|
|
1956
|
+
//#endregion
|
|
1957
|
+
//#region ../../node_modules/dotenv/config.js
|
|
1958
|
+
(function() {
|
|
1959
|
+
require_main().config(Object.assign({}, require_env_options(), require_cli_options()(process.argv)));
|
|
1960
|
+
})();
|
|
1961
|
+
|
|
1962
|
+
//#endregion
|
|
1963
|
+
//#region package.json
|
|
1964
|
+
var version = "0.0.1";
|
|
1965
|
+
|
|
1966
|
+
//#endregion
|
|
1967
|
+
//#region index.ts
|
|
1968
|
+
if (!process$1.env.PANTHEON_API_KEY) console.error("PANTHEON_API_KEY environment variable is not set.");
|
|
1969
|
+
if (!process$1.env.DATABASE_URL) console.error("DATABASE_URL environment variable is not set.");
|
|
1970
|
+
const configAgentCommand = createCommand("pantheon-agents config").version(version).description("Configure agent for pantheon project").argument("<name>", "The name of the agent.").argument("<role>", "The role of the agent.").argument("<project-id>", "The project id of the agent.").option("--execute-agent <agent>", "The execute agent of the agent.", "codex").option("--root-branch-id <branchId>", "The root branch id of the agent. Default to project root branch id.").option("--no-bootstrap", "Prevent bootstrap base branch for agent. Use the root branch as base branch.").action(async function() {
|
|
1971
|
+
const [name, role, projectId] = this.args;
|
|
1972
|
+
await configAgent(name, {
|
|
1973
|
+
role,
|
|
1974
|
+
projectId,
|
|
1975
|
+
...this.opts()
|
|
1976
|
+
});
|
|
1977
|
+
});
|
|
1978
|
+
const addTaskCommand = createCommand("pantheon-agents add-task").version(version).description("Add a task to an agent").argument("<name>", "The name of the agent.").argument("<project-id>", "The project id of the agent.").argument("<task-prompt>", "The prompt of the task.").action(async function() {
|
|
1979
|
+
const [name, projectId, taskPrompt] = this.args;
|
|
1980
|
+
await addTask(name, {
|
|
1981
|
+
projectId,
|
|
1982
|
+
prompt: taskPrompt
|
|
1983
|
+
});
|
|
1984
|
+
});
|
|
1985
|
+
const runAgentCommand = createCommand("pantheon-agents run").version(version).description("Start a pantheon agents").argument("<name>", "The name of the agent.").option("--data-dir [dir]", "Data directory.", expandTilde("~/.pantheon-agents")).option("--mcp-port", "The port of the MCP server. Defaults to a random port.").option("--loop-interval <seconds>", "The interval of the loop in seconds. Defaults to 5.", (val) => parseInt(val, 10), 5).action(async function() {
|
|
1986
|
+
const [name] = this.args;
|
|
1987
|
+
const options = this.opts();
|
|
1988
|
+
const logFileTransport = transport({
|
|
1989
|
+
target: "pino-roll",
|
|
1990
|
+
options: {
|
|
1991
|
+
file: path.join(options.dataDir, "agents", name, "logs", "log"),
|
|
1992
|
+
frequency: "daily",
|
|
1993
|
+
mkdir: true
|
|
1994
|
+
}
|
|
1995
|
+
});
|
|
1996
|
+
const prettyTransport = transport({
|
|
1997
|
+
target: "pino-pretty",
|
|
1998
|
+
options: {
|
|
1999
|
+
colorize: true,
|
|
2000
|
+
ignore: "pid,hostname,level-label"
|
|
2001
|
+
}
|
|
2002
|
+
});
|
|
2003
|
+
await runAgent(name, options, pino({
|
|
2004
|
+
timestamp: pino.stdTimeFunctions.isoTime,
|
|
2005
|
+
formatters: { level(label) {
|
|
2006
|
+
return { level: label.toUpperCase() };
|
|
2007
|
+
} }
|
|
2008
|
+
}, multistream([{ stream: logFileTransport }, { stream: prettyTransport }])));
|
|
2009
|
+
});
|
|
2010
|
+
function printCommandHelpAndExit(command) {
|
|
2011
|
+
console.error(`Invalid command: ${command}. Supported commands: ${Object.keys(commands).join(", ")}.`);
|
|
2012
|
+
console.error(` Run pantheon-agents help <command> for more information.`);
|
|
2013
|
+
process$1.exit(1);
|
|
2014
|
+
}
|
|
2015
|
+
const commands = {
|
|
2016
|
+
"add-task": addTaskCommand,
|
|
2017
|
+
config: configAgentCommand,
|
|
2018
|
+
run: runAgentCommand
|
|
2019
|
+
};
|
|
2020
|
+
if (process$1.argv[2] === "help") {
|
|
2021
|
+
const command = process$1.argv[3];
|
|
2022
|
+
if (command in commands) commands[command].help({ error: false });
|
|
2023
|
+
else printCommandHelpAndExit(command);
|
|
2024
|
+
}
|
|
2025
|
+
if (!commands[process$1.argv[2]]) printCommandHelpAndExit(process$1.argv[2]);
|
|
2026
|
+
commands[process$1.argv[2]].parse(process$1.argv.slice(3), { from: "user" });
|
|
2027
|
+
|
|
2028
|
+
//#endregion
|
|
2029
|
+
export { };
|