@kraken-ai/platform 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/LICENSE +67 -0
- package/README.md +36 -0
- package/dist/chunk-HGJSK6MW.js +294 -0
- package/dist/chunk-HGJSK6MW.js.map +1 -0
- package/dist/cli.js +1297 -0
- package/dist/cli.js.map +1 -0
- package/dist/connector-CumEDPfS.d.cts +103 -0
- package/dist/connector-CumEDPfS.d.ts +103 -0
- package/dist/index.cjs +1381 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +796 -0
- package/dist/index.d.ts +796 -0
- package/dist/index.js +1240 -0
- package/dist/index.js.map +1 -0
- package/dist/server.cjs +315 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +15 -0
- package/dist/server.d.ts +15 -0
- package/dist/server.js +7 -0
- package/dist/server.js.map +1 -0
- package/package.json +46 -0
package/dist/cli.js
ADDED
|
@@ -0,0 +1,1297 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// src/cli.ts
|
|
4
|
+
import * as z12 from "zod";
|
|
5
|
+
|
|
6
|
+
// src/cli/codegen.ts
|
|
7
|
+
import fs from "fs";
|
|
8
|
+
import path from "path";
|
|
9
|
+
|
|
10
|
+
// src/cli/log.ts
|
|
11
|
+
var supportsColor = !("NO_COLOR" in process.env) && process.env.FORCE_COLOR !== "0" && (process.stderr.isTTY ?? false);
|
|
12
|
+
var code = (open, close) => {
|
|
13
|
+
const openStr = `\x1B[${open}m`;
|
|
14
|
+
const closeStr = `\x1B[${close}m`;
|
|
15
|
+
return (s) => supportsColor ? `${openStr}${s}${closeStr}` : s;
|
|
16
|
+
};
|
|
17
|
+
var bold = code(1, 22);
|
|
18
|
+
var dim = code(2, 22);
|
|
19
|
+
var red = code(31, 39);
|
|
20
|
+
var yellow = code(33, 39);
|
|
21
|
+
var green = code(32, 39);
|
|
22
|
+
var cyan = code(36, 39);
|
|
23
|
+
var warn = (msg) => {
|
|
24
|
+
process.stderr.write(` ${dim("[kraken-ai:")} ${yellow("warn")}${dim("]")} ${msg}
|
|
25
|
+
`);
|
|
26
|
+
};
|
|
27
|
+
|
|
28
|
+
// src/cli/validate.ts
|
|
29
|
+
var ENTITY_NAME_REGEX = /^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]$/;
|
|
30
|
+
var isValidEntityName = (name) => name.length === 1 ? /^[a-z0-9]$/.test(name) : ENTITY_NAME_REGEX.test(name);
|
|
31
|
+
var SKILL_NAME_REGEX = /^[a-zA-Z0-9][a-zA-Z0-9-]{0,62}[a-zA-Z0-9]$/;
|
|
32
|
+
var isValidSkillName = (basename) => basename.length === 1 ? /^[a-zA-Z0-9]$/.test(basename) : SKILL_NAME_REGEX.test(basename);
|
|
33
|
+
var isValidSkillId = (id) => {
|
|
34
|
+
const base = id.endsWith(".md") ? id.slice(0, -3) : id;
|
|
35
|
+
return isValidSkillName(base);
|
|
36
|
+
};
|
|
37
|
+
var TOOL_NAME_REGEX = /^[a-z][a-z0-9_-]{0,62}[a-z0-9]$/;
|
|
38
|
+
var isValidToolName = (name) => name.length === 1 ? /^[a-z]$/.test(name) : TOOL_NAME_REGEX.test(name);
|
|
39
|
+
var PROPERTY_NAME_REGEX = /^[a-zA-Z_$][a-zA-Z0-9_$]{0,254}$/;
|
|
40
|
+
var FORBIDDEN_PROPS = /* @__PURE__ */ new Set([
|
|
41
|
+
"__proto__",
|
|
42
|
+
"constructor",
|
|
43
|
+
"prototype",
|
|
44
|
+
"__defineGetter__",
|
|
45
|
+
"__defineSetter__",
|
|
46
|
+
"__lookupGetter__",
|
|
47
|
+
"__lookupSetter__"
|
|
48
|
+
]);
|
|
49
|
+
var isValidPropertyName = (name) => PROPERTY_NAME_REGEX.test(name) && !FORBIDDEN_PROPS.has(name);
|
|
50
|
+
var MAX_SCHEMA_DEPTH = 20;
|
|
51
|
+
var MAX_OBJECT_BREADTH = 200;
|
|
52
|
+
var validateSchemaBundle = (bundle) => {
|
|
53
|
+
for (const agent of bundle.agents) {
|
|
54
|
+
assertValidEntity("agent id", agent.id);
|
|
55
|
+
validateJsonSchemaProperties("agent input schema", agent.input, 0);
|
|
56
|
+
validateJsonSchemaProperties("agent output schema", agent.output, 0);
|
|
57
|
+
if (agent.actions) {
|
|
58
|
+
for (const [actionName, actionSchema] of Object.entries(agent.actions)) {
|
|
59
|
+
assertValidEntity("agent action name", actionName);
|
|
60
|
+
validateJsonSchemaProperties("agent action schema", actionSchema, 0);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
for (const query of bundle.queries) {
|
|
65
|
+
assertValidEntity("query name", query.name);
|
|
66
|
+
validateJsonSchemaProperties("query params schema", query.params, 0);
|
|
67
|
+
for (const col of query.columns) {
|
|
68
|
+
assertValidProperty("query column name", col.name);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
for (const connector of bundle.connectors) {
|
|
72
|
+
assertValidEntity("connector id", connector.id);
|
|
73
|
+
for (const tool of connector.tools) {
|
|
74
|
+
assertValidTool("connector tool name", tool.name);
|
|
75
|
+
validateJsonSchemaProperties("connector tool parameters", tool.parameters, 0);
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
for (const pipeline of bundle.pipelines) {
|
|
79
|
+
assertValidEntity("pipeline name", pipeline.pipeline);
|
|
80
|
+
for (const query of pipeline.queries) {
|
|
81
|
+
assertValidEntity("pipeline query name", query.name);
|
|
82
|
+
validatePipelineSchema("pipeline query params", query.params, 0);
|
|
83
|
+
validatePipelineSchema("pipeline query returns", query.returns, 0);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
for (const skill of bundle.skills) {
|
|
87
|
+
assertValidSkill("skill id", skill.id);
|
|
88
|
+
}
|
|
89
|
+
};
|
|
90
|
+
var assertValidEntity = (entityType, value) => {
|
|
91
|
+
if (!isValidEntityName(value)) {
|
|
92
|
+
throw new Error(
|
|
93
|
+
`Invalid remote schema: ${entityType} "${value}". Must match ${ENTITY_NAME_REGEX}`
|
|
94
|
+
);
|
|
95
|
+
}
|
|
96
|
+
};
|
|
97
|
+
var assertValidTool = (entityType, value) => {
|
|
98
|
+
if (!isValidToolName(value)) {
|
|
99
|
+
throw new Error(
|
|
100
|
+
`Invalid remote schema: ${entityType} "${value}". Must match ${TOOL_NAME_REGEX}`
|
|
101
|
+
);
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
var assertValidProperty = (entityType, value) => {
|
|
105
|
+
if (!isValidPropertyName(value)) {
|
|
106
|
+
throw new Error(
|
|
107
|
+
`Invalid remote schema: ${entityType} "${value}". Must match ${PROPERTY_NAME_REGEX} and not be a forbidden property`
|
|
108
|
+
);
|
|
109
|
+
}
|
|
110
|
+
};
|
|
111
|
+
var assertValidSkill = (entityType, value) => {
|
|
112
|
+
if (!isValidSkillId(value)) {
|
|
113
|
+
throw new Error(
|
|
114
|
+
`Invalid remote schema: ${entityType} "${value}". Must match ${SKILL_NAME_REGEX} (with optional .md extension)`
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
};
|
|
118
|
+
var validateJsonSchemaProperties = (context, schema, depth) => {
|
|
119
|
+
if (!schema || typeof schema !== "object") return;
|
|
120
|
+
if (depth > MAX_SCHEMA_DEPTH) {
|
|
121
|
+
throw new Error(
|
|
122
|
+
`Invalid remote schema: ${context} exceeds maximum nesting depth of ${MAX_SCHEMA_DEPTH}`
|
|
123
|
+
);
|
|
124
|
+
}
|
|
125
|
+
const props = schema.properties;
|
|
126
|
+
if (props) {
|
|
127
|
+
const keys = Object.keys(props);
|
|
128
|
+
if (keys.length > MAX_OBJECT_BREADTH) {
|
|
129
|
+
throw new Error(
|
|
130
|
+
`Invalid remote schema: ${context} has ${keys.length} properties, exceeding limit of ${MAX_OBJECT_BREADTH}`
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
for (const key of keys) {
|
|
134
|
+
assertValidProperty(`${context} property name`, key);
|
|
135
|
+
validateJsonSchemaProperties(context, props[key] ?? {}, depth + 1);
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
const items = schema.items;
|
|
139
|
+
if (items) {
|
|
140
|
+
validateJsonSchemaProperties(context, items, depth + 1);
|
|
141
|
+
}
|
|
142
|
+
for (const keyword of ["anyOf", "oneOf", "allOf"]) {
|
|
143
|
+
const variants = schema[keyword];
|
|
144
|
+
if (variants) {
|
|
145
|
+
for (const variant of variants) {
|
|
146
|
+
validateJsonSchemaProperties(context, variant, depth + 1);
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
};
|
|
151
|
+
var validatePipelineSchema = (context, schema, depth) => {
|
|
152
|
+
if (!schema || typeof schema !== "object") return;
|
|
153
|
+
if (depth > MAX_SCHEMA_DEPTH) {
|
|
154
|
+
throw new Error(
|
|
155
|
+
`Invalid remote schema: ${context} exceeds maximum nesting depth of ${MAX_SCHEMA_DEPTH}`
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
if ("$ref" in schema) {
|
|
159
|
+
throw new Error(
|
|
160
|
+
`Invalid remote schema: ${context} contains "$ref" which is not supported in pipeline schemas`
|
|
161
|
+
);
|
|
162
|
+
}
|
|
163
|
+
if ("pattern" in schema) {
|
|
164
|
+
delete schema.pattern;
|
|
165
|
+
}
|
|
166
|
+
const props = schema.properties;
|
|
167
|
+
if (props) {
|
|
168
|
+
const keys = Object.keys(props);
|
|
169
|
+
if (keys.length > MAX_OBJECT_BREADTH) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`Invalid remote schema: ${context} has ${keys.length} properties, exceeding limit of ${MAX_OBJECT_BREADTH}`
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
for (const key of keys) {
|
|
175
|
+
assertValidProperty(`${context} property name`, key);
|
|
176
|
+
validatePipelineSchema(context, props[key] ?? {}, depth + 1);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
const items = schema.items;
|
|
180
|
+
if (items) {
|
|
181
|
+
validatePipelineSchema(context, items, depth + 1);
|
|
182
|
+
}
|
|
183
|
+
for (const keyword of ["anyOf", "oneOf", "allOf"]) {
|
|
184
|
+
const variants = schema[keyword];
|
|
185
|
+
if (variants) {
|
|
186
|
+
for (const variant of variants) {
|
|
187
|
+
validatePipelineSchema(context, variant, depth + 1);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
|
|
193
|
+
// src/cli/codegen.ts
|
|
194
|
+
var generateTypes = (schemas, projectRoot) => {
|
|
195
|
+
validateSchemaBundle(schemas);
|
|
196
|
+
const outDir = path.join(projectRoot, ".kraken-ai");
|
|
197
|
+
if (!fs.existsSync(outDir)) {
|
|
198
|
+
fs.mkdirSync(outDir, { recursive: true });
|
|
199
|
+
}
|
|
200
|
+
const stalePipelinesTs = path.join(outDir, "pipelines.ts");
|
|
201
|
+
if (fs.existsSync(stalePipelinesTs)) {
|
|
202
|
+
fs.rmSync(stalePipelinesTs);
|
|
203
|
+
warn(
|
|
204
|
+
"Migrated: removed .kraken-ai/pipelines.ts. Pipeline schemas now in pipelines.json + pipelines.d.ts."
|
|
205
|
+
);
|
|
206
|
+
}
|
|
207
|
+
fs.writeFileSync(path.join(outDir, "agents.d.ts"), generateAgentsDts(schemas.agents));
|
|
208
|
+
fs.writeFileSync(path.join(outDir, "queries.d.ts"), generateQueriesDts(schemas.queries));
|
|
209
|
+
const connectorsDtsPath = path.join(outDir, "connectors.d.ts");
|
|
210
|
+
if (schemas.connectors.length > 0) {
|
|
211
|
+
fs.writeFileSync(connectorsDtsPath, generateConnectorsDts(schemas.connectors));
|
|
212
|
+
} else if (fs.existsSync(connectorsDtsPath)) {
|
|
213
|
+
fs.rmSync(connectorsDtsPath);
|
|
214
|
+
}
|
|
215
|
+
fs.writeFileSync(path.join(outDir, "pipelines.json"), generatePipelinesJson(schemas.pipelines));
|
|
216
|
+
fs.writeFileSync(path.join(outDir, "pipelines.d.ts"), generatePipelinesDts(schemas.pipelines));
|
|
217
|
+
const platformTypesDtsPath = path.join(outDir, "platform-types.d.ts");
|
|
218
|
+
const platformTypesDts = generatePlatformTypesDts(
|
|
219
|
+
schemas.agents,
|
|
220
|
+
schemas.connectors,
|
|
221
|
+
schemas.skills
|
|
222
|
+
);
|
|
223
|
+
if (platformTypesDts) {
|
|
224
|
+
fs.writeFileSync(platformTypesDtsPath, platformTypesDts);
|
|
225
|
+
} else if (fs.existsSync(platformTypesDtsPath)) {
|
|
226
|
+
fs.rmSync(platformTypesDtsPath);
|
|
227
|
+
}
|
|
228
|
+
fs.writeFileSync(
|
|
229
|
+
path.join(outDir, "index.d.ts"),
|
|
230
|
+
generateIndexDts(
|
|
231
|
+
schemas.connectors.length > 0,
|
|
232
|
+
schemas.pipelines.length > 0,
|
|
233
|
+
platformTypesDts != null
|
|
234
|
+
)
|
|
235
|
+
);
|
|
236
|
+
fs.writeFileSync(path.join(outDir, "manifest.json"), JSON.stringify(schemas, null, 2));
|
|
237
|
+
};
|
|
238
|
+
var generateAgentsDts = (agents) => {
|
|
239
|
+
const entries = agents.map((a) => {
|
|
240
|
+
const input = jsonSchemaToTsType(a.input);
|
|
241
|
+
const output = jsonSchemaToTsType(a.output);
|
|
242
|
+
const actions = generateActionsType(a.actions);
|
|
243
|
+
return ` "${a.id}": {
|
|
244
|
+
input: ${input}
|
|
245
|
+
output: ${output}
|
|
246
|
+
actions: ${actions}
|
|
247
|
+
}`;
|
|
248
|
+
}).join("\n");
|
|
249
|
+
return `// Auto-generated by \`kraken generate\` \u2014 do not edit manually
|
|
250
|
+
|
|
251
|
+
export interface AgentRegistry {
|
|
252
|
+
${entries}
|
|
253
|
+
}
|
|
254
|
+
`;
|
|
255
|
+
};
|
|
256
|
+
var generateActionsType = (actions) => {
|
|
257
|
+
if (!actions || Object.keys(actions).length === 0) {
|
|
258
|
+
return "Record<string, never>";
|
|
259
|
+
}
|
|
260
|
+
const entries = Object.entries(actions).map(([name, schema]) => `"${name}": ${jsonSchemaToTsType(schema)}`).join("; ");
|
|
261
|
+
return `{ ${entries} }`;
|
|
262
|
+
};
|
|
263
|
+
var generateQueriesDts = (queries) => {
|
|
264
|
+
const entries = queries.map((q) => {
|
|
265
|
+
const params = jsonSchemaToTsType(q.params);
|
|
266
|
+
const row = columnsToTsType(q.columns);
|
|
267
|
+
return ` "${q.name}": {
|
|
268
|
+
params: ${params}
|
|
269
|
+
row: ${row}
|
|
270
|
+
}`;
|
|
271
|
+
}).join("\n");
|
|
272
|
+
return `// Auto-generated by \`kraken generate\` \u2014 do not edit manually
|
|
273
|
+
|
|
274
|
+
export interface QueryRegistry {
|
|
275
|
+
${entries}
|
|
276
|
+
}
|
|
277
|
+
`;
|
|
278
|
+
};
|
|
279
|
+
var generateConnectorsDts = (connectors) => {
|
|
280
|
+
const ids = connectors.map((c) => `"${c.id}"`).join(" | ");
|
|
281
|
+
const entries = connectors.map((c) => {
|
|
282
|
+
const tools = c.tools.map((t) => {
|
|
283
|
+
const params = jsonSchemaToTsType(t.parameters);
|
|
284
|
+
return ` "${t.name}": ${params}`;
|
|
285
|
+
}).join("\n");
|
|
286
|
+
return ` "${c.id}": {
|
|
287
|
+
${tools}
|
|
288
|
+
}`;
|
|
289
|
+
}).join("\n");
|
|
290
|
+
return `// Auto-generated by \`kraken generate\` \u2014 do not edit manually
|
|
291
|
+
|
|
292
|
+
export type ConnectorId = ${ids};
|
|
293
|
+
|
|
294
|
+
export interface ConnectorTools {
|
|
295
|
+
${entries}
|
|
296
|
+
}
|
|
297
|
+
`;
|
|
298
|
+
};
|
|
299
|
+
var generateIndexDts = (hasConnectors, hasPipelines, hasPlatformTypes) => {
|
|
300
|
+
let content = `// Auto-generated by \`kraken generate\` \u2014 do not edit manually
|
|
301
|
+
|
|
302
|
+
export type { AgentRegistry } from "./agents"
|
|
303
|
+
export type { QueryRegistry } from "./queries"
|
|
304
|
+
`;
|
|
305
|
+
if (hasConnectors) {
|
|
306
|
+
content += `export type { ConnectorId, ConnectorTools } from "./connectors"
|
|
307
|
+
`;
|
|
308
|
+
}
|
|
309
|
+
if (hasPipelines) {
|
|
310
|
+
content += `/// <reference path="./pipelines.d.ts" />
|
|
311
|
+
`;
|
|
312
|
+
}
|
|
313
|
+
if (hasPlatformTypes) {
|
|
314
|
+
content += `/// <reference path="./platform-types.d.ts" />
|
|
315
|
+
`;
|
|
316
|
+
}
|
|
317
|
+
return content;
|
|
318
|
+
};
|
|
319
|
+
var generatePlatformTypesDts = (agents, connectors, skills) => {
|
|
320
|
+
const entries = [];
|
|
321
|
+
if (agents.length > 0) {
|
|
322
|
+
const ids = agents.map((a) => `"${a.id}"`).join(" | ");
|
|
323
|
+
entries.push(` agentId: ${ids};`);
|
|
324
|
+
}
|
|
325
|
+
if (connectors.length > 0) {
|
|
326
|
+
const ids = connectors.map((c) => `"${c.id}"`).join(" | ");
|
|
327
|
+
entries.push(` connectorId: ${ids};`);
|
|
328
|
+
}
|
|
329
|
+
if (skills.length > 0) {
|
|
330
|
+
const ids = skills.map((s) => `"${s.id}"`).join(" | ");
|
|
331
|
+
entries.push(` skillId: ${ids};`);
|
|
332
|
+
}
|
|
333
|
+
if (entries.length === 0) return null;
|
|
334
|
+
return [
|
|
335
|
+
`// Auto-generated by \`kraken generate\` \u2014 do not edit manually`,
|
|
336
|
+
`export {};`,
|
|
337
|
+
``,
|
|
338
|
+
`declare module "@kraken-ai/platform" {`,
|
|
339
|
+
` interface KrakenTypeRegistry {`,
|
|
340
|
+
...entries,
|
|
341
|
+
` }`,
|
|
342
|
+
`}`,
|
|
343
|
+
``
|
|
344
|
+
].join("\n");
|
|
345
|
+
};
|
|
346
|
+
var MAX_TS_TYPE_DEPTH = 20;
|
|
347
|
+
var jsonSchemaToTsType = (schema, depth = 0) => {
|
|
348
|
+
if (depth > MAX_TS_TYPE_DEPTH) return "unknown";
|
|
349
|
+
if (!schema || Object.keys(schema).length === 0) return "unknown";
|
|
350
|
+
const anyOf = schema.anyOf;
|
|
351
|
+
if (anyOf) {
|
|
352
|
+
const nonNull = anyOf.filter((s) => s.type !== "null");
|
|
353
|
+
const hasNull = anyOf.some((s) => s.type === "null");
|
|
354
|
+
if (nonNull.length === 1 && nonNull[0] && hasNull) {
|
|
355
|
+
return `${jsonSchemaToTsType(nonNull[0], depth + 1)} | null`;
|
|
356
|
+
}
|
|
357
|
+
if (nonNull.length > 1) {
|
|
358
|
+
const variants = nonNull.map((s) => jsonSchemaToTsType(s, depth + 1)).join(" | ");
|
|
359
|
+
return hasNull ? `${variants} | null` : variants;
|
|
360
|
+
}
|
|
361
|
+
if (nonNull.length === 0 && hasNull) {
|
|
362
|
+
return "null";
|
|
363
|
+
}
|
|
364
|
+
}
|
|
365
|
+
const type = schema.type;
|
|
366
|
+
switch (type) {
|
|
367
|
+
case "string":
|
|
368
|
+
return "string";
|
|
369
|
+
case "number":
|
|
370
|
+
case "integer":
|
|
371
|
+
return "number";
|
|
372
|
+
case "boolean":
|
|
373
|
+
return "boolean";
|
|
374
|
+
case "null":
|
|
375
|
+
return "null";
|
|
376
|
+
case "object": {
|
|
377
|
+
const props = schema.properties;
|
|
378
|
+
if (!props) return "Record<string, unknown>";
|
|
379
|
+
const required = new Set(schema.required ?? []);
|
|
380
|
+
const fields = Object.entries(props).map(([k, val]) => {
|
|
381
|
+
const optional = !required.has(k);
|
|
382
|
+
const tsType = jsonSchemaToTsType(val, depth + 1);
|
|
383
|
+
return `${k}${optional ? "?" : ""}: ${tsType}`;
|
|
384
|
+
}).join("; ");
|
|
385
|
+
return `{ ${fields} }`;
|
|
386
|
+
}
|
|
387
|
+
case "array": {
|
|
388
|
+
const items = schema.items;
|
|
389
|
+
return `${jsonSchemaToTsType(items ?? {}, depth + 1)}[]`;
|
|
390
|
+
}
|
|
391
|
+
default:
|
|
392
|
+
return "unknown";
|
|
393
|
+
}
|
|
394
|
+
};
|
|
395
|
+
var columnsToTsType = (columns) => {
|
|
396
|
+
if (columns.length === 0) return "Record<string, unknown>";
|
|
397
|
+
const fields = columns.map((c) => `${c.name}: ${columnTypeToTs(c.type)}`).join("; ");
|
|
398
|
+
return `{ ${fields} }`;
|
|
399
|
+
};
|
|
400
|
+
var columnTypeToTs = (type) => {
|
|
401
|
+
switch (type.toLowerCase()) {
|
|
402
|
+
case "string":
|
|
403
|
+
case "text":
|
|
404
|
+
case "varchar":
|
|
405
|
+
return "string";
|
|
406
|
+
case "number":
|
|
407
|
+
case "integer":
|
|
408
|
+
case "float":
|
|
409
|
+
case "double":
|
|
410
|
+
case "decimal":
|
|
411
|
+
return "number";
|
|
412
|
+
case "boolean":
|
|
413
|
+
case "bool":
|
|
414
|
+
return "boolean";
|
|
415
|
+
default:
|
|
416
|
+
return "unknown";
|
|
417
|
+
}
|
|
418
|
+
};
|
|
419
|
+
var generatePipelinesJson = (pipelines) => {
|
|
420
|
+
if (pipelines.length === 0) return JSON.stringify({}, null, 2);
|
|
421
|
+
const result = {};
|
|
422
|
+
for (const p of pipelines) {
|
|
423
|
+
const queries = {};
|
|
424
|
+
for (const q of p.queries) {
|
|
425
|
+
queries[q.name] = { params: q.params, returns: q.returns };
|
|
426
|
+
}
|
|
427
|
+
result[p.pipeline] = queries;
|
|
428
|
+
}
|
|
429
|
+
return JSON.stringify(result, null, 2);
|
|
430
|
+
};
|
|
431
|
+
var generatePipelinesDts = (pipelines) => {
|
|
432
|
+
if (pipelines.length === 0) {
|
|
433
|
+
return [
|
|
434
|
+
`// Auto-generated by \`kraken generate\` \u2014 do not edit manually`,
|
|
435
|
+
`export {};`,
|
|
436
|
+
``,
|
|
437
|
+
`declare module "@kraken-ai/platform" {`,
|
|
438
|
+
` interface PipelineRegistry {}`,
|
|
439
|
+
`}`,
|
|
440
|
+
``
|
|
441
|
+
].join("\n");
|
|
442
|
+
}
|
|
443
|
+
const entries = pipelines.map((p) => {
|
|
444
|
+
const queryEntries = p.queries.map((q) => {
|
|
445
|
+
const params = jsonSchemaToTsType(q.params);
|
|
446
|
+
const returns = jsonSchemaToTsType(q.returns);
|
|
447
|
+
return ` "${q.name}": {
|
|
448
|
+
params: ${params}
|
|
449
|
+
returns: ${returns}
|
|
450
|
+
}`;
|
|
451
|
+
}).join("\n");
|
|
452
|
+
return ` "${p.pipeline}": {
|
|
453
|
+
${queryEntries}
|
|
454
|
+
}`;
|
|
455
|
+
}).join("\n");
|
|
456
|
+
return [
|
|
457
|
+
`// Auto-generated by \`kraken generate\` \u2014 do not edit manually`,
|
|
458
|
+
`export {};`,
|
|
459
|
+
``,
|
|
460
|
+
`declare module "@kraken-ai/platform" {`,
|
|
461
|
+
` interface PipelineRegistry {`,
|
|
462
|
+
entries,
|
|
463
|
+
` }`,
|
|
464
|
+
`}`,
|
|
465
|
+
``
|
|
466
|
+
].join("\n");
|
|
467
|
+
};
|
|
468
|
+
|
|
469
|
+
// src/cli/credentials.ts
|
|
470
|
+
import fs2 from "fs";
|
|
471
|
+
import os from "os";
|
|
472
|
+
import path2 from "path";
|
|
473
|
+
var credentialsDir = () => path2.join(os.homedir(), ".kraken-ai");
|
|
474
|
+
var credentialsPath = () => path2.join(credentialsDir(), "credentials.json");
|
|
475
|
+
var saveCredentials = (creds) => {
|
|
476
|
+
const dir = credentialsDir();
|
|
477
|
+
if (!fs2.existsSync(dir)) {
|
|
478
|
+
fs2.mkdirSync(dir, { recursive: true, mode: 448 });
|
|
479
|
+
}
|
|
480
|
+
const filePath = credentialsPath();
|
|
481
|
+
fs2.writeFileSync(filePath, JSON.stringify(creds, null, 2), { mode: 384 });
|
|
482
|
+
};
|
|
483
|
+
var loadCredentials = () => {
|
|
484
|
+
const filePath = credentialsPath();
|
|
485
|
+
let creds = null;
|
|
486
|
+
if (fs2.existsSync(filePath)) {
|
|
487
|
+
try {
|
|
488
|
+
creds = JSON.parse(fs2.readFileSync(filePath, "utf-8"));
|
|
489
|
+
} catch {
|
|
490
|
+
return null;
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
const envKey = process.env.KRAKEN_API_KEY;
|
|
494
|
+
const envUrl = process.env.KRAKEN_BASE_URL;
|
|
495
|
+
if (envKey || envUrl) {
|
|
496
|
+
return {
|
|
497
|
+
apiKey: envKey ?? creds?.apiKey ?? "",
|
|
498
|
+
baseUrl: envUrl ?? creds?.baseUrl ?? ""
|
|
499
|
+
};
|
|
500
|
+
}
|
|
501
|
+
return creds;
|
|
502
|
+
};
|
|
503
|
+
var clearCredentials = () => {
|
|
504
|
+
const filePath = credentialsPath();
|
|
505
|
+
if (fs2.existsSync(filePath)) {
|
|
506
|
+
fs2.unlinkSync(filePath);
|
|
507
|
+
}
|
|
508
|
+
};
|
|
509
|
+
|
|
510
|
+
// src/cli/discover.ts
|
|
511
|
+
import fs3 from "fs";
|
|
512
|
+
import path3 from "path";
|
|
513
|
+
import { pathToFileURL } from "url";
|
|
514
|
+
import * as z10 from "zod";
|
|
515
|
+
|
|
516
|
+
// src/agents/types/action.ts
|
|
517
|
+
import * as z from "zod";
|
|
518
|
+
var actionVariantConfigSchema = z.object({
|
|
519
|
+
schema: z.record(z.string(), z.unknown()),
|
|
520
|
+
webhook: z.string().url().optional(),
|
|
521
|
+
hasHandler: z.boolean()
|
|
522
|
+
});
|
|
523
|
+
var actionsConfigSchema = z.object({
|
|
524
|
+
variants: z.record(z.string(), actionVariantConfigSchema)
|
|
525
|
+
}).strict();
|
|
526
|
+
|
|
527
|
+
// src/agents/types/environment.ts
|
|
528
|
+
import * as z2 from "zod";
|
|
529
|
+
var environmentSchema = z2.enum(["dev", "staging", "prod"]);
|
|
530
|
+
|
|
531
|
+
// src/agents/types/identity.ts
|
|
532
|
+
import * as z3 from "zod";
|
|
533
|
+
var jitPolicySchema = z3.enum(["auto-approve", "policy-based", "require-approval"]);
|
|
534
|
+
var identityConfigSchema = z3.object({
|
|
535
|
+
basePermissions: z3.array(z3.string()),
|
|
536
|
+
requestablePermissions: z3.array(z3.string()).optional(),
|
|
537
|
+
jitPolicy: jitPolicySchema.optional(),
|
|
538
|
+
maxJitDurationMinutes: z3.number().int().positive().optional()
|
|
539
|
+
});
|
|
540
|
+
|
|
541
|
+
// src/agents/types/notifications.ts
|
|
542
|
+
import * as z4 from "zod";
|
|
543
|
+
var notificationConfigSchema = z4.object({
|
|
544
|
+
slack: z4.string().optional(),
|
|
545
|
+
onSuccess: z4.boolean().optional(),
|
|
546
|
+
onFailure: z4.boolean().optional(),
|
|
547
|
+
onTimeout: z4.boolean().optional()
|
|
548
|
+
});
|
|
549
|
+
|
|
550
|
+
// src/agents/types/platform-agent.ts
|
|
551
|
+
import * as z8 from "zod";
|
|
552
|
+
|
|
553
|
+
// src/agents/types/resources.ts
|
|
554
|
+
import * as z5 from "zod";
|
|
555
|
+
var resourceLimitsSchema = z5.object({
|
|
556
|
+
maxTokens: z5.number().int().positive().optional(),
|
|
557
|
+
maxCostUsd: z5.number().positive().optional(),
|
|
558
|
+
timeoutSeconds: z5.number().int().positive().optional()
|
|
559
|
+
});
|
|
560
|
+
var retryPolicySchema = z5.object({
|
|
561
|
+
maxAttempts: z5.number().int().min(1).optional(),
|
|
562
|
+
backoffSeconds: z5.number().positive().optional()
|
|
563
|
+
});
|
|
564
|
+
var concurrencyPolicySchema = z5.object({
|
|
565
|
+
maxParallelRuns: z5.number().int().min(1).optional()
|
|
566
|
+
});
|
|
567
|
+
|
|
568
|
+
// src/agents/types/team.ts
|
|
569
|
+
import * as z6 from "zod";
|
|
570
|
+
var teamConfigSchema = z6.object({
|
|
571
|
+
members: z6.array(z6.string()).min(1),
|
|
572
|
+
maxConcurrentWorkers: z6.number().int().min(1).optional(),
|
|
573
|
+
maxTokenBudgetPerWorker: z6.number().int().positive().optional(),
|
|
574
|
+
maxDurationPerWorker: z6.number().positive().optional()
|
|
575
|
+
});
|
|
576
|
+
|
|
577
|
+
// src/agents/types/trigger.ts
|
|
578
|
+
import * as z7 from "zod";
|
|
579
|
+
var cronTriggerSchema = z7.object({
|
|
580
|
+
type: z7.literal("cron"),
|
|
581
|
+
expression: z7.string(),
|
|
582
|
+
timezone: z7.string().optional()
|
|
583
|
+
});
|
|
584
|
+
var webhookTriggerSchema = z7.object({
|
|
585
|
+
type: z7.literal("webhook"),
|
|
586
|
+
path: z7.string().startsWith("/"),
|
|
587
|
+
method: z7.enum(["POST", "GET"]).optional()
|
|
588
|
+
});
|
|
589
|
+
var eventTriggerSchema = z7.object({
|
|
590
|
+
type: z7.literal("event"),
|
|
591
|
+
source: z7.string(),
|
|
592
|
+
event: z7.string()
|
|
593
|
+
});
|
|
594
|
+
var apiTriggerSchema = z7.object({ type: z7.literal("api") });
|
|
595
|
+
var manualTriggerSchema = z7.object({ type: z7.literal("manual") });
|
|
596
|
+
var triggerConfigSchema = z7.discriminatedUnion("type", [
|
|
597
|
+
cronTriggerSchema,
|
|
598
|
+
webhookTriggerSchema,
|
|
599
|
+
eventTriggerSchema,
|
|
600
|
+
apiTriggerSchema,
|
|
601
|
+
manualTriggerSchema
|
|
602
|
+
]);
|
|
603
|
+
|
|
604
|
+
// src/agents/types/platform-agent.ts
|
|
605
|
+
var thinkingLevelSchema = z8.enum(["low", "medium", "high"]);
|
|
606
|
+
var logLevelSchema = z8.enum(["silent", "debug", "info", "warn", "error"]);
|
|
607
|
+
var agentDefinitionSchema = z8.object({
|
|
608
|
+
name: z8.string().min(1),
|
|
609
|
+
model: z8.string().min(1),
|
|
610
|
+
instructions: z8.string().min(1),
|
|
611
|
+
description: z8.string().optional(),
|
|
612
|
+
skills: z8.array(z8.string()).optional(),
|
|
613
|
+
temperature: z8.number().min(0).max(2).optional(),
|
|
614
|
+
allowTemperatureOverride: z8.boolean().optional(),
|
|
615
|
+
maxOutputTokens: z8.number().int().positive().optional(),
|
|
616
|
+
thinkingLevel: thinkingLevelSchema.optional(),
|
|
617
|
+
logLevel: logLevelSchema.optional()
|
|
618
|
+
}).strict();
|
|
619
|
+
var platformAgentConfigSchema = z8.object({
|
|
620
|
+
agent: agentDefinitionSchema,
|
|
621
|
+
connectors: z8.array(z8.string()).optional(),
|
|
622
|
+
trigger: triggerConfigSchema,
|
|
623
|
+
identity: identityConfigSchema.optional(),
|
|
624
|
+
resources: resourceLimitsSchema.optional(),
|
|
625
|
+
retries: retryPolicySchema.optional(),
|
|
626
|
+
concurrency: concurrencyPolicySchema.optional(),
|
|
627
|
+
team: teamConfigSchema.optional(),
|
|
628
|
+
notifications: notificationConfigSchema.optional(),
|
|
629
|
+
environment: environmentSchema.optional(),
|
|
630
|
+
actions: actionsConfigSchema.optional()
|
|
631
|
+
}).strict();
|
|
632
|
+
|
|
633
|
+
// src/agents/types/skill.ts
|
|
634
|
+
import * as z9 from "zod";
|
|
635
|
+
var platformSkillInputSchema = z9.object({
|
|
636
|
+
name: z9.string().min(1),
|
|
637
|
+
description: z9.string().optional()
|
|
638
|
+
}).strict();
|
|
639
|
+
|
|
640
|
+
// src/cli/discover.ts
|
|
641
|
+
var MANIFEST_START = "---KRAKEN-MANIFEST-START---";
|
|
642
|
+
var MANIFEST_END = "---KRAKEN-MANIFEST-END---";
|
|
643
|
+
var skillEntrySchema = z10.object({
|
|
644
|
+
name: z10.string().min(1),
|
|
645
|
+
path: z10.string().min(1),
|
|
646
|
+
content: z10.string()
|
|
647
|
+
});
|
|
648
|
+
var connectorEntrySchema = z10.object({
|
|
649
|
+
name: z10.string().min(1),
|
|
650
|
+
path: z10.string().min(1)
|
|
651
|
+
});
|
|
652
|
+
var agentEntrySchema = z10.object({
|
|
653
|
+
name: z10.string().min(1),
|
|
654
|
+
entryPoint: z10.string().min(1),
|
|
655
|
+
config: platformAgentConfigSchema
|
|
656
|
+
});
|
|
657
|
+
var projectManifestSchema = z10.object({
|
|
658
|
+
agents: z10.array(agentEntrySchema),
|
|
659
|
+
skills: z10.array(skillEntrySchema),
|
|
660
|
+
connectors: z10.array(connectorEntrySchema)
|
|
661
|
+
});
|
|
662
|
+
var isPlatformAgentExport = (value) => value != null && typeof value === "object" && value.__type === "PlatformAgent" && "config" in value;
|
|
663
|
+
var discoverAgents = async (projectRoot) => {
|
|
664
|
+
const agentsDir = path3.join(projectRoot, "agents");
|
|
665
|
+
if (!fs3.existsSync(agentsDir) || !fs3.statSync(agentsDir).isDirectory()) {
|
|
666
|
+
return [];
|
|
667
|
+
}
|
|
668
|
+
const files = fs3.readdirSync(agentsDir).filter((f) => f.endsWith(".js") || f.endsWith(".mjs")).sort();
|
|
669
|
+
const seen = /* @__PURE__ */ new Map();
|
|
670
|
+
for (const file of files) {
|
|
671
|
+
const filePath = path3.join(agentsDir, file);
|
|
672
|
+
try {
|
|
673
|
+
const mod = await import(pathToFileURL(filePath).href);
|
|
674
|
+
const exported = mod.default;
|
|
675
|
+
if (isPlatformAgentExport(exported) && !seen.has(exported.config.agent.name)) {
|
|
676
|
+
seen.set(exported.config.agent.name, {
|
|
677
|
+
config: exported.config,
|
|
678
|
+
entryPoint: `agents/${file}`
|
|
679
|
+
});
|
|
680
|
+
}
|
|
681
|
+
} catch (err) {
|
|
682
|
+
warn(`Skipping agents/${file}: ${err instanceof Error ? err.message : String(err)}`);
|
|
683
|
+
}
|
|
684
|
+
}
|
|
685
|
+
return [...seen.values()];
|
|
686
|
+
};
|
|
687
|
+
var MAX_SKILL_SIZE = 100 * 1024;
|
|
688
|
+
var discoverSkills = (projectRoot) => {
|
|
689
|
+
const skillsDir = path3.join(projectRoot, "skills");
|
|
690
|
+
if (!fs3.existsSync(skillsDir) || !fs3.statSync(skillsDir).isDirectory()) {
|
|
691
|
+
return [];
|
|
692
|
+
}
|
|
693
|
+
const files = fs3.readdirSync(skillsDir).sort();
|
|
694
|
+
const skills = [];
|
|
695
|
+
for (const file of files) {
|
|
696
|
+
if (!file.endsWith(".md")) {
|
|
697
|
+
warn(`Skipping skills/${file}: skill files must have a .md extension.`);
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
const basename = file.replace(/\.md$/, "");
|
|
701
|
+
if (!isValidSkillName(basename)) {
|
|
702
|
+
warn(
|
|
703
|
+
`Skipping skills/${file}: name must match [a-zA-Z0-9-] (letters, digits, hyphens only).`
|
|
704
|
+
);
|
|
705
|
+
continue;
|
|
706
|
+
}
|
|
707
|
+
const filePath = path3.join(skillsDir, file);
|
|
708
|
+
const stat = fs3.statSync(filePath);
|
|
709
|
+
if (stat.size > MAX_SKILL_SIZE) {
|
|
710
|
+
warn(`Skipping skills/${file}: exceeds ${MAX_SKILL_SIZE} byte limit.`);
|
|
711
|
+
continue;
|
|
712
|
+
}
|
|
713
|
+
const content = fs3.readFileSync(filePath, "utf-8");
|
|
714
|
+
skills.push({ name: file, path: `skills/${file}`, content });
|
|
715
|
+
}
|
|
716
|
+
return skills;
|
|
717
|
+
};
|
|
718
|
+
var discoverConnectors = (projectRoot) => {
|
|
719
|
+
const connectorsDir = path3.join(projectRoot, "connectors");
|
|
720
|
+
if (!fs3.existsSync(connectorsDir) || !fs3.statSync(connectorsDir).isDirectory()) {
|
|
721
|
+
return [];
|
|
722
|
+
}
|
|
723
|
+
const entries = fs3.readdirSync(connectorsDir, { withFileTypes: true });
|
|
724
|
+
const connectors = [];
|
|
725
|
+
for (const entry of entries) {
|
|
726
|
+
if (!entry.isDirectory()) continue;
|
|
727
|
+
const name = entry.name;
|
|
728
|
+
if (!isValidEntityName(name)) {
|
|
729
|
+
warn(
|
|
730
|
+
`Skipping connectors/${name}: name must match [a-z0-9-] (lowercase, digits, hyphens only).`
|
|
731
|
+
);
|
|
732
|
+
continue;
|
|
733
|
+
}
|
|
734
|
+
const connDir = path3.join(connectorsDir, name);
|
|
735
|
+
const hasPackageJson = fs3.existsSync(path3.join(connDir, "package.json"));
|
|
736
|
+
const hasDockerfile = fs3.existsSync(path3.join(connDir, "Dockerfile"));
|
|
737
|
+
if (!hasPackageJson && !hasDockerfile) {
|
|
738
|
+
continue;
|
|
739
|
+
}
|
|
740
|
+
connectors.push({ name, path: `connectors/${name}/` });
|
|
741
|
+
}
|
|
742
|
+
return connectors.sort((a, b) => a.name.localeCompare(b.name));
|
|
743
|
+
};
|
|
744
|
+
var discoverProject = async (projectRoot) => {
|
|
745
|
+
const discovered = await discoverAgents(projectRoot);
|
|
746
|
+
const agents = [];
|
|
747
|
+
for (const { config, entryPoint } of discovered) {
|
|
748
|
+
const name = config.agent.name;
|
|
749
|
+
if (!isValidEntityName(name)) {
|
|
750
|
+
throw new Error(`Invalid agent name: "${name}". Names must match ${ENTITY_NAME_REGEX}`);
|
|
751
|
+
}
|
|
752
|
+
agents.push({ name, entryPoint, config });
|
|
753
|
+
}
|
|
754
|
+
const skills = discoverSkills(projectRoot);
|
|
755
|
+
const connectors = discoverConnectors(projectRoot);
|
|
756
|
+
return { agents, skills, connectors };
|
|
757
|
+
};
|
|
758
|
+
var emitManifest = (manifest) => {
|
|
759
|
+
process.stdout.write(`${MANIFEST_START}
|
|
760
|
+
`);
|
|
761
|
+
process.stdout.write(JSON.stringify(manifest));
|
|
762
|
+
process.stdout.write(`
|
|
763
|
+
${MANIFEST_END}
|
|
764
|
+
`);
|
|
765
|
+
};
|
|
766
|
+
|
|
767
|
+
// src/cli/pick.ts
|
|
768
|
+
var pick = async (label, items) => {
|
|
769
|
+
if (items.length === 0) return null;
|
|
770
|
+
if (items.length === 1) return items[0] ?? null;
|
|
771
|
+
const { stdin, stdout } = process;
|
|
772
|
+
if (!stdin.isTTY) return null;
|
|
773
|
+
let cursor = 0;
|
|
774
|
+
const render = () => {
|
|
775
|
+
stdout.write(` ${dim(label)}
|
|
776
|
+
`);
|
|
777
|
+
for (let i = 0; i < items.length; i++) {
|
|
778
|
+
const marker = i === cursor ? cyan("\u276F") : " ";
|
|
779
|
+
const item = items[i] ?? "";
|
|
780
|
+
const text = i === cursor ? cyan(item) : dim(item);
|
|
781
|
+
stdout.write(` ${marker} ${text}
|
|
782
|
+
`);
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
const clear = () => {
|
|
786
|
+
const lines = items.length + 1;
|
|
787
|
+
for (let i = 0; i < lines; i++) {
|
|
788
|
+
stdout.write("\x1B[1A\x1B[2K");
|
|
789
|
+
}
|
|
790
|
+
};
|
|
791
|
+
stdin.setRawMode(true);
|
|
792
|
+
stdin.resume();
|
|
793
|
+
render();
|
|
794
|
+
return new Promise((resolve) => {
|
|
795
|
+
const onData = (data) => {
|
|
796
|
+
const key = data.toString();
|
|
797
|
+
if (key === "\x1B[A" || key === "k") {
|
|
798
|
+
clear();
|
|
799
|
+
cursor = (cursor - 1 + items.length) % items.length;
|
|
800
|
+
render();
|
|
801
|
+
} else if (key === "\x1B[B" || key === "j") {
|
|
802
|
+
clear();
|
|
803
|
+
cursor = (cursor + 1) % items.length;
|
|
804
|
+
render();
|
|
805
|
+
} else if (key === "\r" || key === "\n") {
|
|
806
|
+
cleanup();
|
|
807
|
+
clear();
|
|
808
|
+
resolve(items[cursor] ?? null);
|
|
809
|
+
} else if (key === "" || key === "\x1B" || key === "q") {
|
|
810
|
+
cleanup();
|
|
811
|
+
clear();
|
|
812
|
+
resolve(null);
|
|
813
|
+
}
|
|
814
|
+
};
|
|
815
|
+
const cleanup = () => {
|
|
816
|
+
stdin.removeListener("data", onData);
|
|
817
|
+
stdin.setRawMode(false);
|
|
818
|
+
stdin.pause();
|
|
819
|
+
};
|
|
820
|
+
stdin.on("data", onData);
|
|
821
|
+
});
|
|
822
|
+
};
|
|
823
|
+
|
|
824
|
+
// src/platform/types.ts
|
|
825
|
+
import * as z11 from "zod";
|
|
826
|
+
var jsonSchemaValue = z11.record(z11.string(), z11.unknown());
|
|
827
|
+
var agentSchemaValidator = z11.object({
|
|
828
|
+
id: z11.string(),
|
|
829
|
+
name: z11.string(),
|
|
830
|
+
input: jsonSchemaValue,
|
|
831
|
+
output: jsonSchemaValue,
|
|
832
|
+
actions: z11.record(z11.string(), jsonSchemaValue).optional()
|
|
833
|
+
}).passthrough();
|
|
834
|
+
var queryColumnValidator = z11.object({
|
|
835
|
+
name: z11.string(),
|
|
836
|
+
type: z11.string(),
|
|
837
|
+
description: z11.string().optional()
|
|
838
|
+
}).passthrough();
|
|
839
|
+
var querySchemaValidator = z11.object({
|
|
840
|
+
name: z11.string(),
|
|
841
|
+
params: jsonSchemaValue,
|
|
842
|
+
columns: z11.array(queryColumnValidator)
|
|
843
|
+
}).passthrough();
|
|
844
|
+
var connectorToolValidator = z11.object({
|
|
845
|
+
name: z11.string(),
|
|
846
|
+
description: z11.string(),
|
|
847
|
+
parameters: jsonSchemaValue
|
|
848
|
+
}).passthrough();
|
|
849
|
+
var connectorSchemaValidator = z11.object({
|
|
850
|
+
id: z11.string(),
|
|
851
|
+
tools: z11.array(connectorToolValidator)
|
|
852
|
+
}).passthrough();
|
|
853
|
+
var skillSchemaValidator = z11.object({
|
|
854
|
+
id: z11.string(),
|
|
855
|
+
name: z11.string(),
|
|
856
|
+
description: z11.string().optional()
|
|
857
|
+
}).passthrough();
|
|
858
|
+
var pipelineQuerySchemaValidator = z11.object({
|
|
859
|
+
name: z11.string(),
|
|
860
|
+
description: z11.string(),
|
|
861
|
+
params: jsonSchemaValue,
|
|
862
|
+
returns: jsonSchemaValue
|
|
863
|
+
}).passthrough();
|
|
864
|
+
var pipelineSchemaValidator = z11.object({
|
|
865
|
+
pipeline: z11.string(),
|
|
866
|
+
queries: z11.array(pipelineQuerySchemaValidator)
|
|
867
|
+
}).passthrough();
|
|
868
|
+
|
|
869
|
+
// src/cli.ts
|
|
870
|
+
var COMMANDS = /* @__PURE__ */ new Set(["login", "generate", "logout", "discover", "init", "dev"]);
|
|
871
|
+
var parseArgs = (args) => {
|
|
872
|
+
const command = args[0];
|
|
873
|
+
if (!command || command === "--help" || !COMMANDS.has(command)) {
|
|
874
|
+
return { command: "help", positional: [], flags: {} };
|
|
875
|
+
}
|
|
876
|
+
const BOOLEAN_FLAGS = /* @__PURE__ */ new Set(["check", "emit"]);
|
|
877
|
+
const positional = [];
|
|
878
|
+
const flags = {};
|
|
879
|
+
for (let i = 1; i < args.length; i++) {
|
|
880
|
+
const arg = args[i];
|
|
881
|
+
if (arg?.startsWith("--")) {
|
|
882
|
+
const name = arg.slice(2);
|
|
883
|
+
if (BOOLEAN_FLAGS.has(name)) {
|
|
884
|
+
flags[name] = "";
|
|
885
|
+
} else {
|
|
886
|
+
const next = args[++i];
|
|
887
|
+
if (next !== void 0) {
|
|
888
|
+
flags[name] = next;
|
|
889
|
+
}
|
|
890
|
+
}
|
|
891
|
+
} else if (arg) {
|
|
892
|
+
positional.push(arg);
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
return { command, positional, flags };
|
|
896
|
+
};
|
|
897
|
+
var runCommand = async (parsed, deps) => {
|
|
898
|
+
switch (parsed.command) {
|
|
899
|
+
case "login":
|
|
900
|
+
await handleLogin(parsed, deps);
|
|
901
|
+
return 0;
|
|
902
|
+
case "generate":
|
|
903
|
+
return handleGenerate(parsed, deps);
|
|
904
|
+
case "dev":
|
|
905
|
+
return handleDev(parsed, deps);
|
|
906
|
+
case "discover":
|
|
907
|
+
return handleDiscover(parsed, deps);
|
|
908
|
+
case "init":
|
|
909
|
+
return handleInit(parsed, deps);
|
|
910
|
+
case "logout":
|
|
911
|
+
handleLogout(deps);
|
|
912
|
+
return 0;
|
|
913
|
+
case "help":
|
|
914
|
+
printHelp(deps);
|
|
915
|
+
return 0;
|
|
916
|
+
default:
|
|
917
|
+
return 0;
|
|
918
|
+
}
|
|
919
|
+
};
|
|
920
|
+
var handleLogin = async (parsed, deps) => {
|
|
921
|
+
const url = parsed.flags.url ?? await deps.prompt("Platform URL: ");
|
|
922
|
+
const key = parsed.flags.key ?? await deps.prompt("API Key: ");
|
|
923
|
+
if (!url || !key) {
|
|
924
|
+
deps.log("Error: both URL and API key are required.");
|
|
925
|
+
return;
|
|
926
|
+
}
|
|
927
|
+
deps.saveCredentials({ baseUrl: url, apiKey: key });
|
|
928
|
+
deps.log(`Credentials saved. Connected to ${url}`);
|
|
929
|
+
};
|
|
930
|
+
var emptySchemaBundle = {
|
|
931
|
+
agents: [],
|
|
932
|
+
queries: [],
|
|
933
|
+
connectors: [],
|
|
934
|
+
pipelines: [],
|
|
935
|
+
skills: []
|
|
936
|
+
};
|
|
937
|
+
var fetchRemoteSchemas = async (creds, deps) => {
|
|
938
|
+
const headers = { Authorization: `Bearer ${creds.apiKey}` };
|
|
939
|
+
const controller = new AbortController();
|
|
940
|
+
const timeout = setTimeout(() => controller.abort(), 1e4);
|
|
941
|
+
try {
|
|
942
|
+
const endpoints = ["agents", "queries", "connectors", "pipelines", "skills"];
|
|
943
|
+
const responses = await Promise.all(
|
|
944
|
+
endpoints.map(
|
|
945
|
+
(ep) => deps.fetch(`${creds.baseUrl}/api/v1/schema/${ep}`, { headers, signal: controller.signal }).then(async (res) => {
|
|
946
|
+
if (!res.ok) return res;
|
|
947
|
+
const data = await res.json();
|
|
948
|
+
res._jsonData = data;
|
|
949
|
+
return res;
|
|
950
|
+
}).catch(() => null)
|
|
951
|
+
)
|
|
952
|
+
);
|
|
953
|
+
const [agentsRes, queriesRes, connectorsRes, pipelinesRes, skillsRes] = responses;
|
|
954
|
+
const allFailed = responses.every((r) => !r?.ok);
|
|
955
|
+
if (allFailed) {
|
|
956
|
+
warn(`Could not reach platform at ${creds.baseUrl}. Generating from local definitions only.`);
|
|
957
|
+
return emptySchemaBundle;
|
|
958
|
+
}
|
|
959
|
+
const agents = parseEndpointData(agentsRes, z12.array(agentSchemaValidator), "agents");
|
|
960
|
+
const queries = parseEndpointData(queriesRes, z12.array(querySchemaValidator), "queries");
|
|
961
|
+
const connectors = parseEndpointData(connectorsRes, z12.array(connectorSchemaValidator), "connectors");
|
|
962
|
+
const pipelines = parseEndpointData(pipelinesRes, z12.array(pipelineSchemaValidator), "pipelines");
|
|
963
|
+
const skills = parseEndpointData(skillsRes, z12.array(skillSchemaValidator), "skills");
|
|
964
|
+
return { agents, queries, connectors, pipelines, skills };
|
|
965
|
+
} finally {
|
|
966
|
+
clearTimeout(timeout);
|
|
967
|
+
}
|
|
968
|
+
};
|
|
969
|
+
var parseEndpointData = (res, validator, endpointName) => {
|
|
970
|
+
if (!res?.ok) return [];
|
|
971
|
+
const data = res._jsonData;
|
|
972
|
+
const result = validator.safeParse(data);
|
|
973
|
+
if (!result.success) {
|
|
974
|
+
throw new Error(
|
|
975
|
+
`Invalid remote schema from ${endpointName} endpoint: ${z12.prettifyError(result.error)}`
|
|
976
|
+
);
|
|
977
|
+
}
|
|
978
|
+
return result.data;
|
|
979
|
+
};
|
|
980
|
+
var mergeLocalAndRemote = (local, remote) => {
|
|
981
|
+
const remoteAgentIds = new Set(remote.agents.map((a) => a.id));
|
|
982
|
+
const remoteConnectorIds = new Set(remote.connectors.map((c) => c.id));
|
|
983
|
+
const remoteSkillIds = new Set(remote.skills.map((s) => s.id));
|
|
984
|
+
const localAgents = local.agents.filter((a) => !remoteAgentIds.has(a.name)).map((a) => ({ id: a.name, name: a.name, input: {}, output: {} }));
|
|
985
|
+
const localSkills = local.skills.filter((s) => !remoteSkillIds.has(s.name)).map((s) => ({ id: s.name, name: s.name }));
|
|
986
|
+
const localConnectors = local.connectors.filter((c) => !remoteConnectorIds.has(c.name)).map((c) => ({ id: c.name, tools: [] }));
|
|
987
|
+
return {
|
|
988
|
+
agents: [...remote.agents, ...localAgents],
|
|
989
|
+
queries: remote.queries,
|
|
990
|
+
connectors: [...remote.connectors, ...localConnectors],
|
|
991
|
+
pipelines: remote.pipelines,
|
|
992
|
+
skills: [...remote.skills, ...localSkills]
|
|
993
|
+
};
|
|
994
|
+
};
|
|
995
|
+
var handleGenerate = async (parsed, deps) => {
|
|
996
|
+
const outDir = parsed.flags.dir ?? process.cwd();
|
|
997
|
+
let manifest;
|
|
998
|
+
try {
|
|
999
|
+
manifest = await deps.discoverProject(outDir);
|
|
1000
|
+
} catch (err) {
|
|
1001
|
+
deps.log(`Error discovering project: ${err instanceof Error ? err.message : String(err)}`);
|
|
1002
|
+
return 1;
|
|
1003
|
+
}
|
|
1004
|
+
const creds = deps.loadCredentials();
|
|
1005
|
+
let remote;
|
|
1006
|
+
if (creds?.apiKey && creds?.baseUrl) {
|
|
1007
|
+
try {
|
|
1008
|
+
remote = await fetchRemoteSchemas(creds, deps);
|
|
1009
|
+
} catch (err) {
|
|
1010
|
+
deps.log(`Error fetching remote schemas: ${err instanceof Error ? err.message : String(err)}`);
|
|
1011
|
+
return 1;
|
|
1012
|
+
}
|
|
1013
|
+
} else {
|
|
1014
|
+
warn(
|
|
1015
|
+
"Not logged in. Generating from local definitions only. Run `kraken login` to sync with the platform."
|
|
1016
|
+
);
|
|
1017
|
+
remote = emptySchemaBundle;
|
|
1018
|
+
}
|
|
1019
|
+
const bundle = mergeLocalAndRemote(manifest, remote);
|
|
1020
|
+
if ("check" in parsed.flags) {
|
|
1021
|
+
const { mkdtempSync, readFileSync, rmSync } = await import("fs");
|
|
1022
|
+
const { join } = await import("path");
|
|
1023
|
+
const { tmpdir } = await import("os");
|
|
1024
|
+
const tempDir = mkdtempSync(join(tmpdir(), "kraken-check-"));
|
|
1025
|
+
try {
|
|
1026
|
+
deps.generateTypes(bundle, tempDir);
|
|
1027
|
+
} catch (err) {
|
|
1028
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
1029
|
+
deps.log(`Error generating types: ${err instanceof Error ? err.message : String(err)}`);
|
|
1030
|
+
return 1;
|
|
1031
|
+
}
|
|
1032
|
+
try {
|
|
1033
|
+
const files = [
|
|
1034
|
+
"pipelines.json",
|
|
1035
|
+
"pipelines.d.ts",
|
|
1036
|
+
"pipelines.ts",
|
|
1037
|
+
// stale file detection — should not exist after migration
|
|
1038
|
+
"agents.d.ts",
|
|
1039
|
+
"queries.d.ts",
|
|
1040
|
+
"connectors.d.ts",
|
|
1041
|
+
"platform-types.d.ts",
|
|
1042
|
+
"index.d.ts",
|
|
1043
|
+
"manifest.json"
|
|
1044
|
+
];
|
|
1045
|
+
let stale = false;
|
|
1046
|
+
for (const file of files) {
|
|
1047
|
+
const existingPath = join(outDir, ".kraken-ai", file);
|
|
1048
|
+
const generatedPath = join(tempDir, ".kraken-ai", file);
|
|
1049
|
+
const existing = safeReadFile(readFileSync, existingPath);
|
|
1050
|
+
const generated = safeReadFile(readFileSync, generatedPath);
|
|
1051
|
+
if (existing !== generated) {
|
|
1052
|
+
deps.log(`Schema drift detected: .kraken-ai/${file}`);
|
|
1053
|
+
stale = true;
|
|
1054
|
+
}
|
|
1055
|
+
}
|
|
1056
|
+
if (stale) {
|
|
1057
|
+
deps.log("Run `kraken generate` to update generated types.");
|
|
1058
|
+
return 1;
|
|
1059
|
+
}
|
|
1060
|
+
deps.log("Schemas are up to date.");
|
|
1061
|
+
return 0;
|
|
1062
|
+
} finally {
|
|
1063
|
+
rmSync(tempDir, { recursive: true, force: true });
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
try {
|
|
1067
|
+
deps.generateTypes(bundle, outDir);
|
|
1068
|
+
} catch (err) {
|
|
1069
|
+
deps.log(`Error generating types: ${err instanceof Error ? err.message : String(err)}`);
|
|
1070
|
+
return 1;
|
|
1071
|
+
}
|
|
1072
|
+
const localCount = manifest.agents.length + manifest.skills.length + manifest.connectors.length;
|
|
1073
|
+
const remoteCount = remote.agents.length + remote.connectors.length + remote.skills.length;
|
|
1074
|
+
deps.log(`Generated types for ${localCount} local + ${remoteCount} remote entities.`);
|
|
1075
|
+
return 0;
|
|
1076
|
+
};
|
|
1077
|
+
var safeReadFile = (readFileSync, filePath) => {
|
|
1078
|
+
try {
|
|
1079
|
+
return readFileSync(filePath, "utf-8");
|
|
1080
|
+
} catch {
|
|
1081
|
+
return null;
|
|
1082
|
+
}
|
|
1083
|
+
};
|
|
1084
|
+
var buildDevBootstrap = (fileUrl, file) => [
|
|
1085
|
+
`void (async () => {`,
|
|
1086
|
+
` const mod = await import("${fileUrl}");`,
|
|
1087
|
+
` const a = mod.default;`,
|
|
1088
|
+
` if (!a || a.__type !== "PlatformAgent") {`,
|
|
1089
|
+
` console.error("Error: " + ${JSON.stringify(file)} + " must export a PlatformAgent as default.");`,
|
|
1090
|
+
` process.exit(1);`,
|
|
1091
|
+
` }`,
|
|
1092
|
+
` const { runDev } = await import("@kraken-ai/platform");`,
|
|
1093
|
+
` await runDev(a);`,
|
|
1094
|
+
`})();`
|
|
1095
|
+
].join("\n");
|
|
1096
|
+
var discoverAgentFiles = async () => {
|
|
1097
|
+
const { readdirSync, existsSync } = await import("fs");
|
|
1098
|
+
const agentsDir = "agents";
|
|
1099
|
+
if (!existsSync(agentsDir)) return [];
|
|
1100
|
+
return readdirSync(agentsDir).filter((f) => f.endsWith(".ts") || f.endsWith(".js") || f.endsWith(".mjs")).sort();
|
|
1101
|
+
};
|
|
1102
|
+
var handleDev = async (parsed, deps) => {
|
|
1103
|
+
let name = parsed.positional[0];
|
|
1104
|
+
if (!name) {
|
|
1105
|
+
const agents = await discoverAgentFiles();
|
|
1106
|
+
if (agents.length === 0) {
|
|
1107
|
+
deps.log("No agent files found in agents/. Create one or pass a name: kraken dev <agent>");
|
|
1108
|
+
return 1;
|
|
1109
|
+
}
|
|
1110
|
+
if (agents.length === 1) {
|
|
1111
|
+
name = agents[0];
|
|
1112
|
+
} else {
|
|
1113
|
+
const selected = await pick("Select an agent:", agents);
|
|
1114
|
+
if (!selected) return 0;
|
|
1115
|
+
name = selected;
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
if (!name) return 1;
|
|
1119
|
+
const file = name.includes("/") ? name : `agents/${name}`;
|
|
1120
|
+
const { spawn } = await import("child_process");
|
|
1121
|
+
const { resolve } = await import("path");
|
|
1122
|
+
const { pathToFileURL: pathToFileURL2 } = await import("url");
|
|
1123
|
+
const fileUrl = pathToFileURL2(resolve(file)).href;
|
|
1124
|
+
const bootstrap = buildDevBootstrap(fileUrl, file);
|
|
1125
|
+
const child = spawn("tsx", ["-e", bootstrap], {
|
|
1126
|
+
stdio: "inherit",
|
|
1127
|
+
cwd: process.cwd()
|
|
1128
|
+
});
|
|
1129
|
+
return new Promise((resolve2) => {
|
|
1130
|
+
child.on("exit", (code2) => resolve2(code2 ?? 1));
|
|
1131
|
+
});
|
|
1132
|
+
};
|
|
1133
|
+
var handleDiscover = async (parsed, deps) => {
|
|
1134
|
+
const dir = parsed.flags.dir ?? process.cwd();
|
|
1135
|
+
const manifest = await deps.discoverProject(dir);
|
|
1136
|
+
const total = manifest.agents.length + manifest.skills.length + manifest.connectors.length;
|
|
1137
|
+
if (total === 0) {
|
|
1138
|
+
deps.log("No entities found in agents/, skills/, or connectors/ directories.");
|
|
1139
|
+
return 1;
|
|
1140
|
+
}
|
|
1141
|
+
if ("emit" in parsed.flags) {
|
|
1142
|
+
emitManifest(manifest);
|
|
1143
|
+
} else {
|
|
1144
|
+
deps.log(JSON.stringify(manifest, null, 2));
|
|
1145
|
+
}
|
|
1146
|
+
return 0;
|
|
1147
|
+
};
|
|
1148
|
+
var handleInit = async (parsed, deps) => {
|
|
1149
|
+
const name = parsed.flags.name ?? await deps.prompt("Project name: ");
|
|
1150
|
+
if (!name) {
|
|
1151
|
+
deps.log("Error: project name is required.");
|
|
1152
|
+
return 1;
|
|
1153
|
+
}
|
|
1154
|
+
const { writeFileSync, mkdirSync } = await import("fs");
|
|
1155
|
+
const { join } = await import("path");
|
|
1156
|
+
const root = join(process.cwd(), name);
|
|
1157
|
+
mkdirSync(join(root, "agents"), { recursive: true });
|
|
1158
|
+
mkdirSync(join(root, "skills"), { recursive: true });
|
|
1159
|
+
mkdirSync(join(root, "connectors"), { recursive: true });
|
|
1160
|
+
writeFileSync(
|
|
1161
|
+
join(root, "package.json"),
|
|
1162
|
+
JSON.stringify(
|
|
1163
|
+
{
|
|
1164
|
+
name,
|
|
1165
|
+
private: true,
|
|
1166
|
+
type: "module",
|
|
1167
|
+
scripts: { build: "tsc" },
|
|
1168
|
+
dependencies: {
|
|
1169
|
+
"kraken-ai": "latest",
|
|
1170
|
+
"@kraken-ai/platform": "latest"
|
|
1171
|
+
},
|
|
1172
|
+
devDependencies: {
|
|
1173
|
+
typescript: "^5"
|
|
1174
|
+
}
|
|
1175
|
+
},
|
|
1176
|
+
null,
|
|
1177
|
+
2
|
|
1178
|
+
)
|
|
1179
|
+
);
|
|
1180
|
+
writeFileSync(
|
|
1181
|
+
join(root, "tsconfig.json"),
|
|
1182
|
+
JSON.stringify(
|
|
1183
|
+
{
|
|
1184
|
+
compilerOptions: {
|
|
1185
|
+
target: "ES2022",
|
|
1186
|
+
module: "NodeNext",
|
|
1187
|
+
moduleResolution: "nodenext",
|
|
1188
|
+
resolveJsonModule: true,
|
|
1189
|
+
strict: true,
|
|
1190
|
+
outDir: "dist",
|
|
1191
|
+
rootDir: ".",
|
|
1192
|
+
declaration: true,
|
|
1193
|
+
esModuleInterop: true,
|
|
1194
|
+
skipLibCheck: true
|
|
1195
|
+
},
|
|
1196
|
+
include: ["agents", "skills", "connectors"]
|
|
1197
|
+
},
|
|
1198
|
+
null,
|
|
1199
|
+
2
|
|
1200
|
+
)
|
|
1201
|
+
);
|
|
1202
|
+
writeFileSync(
|
|
1203
|
+
join(root, "agents", "my-agent.ts"),
|
|
1204
|
+
`import { definePlatformAgent } from "@kraken-ai/platform";
|
|
1205
|
+
|
|
1206
|
+
export default definePlatformAgent({
|
|
1207
|
+
agent: {
|
|
1208
|
+
name: "my-agent",
|
|
1209
|
+
model: "google/gemini-2.5-flash-preview-05-20",
|
|
1210
|
+
instructions: "You are a helpful assistant.",
|
|
1211
|
+
},
|
|
1212
|
+
trigger: { type: "manual" },
|
|
1213
|
+
});
|
|
1214
|
+
`
|
|
1215
|
+
);
|
|
1216
|
+
writeFileSync(join(root, ".gitignore"), `node_modules/
|
|
1217
|
+
dist/
|
|
1218
|
+
.kraken-ai/
|
|
1219
|
+
data/
|
|
1220
|
+
.env
|
|
1221
|
+
`);
|
|
1222
|
+
deps.log(`Created project at ${root}/`);
|
|
1223
|
+
deps.log(`
|
|
1224
|
+
cd ${name}
|
|
1225
|
+
pnpm install
|
|
1226
|
+
kraken login
|
|
1227
|
+
kraken generate
|
|
1228
|
+
`);
|
|
1229
|
+
return 0;
|
|
1230
|
+
};
|
|
1231
|
+
var handleLogout = (deps) => {
|
|
1232
|
+
deps.clearCredentials();
|
|
1233
|
+
deps.log("Credentials cleared.");
|
|
1234
|
+
};
|
|
1235
|
+
var printHelp = (deps) => {
|
|
1236
|
+
deps.log(
|
|
1237
|
+
`
|
|
1238
|
+
kraken \u2014 Kraken AI Platform CLI
|
|
1239
|
+
|
|
1240
|
+
Commands:
|
|
1241
|
+
dev Run an agent locally with an interactive REPL
|
|
1242
|
+
[agent] Agent filename, e.g. researcher.ts (optional \u2014 picks from agents/ if omitted)
|
|
1243
|
+
|
|
1244
|
+
login Store API credentials
|
|
1245
|
+
--url <platform-url> Platform instance URL
|
|
1246
|
+
--key <api-key> API key
|
|
1247
|
+
|
|
1248
|
+
generate Discover local entities and fetch remote schemas to generate types
|
|
1249
|
+
--dir <path> Project root / output directory (default: cwd)
|
|
1250
|
+
--check Check if types are up-to-date (exit 1 if stale)
|
|
1251
|
+
|
|
1252
|
+
discover Scan agents/, skills/, connectors/ and output project manifest
|
|
1253
|
+
--dir <path> Project root (default: cwd)
|
|
1254
|
+
--emit Output with sentinel markers (for orchestrator)
|
|
1255
|
+
|
|
1256
|
+
init Create a new Kraken project
|
|
1257
|
+
--name <project-name> Project name
|
|
1258
|
+
|
|
1259
|
+
logout Clear stored credentials
|
|
1260
|
+
|
|
1261
|
+
Environment variables:
|
|
1262
|
+
KRAKEN_API_KEY API key (overrides stored credentials)
|
|
1263
|
+
KRAKEN_BASE_URL Platform URL (overrides stored credentials)
|
|
1264
|
+
`.trim()
|
|
1265
|
+
);
|
|
1266
|
+
};
|
|
1267
|
+
var readlinePrompt = async (question) => {
|
|
1268
|
+
const { createInterface } = await import("readline");
|
|
1269
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
1270
|
+
return new Promise((resolve) => {
|
|
1271
|
+
rl.question(question, (answer) => {
|
|
1272
|
+
rl.close();
|
|
1273
|
+
resolve(answer);
|
|
1274
|
+
});
|
|
1275
|
+
});
|
|
1276
|
+
};
|
|
1277
|
+
var main = async () => {
|
|
1278
|
+
const parsed = parseArgs(process.argv.slice(2));
|
|
1279
|
+
const exitCode = await runCommand(parsed, {
|
|
1280
|
+
clearCredentials,
|
|
1281
|
+
loadCredentials,
|
|
1282
|
+
saveCredentials,
|
|
1283
|
+
generateTypes,
|
|
1284
|
+
discoverProject,
|
|
1285
|
+
fetch: globalThis.fetch,
|
|
1286
|
+
prompt: readlinePrompt,
|
|
1287
|
+
log: console.log
|
|
1288
|
+
});
|
|
1289
|
+
if (exitCode !== 0) process.exit(exitCode);
|
|
1290
|
+
};
|
|
1291
|
+
void main();
|
|
1292
|
+
export {
|
|
1293
|
+
buildDevBootstrap,
|
|
1294
|
+
parseArgs,
|
|
1295
|
+
runCommand
|
|
1296
|
+
};
|
|
1297
|
+
//# sourceMappingURL=cli.js.map
|