@keystrokehq/cli 0.0.136 → 0.0.138
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/{discovery-XqwkB9H_-C2XdYbG2.mjs → discovery-DV7FkTRA-BFmtZG9u.mjs} +432 -6
- package/dist/discovery-DV7FkTRA-BFmtZG9u.mjs.map +1 -0
- package/dist/dist-CmCvzhNH.mjs +676 -0
- package/dist/dist-CmCvzhNH.mjs.map +1 -0
- package/dist/dist-CqVk9JsS.mjs +1569 -0
- package/dist/dist-CqVk9JsS.mjs.map +1 -0
- package/dist/{dist-uZuvgIVp.mjs → dist-QMg0gSzo.mjs} +25 -29
- package/dist/dist-QMg0gSzo.mjs.map +1 -0
- package/dist/index.mjs +180 -1764
- package/dist/index.mjs.map +1 -1
- package/dist/walk-project-171B4cvO-DJy3qZKd.mjs +102 -0
- package/dist/walk-project-171B4cvO-DJy3qZKd.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/discovery-XqwkB9H_-C2XdYbG2.mjs.map +0 -1
- package/dist/dist-uZuvgIVp.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,18 +1,94 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { _ as
|
|
2
|
+
import { $ as SkillSummaryListResponseSchema, A as ListProjectFilesResponseSchema, B as PresignProjectSourceResponseSchema, C as HealthResponseSchema, D as ListOrganizationMembersResponseSchema, E as ListOrganizationInvitationsResponseSchema, F as PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS, G as ProjectSlugAvailabilityResponseSchema, H as PresignUserAvatarResponseSchema, I as PollRunResponseSchema, J as QueuedAgentPromptResponseSchema, K as PromptInputSchema, L as PresignOrgLogoRequestSchema, M as ListProjectsResponseSchema, N as OrganizationSidebarBrandingPatchSchema, O as ListOrganizationsResponseSchema, P as OrganizationSidebarBrandingSchema, Q as SkillSummaryDetailResponseSchema, R as PresignOrgLogoResponseSchema, S as GatewayAttachmentRecordSchema, St as parseErrorResponse, T as InviteOrganizationMembersResponseSchema, U as ProjectReachabilityResponseSchema, V as PresignUserAvatarRequestSchema, W as ProjectResponseSchema, X as ROUTE_MANIFEST_REL_PATH, Y as QueuedRunResponseSchema, Z as RecentResourceListResponseSchema, _ as CreateProjectResponseSchema, _t as WorkflowSummaryDetailResponseSchema, a as AgentSessionDetailResponseSchema, at as UpdateCredentialInstanceBodySchema, b as DeclineOrganizationInvitationResponseSchema, c as AgentSummaryListResponseSchema, ct as UpdateOrganizationRequestSchema, d as ConnectProvidersResponseSchema, dt as UploadProjectSourceResponseSchema, et as SlugAvailabilityResponseSchema, f as CreateCredentialInstanceBodySchema, ft as UpsertGatewayAttachmentBodySchema, g as CreateProjectRequestSchema, gt as WorkflowRunListResponseSchema, h as CreateProjectArtifactResponseSchema, ht as WorkflowRunDetailResponseSchema, i as AgentListResponseSchema, it as TriggerRunListResponseSchema, j as ListProjectMetricsResponseSchema, k as ListProjectDeploymentsResponseSchema, l as CompleteProjectArtifactResponseSchema, lt as UpdateProjectRequestSchema, m as CreateOrganizationResponseSchema, mt as UserAvatarSchema, n as AcceptOrganizationInvitationResponseSchema, nt as TriggerListResponseSchema, o as AgentSessionListResponseSchema, ot as UpdateOrganizationMemberRequestSchema, p as CreateOrganizationRequestSchema, pt as UserAvatarPatchSchema, q as PromptResponseSchema, r as ActiveOrganizationResponseSchema, rt as TriggerRunDetailResponseSchema, s as AgentSummaryDetailResponseSchema, st as UpdateOrganizationMemberResponseSchema, t as ACTIVE_ORG_HEADER, tt as TriggerDetailResponseSchema, u as ConnectAuthorizeUrlResponseSchema, ut as UploadProjectSourceManifestRequestSchema, v as CredentialInstanceListResponseSchema, vt as WorkflowSummaryListResponseSchema, w as InviteOrganizationMembersRequestSchema, x as ErrorResponseSchema, xt as originFromPublicUrl, y as CredentialInstanceRecordSchema, yt as listenPortFromPublicUrl, z as PresignProjectSourceRequestSchema } from "./dist-CqVk9JsS.mjs";
|
|
3
|
+
import { t as walkProject } from "./walk-project-171B4cvO-DJy3qZKd.mjs";
|
|
3
4
|
import { a as installPlaygroundDependencies, i as installDependencies, n as buildPlaygroundWorkspace, o as resolvePackageManager, s as resolveCliRoot, t as readCliVersion } from "./version-DESgLEkE.mjs";
|
|
4
5
|
import { createRequire } from "node:module";
|
|
5
6
|
import { Command } from "commander";
|
|
6
|
-
import { Entry } from "@napi-rs/keyring";
|
|
7
7
|
import Conf from "conf";
|
|
8
8
|
import { homedir, platform, tmpdir } from "node:os";
|
|
9
|
-
import { basename, dirname, isAbsolute, join, relative, resolve
|
|
9
|
+
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
10
|
+
import { Entry } from "@napi-rs/keyring";
|
|
10
11
|
import { confirm, input, select } from "@inquirer/prompts";
|
|
11
|
-
import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync,
|
|
12
|
+
import { existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, rmSync, unlinkSync, writeFileSync } from "node:fs";
|
|
12
13
|
import { spawn, spawnSync } from "node:child_process";
|
|
13
|
-
import { createHash } from "node:crypto";
|
|
14
|
-
import { pathToFileURL } from "node:url";
|
|
15
14
|
import { access, copyFile, cp, lstat, mkdir, readFile, readdir, rm, stat, symlink, unlink, writeFile } from "node:fs/promises";
|
|
15
|
+
import { pathToFileURL } from "node:url";
|
|
16
|
+
//#region src/resolve-platform-url.ts
|
|
17
|
+
const DEFAULT_WEB_URL = "https://app.keystroke.ai";
|
|
18
|
+
const DEFAULT_PLATFORM_URL = "https://api.keystroke.ai";
|
|
19
|
+
const LOCAL_PLATFORM_URL = "http://localhost:3002";
|
|
20
|
+
function webOriginFromUrl(webUrl) {
|
|
21
|
+
return originFromPublicUrl(webUrl, webUrl.replace(/\/+$/, ""));
|
|
22
|
+
}
|
|
23
|
+
/** Known web origins with a fixed platform API — undefined for custom/staging URLs. */
|
|
24
|
+
function knownPlatformUrlForWebUrl(webUrl) {
|
|
25
|
+
const webOrigin = webOriginFromUrl(webUrl);
|
|
26
|
+
if (webOrigin === "http://localhost:3000" || webOrigin === "http://127.0.0.1:3000") return LOCAL_PLATFORM_URL;
|
|
27
|
+
if (webOrigin === "https://app.keystroke.ai") return DEFAULT_PLATFORM_URL;
|
|
28
|
+
}
|
|
29
|
+
function resolvePlatformUrlForWebUrl(webUrl, options = {}) {
|
|
30
|
+
const explicit = options.platformUrl?.trim();
|
|
31
|
+
if (explicit) return explicit.replace(/\/+$/, "");
|
|
32
|
+
const known = knownPlatformUrlForWebUrl(webUrl);
|
|
33
|
+
if (known) return known;
|
|
34
|
+
return (options.fallback?.trim() || "https://api.keystroke.ai").replace(/\/+$/, "");
|
|
35
|
+
}
|
|
36
|
+
//#endregion
|
|
37
|
+
//#region src/config.ts
|
|
38
|
+
function getCliConfigDir(cwd = join(homedir(), ".keystroke")) {
|
|
39
|
+
return cwd;
|
|
40
|
+
}
|
|
41
|
+
function getConfigDir(config) {
|
|
42
|
+
return dirname(config.path);
|
|
43
|
+
}
|
|
44
|
+
function getEffectiveApiTarget(config) {
|
|
45
|
+
const explicit = config.get("apiTarget");
|
|
46
|
+
if (explicit === "local" || explicit === "platform") return explicit;
|
|
47
|
+
return "local";
|
|
48
|
+
}
|
|
49
|
+
function syncPlatformUrlWithWebUrl(config) {
|
|
50
|
+
const known = knownPlatformUrlForWebUrl(config.get("webUrl"));
|
|
51
|
+
if (!known) return;
|
|
52
|
+
if (config.get("platformUrl") !== known) config.set("platformUrl", known);
|
|
53
|
+
}
|
|
54
|
+
function createCliConfig(cwd = getCliConfigDir()) {
|
|
55
|
+
const config = new Conf({
|
|
56
|
+
projectName: "keystroke",
|
|
57
|
+
cwd,
|
|
58
|
+
schema: {
|
|
59
|
+
serverUrl: {
|
|
60
|
+
type: "string",
|
|
61
|
+
default: "http://localhost:3001"
|
|
62
|
+
},
|
|
63
|
+
webUrl: {
|
|
64
|
+
type: "string",
|
|
65
|
+
default: DEFAULT_WEB_URL
|
|
66
|
+
},
|
|
67
|
+
platformUrl: {
|
|
68
|
+
type: "string",
|
|
69
|
+
default: DEFAULT_PLATFORM_URL
|
|
70
|
+
},
|
|
71
|
+
activeOrganizationId: { type: "string" },
|
|
72
|
+
activeProjectId: { type: "string" },
|
|
73
|
+
apiTarget: {
|
|
74
|
+
type: "string",
|
|
75
|
+
enum: ["local", "platform"]
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
});
|
|
79
|
+
syncPlatformUrlWithWebUrl(config);
|
|
80
|
+
return config;
|
|
81
|
+
}
|
|
82
|
+
function getServerUrl(config) {
|
|
83
|
+
return config.get("serverUrl");
|
|
84
|
+
}
|
|
85
|
+
function getWebUrl(config) {
|
|
86
|
+
return config.get("webUrl");
|
|
87
|
+
}
|
|
88
|
+
function getPlatformUrl(config) {
|
|
89
|
+
return resolvePlatformUrlForWebUrl(getWebUrl(config), { fallback: config.get("platformUrl") });
|
|
90
|
+
}
|
|
91
|
+
//#endregion
|
|
16
92
|
//#region ../../node_modules/.pnpm/ky@2.0.2/node_modules/ky/distribution/errors/KyError.js
|
|
17
93
|
/**
|
|
18
94
|
Base class for all Ky-specific errors. `HTTPError`, `NetworkError`, `TimeoutError`, and `ForceRetryError` extend this class.
|
|
@@ -1292,1539 +1368,6 @@ const createInstance = (defaults) => {
|
|
|
1292
1368
|
};
|
|
1293
1369
|
const ky = createInstance();
|
|
1294
1370
|
//#endregion
|
|
1295
|
-
//#region ../../node_modules/.pnpm/zod@4.4.3/node_modules/zod/v4/classic/coerce.js
|
|
1296
|
-
function number(params) {
|
|
1297
|
-
return _coercedNumber(ZodNumber, params);
|
|
1298
|
-
}
|
|
1299
|
-
//#endregion
|
|
1300
|
-
//#region ../../packages/shared/dist/index.mjs
|
|
1301
|
-
const ACTIVE_ORG_HEADER = "x-keystroke-org-id";
|
|
1302
|
-
/** Auth, session, and account-entry URL segments. */
|
|
1303
|
-
const AUTH_ACCOUNT_SLUGS = [
|
|
1304
|
-
"2fa",
|
|
1305
|
-
"accept-invite",
|
|
1306
|
-
"auth",
|
|
1307
|
-
"authorize",
|
|
1308
|
-
"callback",
|
|
1309
|
-
"callbacks",
|
|
1310
|
-
"confirm-email",
|
|
1311
|
-
"confirmation",
|
|
1312
|
-
"connect",
|
|
1313
|
-
"device",
|
|
1314
|
-
"email-verification",
|
|
1315
|
-
"forgot-password",
|
|
1316
|
-
"invite",
|
|
1317
|
-
"invites",
|
|
1318
|
-
"login",
|
|
1319
|
-
"logout",
|
|
1320
|
-
"magic-link",
|
|
1321
|
-
"mfa",
|
|
1322
|
-
"oauth",
|
|
1323
|
-
"onboarding",
|
|
1324
|
-
"password",
|
|
1325
|
-
"recovery",
|
|
1326
|
-
"register",
|
|
1327
|
-
"reset-password",
|
|
1328
|
-
"saml",
|
|
1329
|
-
"session",
|
|
1330
|
-
"sessions",
|
|
1331
|
-
"sign-in",
|
|
1332
|
-
"sign-up",
|
|
1333
|
-
"signin",
|
|
1334
|
-
"signout",
|
|
1335
|
-
"signup",
|
|
1336
|
-
"sso",
|
|
1337
|
-
"token",
|
|
1338
|
-
"tokens",
|
|
1339
|
-
"unlink",
|
|
1340
|
-
"verify",
|
|
1341
|
-
"verify-email"
|
|
1342
|
-
];
|
|
1343
|
-
/** Org, workspace, billing, and account-management URL segments. */
|
|
1344
|
-
const ORG_ACCOUNT_SLUGS = [
|
|
1345
|
-
"account",
|
|
1346
|
-
"accounts",
|
|
1347
|
-
"billing",
|
|
1348
|
-
"console",
|
|
1349
|
-
"invoice",
|
|
1350
|
-
"invoices",
|
|
1351
|
-
"member",
|
|
1352
|
-
"members",
|
|
1353
|
-
"me",
|
|
1354
|
-
"org",
|
|
1355
|
-
"organization",
|
|
1356
|
-
"organizations",
|
|
1357
|
-
"orgs",
|
|
1358
|
-
"payment",
|
|
1359
|
-
"payments",
|
|
1360
|
-
"plan",
|
|
1361
|
-
"plans",
|
|
1362
|
-
"portal",
|
|
1363
|
-
"preferences",
|
|
1364
|
-
"profile",
|
|
1365
|
-
"settings",
|
|
1366
|
-
"subscription",
|
|
1367
|
-
"subscriptions",
|
|
1368
|
-
"team",
|
|
1369
|
-
"teams",
|
|
1370
|
-
"upgrade",
|
|
1371
|
-
"usage",
|
|
1372
|
-
"user",
|
|
1373
|
-
"users",
|
|
1374
|
-
"workspace",
|
|
1375
|
-
"workspaces"
|
|
1376
|
-
];
|
|
1377
|
-
/** Product surfaces, resource types, and in-app navigation segments. */
|
|
1378
|
-
const PRODUCT_SLUGS = [
|
|
1379
|
-
"action",
|
|
1380
|
-
"actions",
|
|
1381
|
-
"activity",
|
|
1382
|
-
"agent",
|
|
1383
|
-
"agents",
|
|
1384
|
-
"analytics",
|
|
1385
|
-
"app",
|
|
1386
|
-
"apps",
|
|
1387
|
-
"artifact",
|
|
1388
|
-
"artifacts",
|
|
1389
|
-
"assistant",
|
|
1390
|
-
"assistants",
|
|
1391
|
-
"audit",
|
|
1392
|
-
"audit-log",
|
|
1393
|
-
"automation",
|
|
1394
|
-
"automations",
|
|
1395
|
-
"branch",
|
|
1396
|
-
"branches",
|
|
1397
|
-
"canvas",
|
|
1398
|
-
"chat",
|
|
1399
|
-
"chats",
|
|
1400
|
-
"connection",
|
|
1401
|
-
"connections",
|
|
1402
|
-
"create",
|
|
1403
|
-
"credential",
|
|
1404
|
-
"credentials",
|
|
1405
|
-
"dashboard",
|
|
1406
|
-
"deployment",
|
|
1407
|
-
"deployments",
|
|
1408
|
-
"examples",
|
|
1409
|
-
"execute",
|
|
1410
|
-
"execution",
|
|
1411
|
-
"executions",
|
|
1412
|
-
"explore",
|
|
1413
|
-
"get-started",
|
|
1414
|
-
"history",
|
|
1415
|
-
"inbox",
|
|
1416
|
-
"inspector",
|
|
1417
|
-
"integration",
|
|
1418
|
-
"integrations",
|
|
1419
|
-
"library",
|
|
1420
|
-
"logs",
|
|
1421
|
-
"marketplace",
|
|
1422
|
-
"mcp",
|
|
1423
|
-
"mcps",
|
|
1424
|
-
"new",
|
|
1425
|
-
"notifications",
|
|
1426
|
-
"observe",
|
|
1427
|
-
"plugin",
|
|
1428
|
-
"plugins",
|
|
1429
|
-
"primitive",
|
|
1430
|
-
"primitives",
|
|
1431
|
-
"project",
|
|
1432
|
-
"projects",
|
|
1433
|
-
"recents",
|
|
1434
|
-
"registry",
|
|
1435
|
-
"reports",
|
|
1436
|
-
"run",
|
|
1437
|
-
"runs",
|
|
1438
|
-
"runtime",
|
|
1439
|
-
"runtimes",
|
|
1440
|
-
"sandbox",
|
|
1441
|
-
"sandboxes",
|
|
1442
|
-
"search",
|
|
1443
|
-
"skill",
|
|
1444
|
-
"skills",
|
|
1445
|
-
"templates",
|
|
1446
|
-
"thread",
|
|
1447
|
-
"threads",
|
|
1448
|
-
"trigger",
|
|
1449
|
-
"triggers",
|
|
1450
|
-
"version",
|
|
1451
|
-
"versions",
|
|
1452
|
-
"workflow",
|
|
1453
|
-
"workflows"
|
|
1454
|
-
];
|
|
1455
|
-
/** Marketing, docs, company, and go-to-market URL segments. */
|
|
1456
|
-
const MARKETING_SITE_SLUGS = [
|
|
1457
|
-
"about",
|
|
1458
|
-
"affiliates",
|
|
1459
|
-
"ai",
|
|
1460
|
-
"announcements",
|
|
1461
|
-
"anthropic",
|
|
1462
|
-
"blog",
|
|
1463
|
-
"book-demo",
|
|
1464
|
-
"brand",
|
|
1465
|
-
"campaigns",
|
|
1466
|
-
"career",
|
|
1467
|
-
"careers",
|
|
1468
|
-
"case-studies",
|
|
1469
|
-
"casestudies",
|
|
1470
|
-
"changelog",
|
|
1471
|
-
"chatgpt",
|
|
1472
|
-
"chrome-extension",
|
|
1473
|
-
"claude",
|
|
1474
|
-
"codex",
|
|
1475
|
-
"community",
|
|
1476
|
-
"company",
|
|
1477
|
-
"compare",
|
|
1478
|
-
"contact",
|
|
1479
|
-
"contribute",
|
|
1480
|
-
"creators",
|
|
1481
|
-
"customers",
|
|
1482
|
-
"demo",
|
|
1483
|
-
"demos",
|
|
1484
|
-
"discord",
|
|
1485
|
-
"docs",
|
|
1486
|
-
"documentation",
|
|
1487
|
-
"download",
|
|
1488
|
-
"downloads",
|
|
1489
|
-
"dust",
|
|
1490
|
-
"emerging-talent",
|
|
1491
|
-
"engineering-blog",
|
|
1492
|
-
"enterprise",
|
|
1493
|
-
"events",
|
|
1494
|
-
"experts",
|
|
1495
|
-
"extension",
|
|
1496
|
-
"faq",
|
|
1497
|
-
"faqs",
|
|
1498
|
-
"features",
|
|
1499
|
-
"forum",
|
|
1500
|
-
"glean",
|
|
1501
|
-
"grok",
|
|
1502
|
-
"guide",
|
|
1503
|
-
"guides",
|
|
1504
|
-
"gumloop",
|
|
1505
|
-
"handbook",
|
|
1506
|
-
"help",
|
|
1507
|
-
"help-center",
|
|
1508
|
-
"home",
|
|
1509
|
-
"how-it-works",
|
|
1510
|
-
"howitworks",
|
|
1511
|
-
"inspo",
|
|
1512
|
-
"intern",
|
|
1513
|
-
"investors",
|
|
1514
|
-
"jobs",
|
|
1515
|
-
"legal",
|
|
1516
|
-
"lindy",
|
|
1517
|
-
"llm",
|
|
1518
|
-
"llms",
|
|
1519
|
-
"love",
|
|
1520
|
-
"make",
|
|
1521
|
-
"manifesto",
|
|
1522
|
-
"media",
|
|
1523
|
-
"merch",
|
|
1524
|
-
"mission",
|
|
1525
|
-
"mobile",
|
|
1526
|
-
"models",
|
|
1527
|
-
"n8n",
|
|
1528
|
-
"news",
|
|
1529
|
-
"newsroom",
|
|
1530
|
-
"open",
|
|
1531
|
-
"open-claw",
|
|
1532
|
-
"open-source",
|
|
1533
|
-
"openai",
|
|
1534
|
-
"our-story",
|
|
1535
|
-
"overview",
|
|
1536
|
-
"partners",
|
|
1537
|
-
"pi",
|
|
1538
|
-
"pipedream",
|
|
1539
|
-
"platform",
|
|
1540
|
-
"press",
|
|
1541
|
-
"press-kit",
|
|
1542
|
-
"pricing",
|
|
1543
|
-
"privacy",
|
|
1544
|
-
"product",
|
|
1545
|
-
"products",
|
|
1546
|
-
"provider",
|
|
1547
|
-
"providers",
|
|
1548
|
-
"quick-start",
|
|
1549
|
-
"quickstart",
|
|
1550
|
-
"refer",
|
|
1551
|
-
"relay",
|
|
1552
|
-
"relay-app",
|
|
1553
|
-
"reporting",
|
|
1554
|
-
"request-demo",
|
|
1555
|
-
"resources",
|
|
1556
|
-
"roadmap",
|
|
1557
|
-
"schedule-demo",
|
|
1558
|
-
"security",
|
|
1559
|
-
"solutions",
|
|
1560
|
-
"stack-ai",
|
|
1561
|
-
"stackai",
|
|
1562
|
-
"startup",
|
|
1563
|
-
"startups",
|
|
1564
|
-
"status",
|
|
1565
|
-
"stories",
|
|
1566
|
-
"story",
|
|
1567
|
-
"students",
|
|
1568
|
-
"support",
|
|
1569
|
-
"swag",
|
|
1570
|
-
"switch",
|
|
1571
|
-
"talent",
|
|
1572
|
-
"terms",
|
|
1573
|
-
"testimonials",
|
|
1574
|
-
"thesis",
|
|
1575
|
-
"tines",
|
|
1576
|
-
"trust",
|
|
1577
|
-
"tutorials",
|
|
1578
|
-
"university",
|
|
1579
|
-
"use-case",
|
|
1580
|
-
"use-cases",
|
|
1581
|
-
"usecases",
|
|
1582
|
-
"versus",
|
|
1583
|
-
"vellum",
|
|
1584
|
-
"vs",
|
|
1585
|
-
"webinars",
|
|
1586
|
-
"workato",
|
|
1587
|
-
"xai",
|
|
1588
|
-
"yc",
|
|
1589
|
-
"zapier"
|
|
1590
|
-
];
|
|
1591
|
-
/** Integrations, competitors, and partner brand slugs (marketing / integration pages). */
|
|
1592
|
-
const INTEGRATION_BRAND_SLUGS = [
|
|
1593
|
-
"airtable",
|
|
1594
|
-
"asana",
|
|
1595
|
-
"aws",
|
|
1596
|
-
"azure",
|
|
1597
|
-
"bun",
|
|
1598
|
-
"confluence",
|
|
1599
|
-
"copilot",
|
|
1600
|
-
"cursor",
|
|
1601
|
-
"databricks",
|
|
1602
|
-
"figma",
|
|
1603
|
-
"firebase",
|
|
1604
|
-
"fly",
|
|
1605
|
-
"gcp",
|
|
1606
|
-
"gemini",
|
|
1607
|
-
"github",
|
|
1608
|
-
"gitlab",
|
|
1609
|
-
"gmail",
|
|
1610
|
-
"heroku",
|
|
1611
|
-
"hubspot",
|
|
1612
|
-
"huggingface",
|
|
1613
|
-
"jira",
|
|
1614
|
-
"linear",
|
|
1615
|
-
"mailchimp",
|
|
1616
|
-
"meta",
|
|
1617
|
-
"mistral",
|
|
1618
|
-
"mixmax",
|
|
1619
|
-
"monday",
|
|
1620
|
-
"netlify",
|
|
1621
|
-
"neon",
|
|
1622
|
-
"notion",
|
|
1623
|
-
"npm",
|
|
1624
|
-
"outlook",
|
|
1625
|
-
"outreach",
|
|
1626
|
-
"perplexity",
|
|
1627
|
-
"planetscale",
|
|
1628
|
-
"pnpm",
|
|
1629
|
-
"postmark",
|
|
1630
|
-
"ramp",
|
|
1631
|
-
"railway",
|
|
1632
|
-
"render",
|
|
1633
|
-
"resend",
|
|
1634
|
-
"salesforce",
|
|
1635
|
-
"segment",
|
|
1636
|
-
"sendgrid",
|
|
1637
|
-
"shopify",
|
|
1638
|
-
"slack",
|
|
1639
|
-
"snowflake",
|
|
1640
|
-
"stripe",
|
|
1641
|
-
"supabase",
|
|
1642
|
-
"terraform",
|
|
1643
|
-
"trello",
|
|
1644
|
-
"turso",
|
|
1645
|
-
"twilio",
|
|
1646
|
-
"typeform",
|
|
1647
|
-
"vercel",
|
|
1648
|
-
"vscode",
|
|
1649
|
-
"windsurf",
|
|
1650
|
-
"yarn"
|
|
1651
|
-
];
|
|
1652
|
-
/** Company, team, and department landing-page segments. */
|
|
1653
|
-
const COMPANY_TEAM_SLUGS = [
|
|
1654
|
-
"engineers",
|
|
1655
|
-
"engineering",
|
|
1656
|
-
"executives",
|
|
1657
|
-
"hc",
|
|
1658
|
-
"intern",
|
|
1659
|
-
"it",
|
|
1660
|
-
"leadership",
|
|
1661
|
-
"marketing",
|
|
1662
|
-
"ops",
|
|
1663
|
-
"revops",
|
|
1664
|
-
"sales",
|
|
1665
|
-
"services",
|
|
1666
|
-
"tech"
|
|
1667
|
-
];
|
|
1668
|
-
/** Legal, trust, compliance, and policy URL segments. */
|
|
1669
|
-
const LEGAL_TRUST_SLUGS = [
|
|
1670
|
-
"accessibility",
|
|
1671
|
-
"agreement",
|
|
1672
|
-
"a11y",
|
|
1673
|
-
"bug-bounty",
|
|
1674
|
-
"compliance",
|
|
1675
|
-
"cookie-policy",
|
|
1676
|
-
"cookies",
|
|
1677
|
-
"disclose",
|
|
1678
|
-
"dpa",
|
|
1679
|
-
"eula",
|
|
1680
|
-
"gdpr",
|
|
1681
|
-
"hipaa",
|
|
1682
|
-
"iso",
|
|
1683
|
-
"msa",
|
|
1684
|
-
"pci",
|
|
1685
|
-
"responsible-disclosure",
|
|
1686
|
-
"sla",
|
|
1687
|
-
"soc2",
|
|
1688
|
-
"tos",
|
|
1689
|
-
"trust-center",
|
|
1690
|
-
"trustcenter",
|
|
1691
|
-
"vulnerability"
|
|
1692
|
-
];
|
|
1693
|
-
/** Developer, API, CLI, and technical URL segments. */
|
|
1694
|
-
const DEVELOPER_TECH_SLUGS = [
|
|
1695
|
-
"api",
|
|
1696
|
-
"api-docs",
|
|
1697
|
-
"cli",
|
|
1698
|
-
"code",
|
|
1699
|
-
"config",
|
|
1700
|
-
"developer",
|
|
1701
|
-
"developer-tools",
|
|
1702
|
-
"developers",
|
|
1703
|
-
"dev-tools",
|
|
1704
|
-
"devtools",
|
|
1705
|
-
"dev",
|
|
1706
|
-
"dev-states",
|
|
1707
|
-
"graphql",
|
|
1708
|
-
"graphql-playground",
|
|
1709
|
-
"mcp-server",
|
|
1710
|
-
"mcp-servers",
|
|
1711
|
-
"openapi",
|
|
1712
|
-
"sdk",
|
|
1713
|
-
"swagger"
|
|
1714
|
-
];
|
|
1715
|
-
/** Infra, ops, static assets, and system URL segments. */
|
|
1716
|
-
const INFRA_SYSTEM_SLUGS = [
|
|
1717
|
-
"acme-challenge",
|
|
1718
|
-
"admin",
|
|
1719
|
-
"apple-app-site-association",
|
|
1720
|
-
"assets",
|
|
1721
|
-
"batch",
|
|
1722
|
-
"cache",
|
|
1723
|
-
"cdn",
|
|
1724
|
-
"cron",
|
|
1725
|
-
"debug",
|
|
1726
|
-
"error",
|
|
1727
|
-
"errors",
|
|
1728
|
-
"favicon",
|
|
1729
|
-
"feed",
|
|
1730
|
-
"files",
|
|
1731
|
-
"health",
|
|
1732
|
-
"healthcheck",
|
|
1733
|
-
"healthz",
|
|
1734
|
-
"hooks",
|
|
1735
|
-
"internal",
|
|
1736
|
-
"item",
|
|
1737
|
-
"manifest",
|
|
1738
|
-
"metrics",
|
|
1739
|
-
"null",
|
|
1740
|
-
"ping",
|
|
1741
|
-
"prod",
|
|
1742
|
-
"public",
|
|
1743
|
-
"redirect",
|
|
1744
|
-
"robots",
|
|
1745
|
-
"rpc",
|
|
1746
|
-
"rss",
|
|
1747
|
-
"sharer",
|
|
1748
|
-
"sitemap",
|
|
1749
|
-
"staging",
|
|
1750
|
-
"static",
|
|
1751
|
-
"storage",
|
|
1752
|
-
"test",
|
|
1753
|
-
"undefined",
|
|
1754
|
-
"universal",
|
|
1755
|
-
"webhooks",
|
|
1756
|
-
"well-known",
|
|
1757
|
-
"www"
|
|
1758
|
-
];
|
|
1759
|
-
/** Reserved slugs that are valid org names in theory but blocked for routing safety. */
|
|
1760
|
-
const ROUTING_SAFETY_SLUGS = [
|
|
1761
|
-
"alpha",
|
|
1762
|
-
"anonymous",
|
|
1763
|
-
"archive",
|
|
1764
|
-
"archived",
|
|
1765
|
-
"beta",
|
|
1766
|
-
"clone",
|
|
1767
|
-
"copy",
|
|
1768
|
-
"default",
|
|
1769
|
-
"deleted",
|
|
1770
|
-
"demo-org",
|
|
1771
|
-
"draft",
|
|
1772
|
-
"drafts",
|
|
1773
|
-
"duplicate",
|
|
1774
|
-
"early-access",
|
|
1775
|
-
"embed",
|
|
1776
|
-
"embedded",
|
|
1777
|
-
"export",
|
|
1778
|
-
"fork",
|
|
1779
|
-
"free",
|
|
1780
|
-
"guest",
|
|
1781
|
-
"import",
|
|
1782
|
-
"index",
|
|
1783
|
-
"list",
|
|
1784
|
-
"manage",
|
|
1785
|
-
"moderator",
|
|
1786
|
-
"newsletter",
|
|
1787
|
-
"owner",
|
|
1788
|
-
"preview",
|
|
1789
|
-
"previews",
|
|
1790
|
-
"private",
|
|
1791
|
-
"pro",
|
|
1792
|
-
"public-api",
|
|
1793
|
-
"publish",
|
|
1794
|
-
"published",
|
|
1795
|
-
"queue",
|
|
1796
|
-
"remove",
|
|
1797
|
-
"root",
|
|
1798
|
-
"sample",
|
|
1799
|
-
"samples",
|
|
1800
|
-
"selection",
|
|
1801
|
-
"share",
|
|
1802
|
-
"shared",
|
|
1803
|
-
"sponsor",
|
|
1804
|
-
"sponsors",
|
|
1805
|
-
"sponsorship",
|
|
1806
|
-
"subscribe",
|
|
1807
|
-
"super",
|
|
1808
|
-
"superuser",
|
|
1809
|
-
"system",
|
|
1810
|
-
"sys",
|
|
1811
|
-
"test-org",
|
|
1812
|
-
"trash",
|
|
1813
|
-
"unpublish",
|
|
1814
|
-
"unsubscribe",
|
|
1815
|
-
"upload",
|
|
1816
|
-
"uploads",
|
|
1817
|
-
"waitlist",
|
|
1818
|
-
"widget",
|
|
1819
|
-
"widgets",
|
|
1820
|
-
"worker",
|
|
1821
|
-
"workers"
|
|
1822
|
-
];
|
|
1823
|
-
/**
|
|
1824
|
-
* URL segments reserved for global (non-org) routes — cannot be used as an org slug.
|
|
1825
|
-
* Prefer adding new entries to the category arrays above; the Set is the enforcement surface.
|
|
1826
|
-
*/
|
|
1827
|
-
const RESERVED_ORGANIZATION_SLUGS = new Set([
|
|
1828
|
-
...AUTH_ACCOUNT_SLUGS,
|
|
1829
|
-
...ORG_ACCOUNT_SLUGS,
|
|
1830
|
-
...PRODUCT_SLUGS,
|
|
1831
|
-
...MARKETING_SITE_SLUGS,
|
|
1832
|
-
...INTEGRATION_BRAND_SLUGS,
|
|
1833
|
-
...COMPANY_TEAM_SLUGS,
|
|
1834
|
-
...LEGAL_TRUST_SLUGS,
|
|
1835
|
-
...DEVELOPER_TECH_SLUGS,
|
|
1836
|
-
...INFRA_SYSTEM_SLUGS,
|
|
1837
|
-
...ROUTING_SAFETY_SLUGS
|
|
1838
|
-
]);
|
|
1839
|
-
/**
|
|
1840
|
-
* Base slug format: lowercase, 2-64 chars, alphanumeric + dashes.
|
|
1841
|
-
*
|
|
1842
|
-
* IMPORTANT: this is the schema for *reading* slugs (persisted rows, API
|
|
1843
|
-
* responses). It intentionally does NOT enforce the reserved-name list — an org
|
|
1844
|
-
* created before a name became reserved must still parse on read. Use
|
|
1845
|
-
* `ClaimableOrganizationSlugSchema` to validate slugs a user is trying to claim.
|
|
1846
|
-
*/
|
|
1847
|
-
const OrganizationSlugSchema = string().trim().toLowerCase().min(2, "Slug must be at least 2 characters").max(64, "Slug must be at most 64 characters").regex(/^[a-z0-9]+(?:-[a-z0-9]+)*$/, "Use lowercase letters, numbers, and dashes only");
|
|
1848
|
-
/**
|
|
1849
|
-
* Slug validation for *claiming* a slug (organization create/rename). Adds the
|
|
1850
|
-
* reserved-name check on top of the base format. Never use this to parse
|
|
1851
|
-
* existing org data, or pre-existing orgs whose slug later became reserved would
|
|
1852
|
-
* fail to load.
|
|
1853
|
-
*/
|
|
1854
|
-
const ClaimableOrganizationSlugSchema = OrganizationSlugSchema.refine((slug) => !RESERVED_ORGANIZATION_SLUGS.has(slug), "This slug is reserved");
|
|
1855
|
-
/** Same format as organization slugs — org-scoped, no global reserved list. */
|
|
1856
|
-
const ProjectSlugSchema = OrganizationSlugSchema;
|
|
1857
|
-
/** Browser→platform request budget (ping + small platform overhead). */
|
|
1858
|
-
const PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS = 17e3;
|
|
1859
|
-
/** Normalize a public origin URL (no trailing slash). */
|
|
1860
|
-
function originFromPublicUrl(value, fallback) {
|
|
1861
|
-
const trimmed = value?.trim();
|
|
1862
|
-
if (!trimmed) return fallback.replace(/\/+$/, "");
|
|
1863
|
-
return trimmed.replace(/\/+$/, "");
|
|
1864
|
-
}
|
|
1865
|
-
/** TCP port to bind for a local server, derived from a public URL. */
|
|
1866
|
-
function listenPortFromUrl(url, fallback) {
|
|
1867
|
-
const parsed = new URL(url);
|
|
1868
|
-
if (parsed.port) {
|
|
1869
|
-
const port = Number(parsed.port);
|
|
1870
|
-
if (Number.isFinite(port) && port > 0) return port;
|
|
1871
|
-
}
|
|
1872
|
-
if (parsed.protocol === "https:") return 443;
|
|
1873
|
-
if (parsed.protocol === "http:") return 80;
|
|
1874
|
-
return fallback;
|
|
1875
|
-
}
|
|
1876
|
-
/** Shorthand: listen port from `PUBLIC_*_URL` or fallback. */
|
|
1877
|
-
function listenPortFromPublicUrl(value, fallback) {
|
|
1878
|
-
const trimmed = value?.trim();
|
|
1879
|
-
if (!trimmed) return fallback;
|
|
1880
|
-
try {
|
|
1881
|
-
return listenPortFromUrl(trimmed, fallback);
|
|
1882
|
-
} catch {
|
|
1883
|
-
return fallback;
|
|
1884
|
-
}
|
|
1885
|
-
}
|
|
1886
|
-
const serializedRouteManifestEntrySchema = discriminatedUnion("kind", [
|
|
1887
|
-
object({
|
|
1888
|
-
kind: literal("health"),
|
|
1889
|
-
method: literal("GET"),
|
|
1890
|
-
path: literal("/health")
|
|
1891
|
-
}),
|
|
1892
|
-
object({
|
|
1893
|
-
kind: literal("agent"),
|
|
1894
|
-
method: literal("POST"),
|
|
1895
|
-
path: string(),
|
|
1896
|
-
agentSlug: string(),
|
|
1897
|
-
moduleFile: string(),
|
|
1898
|
-
requestSchema: record(string(), unknown()),
|
|
1899
|
-
responseSchema: record(string(), unknown())
|
|
1900
|
-
}),
|
|
1901
|
-
object({
|
|
1902
|
-
kind: literal("agent-sessions-list"),
|
|
1903
|
-
method: literal("GET"),
|
|
1904
|
-
path: string(),
|
|
1905
|
-
agentSlug: string(),
|
|
1906
|
-
moduleFile: string()
|
|
1907
|
-
}),
|
|
1908
|
-
object({
|
|
1909
|
-
kind: literal("agent-session-detail"),
|
|
1910
|
-
method: literal("GET"),
|
|
1911
|
-
path: string(),
|
|
1912
|
-
agentSlug: string(),
|
|
1913
|
-
moduleFile: string()
|
|
1914
|
-
}),
|
|
1915
|
-
object({
|
|
1916
|
-
kind: literal("workflow"),
|
|
1917
|
-
method: literal("POST"),
|
|
1918
|
-
path: string(),
|
|
1919
|
-
workflowSlug: string(),
|
|
1920
|
-
workflowName: string().optional(),
|
|
1921
|
-
moduleFile: string(),
|
|
1922
|
-
requestSchema: record(string(), unknown()),
|
|
1923
|
-
responseSchema: record(string(), unknown())
|
|
1924
|
-
}),
|
|
1925
|
-
object({
|
|
1926
|
-
kind: literal("workflow-runs-list"),
|
|
1927
|
-
method: literal("GET"),
|
|
1928
|
-
path: string(),
|
|
1929
|
-
workflowSlug: string(),
|
|
1930
|
-
workflowName: string().optional(),
|
|
1931
|
-
moduleFile: string()
|
|
1932
|
-
}),
|
|
1933
|
-
object({
|
|
1934
|
-
kind: literal("workflow-run-detail"),
|
|
1935
|
-
method: literal("GET"),
|
|
1936
|
-
path: string(),
|
|
1937
|
-
workflowSlug: string(),
|
|
1938
|
-
workflowName: string().optional(),
|
|
1939
|
-
moduleFile: string()
|
|
1940
|
-
}),
|
|
1941
|
-
object({
|
|
1942
|
-
kind: literal("trigger-webhook"),
|
|
1943
|
-
method: literal("POST"),
|
|
1944
|
-
path: string(),
|
|
1945
|
-
attachmentIds: array(string()),
|
|
1946
|
-
moduleFile: string(),
|
|
1947
|
-
requestSchema: record(string(), unknown()),
|
|
1948
|
-
attachmentSchemas: record(string(), object({
|
|
1949
|
-
requestSchema: record(string(), unknown()),
|
|
1950
|
-
filterSchema: record(string(), unknown()).optional()
|
|
1951
|
-
})),
|
|
1952
|
-
responseSchema: record(string(), unknown())
|
|
1953
|
-
}),
|
|
1954
|
-
object({
|
|
1955
|
-
kind: literal("trigger-poll"),
|
|
1956
|
-
method: literal("POST"),
|
|
1957
|
-
path: string(),
|
|
1958
|
-
attachmentId: string(),
|
|
1959
|
-
moduleFile: string(),
|
|
1960
|
-
schedule: string(),
|
|
1961
|
-
responseSchema: record(string(), unknown())
|
|
1962
|
-
}),
|
|
1963
|
-
object({
|
|
1964
|
-
kind: literal("trigger-poll-group"),
|
|
1965
|
-
method: literal("POST"),
|
|
1966
|
-
path: string(),
|
|
1967
|
-
pollId: string(),
|
|
1968
|
-
attachmentIds: array(string()),
|
|
1969
|
-
moduleFile: string(),
|
|
1970
|
-
schedule: string(),
|
|
1971
|
-
responseSchema: record(string(), unknown())
|
|
1972
|
-
}),
|
|
1973
|
-
object({
|
|
1974
|
-
kind: literal("trigger-runs-list"),
|
|
1975
|
-
method: literal("GET"),
|
|
1976
|
-
path: string(),
|
|
1977
|
-
attachmentId: string(),
|
|
1978
|
-
moduleFile: string()
|
|
1979
|
-
}),
|
|
1980
|
-
object({
|
|
1981
|
-
kind: literal("trigger-run-detail"),
|
|
1982
|
-
method: literal("GET"),
|
|
1983
|
-
path: string(),
|
|
1984
|
-
attachmentId: string(),
|
|
1985
|
-
moduleFile: string()
|
|
1986
|
-
}),
|
|
1987
|
-
object({
|
|
1988
|
-
kind: literal("cron-schedule"),
|
|
1989
|
-
attachmentId: string(),
|
|
1990
|
-
moduleFile: string(),
|
|
1991
|
-
schedule: string()
|
|
1992
|
-
}),
|
|
1993
|
-
object({
|
|
1994
|
-
kind: literal("plugin"),
|
|
1995
|
-
method: _enum([
|
|
1996
|
-
"GET",
|
|
1997
|
-
"POST",
|
|
1998
|
-
"PUT",
|
|
1999
|
-
"PATCH",
|
|
2000
|
-
"DELETE"
|
|
2001
|
-
]),
|
|
2002
|
-
path: string(),
|
|
2003
|
-
plugin: string()
|
|
2004
|
-
})
|
|
2005
|
-
]);
|
|
2006
|
-
object({
|
|
2007
|
-
version: literal(1),
|
|
2008
|
-
entries: array(serializedRouteManifestEntrySchema),
|
|
2009
|
-
integrations: array(string()).optional()
|
|
2010
|
-
});
|
|
2011
|
-
/** How a credential instance is stored (`credential_instances.auth_kind`). */
|
|
2012
|
-
const CredentialAuthKindSchema = _enum(["api_key", "oauth_managed"]);
|
|
2013
|
-
/** Where a credential instance is stored (`credential_instances.scope_type`). */
|
|
2014
|
-
const CredentialScopeTypeSchema = _enum([
|
|
2015
|
-
"global",
|
|
2016
|
-
"organization",
|
|
2017
|
-
"project",
|
|
2018
|
-
"user"
|
|
2019
|
-
]);
|
|
2020
|
-
/**
|
|
2021
|
-
* Resolution chain step when an action/tool looks up credentials.
|
|
2022
|
-
* `selection` uses explicit instance ids; other levels map to {@link CredentialScopeType}.
|
|
2023
|
-
*/
|
|
2024
|
-
const CredentialScopeLevelSchema = _enum([
|
|
2025
|
-
"selection",
|
|
2026
|
-
"organization",
|
|
2027
|
-
"project",
|
|
2028
|
-
"user"
|
|
2029
|
-
]);
|
|
2030
|
-
CredentialAuthKindSchema.options;
|
|
2031
|
-
CredentialScopeTypeSchema.options;
|
|
2032
|
-
CredentialScopeLevelSchema.options;
|
|
2033
|
-
function isCredentialInput(value) {
|
|
2034
|
-
if (typeof value !== "object" || value === null) return false;
|
|
2035
|
-
const candidate = value;
|
|
2036
|
-
return typeof candidate.key === "string" && CredentialAuthKindSchema.safeParse(candidate.kind).success && candidate.schema instanceof ZodType;
|
|
2037
|
-
}
|
|
2038
|
-
custom((value) => isCredentialInput(value), "must be a credential requirement");
|
|
2039
|
-
const OrganizationSlugErrorCodeSchema = _enum([
|
|
2040
|
-
"slug_taken",
|
|
2041
|
-
"slug_reserved",
|
|
2042
|
-
"slug_invalid"
|
|
2043
|
-
]);
|
|
2044
|
-
const SlugAvailabilityReasonSchema = _enum([
|
|
2045
|
-
"taken",
|
|
2046
|
-
"reserved",
|
|
2047
|
-
"invalid"
|
|
2048
|
-
]);
|
|
2049
|
-
const SlugAvailabilityResponseSchema = object({
|
|
2050
|
-
slug: string(),
|
|
2051
|
-
available: boolean(),
|
|
2052
|
-
reason: SlugAvailabilityReasonSchema.optional(),
|
|
2053
|
-
suggestion: OrganizationSlugSchema.optional()
|
|
2054
|
-
});
|
|
2055
|
-
object({
|
|
2056
|
-
slug: string().trim().min(1),
|
|
2057
|
-
excludeOrganizationId: string().min(1).optional()
|
|
2058
|
-
});
|
|
2059
|
-
const ProjectSlugAvailabilityReasonSchema = _enum(["taken", "invalid"]);
|
|
2060
|
-
const ProjectSlugAvailabilityResponseSchema = object({
|
|
2061
|
-
slug: string(),
|
|
2062
|
-
available: boolean(),
|
|
2063
|
-
reason: ProjectSlugAvailabilityReasonSchema.optional(),
|
|
2064
|
-
suggestion: ProjectSlugSchema.optional()
|
|
2065
|
-
});
|
|
2066
|
-
object({
|
|
2067
|
-
slug: string().trim().min(1),
|
|
2068
|
-
excludeProjectId: string().min(1).optional()
|
|
2069
|
-
});
|
|
2070
|
-
const ProjectStatusSchema = _enum([
|
|
2071
|
-
"inactive",
|
|
2072
|
-
"starting",
|
|
2073
|
-
"active",
|
|
2074
|
-
"failed"
|
|
2075
|
-
]);
|
|
2076
|
-
const OrganizationUserRoleSchema = _enum([
|
|
2077
|
-
"owner",
|
|
2078
|
-
"admin",
|
|
2079
|
-
"builder"
|
|
2080
|
-
]);
|
|
2081
|
-
const isoDateTime$3 = string().datetime();
|
|
2082
|
-
const OrganizationSchema = object({
|
|
2083
|
-
id: string(),
|
|
2084
|
-
name: string(),
|
|
2085
|
-
slug: OrganizationSlugSchema,
|
|
2086
|
-
createdAt: isoDateTime$3,
|
|
2087
|
-
updatedAt: isoDateTime$3
|
|
2088
|
-
});
|
|
2089
|
-
const ProjectSchema = object({
|
|
2090
|
-
id: string(),
|
|
2091
|
-
organizationId: string(),
|
|
2092
|
-
name: string(),
|
|
2093
|
-
slug: ProjectSlugSchema,
|
|
2094
|
-
description: string().nullable(),
|
|
2095
|
-
status: ProjectStatusSchema,
|
|
2096
|
-
baseUrl: string().nullable(),
|
|
2097
|
-
runtimeId: string().nullable(),
|
|
2098
|
-
lastError: string().nullable(),
|
|
2099
|
-
createdAt: isoDateTime$3,
|
|
2100
|
-
updatedAt: isoDateTime$3
|
|
2101
|
-
});
|
|
2102
|
-
const UserOrganizationSchema = object({
|
|
2103
|
-
organization: OrganizationSchema,
|
|
2104
|
-
role: OrganizationUserRoleSchema
|
|
2105
|
-
});
|
|
2106
|
-
const ActiveOrganizationResponseSchema = object({ organization: UserOrganizationSchema.nullable() });
|
|
2107
|
-
const ListOrganizationsResponseSchema = object({ organizations: array(UserOrganizationSchema) });
|
|
2108
|
-
const CreateOrganizationRequestSchema = object({
|
|
2109
|
-
name: string().trim().min(1),
|
|
2110
|
-
/** Format-only at the wire boundary; reserved-name checks run in platform-database. */
|
|
2111
|
-
slug: OrganizationSlugSchema.optional()
|
|
2112
|
-
});
|
|
2113
|
-
const UpdateOrganizationRequestSchema = object({
|
|
2114
|
-
name: string().trim().min(1).optional(),
|
|
2115
|
-
slug: ClaimableOrganizationSlugSchema.optional()
|
|
2116
|
-
}).refine((data) => data.name !== void 0 || data.slug !== void 0, { message: "At least one field is required" });
|
|
2117
|
-
const CreateOrganizationResponseSchema = object({ organization: UserOrganizationSchema });
|
|
2118
|
-
const ListProjectsResponseSchema = object({ projects: array(ProjectSchema) });
|
|
2119
|
-
const ProjectListMetricsSchema = object({
|
|
2120
|
-
agentCount: number$1(),
|
|
2121
|
-
workflowCount: number$1(),
|
|
2122
|
-
skillCount: number$1(),
|
|
2123
|
-
credentialCount: number$1(),
|
|
2124
|
-
lastDeploymentAt: isoDateTime$3.nullable()
|
|
2125
|
-
});
|
|
2126
|
-
const ListProjectMetricsResponseSchema = object({ metrics: record(string(), ProjectListMetricsSchema) });
|
|
2127
|
-
const CreateProjectRequestSchema = object({
|
|
2128
|
-
name: string().trim().min(1),
|
|
2129
|
-
description: string().trim().min(1).optional()
|
|
2130
|
-
});
|
|
2131
|
-
const UpdateProjectRequestSchema = object({
|
|
2132
|
-
name: string().trim().min(1).optional(),
|
|
2133
|
-
description: string().trim().optional(),
|
|
2134
|
-
slug: ProjectSlugSchema.optional()
|
|
2135
|
-
}).refine((data) => data.name !== void 0 || data.description !== void 0 || data.slug !== void 0, { message: "At least one field is required" });
|
|
2136
|
-
const CreateProjectResponseSchema = object({ project: ProjectSchema });
|
|
2137
|
-
const ProjectResponseSchema = object({ project: ProjectSchema });
|
|
2138
|
-
const ProjectReachabilityResponseSchema = object({ reachable: boolean() });
|
|
2139
|
-
const ValidationErrorDetailSchema = object({
|
|
2140
|
-
path: string(),
|
|
2141
|
-
message: string()
|
|
2142
|
-
});
|
|
2143
|
-
/** Machine-readable codes returned in standard API error bodies. */
|
|
2144
|
-
const ErrorResponseCodeSchema = OrganizationSlugErrorCodeSchema.or(_enum(["needs_org_selection"]));
|
|
2145
|
-
/** Standard JSON error body returned by the HTTP API. */
|
|
2146
|
-
const ErrorResponseSchema = object({
|
|
2147
|
-
error: string(),
|
|
2148
|
-
code: ErrorResponseCodeSchema.optional(),
|
|
2149
|
-
message: string().optional(),
|
|
2150
|
-
details: array(ValidationErrorDetailSchema).optional()
|
|
2151
|
-
});
|
|
2152
|
-
const MessageOnlyErrorBodySchema = object({ message: string() });
|
|
2153
|
-
/** Parse a JSON error body from the API. */
|
|
2154
|
-
function parseErrorResponse(body) {
|
|
2155
|
-
const parsed = ErrorResponseSchema.safeParse(body);
|
|
2156
|
-
if (parsed.success) return parsed.data;
|
|
2157
|
-
const messageOnly = MessageOnlyErrorBodySchema.safeParse(body);
|
|
2158
|
-
if (messageOnly.success) return {
|
|
2159
|
-
error: messageOnly.data.message,
|
|
2160
|
-
message: messageOnly.data.message
|
|
2161
|
-
};
|
|
2162
|
-
}
|
|
2163
|
-
const CredentialRunContextSchema = object({
|
|
2164
|
-
orgId: string().min(1).optional(),
|
|
2165
|
-
projectId: string().min(1).optional(),
|
|
2166
|
-
userId: string().min(1).optional(),
|
|
2167
|
-
userIds: record(string(), string()).optional(),
|
|
2168
|
-
selection: record(string(), string()).optional()
|
|
2169
|
-
});
|
|
2170
|
-
const ThinkingLevelSchema = _enum([
|
|
2171
|
-
"off",
|
|
2172
|
-
"minimal",
|
|
2173
|
-
"low",
|
|
2174
|
-
"medium",
|
|
2175
|
-
"high",
|
|
2176
|
-
"xhigh"
|
|
2177
|
-
]);
|
|
2178
|
-
const PromptInputSchema = object({
|
|
2179
|
-
message: string().min(1),
|
|
2180
|
-
sessionId: string().min(1).optional(),
|
|
2181
|
-
subscriptionId: string().min(1).optional(),
|
|
2182
|
-
context: CredentialRunContextSchema.optional(),
|
|
2183
|
-
thinkingLevel: ThinkingLevelSchema.optional()
|
|
2184
|
-
});
|
|
2185
|
-
const PromptResponseSchema = object({
|
|
2186
|
-
sessionId: string(),
|
|
2187
|
-
messages: array(record(string(), unknown())),
|
|
2188
|
-
error: string().nullable()
|
|
2189
|
-
});
|
|
2190
|
-
const SkipResponseSchema = object({
|
|
2191
|
-
ok: literal(true),
|
|
2192
|
-
skipped: literal(true)
|
|
2193
|
-
});
|
|
2194
|
-
const HealthResponseSchema = object({ ok: literal(true) });
|
|
2195
|
-
object({ service: string() });
|
|
2196
|
-
const ConnectProvidersResponseSchema = object({ providers: array(object({
|
|
2197
|
-
key: string(),
|
|
2198
|
-
mode: _enum(["authorize-url", "browser-redirect"]),
|
|
2199
|
-
path: string(),
|
|
2200
|
-
requiresAuth: boolean()
|
|
2201
|
-
})) });
|
|
2202
|
-
const ConnectAuthorizeUrlResponseSchema = object({ url: string() });
|
|
2203
|
-
const QueuedRunResponseSchema = object({ runId: string() });
|
|
2204
|
-
const QueuedAgentPromptResponseSchema = object({ sessionId: string() });
|
|
2205
|
-
object({
|
|
2206
|
-
workflows: array(string().min(1)).optional(),
|
|
2207
|
-
attachments: array(string().min(1)).optional()
|
|
2208
|
-
});
|
|
2209
|
-
const PollRunMultiResponseSchema = object({ results: array(object({
|
|
2210
|
-
attachmentKey: string(),
|
|
2211
|
-
workflowKey: string(),
|
|
2212
|
-
runId: string().optional(),
|
|
2213
|
-
body: unknown().optional(),
|
|
2214
|
-
queued: boolean(),
|
|
2215
|
-
skipped: boolean().optional()
|
|
2216
|
-
})) });
|
|
2217
|
-
const PollRunResponseSchema = union([
|
|
2218
|
-
record(string(), unknown()),
|
|
2219
|
-
PollRunMultiResponseSchema,
|
|
2220
|
-
SkipResponseSchema,
|
|
2221
|
-
object({ runId: string() })
|
|
2222
|
-
]);
|
|
2223
|
-
const RunSourceKindSchema = _enum([
|
|
2224
|
-
"api",
|
|
2225
|
-
"trigger",
|
|
2226
|
-
"gateway",
|
|
2227
|
-
"workflow",
|
|
2228
|
-
"agent"
|
|
2229
|
-
]);
|
|
2230
|
-
object({
|
|
2231
|
-
kind: RunSourceKindSchema,
|
|
2232
|
-
id: string().nullable()
|
|
2233
|
-
});
|
|
2234
|
-
const WorkflowRunStatusSchema = _enum([
|
|
2235
|
-
"pending",
|
|
2236
|
-
"running",
|
|
2237
|
-
"completed",
|
|
2238
|
-
"failed"
|
|
2239
|
-
]);
|
|
2240
|
-
const WorkflowRunTriggerSchema = _enum([
|
|
2241
|
-
"api",
|
|
2242
|
-
"cron",
|
|
2243
|
-
"webhook",
|
|
2244
|
-
"poll",
|
|
2245
|
-
"retry"
|
|
2246
|
-
]);
|
|
2247
|
-
_enum([
|
|
2248
|
-
"run_started",
|
|
2249
|
-
"step_completed",
|
|
2250
|
-
"step_failed",
|
|
2251
|
-
"step_retrying",
|
|
2252
|
-
"sleep_scheduled",
|
|
2253
|
-
"sleep_completed",
|
|
2254
|
-
"hook_created",
|
|
2255
|
-
"hook_resumed",
|
|
2256
|
-
"run_completed",
|
|
2257
|
-
"run_failed"
|
|
2258
|
-
]);
|
|
2259
|
-
const WorkflowRunSummarySchema = object({
|
|
2260
|
-
id: string(),
|
|
2261
|
-
status: WorkflowRunStatusSchema,
|
|
2262
|
-
trigger: WorkflowRunTriggerSchema,
|
|
2263
|
-
triggeredAt: string(),
|
|
2264
|
-
startedAt: string().nullable(),
|
|
2265
|
-
finishedAt: string().nullable(),
|
|
2266
|
-
sourceKind: RunSourceKindSchema,
|
|
2267
|
-
sourceId: string().nullable(),
|
|
2268
|
-
triggerRunId: string().nullable(),
|
|
2269
|
-
attachmentId: string().nullable()
|
|
2270
|
-
});
|
|
2271
|
-
const WorkflowRunRecordSchema = object({
|
|
2272
|
-
id: string(),
|
|
2273
|
-
workflowSlug: string(),
|
|
2274
|
-
status: WorkflowRunStatusSchema,
|
|
2275
|
-
trigger: WorkflowRunTriggerSchema,
|
|
2276
|
-
triggeredAt: string(),
|
|
2277
|
-
startedAt: string().nullable(),
|
|
2278
|
-
finishedAt: string().nullable(),
|
|
2279
|
-
sourceKind: RunSourceKindSchema,
|
|
2280
|
-
sourceId: string().nullable(),
|
|
2281
|
-
triggerRunId: string().nullable(),
|
|
2282
|
-
attachmentId: string().nullable(),
|
|
2283
|
-
parentWorkflowRunId: string().nullable(),
|
|
2284
|
-
parentSpanId: string().nullable(),
|
|
2285
|
-
input: unknown().nullable(),
|
|
2286
|
-
output: unknown().nullable(),
|
|
2287
|
-
error: unknown().nullable()
|
|
2288
|
-
});
|
|
2289
|
-
object({
|
|
2290
|
-
limit: number().int().min(1).max(100).optional().default(20),
|
|
2291
|
-
cursor: string().min(1).optional(),
|
|
2292
|
-
status: WorkflowRunStatusSchema.optional(),
|
|
2293
|
-
trigger: WorkflowRunTriggerSchema.optional()
|
|
2294
|
-
});
|
|
2295
|
-
const WorkflowRunListResponseSchema = object({
|
|
2296
|
-
items: array(WorkflowRunSummarySchema),
|
|
2297
|
-
nextCursor: string().nullable()
|
|
2298
|
-
});
|
|
2299
|
-
_enum([
|
|
2300
|
-
"trigger",
|
|
2301
|
-
"steps",
|
|
2302
|
-
"trace"
|
|
2303
|
-
]);
|
|
2304
|
-
object({ include: string().optional() });
|
|
2305
|
-
const TriggerRunDetailSchema = object({
|
|
2306
|
-
id: string(),
|
|
2307
|
-
attachmentId: string(),
|
|
2308
|
-
attachmentSlug: string().nullable(),
|
|
2309
|
-
triggerType: _enum([
|
|
2310
|
-
"cron",
|
|
2311
|
-
"webhook",
|
|
2312
|
-
"poll"
|
|
2313
|
-
]),
|
|
2314
|
-
sourcePath: string().nullable(),
|
|
2315
|
-
payload: unknown().nullable(),
|
|
2316
|
-
triggeredAt: string()
|
|
2317
|
-
});
|
|
2318
|
-
const WorkflowStepRunSchema = object({
|
|
2319
|
-
id: string(),
|
|
2320
|
-
actionKey: string(),
|
|
2321
|
-
output: unknown(),
|
|
2322
|
-
completedAt: string()
|
|
2323
|
-
});
|
|
2324
|
-
const TraceTriggerSummarySchema = object({
|
|
2325
|
-
triggerType: string(),
|
|
2326
|
-
triggerRunId: string(),
|
|
2327
|
-
workflowSlug: string().optional(),
|
|
2328
|
-
agentSlug: string().optional(),
|
|
2329
|
-
attachmentId: string().nullable().optional(),
|
|
2330
|
-
attachmentSlug: string().nullable().optional(),
|
|
2331
|
-
route: string().optional(),
|
|
2332
|
-
sourcePath: string().nullable().optional()
|
|
2333
|
-
}).nullable();
|
|
2334
|
-
const TraceGatewaySummarySchema = object({
|
|
2335
|
-
gatewayAttachmentId: string(),
|
|
2336
|
-
gatewayAttachmentKey: string(),
|
|
2337
|
-
threadId: string().optional(),
|
|
2338
|
-
channelId: string().optional(),
|
|
2339
|
-
mode: string().optional()
|
|
2340
|
-
}).nullable();
|
|
2341
|
-
const TraceSpanSchema = object({
|
|
2342
|
-
id: string(),
|
|
2343
|
-
traceId: string(),
|
|
2344
|
-
parentSpanId: string().nullable(),
|
|
2345
|
-
kind: string(),
|
|
2346
|
-
refId: string(),
|
|
2347
|
-
name: string(),
|
|
2348
|
-
status: string(),
|
|
2349
|
-
startedAt: string(),
|
|
2350
|
-
finishedAt: string().nullable(),
|
|
2351
|
-
metadata: unknown().nullable(),
|
|
2352
|
-
error: unknown().nullable()
|
|
2353
|
-
});
|
|
2354
|
-
const TraceLogSchema = object({
|
|
2355
|
-
id: string(),
|
|
2356
|
-
traceId: string(),
|
|
2357
|
-
spanId: string(),
|
|
2358
|
-
seq: number$1(),
|
|
2359
|
-
level: string(),
|
|
2360
|
-
message: string(),
|
|
2361
|
-
data: unknown().nullable(),
|
|
2362
|
-
source: string(),
|
|
2363
|
-
createdAt: string()
|
|
2364
|
-
});
|
|
2365
|
-
const TraceResponseSchema = object({
|
|
2366
|
-
traceId: string(),
|
|
2367
|
-
trigger: TraceTriggerSummarySchema,
|
|
2368
|
-
gateway: TraceGatewaySummarySchema,
|
|
2369
|
-
spans: array(TraceSpanSchema),
|
|
2370
|
-
logs: array(TraceLogSchema)
|
|
2371
|
-
});
|
|
2372
|
-
const WorkflowRunDetailResponseSchema = object({
|
|
2373
|
-
run: WorkflowRunRecordSchema,
|
|
2374
|
-
trigger: TriggerRunDetailSchema.nullable(),
|
|
2375
|
-
steps: array(WorkflowStepRunSchema),
|
|
2376
|
-
trace: TraceResponseSchema.nullable()
|
|
2377
|
-
});
|
|
2378
|
-
const AgentSessionStatusSchema = _enum([
|
|
2379
|
-
"running",
|
|
2380
|
-
"completed",
|
|
2381
|
-
"failed"
|
|
2382
|
-
]);
|
|
2383
|
-
const AgentSessionSummarySchema = object({
|
|
2384
|
-
id: string(),
|
|
2385
|
-
status: AgentSessionStatusSchema,
|
|
2386
|
-
source: RunSourceKindSchema,
|
|
2387
|
-
sourceId: string().nullable(),
|
|
2388
|
-
createdAt: string(),
|
|
2389
|
-
updatedAt: string(),
|
|
2390
|
-
messageCount: number$1()
|
|
2391
|
-
});
|
|
2392
|
-
const AgentSessionRecordSchema = object({
|
|
2393
|
-
id: string(),
|
|
2394
|
-
agentSlug: string(),
|
|
2395
|
-
status: AgentSessionStatusSchema,
|
|
2396
|
-
source: RunSourceKindSchema,
|
|
2397
|
-
sourceId: string().nullable(),
|
|
2398
|
-
createdAt: string(),
|
|
2399
|
-
updatedAt: string(),
|
|
2400
|
-
parentSpanId: string().nullable(),
|
|
2401
|
-
messageCount: number$1(),
|
|
2402
|
-
error: unknown().nullable()
|
|
2403
|
-
});
|
|
2404
|
-
object({
|
|
2405
|
-
limit: number().int().min(1).max(100).optional().default(20),
|
|
2406
|
-
cursor: string().min(1).optional(),
|
|
2407
|
-
status: AgentSessionStatusSchema.optional(),
|
|
2408
|
-
source: RunSourceKindSchema.optional()
|
|
2409
|
-
});
|
|
2410
|
-
const AgentSessionListResponseSchema = object({
|
|
2411
|
-
items: array(AgentSessionSummarySchema),
|
|
2412
|
-
nextCursor: string().nullable()
|
|
2413
|
-
});
|
|
2414
|
-
_enum([
|
|
2415
|
-
"gateway",
|
|
2416
|
-
"messages",
|
|
2417
|
-
"events",
|
|
2418
|
-
"trace"
|
|
2419
|
-
]);
|
|
2420
|
-
object({ include: string().optional() });
|
|
2421
|
-
const GatewaySessionDetailSchema = object({
|
|
2422
|
-
threadId: string(),
|
|
2423
|
-
attachmentId: string(),
|
|
2424
|
-
attachmentSlug: string().nullable()
|
|
2425
|
-
});
|
|
2426
|
-
const AgentEventSchema = object({
|
|
2427
|
-
id: string(),
|
|
2428
|
-
sessionId: string(),
|
|
2429
|
-
seq: number$1(),
|
|
2430
|
-
eventType: string(),
|
|
2431
|
-
payload: unknown(),
|
|
2432
|
-
createdAt: string()
|
|
2433
|
-
});
|
|
2434
|
-
const AgentSessionDetailResponseSchema = object({
|
|
2435
|
-
session: AgentSessionRecordSchema,
|
|
2436
|
-
gateway: GatewaySessionDetailSchema.nullable(),
|
|
2437
|
-
messages: array(record(string(), unknown())),
|
|
2438
|
-
events: array(AgentEventSchema),
|
|
2439
|
-
trace: TraceResponseSchema.nullable()
|
|
2440
|
-
});
|
|
2441
|
-
const SlackGatewayModeSchema = _enum([
|
|
2442
|
-
"mention",
|
|
2443
|
-
"channel",
|
|
2444
|
-
"dm"
|
|
2445
|
-
]);
|
|
2446
|
-
const GatewayAttachmentSourceSchema = object({
|
|
2447
|
-
kind: literal("slack"),
|
|
2448
|
-
mode: SlackGatewayModeSchema,
|
|
2449
|
-
credentialKey: string(),
|
|
2450
|
-
channelIds: array(string()).optional(),
|
|
2451
|
-
subscribeOnMention: boolean()
|
|
2452
|
-
});
|
|
2453
|
-
const GatewayAttachmentRecordSchema = object({
|
|
2454
|
-
id: string(),
|
|
2455
|
-
key: string(),
|
|
2456
|
-
agentKey: string(),
|
|
2457
|
-
channelId: string(),
|
|
2458
|
-
teamId: string().nullable().optional(),
|
|
2459
|
-
platform: string(),
|
|
2460
|
-
source: GatewayAttachmentSourceSchema,
|
|
2461
|
-
registeredAt: string(),
|
|
2462
|
-
updatedAt: string()
|
|
2463
|
-
});
|
|
2464
|
-
object({ attachments: array(GatewayAttachmentRecordSchema) });
|
|
2465
|
-
const UpsertGatewayAttachmentBodySchema = object({
|
|
2466
|
-
agentKey: string().min(1),
|
|
2467
|
-
teamId: string().min(1).optional(),
|
|
2468
|
-
mode: SlackGatewayModeSchema.optional(),
|
|
2469
|
-
subscribeOnMention: boolean().optional()
|
|
2470
|
-
});
|
|
2471
|
-
const AgentListResponseSchema = object({ agents: array(object({
|
|
2472
|
-
key: string(),
|
|
2473
|
-
name: string().optional(),
|
|
2474
|
-
route: string()
|
|
2475
|
-
})) });
|
|
2476
|
-
object({ subscriptions: array(object({
|
|
2477
|
-
id: string(),
|
|
2478
|
-
workflowKey: string(),
|
|
2479
|
-
userId: string(),
|
|
2480
|
-
enabled: boolean(),
|
|
2481
|
-
createdAt: string(),
|
|
2482
|
-
updatedAt: string()
|
|
2483
|
-
})) });
|
|
2484
|
-
object({
|
|
2485
|
-
userId: string().min(1).optional(),
|
|
2486
|
-
enabled: boolean().optional()
|
|
2487
|
-
});
|
|
2488
|
-
const CredentialInstanceRecordSchema = object({
|
|
2489
|
-
id: string(),
|
|
2490
|
-
key: string(),
|
|
2491
|
-
scopeType: CredentialScopeTypeSchema,
|
|
2492
|
-
scopeId: string().nullable(),
|
|
2493
|
-
label: string().nullable(),
|
|
2494
|
-
isDefault: boolean(),
|
|
2495
|
-
authKind: CredentialAuthKindSchema
|
|
2496
|
-
});
|
|
2497
|
-
const CredentialInstanceListResponseSchema = object({ instances: array(CredentialInstanceRecordSchema) });
|
|
2498
|
-
const CreateCredentialInstanceBodySchema = object({
|
|
2499
|
-
key: string().min(1),
|
|
2500
|
-
scopeType: CredentialScopeTypeSchema,
|
|
2501
|
-
scopeId: string().nullable().optional(),
|
|
2502
|
-
label: string().nullable().optional(),
|
|
2503
|
-
isDefault: boolean().optional(),
|
|
2504
|
-
value: record(string(), unknown()).refine((value) => Object.keys(value).length > 0, { message: "value must be a non-empty object" })
|
|
2505
|
-
});
|
|
2506
|
-
const UpdateCredentialInstanceBodySchema = object({
|
|
2507
|
-
label: string().nullable().optional(),
|
|
2508
|
-
isDefault: boolean().optional(),
|
|
2509
|
-
value: record(string(), unknown()).refine((value) => Object.keys(value).length > 0, { message: "value must be a non-empty object" }).optional()
|
|
2510
|
-
});
|
|
2511
|
-
const TriggerRunTypeSchema = _enum([
|
|
2512
|
-
"cron",
|
|
2513
|
-
"webhook",
|
|
2514
|
-
"poll"
|
|
2515
|
-
]);
|
|
2516
|
-
const TriggerRunWorkflowSummarySchema = object({
|
|
2517
|
-
id: string(),
|
|
2518
|
-
status: WorkflowRunStatusSchema,
|
|
2519
|
-
workflowSlug: string()
|
|
2520
|
-
});
|
|
2521
|
-
const TriggerRunAgentSessionSummarySchema = object({
|
|
2522
|
-
id: string(),
|
|
2523
|
-
agentSlug: string()
|
|
2524
|
-
});
|
|
2525
|
-
const TriggerRunSummarySchema = object({
|
|
2526
|
-
id: string(),
|
|
2527
|
-
triggerType: TriggerRunTypeSchema,
|
|
2528
|
-
triggeredAt: string(),
|
|
2529
|
-
sourcePath: string().nullable(),
|
|
2530
|
-
workflowRun: TriggerRunWorkflowSummarySchema.nullable(),
|
|
2531
|
-
agentSession: TriggerRunAgentSessionSummarySchema.nullable()
|
|
2532
|
-
});
|
|
2533
|
-
const TriggerRunRecordSchema = object({
|
|
2534
|
-
id: string(),
|
|
2535
|
-
attachmentId: string(),
|
|
2536
|
-
attachmentSlug: string(),
|
|
2537
|
-
triggerType: TriggerRunTypeSchema,
|
|
2538
|
-
sourcePath: string().nullable(),
|
|
2539
|
-
payload: unknown().nullable(),
|
|
2540
|
-
triggeredAt: string()
|
|
2541
|
-
});
|
|
2542
|
-
object({
|
|
2543
|
-
limit: number().int().min(1).max(100).optional().default(20),
|
|
2544
|
-
cursor: string().min(1).optional(),
|
|
2545
|
-
triggerType: TriggerRunTypeSchema.optional()
|
|
2546
|
-
});
|
|
2547
|
-
const TriggerRunListResponseSchema = object({
|
|
2548
|
-
items: array(TriggerRunSummarySchema),
|
|
2549
|
-
nextCursor: string().nullable()
|
|
2550
|
-
});
|
|
2551
|
-
_enum([
|
|
2552
|
-
"workflows",
|
|
2553
|
-
"agents",
|
|
2554
|
-
"trace"
|
|
2555
|
-
]);
|
|
2556
|
-
object({ include: string().optional() });
|
|
2557
|
-
const TriggerRunAgentSessionDetailSchema = object({
|
|
2558
|
-
id: string(),
|
|
2559
|
-
agentSlug: string()
|
|
2560
|
-
});
|
|
2561
|
-
const TriggerRunDetailResponseSchema = object({
|
|
2562
|
-
run: TriggerRunRecordSchema,
|
|
2563
|
-
workflowRuns: array(WorkflowRunSummarySchema),
|
|
2564
|
-
agentSessions: array(TriggerRunAgentSessionDetailSchema),
|
|
2565
|
-
trace: TraceResponseSchema.nullable()
|
|
2566
|
-
});
|
|
2567
|
-
const TriggerTypeSchema = _enum([
|
|
2568
|
-
"webhook",
|
|
2569
|
-
"poll",
|
|
2570
|
-
"cron"
|
|
2571
|
-
]);
|
|
2572
|
-
const TriggerTargetKindSchema = _enum(["workflow", "agent"]);
|
|
2573
|
-
const TriggerListItemSchema = object({
|
|
2574
|
-
key: string(),
|
|
2575
|
-
type: TriggerTypeSchema,
|
|
2576
|
-
route: string().optional(),
|
|
2577
|
-
webhookUrl: string().url().optional(),
|
|
2578
|
-
targetKind: TriggerTargetKindSchema,
|
|
2579
|
-
workflowKey: string().optional(),
|
|
2580
|
-
agentKey: string().optional()
|
|
2581
|
-
});
|
|
2582
|
-
const TriggerListResponseSchema = object({ triggers: array(TriggerListItemSchema) });
|
|
2583
|
-
object({ endpoint: string().min(1).optional() });
|
|
2584
|
-
const TriggerDetailResponseSchema = TriggerListItemSchema;
|
|
2585
|
-
const OrganizationMemberRoleSchema = _enum([
|
|
2586
|
-
"owner",
|
|
2587
|
-
"admin",
|
|
2588
|
-
"builder"
|
|
2589
|
-
]);
|
|
2590
|
-
const OrganizationMemberStatusSchema = _enum([
|
|
2591
|
-
"invited",
|
|
2592
|
-
"active",
|
|
2593
|
-
"rejected",
|
|
2594
|
-
"suspended"
|
|
2595
|
-
]);
|
|
2596
|
-
const InvitableOrganizationMemberRoleSchema = _enum(["admin", "builder"]);
|
|
2597
|
-
const isoDateTime$2 = string().datetime();
|
|
2598
|
-
const OrganizationMemberSchema = object({
|
|
2599
|
-
id: string(),
|
|
2600
|
-
name: string(),
|
|
2601
|
-
email: string().email(),
|
|
2602
|
-
role: OrganizationMemberRoleSchema,
|
|
2603
|
-
status: OrganizationMemberStatusSchema,
|
|
2604
|
-
avatarUrl: string().optional(),
|
|
2605
|
-
joinedAt: isoDateTime$2.optional(),
|
|
2606
|
-
lastActiveAt: isoDateTime$2.nullable().optional()
|
|
2607
|
-
});
|
|
2608
|
-
const ListOrganizationMembersResponseSchema = object({ members: array(OrganizationMemberSchema) });
|
|
2609
|
-
const InviteOrganizationMembersRequestSchema = object({
|
|
2610
|
-
emails: array(string().trim().email()).min(1),
|
|
2611
|
-
role: InvitableOrganizationMemberRoleSchema
|
|
2612
|
-
});
|
|
2613
|
-
const InviteOrganizationMemberResultStatusSchema = _enum([
|
|
2614
|
-
"sent",
|
|
2615
|
-
"already_member",
|
|
2616
|
-
"pending",
|
|
2617
|
-
"invalid"
|
|
2618
|
-
]);
|
|
2619
|
-
const InviteOrganizationMembersResponseSchema = object({ results: array(object({
|
|
2620
|
-
email: string(),
|
|
2621
|
-
status: InviteOrganizationMemberResultStatusSchema,
|
|
2622
|
-
invitationId: string().optional()
|
|
2623
|
-
})) });
|
|
2624
|
-
const UpdateOrganizationMemberRequestSchema = object({ role: InvitableOrganizationMemberRoleSchema });
|
|
2625
|
-
const UpdateOrganizationMemberResponseSchema = object({ member: OrganizationMemberSchema });
|
|
2626
|
-
const ListOrganizationInvitationsResponseSchema = object({ invitations: array(object({
|
|
2627
|
-
id: string(),
|
|
2628
|
-
organizationName: string(),
|
|
2629
|
-
organizationSlug: OrganizationSlugSchema,
|
|
2630
|
-
invitedByName: string().optional(),
|
|
2631
|
-
invitedByEmail: string().email().optional(),
|
|
2632
|
-
role: OrganizationMemberRoleSchema
|
|
2633
|
-
})) });
|
|
2634
|
-
const AcceptOrganizationInvitationResponseSchema = object({ organization: UserOrganizationSchema });
|
|
2635
|
-
const DeclineOrganizationInvitationResponseSchema = object({ success: literal(true) });
|
|
2636
|
-
/** Custom avatar override; null means fall back to OAuth `users.image`. */
|
|
2637
|
-
const UserAvatarSchema = object({ url: url().nullable() });
|
|
2638
|
-
const UserAvatarPatchSchema = object({
|
|
2639
|
-
/** Storage key returned from presign; null removes the custom override. */
|
|
2640
|
-
storageKey: string().min(1).nullable() });
|
|
2641
|
-
const PresignUserAvatarRequestSchema = object({ contentType: string().trim().min(1) });
|
|
2642
|
-
const PresignUserAvatarResponseSchema = object({
|
|
2643
|
-
uploadUrl: url(),
|
|
2644
|
-
storageKey: string().min(1)
|
|
2645
|
-
});
|
|
2646
|
-
const OrganizationLogoVariantSchema = _enum(["light", "dark"]);
|
|
2647
|
-
const OrganizationSidebarBrandingSchema = object({
|
|
2648
|
-
customLogoEnabled: boolean(),
|
|
2649
|
-
customLogoExplicitlyDisabled: boolean(),
|
|
2650
|
-
logoLightUrl: url().nullable(),
|
|
2651
|
-
logoDarkUrl: url().nullable(),
|
|
2652
|
-
logoHeightPx: number$1().int().min(14).max(32)
|
|
2653
|
-
});
|
|
2654
|
-
const OrganizationSidebarBrandingPatchSchema = object({
|
|
2655
|
-
customLogoEnabled: boolean().optional(),
|
|
2656
|
-
customLogoExplicitlyDisabled: boolean().optional(),
|
|
2657
|
-
logoLightStorageKey: string().min(1).nullable().optional(),
|
|
2658
|
-
logoDarkStorageKey: string().min(1).nullable().optional(),
|
|
2659
|
-
logoHeightPx: number$1().int().min(14).max(32).optional()
|
|
2660
|
-
}).refine((value) => value.customLogoEnabled !== void 0 || value.customLogoExplicitlyDisabled !== void 0 || value.logoLightStorageKey !== void 0 || value.logoDarkStorageKey !== void 0 || value.logoHeightPx !== void 0, { message: "At least one branding field is required" });
|
|
2661
|
-
const PresignOrgLogoRequestSchema = object({
|
|
2662
|
-
variant: OrganizationLogoVariantSchema,
|
|
2663
|
-
contentType: string().trim().min(1)
|
|
2664
|
-
});
|
|
2665
|
-
const PresignOrgLogoResponseSchema = object({
|
|
2666
|
-
uploadUrl: url(),
|
|
2667
|
-
storageKey: string().min(1)
|
|
2668
|
-
});
|
|
2669
|
-
const ProjectArtifactStatusSchema = _enum(["pending", "ready"]);
|
|
2670
|
-
const isoDateTime$1 = string().datetime();
|
|
2671
|
-
const ProjectArtifactSchema = object({
|
|
2672
|
-
id: string(),
|
|
2673
|
-
projectId: string(),
|
|
2674
|
-
storageKey: string(),
|
|
2675
|
-
status: ProjectArtifactStatusSchema,
|
|
2676
|
-
createdAt: isoDateTime$1,
|
|
2677
|
-
updatedAt: isoDateTime$1
|
|
2678
|
-
});
|
|
2679
|
-
const CreateProjectArtifactResponseSchema = object({
|
|
2680
|
-
artifact: ProjectArtifactSchema,
|
|
2681
|
-
uploadUrl: string().url(),
|
|
2682
|
-
expiresInSeconds: number$1().int().positive()
|
|
2683
|
-
});
|
|
2684
|
-
const CompleteProjectArtifactResponseSchema = object({
|
|
2685
|
-
artifact: ProjectArtifactSchema,
|
|
2686
|
-
project: ProjectSchema
|
|
2687
|
-
});
|
|
2688
|
-
const ListProjectDeploymentsResponseSchema = object({ deployments: array(object({
|
|
2689
|
-
id: string(),
|
|
2690
|
-
projectId: string(),
|
|
2691
|
-
version: number$1().int().positive(),
|
|
2692
|
-
deployedBy: string().nullable(),
|
|
2693
|
-
deployedByEmail: string().optional(),
|
|
2694
|
-
deployedByAvatarUrl: string().optional(),
|
|
2695
|
-
createdAt: isoDateTime$1,
|
|
2696
|
-
active: boolean()
|
|
2697
|
-
})) });
|
|
2698
|
-
const optionalCount = number$1().int().nonnegative().nullable().optional();
|
|
2699
|
-
const optionalTimestamp = string().nullable().optional();
|
|
2700
|
-
const AgentSummarySchema = object({
|
|
2701
|
-
id: string().min(1),
|
|
2702
|
-
slug: string().min(1),
|
|
2703
|
-
name: string().min(1),
|
|
2704
|
-
projectId: string().min(1),
|
|
2705
|
-
updatedAt: string().min(1),
|
|
2706
|
-
description: string().optional(),
|
|
2707
|
-
sourcePath: string().min(1).optional(),
|
|
2708
|
-
model: string().optional(),
|
|
2709
|
-
toolCount: optionalCount,
|
|
2710
|
-
credentialCount: optionalCount,
|
|
2711
|
-
lastRunAt: optionalTimestamp
|
|
2712
|
-
});
|
|
2713
|
-
const WorkflowSummarySchema = object({
|
|
2714
|
-
id: string().min(1),
|
|
2715
|
-
slug: string().min(1),
|
|
2716
|
-
name: string().min(1),
|
|
2717
|
-
projectId: string().min(1),
|
|
2718
|
-
updatedAt: string().min(1),
|
|
2719
|
-
description: string().optional(),
|
|
2720
|
-
sourcePath: string().min(1).optional(),
|
|
2721
|
-
lastRunAt: optionalTimestamp
|
|
2722
|
-
});
|
|
2723
|
-
const SkillSummarySchema = object({
|
|
2724
|
-
id: string().min(1),
|
|
2725
|
-
slug: string().min(1),
|
|
2726
|
-
name: string().min(1),
|
|
2727
|
-
projectId: string().min(1),
|
|
2728
|
-
updatedAt: string().min(1),
|
|
2729
|
-
description: string().optional(),
|
|
2730
|
-
sourcePath: string().min(1).optional()
|
|
2731
|
-
});
|
|
2732
|
-
const AgentSummaryListResponseSchema = array(AgentSummarySchema);
|
|
2733
|
-
const AgentSummaryDetailResponseSchema = AgentSummarySchema.nullable();
|
|
2734
|
-
const WorkflowSummaryListResponseSchema = array(WorkflowSummarySchema);
|
|
2735
|
-
const WorkflowSummaryDetailResponseSchema = WorkflowSummarySchema.nullable();
|
|
2736
|
-
const SkillSummaryListResponseSchema = array(SkillSummarySchema);
|
|
2737
|
-
const SkillSummaryDetailResponseSchema = SkillSummarySchema.nullable();
|
|
2738
|
-
const RecentResourceKindSchema = _enum([
|
|
2739
|
-
"agent",
|
|
2740
|
-
"workflow",
|
|
2741
|
-
"skill"
|
|
2742
|
-
]);
|
|
2743
|
-
const RecentResourceSourceSchema = _enum(["owned", "shared"]);
|
|
2744
|
-
const RecentResourceListResponseSchema = array(object({
|
|
2745
|
-
id: string().min(1),
|
|
2746
|
-
resourceKind: RecentResourceKindSchema,
|
|
2747
|
-
resourceId: string().min(1),
|
|
2748
|
-
name: string().min(1),
|
|
2749
|
-
description: string().optional(),
|
|
2750
|
-
projectId: string().min(1),
|
|
2751
|
-
projectName: string().min(1),
|
|
2752
|
-
sourcePath: string().min(1).optional(),
|
|
2753
|
-
source: RecentResourceSourceSchema,
|
|
2754
|
-
lastOpenedAt: string().min(1),
|
|
2755
|
-
lastModifiedAt: string().min(1)
|
|
2756
|
-
}));
|
|
2757
|
-
const isoDateTime = string().datetime();
|
|
2758
|
-
const sha256Hex = string().regex(/^[a-f0-9]{64}$/, "Expected a lowercase hex sha256 digest");
|
|
2759
|
-
/**
|
|
2760
|
-
* A single entry in a deploy's file tree, as served to the dashboard. Carries
|
|
2761
|
-
* no contents: `id` is a stable, path-derived handle used for selection and
|
|
2762
|
-
* `?file=` deep links; `hash` is the content address used to fetch the bytes
|
|
2763
|
-
* lazily and to cache them immutably in the browser.
|
|
2764
|
-
*/
|
|
2765
|
-
const ProjectFileSummarySchema = object({
|
|
2766
|
-
id: string(),
|
|
2767
|
-
path: string().min(1),
|
|
2768
|
-
hash: sha256Hex
|
|
2769
|
-
});
|
|
2770
|
-
/** Maps a runtime resource slug (agent/workflow/skill) to its source file path. */
|
|
2771
|
-
const ProjectSourceResourceRefSchema = object({
|
|
2772
|
-
slug: string().min(1),
|
|
2773
|
-
path: string().min(1)
|
|
2774
|
-
});
|
|
2775
|
-
const ProjectSourceResourcesSchema = object({
|
|
2776
|
-
agents: array(ProjectSourceResourceRefSchema).default([]),
|
|
2777
|
-
workflows: array(ProjectSourceResourceRefSchema).default([]),
|
|
2778
|
-
skills: array(ProjectSourceResourceRefSchema).default([])
|
|
2779
|
-
});
|
|
2780
|
-
const emptyResources = () => ({
|
|
2781
|
-
agents: [],
|
|
2782
|
-
workflows: [],
|
|
2783
|
-
skills: []
|
|
2784
|
-
});
|
|
2785
|
-
/** Response for the file-tree listing of a project's active deploy. */
|
|
2786
|
-
const ListProjectFilesResponseSchema = object({
|
|
2787
|
-
artifactId: string().nullable(),
|
|
2788
|
-
files: array(ProjectFileSummarySchema),
|
|
2789
|
-
resources: ProjectSourceResourcesSchema.default(emptyResources())
|
|
2790
|
-
});
|
|
2791
|
-
object({
|
|
2792
|
-
path: string().min(1),
|
|
2793
|
-
contents: string(),
|
|
2794
|
-
hash: sha256Hex
|
|
2795
|
-
});
|
|
2796
|
-
/** Request: ask the platform which blobs are missing and get presigned PUTs. */
|
|
2797
|
-
const PresignProjectSourceRequestSchema = object({ blobs: array(object({
|
|
2798
|
-
hash: sha256Hex,
|
|
2799
|
-
size: number$1().int().nonnegative()
|
|
2800
|
-
})) });
|
|
2801
|
-
/** Response: presigned PUTs for the subset of blobs not already stored. */
|
|
2802
|
-
const PresignProjectSourceResponseSchema = object({ uploads: array(object({
|
|
2803
|
-
hash: sha256Hex,
|
|
2804
|
-
url: string().url()
|
|
2805
|
-
})) });
|
|
2806
|
-
/** Request body the CLI sends to finalize a deploy's source manifest. */
|
|
2807
|
-
const UploadProjectSourceManifestRequestSchema = object({
|
|
2808
|
-
files: array(object({
|
|
2809
|
-
path: string().min(1),
|
|
2810
|
-
hash: sha256Hex
|
|
2811
|
-
})),
|
|
2812
|
-
resources: ProjectSourceResourcesSchema.default(emptyResources())
|
|
2813
|
-
});
|
|
2814
|
-
const UploadProjectSourceResponseSchema = object({
|
|
2815
|
-
ok: literal(true),
|
|
2816
|
-
fileCount: number$1().int().nonnegative()
|
|
2817
|
-
});
|
|
2818
|
-
object({
|
|
2819
|
-
files: array(object({
|
|
2820
|
-
id: string(),
|
|
2821
|
-
path: string().min(1),
|
|
2822
|
-
hash: sha256Hex
|
|
2823
|
-
})),
|
|
2824
|
-
resources: ProjectSourceResourcesSchema.default(emptyResources()),
|
|
2825
|
-
generatedAt: isoDateTime
|
|
2826
|
-
});
|
|
2827
|
-
//#endregion
|
|
2828
1371
|
//#region ../../packages/sdk/dist/index.mjs
|
|
2829
1372
|
function normalizeBaseUrl$1(baseUrl) {
|
|
2830
1373
|
return baseUrl.replace(/\/+$/, "");
|
|
@@ -4781,9 +3324,11 @@ async function runDeviceLogin(options) {
|
|
|
4781
3324
|
});
|
|
4782
3325
|
if (!tokenResult.error) {
|
|
4783
3326
|
const token = tokenResult.data;
|
|
3327
|
+
const organizationId = token.scope?.trim();
|
|
4784
3328
|
return {
|
|
4785
3329
|
accessToken: token.access_token,
|
|
4786
|
-
expiresIn: token.expires_in
|
|
3330
|
+
expiresIn: token.expires_in,
|
|
3331
|
+
organizationId: organizationId || void 0
|
|
4787
3332
|
};
|
|
4788
3333
|
}
|
|
4789
3334
|
const errorPayload = tokenResult.error;
|
|
@@ -4835,82 +3380,6 @@ async function getCliJwt(platformUrl, force = false) {
|
|
|
4835
3380
|
return cache.get(force);
|
|
4836
3381
|
}
|
|
4837
3382
|
//#endregion
|
|
4838
|
-
//#region src/resolve-platform-url.ts
|
|
4839
|
-
const DEFAULT_WEB_URL = "https://app.keystroke.ai";
|
|
4840
|
-
const DEFAULT_PLATFORM_URL = "https://api.keystroke.ai";
|
|
4841
|
-
const LOCAL_PLATFORM_URL = "http://localhost:3002";
|
|
4842
|
-
function webOriginFromUrl(webUrl) {
|
|
4843
|
-
return originFromPublicUrl(webUrl, webUrl.replace(/\/+$/, ""));
|
|
4844
|
-
}
|
|
4845
|
-
/** Known web origins with a fixed platform API — undefined for custom/staging URLs. */
|
|
4846
|
-
function knownPlatformUrlForWebUrl(webUrl) {
|
|
4847
|
-
const webOrigin = webOriginFromUrl(webUrl);
|
|
4848
|
-
if (webOrigin === "http://localhost:3000" || webOrigin === "http://127.0.0.1:3000") return LOCAL_PLATFORM_URL;
|
|
4849
|
-
if (webOrigin === "https://app.keystroke.ai") return DEFAULT_PLATFORM_URL;
|
|
4850
|
-
}
|
|
4851
|
-
function resolvePlatformUrlForWebUrl(webUrl, options = {}) {
|
|
4852
|
-
const explicit = options.platformUrl?.trim();
|
|
4853
|
-
if (explicit) return explicit.replace(/\/+$/, "");
|
|
4854
|
-
const known = knownPlatformUrlForWebUrl(webUrl);
|
|
4855
|
-
if (known) return known;
|
|
4856
|
-
return (options.fallback?.trim() || "https://api.keystroke.ai").replace(/\/+$/, "");
|
|
4857
|
-
}
|
|
4858
|
-
//#endregion
|
|
4859
|
-
//#region src/config.ts
|
|
4860
|
-
function getCliConfigDir(cwd = join(homedir(), ".keystroke")) {
|
|
4861
|
-
return cwd;
|
|
4862
|
-
}
|
|
4863
|
-
function getConfigDir(config) {
|
|
4864
|
-
return dirname(config.path);
|
|
4865
|
-
}
|
|
4866
|
-
function getEffectiveApiTarget(config) {
|
|
4867
|
-
const explicit = config.get("apiTarget");
|
|
4868
|
-
if (explicit === "local" || explicit === "platform") return explicit;
|
|
4869
|
-
return "local";
|
|
4870
|
-
}
|
|
4871
|
-
function syncPlatformUrlWithWebUrl(config) {
|
|
4872
|
-
const known = knownPlatformUrlForWebUrl(config.get("webUrl"));
|
|
4873
|
-
if (!known) return;
|
|
4874
|
-
if (config.get("platformUrl") !== known) config.set("platformUrl", known);
|
|
4875
|
-
}
|
|
4876
|
-
function createCliConfig(cwd = getCliConfigDir()) {
|
|
4877
|
-
const config = new Conf({
|
|
4878
|
-
projectName: "keystroke",
|
|
4879
|
-
cwd,
|
|
4880
|
-
schema: {
|
|
4881
|
-
serverUrl: {
|
|
4882
|
-
type: "string",
|
|
4883
|
-
default: "http://localhost:3001"
|
|
4884
|
-
},
|
|
4885
|
-
webUrl: {
|
|
4886
|
-
type: "string",
|
|
4887
|
-
default: DEFAULT_WEB_URL
|
|
4888
|
-
},
|
|
4889
|
-
platformUrl: {
|
|
4890
|
-
type: "string",
|
|
4891
|
-
default: DEFAULT_PLATFORM_URL
|
|
4892
|
-
},
|
|
4893
|
-
activeOrganizationId: { type: "string" },
|
|
4894
|
-
activeProjectId: { type: "string" },
|
|
4895
|
-
apiTarget: {
|
|
4896
|
-
type: "string",
|
|
4897
|
-
enum: ["local", "platform"]
|
|
4898
|
-
}
|
|
4899
|
-
}
|
|
4900
|
-
});
|
|
4901
|
-
syncPlatformUrlWithWebUrl(config);
|
|
4902
|
-
return config;
|
|
4903
|
-
}
|
|
4904
|
-
function getServerUrl(config) {
|
|
4905
|
-
return config.get("serverUrl");
|
|
4906
|
-
}
|
|
4907
|
-
function getWebUrl(config) {
|
|
4908
|
-
return config.get("webUrl");
|
|
4909
|
-
}
|
|
4910
|
-
function getPlatformUrl(config) {
|
|
4911
|
-
return resolvePlatformUrlForWebUrl(getWebUrl(config), { fallback: config.get("platformUrl") });
|
|
4912
|
-
}
|
|
4913
|
-
//#endregion
|
|
4914
3383
|
//#region src/auth/resolve-cli-auth.ts
|
|
4915
3384
|
/** Returns JWT bearer auth when a session refresh token is stored; otherwise none. */
|
|
4916
3385
|
function resolveCliAuth(config) {
|
|
@@ -8674,6 +7143,15 @@ async function activateOrganization(config, organizationId) {
|
|
|
8674
7143
|
platform.setActiveOrganizationId(membership.organization.id);
|
|
8675
7144
|
return membership;
|
|
8676
7145
|
}
|
|
7146
|
+
function resolveOrganizationIdForLogin(organizations, options = {}) {
|
|
7147
|
+
if (options.organizationRef ?? options.organizationId) return resolveOrganizationRef(organizations, options.organizationRef ?? options.organizationId).organization.id;
|
|
7148
|
+
for (const candidateId of [options.deviceOrganizationId, options.storedOrganizationId]) {
|
|
7149
|
+
const organizationId = candidateId?.trim();
|
|
7150
|
+
if (organizationId && organizations.some((entry) => entry.organization.id === organizationId)) return organizationId;
|
|
7151
|
+
}
|
|
7152
|
+
if (organizations.length === 1) return organizations[0].organization.id;
|
|
7153
|
+
return [...organizations].sort((left, right) => left.organization.slug.localeCompare(right.organization.slug))[0].organization.id;
|
|
7154
|
+
}
|
|
8677
7155
|
async function pickOrganization(config, organizations, organizationRef) {
|
|
8678
7156
|
if (organizationRef) return activateOrganization(config, resolveOrganizationRef(organizations, organizationRef).organization.id);
|
|
8679
7157
|
if (!process.stdin.isTTY) {
|
|
@@ -8697,33 +7175,21 @@ async function selectActiveOrganization(config, options = {}) {
|
|
|
8697
7175
|
async function syncActiveOrganizationAfterLogin(config, options = {}) {
|
|
8698
7176
|
const organizations = await listOrganizations(config);
|
|
8699
7177
|
if (organizations.length === 0) throw new Error(`No organization found — create one at ${getWebUrl(config)}`);
|
|
8700
|
-
|
|
8701
|
-
|
|
8702
|
-
|
|
8703
|
-
|
|
8704
|
-
|
|
8705
|
-
}
|
|
8706
|
-
if (organizations.length === 1) {
|
|
8707
|
-
const membership = await activateOrganization(config, organizations[0].organization.id);
|
|
8708
|
-
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
8709
|
-
return membership;
|
|
8710
|
-
}
|
|
8711
|
-
if (options.organizationRef ?? options.organizationId) {
|
|
8712
|
-
const membership = await pickOrganization(config, organizations, options.organizationRef ?? options.organizationId);
|
|
8713
|
-
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
8714
|
-
return membership;
|
|
8715
|
-
}
|
|
8716
|
-
const membership = await pickOrganization(config, organizations);
|
|
8717
|
-
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
8718
|
-
return membership;
|
|
7178
|
+
return activateOrganization(config, resolveOrganizationIdForLogin(organizations, {
|
|
7179
|
+
organizationRef: options.organizationRef,
|
|
7180
|
+
organizationId: options.organizationId,
|
|
7181
|
+
deviceOrganizationId: options.deviceOrganizationId,
|
|
7182
|
+
storedOrganizationId: config.get("activeOrganizationId")
|
|
7183
|
+
}));
|
|
8719
7184
|
}
|
|
8720
7185
|
async function ensureActiveOrganization(config) {
|
|
7186
|
+
const organizations = await listOrganizations(config);
|
|
7187
|
+
if (organizations.length === 0) throw new Error("No organization found. Run `keystroke auth login` after creating one in the dashboard.");
|
|
8721
7188
|
const storedId = config.get("activeOrganizationId");
|
|
8722
|
-
if (storedId) {
|
|
7189
|
+
if (storedId && organizations.some((entry) => entry.organization.id === storedId)) {
|
|
8723
7190
|
await activateOrganization(config, storedId);
|
|
8724
7191
|
return;
|
|
8725
7192
|
}
|
|
8726
|
-
const organizations = await listOrganizations(config);
|
|
8727
7193
|
if (organizations.length === 1) {
|
|
8728
7194
|
await activateOrganization(config, organizations[0].organization.id);
|
|
8729
7195
|
return;
|
|
@@ -8965,6 +7431,30 @@ function parseJsonOption(value, flag) {
|
|
|
8965
7431
|
}
|
|
8966
7432
|
}
|
|
8967
7433
|
//#endregion
|
|
7434
|
+
//#region src/resolve-project-target.ts
|
|
7435
|
+
async function resolveActiveProject(config, platform) {
|
|
7436
|
+
const ref = getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
7437
|
+
if (!ref) return;
|
|
7438
|
+
const client = platform ?? createCliPlatformClient(config);
|
|
7439
|
+
if (!getCliTargetOptions().projectId && looksLikeUuid(ref)) return resolveProjectRef(client, ref);
|
|
7440
|
+
return resolveProjectRef(client, ref);
|
|
7441
|
+
}
|
|
7442
|
+
async function resolveActiveProjectId(config) {
|
|
7443
|
+
return (await resolveActiveProject(config))?.id;
|
|
7444
|
+
}
|
|
7445
|
+
//#endregion
|
|
7446
|
+
//#region src/commands/agent/list.ts
|
|
7447
|
+
function registerAgentListCommand(agent) {
|
|
7448
|
+
agent.command("list").description("List agents in the active organization").action(() => runCliCommand("List agents failed", async () => {
|
|
7449
|
+
const config = createCliConfig();
|
|
7450
|
+
const client = createCliPlatformClient(config);
|
|
7451
|
+
await ensureActiveOrganization(config);
|
|
7452
|
+
const projectId = await resolveActiveProjectId(config);
|
|
7453
|
+
const result = await client.agents.list(projectId ? { projectId } : void 0);
|
|
7454
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
7455
|
+
}, void 0, { orgScoped: true }));
|
|
7456
|
+
}
|
|
7457
|
+
//#endregion
|
|
8968
7458
|
//#region src/commands/agent/prompt.ts
|
|
8969
7459
|
function registerAgentPromptCommand(agent) {
|
|
8970
7460
|
agent.command("prompt").description("Send a message to an agent (or follow up in an existing session)").argument("<agentId>", "Agent key / route id").requiredOption("--message <text>", "Message to send").option("--session-id <id>", "Existing session id for follow-up").action((agentId, options) => runProjectCliCommand("Agent prompt failed", async ({ client }) => {
|
|
@@ -8997,6 +7487,7 @@ function registerAgentSessionsCommand(agent) {
|
|
|
8997
7487
|
//#region src/commands/agent/index.ts
|
|
8998
7488
|
function registerAgentCommand(program) {
|
|
8999
7489
|
const agent = program.command("agent").description("Invoke and inspect agents");
|
|
7490
|
+
registerAgentListCommand(agent);
|
|
9000
7491
|
registerAgentPromptCommand(agent);
|
|
9001
7492
|
registerAgentSessionsCommand(agent);
|
|
9002
7493
|
}
|
|
@@ -9299,7 +7790,7 @@ function resolveAuthLoginTargets(options, config) {
|
|
|
9299
7790
|
//#endregion
|
|
9300
7791
|
//#region src/commands/auth/login.ts
|
|
9301
7792
|
function registerAuthLoginCommand(auth) {
|
|
9302
|
-
auth.command("login").description("Authenticate via browser device flow").option("--web-url <url>", "Web dashboard origin (omit to use production defaults; local dev: http://localhost:3000)").option("--platform-url <url>", "Platform API origin (derived from web URL when omitted)").option("--org <slug>", "Active organization slug (
|
|
7793
|
+
auth.command("login").description("Authenticate via browser device flow").option("--web-url <url>", "Web dashboard origin (omit to use production defaults; local dev: http://localhost:3000)").option("--platform-url <url>", "Platform API origin (derived from web URL when omitted)").option("--org <slug>", "Active organization slug (overrides browser default)").action(async (options) => {
|
|
9303
7794
|
const config = createCliConfig();
|
|
9304
7795
|
const { webUrl, platformUrl } = resolveAuthLoginTargets(options, config);
|
|
9305
7796
|
config.set("webUrl", webUrl);
|
|
@@ -9312,9 +7803,12 @@ function registerAuthLoginCommand(auth) {
|
|
|
9312
7803
|
});
|
|
9313
7804
|
setAccessToken(platformUrl, result.accessToken);
|
|
9314
7805
|
const user = await getSessionWithBearer(platformUrl, result.accessToken);
|
|
9315
|
-
|
|
9316
|
-
|
|
9317
|
-
|
|
7806
|
+
const membership = await syncActiveOrganizationAfterLogin(config, {
|
|
7807
|
+
organizationRef: options.org,
|
|
7808
|
+
deviceOrganizationId: result.organizationId
|
|
7809
|
+
});
|
|
7810
|
+
if (user) process.stdout.write(`Logged in as ${user.name} (${user.email}) — organization ${membership.organization.name}\n`);
|
|
7811
|
+
else process.stdout.write(`Logged in to ${webUrl} — organization ${membership.organization.name}\n`);
|
|
9318
7812
|
} catch (error) {
|
|
9319
7813
|
process.stderr.write(`${formatCliError(error, "Login failed", {
|
|
9320
7814
|
webUrl,
|
|
@@ -9391,7 +7885,7 @@ function registerBuildCommand(program) {
|
|
|
9391
7885
|
program.command("build").description("Build the keystroke project for production").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
|
|
9392
7886
|
try {
|
|
9393
7887
|
const root = resolveProjectRoot(options.dir);
|
|
9394
|
-
const { buildApp } = await import("./dist-
|
|
7888
|
+
const { buildApp } = await import("./dist-QMg0gSzo.mjs");
|
|
9395
7889
|
await buildApp({ root });
|
|
9396
7890
|
process.stdout.write(`Built ${root}\n`);
|
|
9397
7891
|
} catch (error) {
|
|
@@ -9435,115 +7929,10 @@ function packProjectArtifact(projectRoot) {
|
|
|
9435
7929
|
}
|
|
9436
7930
|
//#endregion
|
|
9437
7931
|
//#region src/project/collect-source.ts
|
|
9438
|
-
|
|
9439
|
-
"node_modules",
|
|
9440
|
-
"dist",
|
|
9441
|
-
".git",
|
|
9442
|
-
".turbo",
|
|
9443
|
-
"build",
|
|
9444
|
-
"coverage",
|
|
9445
|
-
".keystroke",
|
|
9446
|
-
".cache",
|
|
9447
|
-
"tmp"
|
|
9448
|
-
]);
|
|
9449
|
-
const IGNORED_ENV_FILE = /\.env/;
|
|
9450
|
-
const IGNORED_LOG_FILE = /\.log$/;
|
|
9451
|
-
const MAX_FILE_BYTES = 256 * 1024;
|
|
9452
|
-
const MAX_TOTAL_BYTES = 8 * 1024 * 1024;
|
|
9453
|
-
const MAX_FILES = 2e3;
|
|
9454
|
-
function isIgnoredFile(name) {
|
|
9455
|
-
return IGNORED_ENV_FILE.test(name) || IGNORED_LOG_FILE.test(name);
|
|
9456
|
-
}
|
|
9457
|
-
function toPosix(path) {
|
|
9458
|
-
return path.split(sep).join("/");
|
|
9459
|
-
}
|
|
9460
|
-
function isProbablyBinary(buffer) {
|
|
9461
|
-
const sampleLength = Math.min(buffer.length, 8e3);
|
|
9462
|
-
for (let index = 0; index < sampleLength; index += 1) if (buffer[index] === 0) return true;
|
|
9463
|
-
return false;
|
|
9464
|
-
}
|
|
9465
|
-
function walkFiles(root, dir, out, totals) {
|
|
9466
|
-
for (const name of readdirSync(dir).sort()) {
|
|
9467
|
-
if (out.length >= MAX_FILES || totals.bytes >= MAX_TOTAL_BYTES) return;
|
|
9468
|
-
const absolute = join(dir, name);
|
|
9469
|
-
const stats = statSync(absolute);
|
|
9470
|
-
if (stats.isDirectory()) {
|
|
9471
|
-
if (IGNORED_DIRS.has(name)) continue;
|
|
9472
|
-
walkFiles(root, absolute, out, totals);
|
|
9473
|
-
continue;
|
|
9474
|
-
}
|
|
9475
|
-
if (!stats.isFile() || stats.size > MAX_FILE_BYTES || isIgnoredFile(name)) continue;
|
|
9476
|
-
const buffer = readFileSync(absolute);
|
|
9477
|
-
if (isProbablyBinary(buffer)) continue;
|
|
9478
|
-
totals.bytes += buffer.byteLength;
|
|
9479
|
-
out.push({
|
|
9480
|
-
path: toPosix(relative(root, absolute)),
|
|
9481
|
-
contents: buffer.toString("utf8"),
|
|
9482
|
-
hash: createHash("sha256").update(buffer).digest("hex")
|
|
9483
|
-
});
|
|
9484
|
-
}
|
|
9485
|
-
}
|
|
9486
|
-
function posixPrefix(root, srcRoot, subdir) {
|
|
9487
|
-
return `${toPosix(relative(root, join(srcRoot, subdir)))}/`;
|
|
9488
|
-
}
|
|
9489
|
-
function collectModuleRefs(srcRoot, root, files, subdir, nestedEntry) {
|
|
9490
|
-
const dir = join(srcRoot, subdir);
|
|
9491
|
-
const prefix = posixPrefix(root, srcRoot, subdir);
|
|
9492
|
-
const refs = [];
|
|
9493
|
-
for (const file of files) {
|
|
9494
|
-
if (!file.path.startsWith(prefix) || !/\.(ts|mts)$/.test(file.path)) continue;
|
|
9495
|
-
const slug = entryIdFromFile(dir, join(root, file.path), { nestedEntry });
|
|
9496
|
-
if (slug) refs.push({
|
|
9497
|
-
slug,
|
|
9498
|
-
path: file.path
|
|
9499
|
-
});
|
|
9500
|
-
}
|
|
9501
|
-
return refs;
|
|
9502
|
-
}
|
|
9503
|
-
function collectSkillRefs(srcRoot, root, files) {
|
|
9504
|
-
const dir = join(srcRoot, "skills");
|
|
9505
|
-
const prefix = posixPrefix(root, srcRoot, "skills");
|
|
9506
|
-
const refs = [];
|
|
9507
|
-
for (const file of files) {
|
|
9508
|
-
if (!file.path.startsWith(prefix) || !file.path.endsWith("SKILL.md")) continue;
|
|
9509
|
-
const slug = toPosix(relative(dir, join(root, file.path)).replace(/\/?SKILL\.md$/, ""));
|
|
9510
|
-
if (slug) refs.push({
|
|
9511
|
-
slug,
|
|
9512
|
-
path: file.path
|
|
9513
|
-
});
|
|
9514
|
-
}
|
|
9515
|
-
return refs;
|
|
9516
|
-
}
|
|
9517
|
-
/**
|
|
9518
|
-
* Collect the project's actual source code into a deploy snapshot: every text
|
|
9519
|
-
* file under the project root (minus build output / deps) plus a map of each
|
|
9520
|
-
* agent / workflow / skill key to its source path. The map mirrors the same
|
|
9521
|
-
* path-derived ids the build step uses.
|
|
9522
|
-
*/
|
|
7932
|
+
/** Collect deploy source files via the shared project walk (for `--skip-build`). */
|
|
9523
7933
|
function collectProjectSource(root) {
|
|
9524
|
-
|
|
9525
|
-
|
|
9526
|
-
const srcRoot = join(root, "src");
|
|
9527
|
-
return {
|
|
9528
|
-
files,
|
|
9529
|
-
resources: {
|
|
9530
|
-
agents: collectModuleRefs(srcRoot, root, files, "agents", "agent"),
|
|
9531
|
-
workflows: collectModuleRefs(srcRoot, root, files, "workflows", "workflow"),
|
|
9532
|
-
skills: collectSkillRefs(srcRoot, root, files)
|
|
9533
|
-
}
|
|
9534
|
-
};
|
|
9535
|
-
}
|
|
9536
|
-
//#endregion
|
|
9537
|
-
//#region src/resolve-project-target.ts
|
|
9538
|
-
async function resolveActiveProject(config, platform) {
|
|
9539
|
-
const ref = getCliTargetOptions().projectId ?? config.get("activeProjectId");
|
|
9540
|
-
if (!ref) return;
|
|
9541
|
-
const client = platform ?? createCliPlatformClient(config);
|
|
9542
|
-
if (!getCliTargetOptions().projectId && looksLikeUuid(ref)) return resolveProjectRef(client, ref);
|
|
9543
|
-
return resolveProjectRef(client, ref);
|
|
9544
|
-
}
|
|
9545
|
-
async function resolveActiveProjectId(config) {
|
|
9546
|
-
return (await resolveActiveProject(config))?.id;
|
|
7934
|
+
if (!existsSync(join(root, "dist/.keystroke/route-manifest.json"))) throw new Error(`Route manifest missing at ${ROUTE_MANIFEST_REL_PATH}. Run keystroke build before deploy --skip-build.`);
|
|
7935
|
+
return { files: walkProject(root, { collectSources: true }).sourceFiles };
|
|
9547
7936
|
}
|
|
9548
7937
|
//#endregion
|
|
9549
7938
|
//#region src/commands/deploy.ts
|
|
@@ -9577,13 +7966,10 @@ async function uploadProjectSourceSnapshot(client, projectId, artifactId, source
|
|
|
9577
7966
|
});
|
|
9578
7967
|
if (!response.ok) throw new Error(`Source blob upload failed (${response.status})`);
|
|
9579
7968
|
}));
|
|
9580
|
-
await client.artifacts.uploadManifest(projectId, artifactId, {
|
|
9581
|
-
|
|
9582
|
-
|
|
9583
|
-
|
|
9584
|
-
})),
|
|
9585
|
-
resources: source.resources
|
|
9586
|
-
});
|
|
7969
|
+
await client.artifacts.uploadManifest(projectId, artifactId, { files: source.files.map((file) => ({
|
|
7970
|
+
path: file.path,
|
|
7971
|
+
hash: file.hash
|
|
7972
|
+
})) });
|
|
9587
7973
|
}
|
|
9588
7974
|
async function sleep(ms) {
|
|
9589
7975
|
await new Promise((resolve) => {
|
|
@@ -9594,16 +7980,20 @@ async function runDeploy(options) {
|
|
|
9594
7980
|
const root = resolveProjectRoot(options.dir);
|
|
9595
7981
|
const config = createCliConfig();
|
|
9596
7982
|
const client = createCliPlatformClient(config);
|
|
7983
|
+
let source;
|
|
9597
7984
|
if (!options.skipBuild) {
|
|
9598
|
-
const { buildApp } = await import("./dist-
|
|
9599
|
-
await buildApp({
|
|
9600
|
-
|
|
7985
|
+
const { buildApp } = await import("./dist-QMg0gSzo.mjs");
|
|
7986
|
+
source = { files: (await buildApp({
|
|
7987
|
+
root,
|
|
7988
|
+
collectSources: true,
|
|
7989
|
+
emitManifest: true
|
|
7990
|
+
})).sourceFiles };
|
|
7991
|
+
} else source = collectProjectSource(root);
|
|
9601
7992
|
const archive = packProjectArtifact(root);
|
|
9602
7993
|
let active = await client.organizations.getActive();
|
|
9603
7994
|
if (!active) active = await selectActiveOrganization(config);
|
|
9604
7995
|
client.setActiveOrganizationId(active.organization.id);
|
|
9605
7996
|
const project = await client.projects.get(options.projectId);
|
|
9606
|
-
const source = collectProjectSource(root);
|
|
9607
7997
|
const created = await client.artifacts.create(project.id);
|
|
9608
7998
|
const uploadPromise = fetch(created.uploadUrl, {
|
|
9609
7999
|
method: "PUT",
|
|
@@ -9692,7 +8082,7 @@ function runtimeChildEnv(parentEnv, overrides) {
|
|
|
9692
8082
|
//#region src/project/bootstrap-run.ts
|
|
9693
8083
|
/** Node args + env for `@keystrokehq/build` bootstrap (shared by start + dev). */
|
|
9694
8084
|
async function resolveBootstrapRun(options) {
|
|
9695
|
-
const { resolveRuntimeBuildArtifact } = await import("./dist-
|
|
8085
|
+
const { resolveRuntimeBuildArtifact } = await import("./dist-QMg0gSzo.mjs");
|
|
9696
8086
|
const loader = pathToFileURL(resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/runtime-loader.mjs")).href;
|
|
9697
8087
|
const bootstrap = resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/bootstrap.mjs");
|
|
9698
8088
|
const args = [`--import=${loader}`];
|
|
@@ -9842,7 +8232,7 @@ async function runDev(options) {
|
|
|
9842
8232
|
process.on("SIGINT", shutdown);
|
|
9843
8233
|
process.on("SIGTERM", shutdown);
|
|
9844
8234
|
try {
|
|
9845
|
-
const { watchApp } = await import("./dist-
|
|
8235
|
+
const { watchApp } = await import("./dist-QMg0gSzo.mjs");
|
|
9846
8236
|
await watchApp({
|
|
9847
8237
|
root,
|
|
9848
8238
|
clean: false,
|
|
@@ -10380,7 +8770,7 @@ async function runStart(options) {
|
|
|
10380
8770
|
const apiPort = Number(new URL(serverUrl).port || 80);
|
|
10381
8771
|
const runtimeNodeModules = resolveCliRuntimeNodeModules(resolveCliRoot(import.meta.url));
|
|
10382
8772
|
ensureNativeDeps(runtimeNodeModules);
|
|
10383
|
-
const { buildApp } = await import("./dist-
|
|
8773
|
+
const { buildApp } = await import("./dist-QMg0gSzo.mjs");
|
|
10384
8774
|
await buildApp({
|
|
10385
8775
|
root,
|
|
10386
8776
|
clean: false
|
|
@@ -10473,6 +8863,18 @@ function registerTriggerCommand(program) {
|
|
|
10473
8863
|
registerTriggerRunsCommand(trigger);
|
|
10474
8864
|
}
|
|
10475
8865
|
//#endregion
|
|
8866
|
+
//#region src/commands/workflow/list.ts
|
|
8867
|
+
function registerWorkflowListCommand(workflow) {
|
|
8868
|
+
workflow.command("list").description("List workflows in the active organization").action(() => runCliCommand("List workflows failed", async () => {
|
|
8869
|
+
const config = createCliConfig();
|
|
8870
|
+
const client = createCliPlatformClient(config);
|
|
8871
|
+
await ensureActiveOrganization(config);
|
|
8872
|
+
const projectId = await resolveActiveProjectId(config);
|
|
8873
|
+
const result = await client.workflows.list(projectId ? { projectId } : void 0);
|
|
8874
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
8875
|
+
}, void 0, { orgScoped: true }));
|
|
8876
|
+
}
|
|
8877
|
+
//#endregion
|
|
10476
8878
|
//#region src/commands/workflow/run.ts
|
|
10477
8879
|
function registerWorkflowRunCommand(workflow) {
|
|
10478
8880
|
workflow.command("run").description("Invoke a workflow").argument("<workflowId>", "Workflow key / route id").option("--input <json>", "JSON request body (defaults to {})", "{}").addHelpText("after", `
|
|
@@ -10511,6 +8913,7 @@ function registerWorkflowRunsCommand(workflow) {
|
|
|
10511
8913
|
//#region src/commands/workflow/index.ts
|
|
10512
8914
|
function registerWorkflowCommand(program) {
|
|
10513
8915
|
const workflow = program.command("workflow").description("Invoke and inspect workflows");
|
|
8916
|
+
registerWorkflowListCommand(workflow);
|
|
10514
8917
|
registerWorkflowRunCommand(workflow);
|
|
10515
8918
|
registerWorkflowRunsCommand(workflow);
|
|
10516
8919
|
}
|
|
@@ -10584,6 +8987,18 @@ function registerConfigCommand(program) {
|
|
|
10584
8987
|
});
|
|
10585
8988
|
}
|
|
10586
8989
|
//#endregion
|
|
8990
|
+
//#region src/commands/skill/index.ts
|
|
8991
|
+
function registerSkillCommand(program) {
|
|
8992
|
+
program.command("skill").description("Inspect platform skills").command("list").description("List skills in the active organization").action(() => runCliCommand("List skills failed", async () => {
|
|
8993
|
+
const config = createCliConfig();
|
|
8994
|
+
const client = createCliPlatformClient(config);
|
|
8995
|
+
await ensureActiveOrganization(config);
|
|
8996
|
+
const projectId = await resolveActiveProjectId(config);
|
|
8997
|
+
const result = await client.skills.list(projectId ? { projectId } : void 0);
|
|
8998
|
+
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
8999
|
+
}, void 0, { orgScoped: true }));
|
|
9000
|
+
}
|
|
9001
|
+
//#endregion
|
|
10587
9002
|
//#region src/commands/skills.ts
|
|
10588
9003
|
function registerSkillsCommand(program) {
|
|
10589
9004
|
program.command("skills").description("Manage bundled agent skills").command("sync").description("Overwrite bundled skills and AGENTS.md with the CLI version").option("--dir <path>", "Project directory", process.cwd()).action(async (options) => {
|
|
@@ -10664,6 +9079,7 @@ function createProgram() {
|
|
|
10664
9079
|
registerHealthCommand(program);
|
|
10665
9080
|
registerInitCommand(program);
|
|
10666
9081
|
registerSkillsCommand(program);
|
|
9082
|
+
registerSkillCommand(program);
|
|
10667
9083
|
registerBuildCommand(program);
|
|
10668
9084
|
registerDeployCommand(program);
|
|
10669
9085
|
registerDevCommand(program);
|