@keystrokehq/cli 0.1.61 → 0.1.63
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/README.md +1 -1
- package/dist/{dist-qm-t5iv6.mjs → dist-BWOtba0o.mjs} +2 -2
- package/dist/{dist-qm-t5iv6.mjs.map → dist-BWOtba0o.mjs.map} +1 -1
- package/dist/{dist-DqFY1hVs.mjs → dist-BnlTZTsD.mjs} +3 -3
- package/dist/{dist-DqFY1hVs.mjs.map → dist-BnlTZTsD.mjs.map} +1 -1
- package/dist/{dist-CnAsi0KI.mjs → dist-D2zm0gm3.mjs} +55 -22
- package/dist/{dist-CnAsi0KI.mjs.map → dist-D2zm0gm3.mjs.map} +1 -1
- package/dist/dist-DqgnpWYF.mjs +3 -0
- package/dist/{dist-BS0qm1w4.mjs → dist-aQ56wvGQ.mjs} +29 -3
- package/dist/dist-aQ56wvGQ.mjs.map +1 -0
- package/dist/index.mjs +331 -238
- package/dist/index.mjs.map +1 -1
- package/dist/{maybe-auto-update-shke2A4n.mjs → maybe-auto-update-KpKNhzFK.mjs} +2 -2
- package/dist/{maybe-auto-update-shke2A4n.mjs.map → maybe-auto-update-KpKNhzFK.mjs.map} +1 -1
- package/dist/skills-bundle/_AGENTS.mcp.md +14 -13
- package/dist/skills-bundle/_AGENTS.md +53 -20
- package/dist/{version-CITcX7L_.mjs → version-DZ9lwyAW.mjs} +2 -3
- package/dist/version-DZ9lwyAW.mjs.map +1 -0
- package/package.json +1 -1
- package/dist/dist-BS0qm1w4.mjs.map +0 -1
- package/dist/dist-CycZREH6.mjs +0 -3
- package/dist/version-CITcX7L_.mjs.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { $ as
|
|
3
|
-
import { i as packProjectArtifact, n as withMcpReadClient, r as mergeFilteredArtifact, t as mapInParallelBatches } from "./dist-
|
|
4
|
-
import { _ as getPlatformUrl, c as detectPackageManager, d as resolveGithubPackagesToken, f as resolvePackageManager, g as getEffectiveApiTarget, h as getConfigDir, i as isReleaseAgeBlock, l as installDependencies$1, m as getCliConfigDir, n as resolveCliRoot, o as detectManagerFromLockfile, p as createCliConfig, s as buildPlaygroundWorkspace, t as readCliVersion, u as installPlaygroundDependencies, v as getWebUrl, x as resolvePlatformUrlForWebUrl, y as DEFAULT_PLATFORM_URL } from "./version-
|
|
2
|
+
import { $ as CredentialConsumerListResponseSchema, $n as WorkflowRunInputsSchema, $t as PresignUserAvatarRequestSchema, A as ConfirmCheckoutResponseSchema, An as UpdateCredentialInstanceBodySchema, At as ListOrganizationInvitationsResponseSchema, B as CreateCreditsCheckoutRequestSchema, Bn as UploadProjectSourceManifestRequestSchema, Bt as McpDiscoverResponseSchema, C as ChannelAccountListResponseSchema, Cn as SubmitTeamRequestRequestSchema, Cr as resolveDocsMcpUrl, D as ChannelPlatformSchema, Dn as TriggerRunListResponseSchema, Dt as ListAppsResponseSchema, E as ChannelDirectoryListResponseSchema, En as TriggerRunDetailResponseSchema, Et as ListApiKeysResponseSchema, F as CreateApiKeyResponseSchema, Fn as UpdateOrganizationRequestSchema, Ft as ListProjectMembersResponseSchema, G as CreateProjectArtifactResponseSchema, Gn as UserPreferencesPatchSchema, Gt as PROJECT_REACHABILITY_REQUEST_TIMEOUT_MS, H as CreateCustomAppResponseSchema, Hn as UpsertGatewayAttachmentBodySchema, Ht as OrganizationSidebarBrandingPatchSchema, I as CreateBillingPortalRequestSchema, In as UpdateProjectMemberRequestSchema, It as ListProjectMetricsResponseSchema, J as CreateSubscriptionCheckoutRequestSchema, Jn as WorkflowCanvasRunSchema, Jt as PresignChatAttachmentResponseSchema, K as CreateProjectRequestSchema, Kn as UserPreferencesSchema, Kt as PollRunResponseSchema, L as CreateCredentialInstanceBodySchema, Ln as UpdateProjectMemberResponseSchema, Lt as ListProjectsResponseSchema, M as ConnectManagedServiceCredentialRequestSchema, Mn as UpdateManagedServiceCredentialRequestSchema, Mt as ListOrganizationsResponseSchema, N as ConnectProvidersResponseSchema, Nn as UpdateOrganizationMemberRequestSchema, Nt as ListProjectDeploymentsResponseSchema, O as CompleteProjectArtifactResponseSchema, On as UpdateAutoTopupRequestSchema, Ot as ListCredentialsResponseSchema, P as CreateApiKeyRequestSchema, Pn as UpdateOrganizationMemberResponseSchema, Pt as ListProjectFilesResponseSchema, Q as CredentialConsumerListQuerySchema, Qn as WorkflowRunInputsPutBodySchema, Qt as PresignProjectSourceResponseSchema, R as CreateCredentialsRequestSchema, Rn as UpdateProjectRequestSchema, Rt as ManagedServiceCredentialSchema, S as CatalogAppsPageResponseSchema, Sn as SubmitMarketingContactRequestSchema, Sr as resolveConnectAppSlug, St as InviteProjectMembersResponseSchema, T as ChannelConnectionSchema, Tn as TriggerListResponseSchema, Tr as slugifyAppName, Tt as ListAgentWorkspaceFilesResponseSchema, U as CreateOrganizationRequestSchema, Un as UserAvatarPatchSchema, Ut as OrganizationSidebarBrandingSchema, V as CreateCustomAppRequestSchema, Vn as UploadProjectSourceResponseSchema, Vt as OpenApiDiscoverResponseSchema, W as CreateOrganizationResponseSchema, Wn as UserAvatarSchema, Wt as PROJECT_PULL_STATE_RELATIVE_PATH, X as CredentialAssignmentListResponseSchema, Xn as WorkflowRunDetailResponseSchema, Xt as PresignOrgLogoResponseSchema, Y as CredentialAssignmentListQuerySchema, Yn as WorkflowCanvasSchema, Yt as PresignOrgLogoRequestSchema, Z as CredentialAssignmentRecordSchema, Zn as WorkflowRunHooksResponseSchema, Zt as PresignProjectSourceRequestSchema, _ as BillingUsageResponseSchema, _n as StartKeystrokeConnectionResultSchema, _t as HistoryRunListQuerySchema, a as AgentSessionDetailResponseSchema, an as ProjectSlugAvailabilityResponseSchema, ar as WorkspaceTriggerFileSchema, at as DeclineOrganizationInvitationResponseSchema, b as CatalogActionsPageResponseSchema, bn as StartOAuthConnectionInputSchema, bt as InviteOrganizationMembersResponseSchema, c as AgentSummaryListResponseSchema, cr as WorkspaceTriggerRunListResponseSchema, ct as ErrorResponseSchema, d as AssignCredentialBodySchema, dt as GetCredentialResponseSchema, en as PresignUserAvatarResponseSchema, er as WorkflowRunListResponseSchema, et as CredentialInstanceListResponseSchema, f as AutoTopupSummarySchema, fn as RecentResourceListResponseSchema, fr as deriveCustomAppDisplay, ft as GetCustomAppResponseSchema, g as BillingSummaryResponseSchema, gn as StartKeystrokeConnectionInputSchema, gt as HistoryRunDetailResponseSchema, h as BillingRedirectResponseSchema, hn as SlugAvailabilityResponseSchema, hr as listenPortFromPublicUrl, ht as HistoryRunCancelResponseSchema, i as AgentSessionChatStateResponseSchema, in as ProjectSettingsResponseSchema, ir as WorkspaceTriggerDetailSchema, it as DOCS_SEARCH_TOOL, j as ConnectAuthorizeUrlResponseSchema, jn as UpdateCredentialRequestSchema, jt as ListOrganizationMembersResponseSchema, k as ConfirmCheckoutRequestSchema, kn as UpdateChannelBindingBodySchema, kt as ListManagedServiceCredentialsResponseSchema, l as AgentTriggerSummaryListResponseSchema, ln as QueuedAgentPromptResponseSchema, lr as WorkspaceWorkflowOverviewSchema, lt as ExecuteKeystrokeToolRequestSchema, m as BillingInvoiceUrlResponseSchema, mn as SkillSummaryListResponseSchema, mr as isAcceptableInstallExit, mt as HealthResponseSchema, n as AcceptOrganizationInvitationResponseSchema, nn as ProjectReachabilityResponseSchema, nr as WorkflowSummaryDetailResponseSchema, o as AgentSessionListResponseSchema, on as PromptInputSchema, or as WorkspaceTriggerListResponseSchema, ot as DownloadActiveProjectArtifactResponseSchema, p as BillingActivityResponseSchema, pn as SkillSummaryDetailResponseSchema, pr as detectProjectPackageManagerFromSnapshot, pt as GraphqlDiscoverResponseSchema, q as CreateProjectResponseSchema, qn as WorkflowCanvasCredentialBindingsSchema, qt as PresignChatAttachmentRequestSchema, r as ActiveOrganizationResponseSchema, rn as ProjectResponseSchema, rr as WorkflowSummaryListResponseSchema, rt as DOCS_QUERY_TOOL, s as AgentSummaryDetailResponseSchema, sn as PromptResponseSchema, sr as WorkspaceTriggerOverviewSchema, st as DownloadActiveProjectSourceResponseSchema, t as ACTIVE_ORG_HEADER, tn as ProjectPullStateSchema, tr as WorkflowRunResponseSchema, tt as CredentialInstanceRecordSchema, u as AppSlugAvailabilityResponseSchema, un as QueuedRunResponseSchema, ur as buildConnectDeeplink, ut as GatewayAttachmentRecordSchema, v as BindChannelBodySchema, vn as StartMcpOAuthConnectionInputSchema, vr as parseAppSlug, vt as HistoryRunListResponseSchema, w as ChannelConnectionListResponseSchema, wn as TriggerDetailResponseSchema, wr as resolvePublicPlatformOrigin, wt as ListAgentMemoryFilesResponseSchema, x as CatalogAppDetailResponseSchema, xn as StartOAuthConnectionResultSchema, xt as InviteProjectMembersRequestSchema, y as CatalogActionDetailResponseSchema, yn as StartMcpOAuthConnectionResultSchema, yr as parseErrorResponse, yt as InviteOrganizationMembersRequestSchema, z as CreateCredentialsResponseSchema, zn as UpdateProjectSettingsRequestSchema, zt as ManagedServiceKindSchema } from "./dist-D2zm0gm3.mjs";
|
|
3
|
+
import { i as packProjectArtifact, n as withMcpReadClient, r as mergeFilteredArtifact, t as mapInParallelBatches } from "./dist-BWOtba0o.mjs";
|
|
4
|
+
import { _ as getPlatformUrl, c as detectPackageManager, d as resolveGithubPackagesToken, f as resolvePackageManager, g as getEffectiveApiTarget, h as getConfigDir, i as isReleaseAgeBlock, l as installDependencies$1, m as getCliConfigDir, n as resolveCliRoot, o as detectManagerFromLockfile, p as createCliConfig, s as buildPlaygroundWorkspace, t as readCliVersion, u as installPlaygroundDependencies, v as getWebUrl, x as resolvePlatformUrlForWebUrl, y as DEFAULT_PLATFORM_URL } from "./version-DZ9lwyAW.mjs";
|
|
5
5
|
import { createRequire } from "node:module";
|
|
6
6
|
import { Command } from "commander";
|
|
7
7
|
import { basename, dirname, isAbsolute, join, relative, resolve } from "node:path";
|
|
8
8
|
import { Entry } from "@napi-rs/keyring";
|
|
9
|
-
import { confirm, input, select } from "@inquirer/prompts";
|
|
10
9
|
import { existsSync, lstatSync, mkdirSync, readFileSync, unlinkSync, writeFileSync } from "node:fs";
|
|
11
10
|
import { access, lstat, mkdir, readFile, readdir, rm, stat, symlink, writeFile } from "node:fs/promises";
|
|
12
11
|
import { spawn, spawnSync } from "node:child_process";
|
|
13
12
|
import { pathToFileURL } from "node:url";
|
|
13
|
+
import { confirm, input } from "@inquirer/prompts";
|
|
14
14
|
//#region ../../node_modules/.pnpm/ky@2.0.2/node_modules/ky/distribution/errors/KyError.js
|
|
15
15
|
/**
|
|
16
16
|
Base class for all Ky-specific errors. `HTTPError`, `NetworkError`, `TimeoutError`, and `ForceRetryError` extend this class.
|
|
@@ -3360,12 +3360,29 @@ function resolveCliAuth(config) {
|
|
|
3360
3360
|
};
|
|
3361
3361
|
}
|
|
3362
3362
|
//#endregion
|
|
3363
|
+
//#region src/target-options.ts
|
|
3364
|
+
let targetOptions = {};
|
|
3365
|
+
let resolvedOrganizationId;
|
|
3366
|
+
function setCliTargetOptions(options) {
|
|
3367
|
+
targetOptions = options;
|
|
3368
|
+
resolvedOrganizationId = void 0;
|
|
3369
|
+
}
|
|
3370
|
+
function getCliTargetOptions() {
|
|
3371
|
+
return targetOptions;
|
|
3372
|
+
}
|
|
3373
|
+
function setResolvedOrganizationId(organizationId) {
|
|
3374
|
+
resolvedOrganizationId = organizationId;
|
|
3375
|
+
}
|
|
3376
|
+
function getResolvedOrganizationId() {
|
|
3377
|
+
return resolvedOrganizationId;
|
|
3378
|
+
}
|
|
3379
|
+
//#endregion
|
|
3363
3380
|
//#region src/client.ts
|
|
3364
3381
|
function createCliClient(config, options) {
|
|
3365
3382
|
return createKeystrokeClient({
|
|
3366
3383
|
baseUrl: options.baseUrl,
|
|
3367
3384
|
auth: resolveCliAuth(config),
|
|
3368
|
-
getActiveOrganizationId: options.platform ? () =>
|
|
3385
|
+
getActiveOrganizationId: options.platform ? () => options.organizationId ?? getResolvedOrganizationId() ?? null : void 0
|
|
3369
3386
|
});
|
|
3370
3387
|
}
|
|
3371
3388
|
//#endregion
|
|
@@ -4458,6 +4475,44 @@ function createApiKeysResource(http) {
|
|
|
4458
4475
|
}
|
|
4459
4476
|
};
|
|
4460
4477
|
}
|
|
4478
|
+
function createManagedServiceCredentialsResource(http) {
|
|
4479
|
+
return {
|
|
4480
|
+
async list(kind) {
|
|
4481
|
+
try {
|
|
4482
|
+
const searchParams = kind ? { kind } : void 0;
|
|
4483
|
+
const data = await http.get("/api/managed-service-credentials", { searchParams }).json();
|
|
4484
|
+
return ListManagedServiceCredentialsResponseSchema.parse(data);
|
|
4485
|
+
} catch (error) {
|
|
4486
|
+
throw await toPlatformError(error);
|
|
4487
|
+
}
|
|
4488
|
+
},
|
|
4489
|
+
async connect(input) {
|
|
4490
|
+
const body = ConnectManagedServiceCredentialRequestSchema.parse(input);
|
|
4491
|
+
try {
|
|
4492
|
+
const data = await http.post("/api/managed-service-credentials", { json: body }).json();
|
|
4493
|
+
return ManagedServiceCredentialSchema.parse(data);
|
|
4494
|
+
} catch (error) {
|
|
4495
|
+
throw await toPlatformError(error);
|
|
4496
|
+
}
|
|
4497
|
+
},
|
|
4498
|
+
async update(id, input) {
|
|
4499
|
+
const body = UpdateManagedServiceCredentialRequestSchema.parse(input);
|
|
4500
|
+
try {
|
|
4501
|
+
const data = await http.patch(`/api/managed-service-credentials/${encodeURIComponent(id)}`, { json: body }).json();
|
|
4502
|
+
return ManagedServiceCredentialSchema.parse(data);
|
|
4503
|
+
} catch (error) {
|
|
4504
|
+
throw await toPlatformError(error);
|
|
4505
|
+
}
|
|
4506
|
+
},
|
|
4507
|
+
async disconnect(id) {
|
|
4508
|
+
try {
|
|
4509
|
+
await http.delete(`/api/managed-service-credentials/${encodeURIComponent(id)}`);
|
|
4510
|
+
} catch (error) {
|
|
4511
|
+
throw await toPlatformError(error);
|
|
4512
|
+
}
|
|
4513
|
+
}
|
|
4514
|
+
};
|
|
4515
|
+
}
|
|
4461
4516
|
function createBillingResource(http) {
|
|
4462
4517
|
return {
|
|
4463
4518
|
async summary() {
|
|
@@ -4793,6 +4848,7 @@ function createPlatformClient(options) {
|
|
|
4793
4848
|
const auth = options.auth ?? { type: "none" };
|
|
4794
4849
|
const base = normalizeBaseUrl(options.baseUrl);
|
|
4795
4850
|
let activeOrganizationId = options.getActiveOrganizationId?.() ?? null;
|
|
4851
|
+
const resolveActiveOrganizationId = () => options.getActiveOrganizationId?.() ?? activeOrganizationId;
|
|
4796
4852
|
const setActiveOrganizationId = (organizationId) => {
|
|
4797
4853
|
activeOrganizationId = organizationId;
|
|
4798
4854
|
options.onActiveOrganizationChange?.(organizationId);
|
|
@@ -4802,7 +4858,7 @@ function createPlatformClient(options) {
|
|
|
4802
4858
|
credentials: "omit",
|
|
4803
4859
|
hooks: {
|
|
4804
4860
|
beforeRequest: [({ request }) => {
|
|
4805
|
-
applyActiveOrganizationHeader(request,
|
|
4861
|
+
applyActiveOrganizationHeader(request, resolveActiveOrganizationId());
|
|
4806
4862
|
return applyAuthHeaders(request, auth);
|
|
4807
4863
|
}],
|
|
4808
4864
|
afterResponse: [async ({ request, response, retryCount }) => {
|
|
@@ -4825,7 +4881,7 @@ function createPlatformClient(options) {
|
|
|
4825
4881
|
health: createHealthResource(http),
|
|
4826
4882
|
organizations: createOrganizationsResource(http, {
|
|
4827
4883
|
onActiveOrganizationChange: setActiveOrganizationId,
|
|
4828
|
-
getActiveOrganizationId:
|
|
4884
|
+
getActiveOrganizationId: resolveActiveOrganizationId
|
|
4829
4885
|
}),
|
|
4830
4886
|
projects: createProjectsResource(http),
|
|
4831
4887
|
artifacts: createArtifactsResource(http),
|
|
@@ -4845,14 +4901,15 @@ function createPlatformClient(options) {
|
|
|
4845
4901
|
members: createMembersResource(http),
|
|
4846
4902
|
invitations: createInvitationsResource(http),
|
|
4847
4903
|
apiKeys: createApiKeysResource(http),
|
|
4904
|
+
managedServiceCredentials: createManagedServiceCredentialsResource(http),
|
|
4848
4905
|
billing: createBillingResource(http),
|
|
4849
4906
|
recents: createRecentsResource(http),
|
|
4850
4907
|
userPreferences: createUserPreferencesResource(http),
|
|
4851
4908
|
userAvatar: createUserAvatarResource(http),
|
|
4852
|
-
organizationSidebarBranding: createOrganizationSidebarBrandingResource(http, { getActiveOrganizationId:
|
|
4909
|
+
organizationSidebarBranding: createOrganizationSidebarBrandingResource(http, { getActiveOrganizationId: resolveActiveOrganizationId }),
|
|
4853
4910
|
teamRequests: createTeamRequestsResource(http),
|
|
4854
4911
|
marketingContact: createMarketingContactResource(http),
|
|
4855
|
-
getActiveOrganizationId:
|
|
4912
|
+
getActiveOrganizationId: resolveActiveOrganizationId,
|
|
4856
4913
|
setActiveOrganizationId
|
|
4857
4914
|
};
|
|
4858
4915
|
}
|
|
@@ -4866,17 +4923,13 @@ function toPlatformAuth(auth) {
|
|
|
4866
4923
|
};
|
|
4867
4924
|
return { type: "none" };
|
|
4868
4925
|
}
|
|
4869
|
-
function createCliPlatformClient(config) {
|
|
4926
|
+
function createCliPlatformClient(config, options = {}) {
|
|
4870
4927
|
const platformUrl = getPlatformUrl(config);
|
|
4871
4928
|
return createPlatformClient({
|
|
4872
4929
|
baseUrl: platformUrl,
|
|
4873
4930
|
auth: toPlatformAuth(resolveCliAuth(config)),
|
|
4874
4931
|
refreshBearerToken: () => getCliJwt(platformUrl, true),
|
|
4875
|
-
getActiveOrganizationId: () =>
|
|
4876
|
-
onActiveOrganizationChange: (organizationId) => {
|
|
4877
|
-
if (organizationId) config.set("activeOrganizationId", organizationId);
|
|
4878
|
-
else config.delete("activeOrganizationId");
|
|
4879
|
-
}
|
|
4932
|
+
getActiveOrganizationId: () => options.organizationId === void 0 ? getResolvedOrganizationId() ?? null : options.organizationId
|
|
4880
4933
|
});
|
|
4881
4934
|
}
|
|
4882
4935
|
//#endregion
|
|
@@ -4908,71 +4961,9 @@ function resolveOrganizationRef(organizations, ref) {
|
|
|
4908
4961
|
}
|
|
4909
4962
|
//#endregion
|
|
4910
4963
|
//#region src/organization/active-organization.ts
|
|
4911
|
-
function formatOrganization(membership) {
|
|
4912
|
-
return `${membership.organization.name} (${membership.role})`;
|
|
4913
|
-
}
|
|
4914
4964
|
async function listOrganizations(config) {
|
|
4915
4965
|
return createCliPlatformClient(config).organizations.list();
|
|
4916
4966
|
}
|
|
4917
|
-
async function activateOrganization(config, organizationId) {
|
|
4918
|
-
const platform = createCliPlatformClient(config);
|
|
4919
|
-
const membership = await platform.organizations.setActive({ organizationId });
|
|
4920
|
-
platform.setActiveOrganizationId(membership.organization.id);
|
|
4921
|
-
return membership;
|
|
4922
|
-
}
|
|
4923
|
-
function resolveOrganizationIdForLogin(organizations, options = {}) {
|
|
4924
|
-
if (options.organizationRef ?? options.organizationId) return resolveOrganizationRef(organizations, options.organizationRef ?? options.organizationId).organization.id;
|
|
4925
|
-
for (const candidateId of [options.deviceOrganizationId, options.storedOrganizationId]) {
|
|
4926
|
-
const organizationId = candidateId?.trim();
|
|
4927
|
-
if (organizationId && organizations.some((entry) => entry.organization.id === organizationId)) return organizationId;
|
|
4928
|
-
}
|
|
4929
|
-
if (organizations.length === 1) return organizations[0].organization.id;
|
|
4930
|
-
return [...organizations].sort((left, right) => left.organization.slug.localeCompare(right.organization.slug))[0].organization.id;
|
|
4931
|
-
}
|
|
4932
|
-
async function pickOrganization(config, organizations, organizationRef) {
|
|
4933
|
-
if (organizationRef) return activateOrganization(config, resolveOrganizationRef(organizations, organizationRef).organization.id);
|
|
4934
|
-
if (!process.stdin.isTTY) {
|
|
4935
|
-
const names = organizations.map((entry) => entry.organization.slug).join(", ");
|
|
4936
|
-
throw new Error(`Multiple organizations found. Run \`keystroke config use org <slug>\`. Options: ${names}`);
|
|
4937
|
-
}
|
|
4938
|
-
return activateOrganization(config, await select({
|
|
4939
|
-
message: "Select an organization",
|
|
4940
|
-
choices: organizations.map((entry) => ({
|
|
4941
|
-
name: formatOrganization(entry),
|
|
4942
|
-
value: entry.organization.id
|
|
4943
|
-
}))
|
|
4944
|
-
}));
|
|
4945
|
-
}
|
|
4946
|
-
async function selectActiveOrganization(config, options = {}) {
|
|
4947
|
-
const organizations = await listOrganizations(config);
|
|
4948
|
-
if (organizations.length === 0) throw new Error(`No organization found — create one at ${getWebUrl(config)}`);
|
|
4949
|
-
if (organizations.length === 1) return activateOrganization(config, organizations[0].organization.id);
|
|
4950
|
-
return pickOrganization(config, organizations, options.organizationRef ?? options.organizationId);
|
|
4951
|
-
}
|
|
4952
|
-
async function syncActiveOrganizationAfterLogin(config, options = {}) {
|
|
4953
|
-
const organizations = await listOrganizations(config);
|
|
4954
|
-
if (organizations.length === 0) throw new Error(`No organization found — create one at ${getWebUrl(config)}`);
|
|
4955
|
-
return activateOrganization(config, resolveOrganizationIdForLogin(organizations, {
|
|
4956
|
-
organizationRef: options.organizationRef,
|
|
4957
|
-
organizationId: options.organizationId,
|
|
4958
|
-
deviceOrganizationId: options.deviceOrganizationId,
|
|
4959
|
-
storedOrganizationId: config.get("activeOrganizationId")
|
|
4960
|
-
}));
|
|
4961
|
-
}
|
|
4962
|
-
async function ensureActiveOrganization(config) {
|
|
4963
|
-
const organizations = await listOrganizations(config);
|
|
4964
|
-
if (organizations.length === 0) throw new Error("No organization found. Run `keystroke auth login` after creating one in the dashboard.");
|
|
4965
|
-
const storedId = config.get("activeOrganizationId");
|
|
4966
|
-
if (storedId && organizations.some((entry) => entry.organization.id === storedId)) {
|
|
4967
|
-
await activateOrganization(config, storedId);
|
|
4968
|
-
return;
|
|
4969
|
-
}
|
|
4970
|
-
if (organizations.length === 1) {
|
|
4971
|
-
await activateOrganization(config, organizations[0].organization.id);
|
|
4972
|
-
return;
|
|
4973
|
-
}
|
|
4974
|
-
throw new Error("No active organization. Run `keystroke auth login` or `keystroke config use org`.");
|
|
4975
|
-
}
|
|
4976
4967
|
//#endregion
|
|
4977
4968
|
//#region src/project/resolve-keystroke-config-root.ts
|
|
4978
4969
|
const KEYSTROKE_CONFIG$2 = "keystroke.config.ts";
|
|
@@ -4987,6 +4978,71 @@ function resolveKeystrokeConfigRoot(fromDir = process.cwd()) {
|
|
|
4987
4978
|
return null;
|
|
4988
4979
|
}
|
|
4989
4980
|
//#endregion
|
|
4981
|
+
//#region src/project/read-project-config.ts
|
|
4982
|
+
const KEYSTROKE_CONFIG$1 = "keystroke.config.ts";
|
|
4983
|
+
/** Remove line and block comments before scanning config literals. */
|
|
4984
|
+
function stripConfigComments(source) {
|
|
4985
|
+
return source.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
4986
|
+
}
|
|
4987
|
+
/** Mask comments while preserving string length so match indices stay aligned. */
|
|
4988
|
+
function stripConfigCommentsPreservingLength(source) {
|
|
4989
|
+
return source.replace(/\/\/[^\n]*/g, (match) => " ".repeat(match.length)).replace(/\/\*[\s\S]*?\*\//g, (match) => " ".repeat(match.length));
|
|
4990
|
+
}
|
|
4991
|
+
function readStringLiteral(source, key) {
|
|
4992
|
+
const stripped = stripConfigComments(source);
|
|
4993
|
+
const pattern = new RegExp(`\\b${key}\\s*:\\s*(['"])([^'"]*)\\1`);
|
|
4994
|
+
return stripped.match(pattern)?.[2]?.trim() || void 0;
|
|
4995
|
+
}
|
|
4996
|
+
function parseLinkedProjectConfig(source) {
|
|
4997
|
+
const project = readStringLiteral(source, "project");
|
|
4998
|
+
const organization = readStringLiteral(source, "organization");
|
|
4999
|
+
return {
|
|
5000
|
+
...project ? { project } : {},
|
|
5001
|
+
...organization ? { organization } : {}
|
|
5002
|
+
};
|
|
5003
|
+
}
|
|
5004
|
+
/** Read optional project/organization slugs from keystroke.config.ts without executing it. */
|
|
5005
|
+
function readLinkedProjectConfig(fromDir = process.cwd()) {
|
|
5006
|
+
const root = resolveKeystrokeConfigRoot(fromDir);
|
|
5007
|
+
if (!root) return {};
|
|
5008
|
+
return parseLinkedProjectConfig(readFileSync(join(root, KEYSTROKE_CONFIG$1), "utf8"));
|
|
5009
|
+
}
|
|
5010
|
+
//#endregion
|
|
5011
|
+
//#region src/target-hints.ts
|
|
5012
|
+
function missingOrganizationRefMessage() {
|
|
5013
|
+
return "No organization selected. Pass `--organization <slug>` or set `organization` in keystroke.config.ts (via `keystroke projects link --project <slug>`).";
|
|
5014
|
+
}
|
|
5015
|
+
function missingProjectRefMessage() {
|
|
5016
|
+
return "No project selected. Pass `--project <slug>` or set `project` in keystroke.config.ts (via `keystroke projects link --project <slug>`).";
|
|
5017
|
+
}
|
|
5018
|
+
function missingOrganizationRefError() {
|
|
5019
|
+
return new Error(missingOrganizationRefMessage());
|
|
5020
|
+
}
|
|
5021
|
+
function missingProjectRefError() {
|
|
5022
|
+
return new Error(missingProjectRefMessage());
|
|
5023
|
+
}
|
|
5024
|
+
//#endregion
|
|
5025
|
+
//#region src/resolve-organization-target.ts
|
|
5026
|
+
/**
|
|
5027
|
+
* The active organization reference for the current command: the explicit global
|
|
5028
|
+
* `--organization` flag when set, otherwise the `organization` recorded in
|
|
5029
|
+
* keystroke.config.ts. Single source of truth for "which organization" across
|
|
5030
|
+
* every CLI command — commands should never read the flag or linked config directly.
|
|
5031
|
+
*/
|
|
5032
|
+
function resolveActiveOrganizationRef(fromDir = process.cwd()) {
|
|
5033
|
+
return (getCliTargetOptions().organizationRef ?? readLinkedProjectConfig(fromDir).organization)?.trim() || void 0;
|
|
5034
|
+
}
|
|
5035
|
+
/** Resolve the active organization slug to a membership and cache its id for platform requests. */
|
|
5036
|
+
async function resolveActiveOrganization(config, fromDir = process.cwd()) {
|
|
5037
|
+
const ref = resolveActiveOrganizationRef(fromDir);
|
|
5038
|
+
if (!ref) throw missingOrganizationRefError();
|
|
5039
|
+
const organizations = await listOrganizations(config);
|
|
5040
|
+
if (organizations.length === 0) throw new Error(`No organization found — create one at ${getWebUrl(config)}`);
|
|
5041
|
+
const membership = resolveOrganizationRef(organizations, ref);
|
|
5042
|
+
setResolvedOrganizationId(membership.organization.id);
|
|
5043
|
+
return membership;
|
|
5044
|
+
}
|
|
5045
|
+
//#endregion
|
|
4990
5046
|
//#region src/project/resolve-project-root.ts
|
|
4991
5047
|
function resolveProjectRoot(fromDir = process.cwd()) {
|
|
4992
5048
|
const root = resolveKeystrokeConfigRoot(fromDir);
|
|
@@ -5060,71 +5116,6 @@ function readDevSession(configDir = getCliConfigDir()) {
|
|
|
5060
5116
|
}
|
|
5061
5117
|
}
|
|
5062
5118
|
//#endregion
|
|
5063
|
-
//#region src/project/read-project-config.ts
|
|
5064
|
-
const KEYSTROKE_CONFIG$1 = "keystroke.config.ts";
|
|
5065
|
-
/** Remove line and block comments before scanning config literals. */
|
|
5066
|
-
function stripConfigComments(source) {
|
|
5067
|
-
return source.replace(/\/\/[^\n]*/g, "").replace(/\/\*[\s\S]*?\*\//g, "");
|
|
5068
|
-
}
|
|
5069
|
-
/** Mask comments while preserving string length so match indices stay aligned. */
|
|
5070
|
-
function stripConfigCommentsPreservingLength(source) {
|
|
5071
|
-
return source.replace(/\/\/[^\n]*/g, (match) => " ".repeat(match.length)).replace(/\/\*[\s\S]*?\*\//g, (match) => " ".repeat(match.length));
|
|
5072
|
-
}
|
|
5073
|
-
function readStringLiteral(source, key) {
|
|
5074
|
-
const stripped = stripConfigComments(source);
|
|
5075
|
-
const pattern = new RegExp(`\\b${key}\\s*:\\s*(['"])([^'"]*)\\1`);
|
|
5076
|
-
return stripped.match(pattern)?.[2]?.trim() || void 0;
|
|
5077
|
-
}
|
|
5078
|
-
function parseLinkedProjectConfig(source) {
|
|
5079
|
-
const project = readStringLiteral(source, "project");
|
|
5080
|
-
const organization = readStringLiteral(source, "organization");
|
|
5081
|
-
return {
|
|
5082
|
-
...project ? { project } : {},
|
|
5083
|
-
...organization ? { organization } : {}
|
|
5084
|
-
};
|
|
5085
|
-
}
|
|
5086
|
-
/** Read optional project/organization slugs from keystroke.config.ts without executing it. */
|
|
5087
|
-
function readLinkedProjectConfig(fromDir = process.cwd()) {
|
|
5088
|
-
const root = resolveKeystrokeConfigRoot(fromDir);
|
|
5089
|
-
if (!root) return {};
|
|
5090
|
-
return parseLinkedProjectConfig(readFileSync(join(root, KEYSTROKE_CONFIG$1), "utf8"));
|
|
5091
|
-
}
|
|
5092
|
-
//#endregion
|
|
5093
|
-
//#region src/target-options.ts
|
|
5094
|
-
let targetOptions = {};
|
|
5095
|
-
function setCliTargetOptions(options) {
|
|
5096
|
-
targetOptions = options;
|
|
5097
|
-
}
|
|
5098
|
-
function getCliTargetOptions() {
|
|
5099
|
-
return targetOptions;
|
|
5100
|
-
}
|
|
5101
|
-
//#endregion
|
|
5102
|
-
//#region src/resolve-project-target.ts
|
|
5103
|
-
/**
|
|
5104
|
-
* The active project reference for the current command: the explicit global
|
|
5105
|
-
* `--project` flag when set, otherwise the `project` recorded in
|
|
5106
|
-
* keystroke.config.ts. Single source of truth for "which project" across every
|
|
5107
|
-
* CLI command — commands should never read the flag or linked config directly.
|
|
5108
|
-
*/
|
|
5109
|
-
function resolveActiveProjectRef(fromDir = process.cwd()) {
|
|
5110
|
-
return (getCliTargetOptions().projectId ?? readLinkedProjectConfig(fromDir).project)?.trim() || void 0;
|
|
5111
|
-
}
|
|
5112
|
-
/** Activate the organization slug from keystroke.config.ts when present. */
|
|
5113
|
-
async function ensureLinkedOrganization(config, fromDir = process.cwd()) {
|
|
5114
|
-
const linked = readLinkedProjectConfig(fromDir);
|
|
5115
|
-
if (!linked.organization) return;
|
|
5116
|
-
await activateOrganization(config, resolveOrganizationRef(await listOrganizations(config), linked.organization).organization.id);
|
|
5117
|
-
}
|
|
5118
|
-
async function resolveActiveProject(config, platform, fromDir = process.cwd()) {
|
|
5119
|
-
const ref = resolveActiveProjectRef(fromDir);
|
|
5120
|
-
if (!ref) return;
|
|
5121
|
-
await ensureLinkedOrganization(config, fromDir);
|
|
5122
|
-
return resolveProjectRef(platform ?? createCliPlatformClient(config), ref);
|
|
5123
|
-
}
|
|
5124
|
-
async function resolveActiveProjectId(config, fromDir = process.cwd()) {
|
|
5125
|
-
return (await resolveActiveProject(config, void 0, fromDir))?.id;
|
|
5126
|
-
}
|
|
5127
|
-
//#endregion
|
|
5128
5119
|
//#region src/resolve-api-target.ts
|
|
5129
5120
|
/** Standalone local server default project id — keep in sync with @keystrokehq/database. */
|
|
5130
5121
|
const DEFAULT_LOCAL_PROJECT_ID = "default";
|
|
@@ -5157,7 +5148,7 @@ function resolveOrgPlatformTarget(config) {
|
|
|
5157
5148
|
};
|
|
5158
5149
|
}
|
|
5159
5150
|
async function resolvePlatformTarget(config, projectRef) {
|
|
5160
|
-
await
|
|
5151
|
+
await resolveActiveOrganization(config);
|
|
5161
5152
|
const platform = createCliPlatformClient(config);
|
|
5162
5153
|
let project;
|
|
5163
5154
|
try {
|
|
@@ -5186,7 +5177,7 @@ async function resolveApiTarget(config, options = {}) {
|
|
|
5186
5177
|
if (getEffectiveApiTarget(config) === "local") return resolveLocalTarget(options);
|
|
5187
5178
|
if (!options.projectScoped) return resolveOrgPlatformTarget(config);
|
|
5188
5179
|
const projectRef = options.projectId ?? readLinkedProjectConfig().project;
|
|
5189
|
-
if (!projectRef) throw
|
|
5180
|
+
if (!projectRef) throw missingProjectRefError();
|
|
5190
5181
|
return resolvePlatformTarget(config, projectRef);
|
|
5191
5182
|
}
|
|
5192
5183
|
//#endregion
|
|
@@ -5284,7 +5275,7 @@ function formatCliError(error, fallback, context) {
|
|
|
5284
5275
|
//#region src/errors/run-command.ts
|
|
5285
5276
|
/**
|
|
5286
5277
|
* Run a command that needs no project/org target or auth (e.g. public docs).
|
|
5287
|
-
* Builds config and formats errors, but skips `resolveApiTarget` /
|
|
5278
|
+
* Builds config and formats errors, but skips `resolveApiTarget` / organization resolution,
|
|
5288
5279
|
* so it works logged-out from any directory.
|
|
5289
5280
|
*/
|
|
5290
5281
|
async function runStandaloneCliCommand(fallback, fn, errorContext) {
|
|
@@ -5311,12 +5302,14 @@ async function runCliCommand(fallback, fn, errorContext, targetOptions = {}) {
|
|
|
5311
5302
|
...getCliTargetOptions(),
|
|
5312
5303
|
...targetOptions
|
|
5313
5304
|
});
|
|
5314
|
-
|
|
5305
|
+
let organizationId;
|
|
5306
|
+
if (target.mode === "platform") organizationId = (await resolveActiveOrganization(config)).organization.id;
|
|
5315
5307
|
const ctx = {
|
|
5316
5308
|
config,
|
|
5317
5309
|
client: createCliClient(config, {
|
|
5318
5310
|
baseUrl: target.baseUrl,
|
|
5319
|
-
platform: target.mode === "platform"
|
|
5311
|
+
platform: target.mode === "platform",
|
|
5312
|
+
organizationId
|
|
5320
5313
|
}),
|
|
5321
5314
|
serverUrl: target.baseUrl,
|
|
5322
5315
|
webUrl: getWebUrl(config),
|
|
@@ -5354,9 +5347,28 @@ function parseJsonOption(value, flag) {
|
|
|
5354
5347
|
//#endregion
|
|
5355
5348
|
//#region src/organization/require-admin-role.ts
|
|
5356
5349
|
async function requireAdminRole(config) {
|
|
5357
|
-
await
|
|
5358
|
-
|
|
5359
|
-
|
|
5350
|
+
const membership = await resolveActiveOrganization(config);
|
|
5351
|
+
if (membership.role !== "owner" && membership.role !== "admin") throw new Error("--admin requires org owner or admin");
|
|
5352
|
+
}
|
|
5353
|
+
//#endregion
|
|
5354
|
+
//#region src/resolve-project-target.ts
|
|
5355
|
+
/**
|
|
5356
|
+
* The active project reference for the current command: the explicit global
|
|
5357
|
+
* `--project` flag when set, otherwise the `project` recorded in
|
|
5358
|
+
* keystroke.config.ts. Single source of truth for "which project" across every
|
|
5359
|
+
* CLI command — commands should never read the flag or linked config directly.
|
|
5360
|
+
*/
|
|
5361
|
+
function resolveActiveProjectRef(fromDir = process.cwd()) {
|
|
5362
|
+
return (getCliTargetOptions().projectId ?? readLinkedProjectConfig(fromDir).project)?.trim() || void 0;
|
|
5363
|
+
}
|
|
5364
|
+
async function resolveActiveProject(config, platform, fromDir = process.cwd()) {
|
|
5365
|
+
const ref = resolveActiveProjectRef(fromDir);
|
|
5366
|
+
if (!ref) return;
|
|
5367
|
+
await resolveActiveOrganization(config, fromDir);
|
|
5368
|
+
return resolveProjectRef(platform ?? createCliPlatformClient(config), ref);
|
|
5369
|
+
}
|
|
5370
|
+
async function resolveActiveProjectId(config, fromDir = process.cwd()) {
|
|
5371
|
+
return (await resolveActiveProject(config, void 0, fromDir))?.id;
|
|
5360
5372
|
}
|
|
5361
5373
|
//#endregion
|
|
5362
5374
|
//#region src/commands/agents/list.ts
|
|
@@ -5364,7 +5376,7 @@ function registerAgentListCommand(agent) {
|
|
|
5364
5376
|
agent.command("list").description("List agents in the active organization").option("--admin", "List all org resources (org owner or admin only)").action((options) => runCliCommand("List agents failed", async () => {
|
|
5365
5377
|
const config = createCliConfig();
|
|
5366
5378
|
const client = createCliPlatformClient(config);
|
|
5367
|
-
await
|
|
5379
|
+
await resolveActiveOrganization(config);
|
|
5368
5380
|
if (options.admin) await requireAdminRole(config);
|
|
5369
5381
|
const projectId = await resolveActiveProjectId(config);
|
|
5370
5382
|
const result = await client.agents.list({
|
|
@@ -5387,13 +5399,9 @@ function registerAgentPromptCommand(agent) {
|
|
|
5387
5399
|
}
|
|
5388
5400
|
//#endregion
|
|
5389
5401
|
//#region src/commands/projects/run-project.ts
|
|
5390
|
-
async function withActivePlatformClient(config, fn, fromDir = process.cwd()
|
|
5391
|
-
|
|
5392
|
-
|
|
5393
|
-
let active = await platform.organizations.getActive();
|
|
5394
|
-
if (!active) active = await selectActiveOrganization(config);
|
|
5395
|
-
platform.setActiveOrganizationId(active.organization.id);
|
|
5396
|
-
await fn(platform);
|
|
5402
|
+
async function withActivePlatformClient(config, fn, fromDir = process.cwd()) {
|
|
5403
|
+
await resolveActiveOrganization(config, fromDir);
|
|
5404
|
+
await fn(createCliPlatformClient(config));
|
|
5397
5405
|
}
|
|
5398
5406
|
function writeInactiveDeployHints(projects) {
|
|
5399
5407
|
const bin = cliBinaryName();
|
|
@@ -5558,6 +5566,85 @@ function registerApiKeyCommand(program) {
|
|
|
5558
5566
|
});
|
|
5559
5567
|
}
|
|
5560
5568
|
//#endregion
|
|
5569
|
+
//#region src/commands/managed-services/run-managed-services.ts
|
|
5570
|
+
async function runManagedServicesList(config, kind = "llm") {
|
|
5571
|
+
await withActivePlatformClient(config, async (platform) => {
|
|
5572
|
+
const managedServices = await platform.managedServiceCredentials.list(kind);
|
|
5573
|
+
process.stdout.write(`${JSON.stringify({ managedServices }, null, 2)}\n`);
|
|
5574
|
+
});
|
|
5575
|
+
}
|
|
5576
|
+
async function runManagedServicesConnect(config, input) {
|
|
5577
|
+
await withActivePlatformClient(config, async (platform) => {
|
|
5578
|
+
const managedService = await platform.managedServiceCredentials.connect(input);
|
|
5579
|
+
process.stdout.write(`${JSON.stringify({ managedService }, null, 2)}\n`);
|
|
5580
|
+
});
|
|
5581
|
+
}
|
|
5582
|
+
async function runManagedServicesUpdate(config, provider, input, kind = "llm") {
|
|
5583
|
+
await withActivePlatformClient(config, async (platform) => {
|
|
5584
|
+
const existing = (await platform.managedServiceCredentials.list(kind)).find((entry) => entry.provider === provider);
|
|
5585
|
+
if (!existing) throw new Error(`No managed service credential connected for provider "${provider}"`);
|
|
5586
|
+
const managedService = await platform.managedServiceCredentials.update(existing.id, input);
|
|
5587
|
+
process.stdout.write(`${JSON.stringify({ managedService }, null, 2)}\n`);
|
|
5588
|
+
});
|
|
5589
|
+
}
|
|
5590
|
+
async function runManagedServicesDisconnect(config, provider, kind = "llm") {
|
|
5591
|
+
await withActivePlatformClient(config, async (platform) => {
|
|
5592
|
+
const existing = (await platform.managedServiceCredentials.list(kind)).find((entry) => entry.provider === provider);
|
|
5593
|
+
if (!existing) throw new Error(`No managed service credential connected for provider "${provider}"`);
|
|
5594
|
+
await platform.managedServiceCredentials.disconnect(existing.id);
|
|
5595
|
+
process.stdout.write(`${JSON.stringify({ disconnected: provider }, null, 2)}\n`);
|
|
5596
|
+
});
|
|
5597
|
+
}
|
|
5598
|
+
//#endregion
|
|
5599
|
+
//#region src/commands/managed-services/index.ts
|
|
5600
|
+
async function handleManagedServicesError(fallback, action) {
|
|
5601
|
+
const config = createCliConfig();
|
|
5602
|
+
try {
|
|
5603
|
+
await action();
|
|
5604
|
+
} catch (error) {
|
|
5605
|
+
process.stderr.write(`${formatCliError(error, fallback, {
|
|
5606
|
+
serverUrl: getPlatformUrl(config),
|
|
5607
|
+
webUrl: getWebUrl(config)
|
|
5608
|
+
})}\n`);
|
|
5609
|
+
process.exitCode = 1;
|
|
5610
|
+
}
|
|
5611
|
+
}
|
|
5612
|
+
function registerManagedServicesCommand(program) {
|
|
5613
|
+
const managedServices = program.command("managed-services").description("Manage organization managed service credentials");
|
|
5614
|
+
managedServices.command("list").description("List connected managed service credentials").option("--kind <kind>", "Managed service kind", "llm").action(async (options) => {
|
|
5615
|
+
const config = createCliConfig();
|
|
5616
|
+
const kind = ManagedServiceKindSchema.parse(options.kind);
|
|
5617
|
+
await handleManagedServicesError("List managed services failed", async () => {
|
|
5618
|
+
await runManagedServicesList(config, kind);
|
|
5619
|
+
});
|
|
5620
|
+
});
|
|
5621
|
+
managedServices.command("connect").description("Connect a managed service provider with your API key").argument("<provider>", "Provider slug (openai, anthropic, google, groq, xai)").requiredOption("--api-key <key>", "Provider API key").option("--kind <kind>", "Managed service kind", "llm").action(async (provider, options) => {
|
|
5622
|
+
const config = createCliConfig();
|
|
5623
|
+
const kind = ManagedServiceKindSchema.parse(options.kind);
|
|
5624
|
+
await handleManagedServicesError("Connect managed service failed", async () => {
|
|
5625
|
+
await runManagedServicesConnect(config, {
|
|
5626
|
+
kind,
|
|
5627
|
+
provider,
|
|
5628
|
+
apiKey: options.apiKey
|
|
5629
|
+
});
|
|
5630
|
+
});
|
|
5631
|
+
});
|
|
5632
|
+
managedServices.command("update").description("Rotate the API key for a connected provider").argument("<provider>", "Provider slug (openai, anthropic, google, groq, xai)").requiredOption("--api-key <key>", "Provider API key").option("--kind <kind>", "Managed service kind", "llm").action(async (provider, options) => {
|
|
5633
|
+
const config = createCliConfig();
|
|
5634
|
+
const kind = ManagedServiceKindSchema.parse(options.kind);
|
|
5635
|
+
await handleManagedServicesError("Update managed service failed", async () => {
|
|
5636
|
+
await runManagedServicesUpdate(config, provider, { apiKey: options.apiKey }, kind);
|
|
5637
|
+
});
|
|
5638
|
+
});
|
|
5639
|
+
managedServices.command("disconnect").description("Disconnect a managed service provider").argument("<provider>", "Provider slug (openai, anthropic, google, groq, xai)").option("--kind <kind>", "Managed service kind", "llm").action(async (provider, options) => {
|
|
5640
|
+
const config = createCliConfig();
|
|
5641
|
+
const kind = ManagedServiceKindSchema.parse(options.kind);
|
|
5642
|
+
await handleManagedServicesError("Disconnect managed service failed", async () => {
|
|
5643
|
+
await runManagedServicesDisconnect(config, provider, kind);
|
|
5644
|
+
});
|
|
5645
|
+
});
|
|
5646
|
+
}
|
|
5647
|
+
//#endregion
|
|
5561
5648
|
//#region src/commands/apps/action-hints.ts
|
|
5562
5649
|
function toCamelCase(value) {
|
|
5563
5650
|
const pascal = value.split(/[^a-zA-Z0-9]+/).filter(Boolean).map((part) => part.charAt(0).toUpperCase() + part.slice(1).toLowerCase()).join("");
|
|
@@ -5574,15 +5661,49 @@ function actionExportName(app, tool) {
|
|
|
5574
5661
|
function actionImportHint(app, tool) {
|
|
5575
5662
|
return `import { ${actionExportName(app, tool)} } from "@keystrokehq/${app.toLowerCase()}/actions"`;
|
|
5576
5663
|
}
|
|
5664
|
+
function placeholderValue(prop) {
|
|
5665
|
+
if (prop.default !== void 0) return JSON.stringify(prop.default);
|
|
5666
|
+
if (prop.enum?.length) return JSON.stringify(prop.enum[0]);
|
|
5667
|
+
switch (prop.type) {
|
|
5668
|
+
case "number":
|
|
5669
|
+
case "integer": return "0";
|
|
5670
|
+
case "boolean": return "false";
|
|
5671
|
+
case "array": return "[]";
|
|
5672
|
+
case "object": return "{}";
|
|
5673
|
+
default: return "\"\"";
|
|
5674
|
+
}
|
|
5675
|
+
}
|
|
5676
|
+
function propertyKey(key) {
|
|
5677
|
+
return /^[A-Za-z_$][A-Za-z0-9_$]*$/.test(key) ? key : JSON.stringify(key);
|
|
5678
|
+
}
|
|
5679
|
+
/**
|
|
5680
|
+
* Example typed `run()` call built from the action's input JSON Schema. Lists fields the
|
|
5681
|
+
* call type requires — schema-required fields plus defaulted ones (a `.default()` input
|
|
5682
|
+
* is still required at the `run()` call site) — and counts the rest as optional.
|
|
5683
|
+
*/
|
|
5684
|
+
function actionRunSnippet(app, tool, inputParameters) {
|
|
5685
|
+
const schema = inputParameters ?? {};
|
|
5686
|
+
const properties = schema.properties ?? {};
|
|
5687
|
+
const required = new Set(schema.required ?? []);
|
|
5688
|
+
const included = Object.entries(properties).filter(([key, prop]) => required.has(key) || prop.default !== void 0);
|
|
5689
|
+
const optionalCount = Object.keys(properties).length - included.length;
|
|
5690
|
+
const fieldLines = included.map(([key, prop]) => {
|
|
5691
|
+
const comments = [prop.type ?? "unknown", prop.default !== void 0 ? "has default" : ""];
|
|
5692
|
+
return ` ${propertyKey(key)}: ${placeholderValue(prop)}, // ${comments.filter(Boolean).join(", ")}`;
|
|
5693
|
+
});
|
|
5694
|
+
if (optionalCount > 0) fieldLines.push(` // +${optionalCount} optional field${optionalCount === 1 ? "" : "s"}`);
|
|
5695
|
+
const args = fieldLines.length > 0 ? `{\n${fieldLines.join("\n")}\n}` : "{}";
|
|
5696
|
+
return `${actionImportHint(app, tool)};\n\nconst result = await ${actionExportName(app, tool)}.run(${args});`;
|
|
5697
|
+
}
|
|
5577
5698
|
/** Next-step hint printed after listing an app's actions. */
|
|
5578
5699
|
function listActionsHint(app) {
|
|
5579
5700
|
const bin = cliBinaryName();
|
|
5580
5701
|
return `\nNext steps:\n Inspect a tool: ${bin} apps actions get ${app} <TOOL_SLUG>\n Run a tool: ${bin} apps execute ${app} <TOOL_SLUG> --input '{...}'\n`;
|
|
5581
5702
|
}
|
|
5582
5703
|
/** Next-step hint printed after showing one action's schema. */
|
|
5583
|
-
function showActionHint(app, tool) {
|
|
5704
|
+
function showActionHint(app, tool, inputParameters) {
|
|
5584
5705
|
const bin = cliBinaryName();
|
|
5585
|
-
return `\nNext steps:\n Run ad-hoc: ${bin} apps execute ${app} ${tool} --input '{...}'\n
|
|
5706
|
+
return `\nNext steps:\n Run ad-hoc: ${bin} apps execute ${app} ${tool} --input '{...}'\n Not connected? ${bin} connect ${app}\n\nUse in code:\n\n${actionRunSnippet(app, tool, inputParameters)}\n`;
|
|
5586
5707
|
}
|
|
5587
5708
|
//#endregion
|
|
5588
5709
|
//#region src/commands/apps/run-app-catalog.ts
|
|
@@ -5628,7 +5749,7 @@ function registerAppActionsCommands(app) {
|
|
|
5628
5749
|
actions.command("list").description("List or search a catalog app's actions").argument("[slug]", "App slug (omit for cross-app search with --search)").option("--search <query>", "Search actions within the app or across all apps").option("--limit <n>", "Page size", (value) => Number.parseInt(value, 10)).option("--cursor <cursor>", "Pagination cursor").action((slug, options) => runCliCommand("App actions list failed", async () => {
|
|
5629
5750
|
const config = createCliConfig();
|
|
5630
5751
|
const client = createCliPlatformClient(config);
|
|
5631
|
-
await
|
|
5752
|
+
await resolveActiveOrganization(config);
|
|
5632
5753
|
const result = await runAppActions(client, {
|
|
5633
5754
|
slug,
|
|
5634
5755
|
...options
|
|
@@ -5639,10 +5760,10 @@ function registerAppActionsCommands(app) {
|
|
|
5639
5760
|
actions.command("get").description("Get a catalog action schema, plus how to run and import it").argument("<app>", "App slug (e.g. github)").argument("<tool>", "Tool slug (e.g. github_create_an_issue)").action((appSlug, toolSlug) => runCliCommand("App action get failed", async () => {
|
|
5640
5761
|
const config = createCliConfig();
|
|
5641
5762
|
const client = createCliPlatformClient(config);
|
|
5642
|
-
await
|
|
5763
|
+
await resolveActiveOrganization(config);
|
|
5643
5764
|
const result = await runAppAction(client, toolSlug);
|
|
5644
5765
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
5645
|
-
process.stderr.write(showActionHint(appSlug.trim().toLowerCase(), toolSlug.trim().toUpperCase()));
|
|
5766
|
+
process.stderr.write(showActionHint(appSlug.trim().toLowerCase(), toolSlug.trim().toUpperCase(), result.inputParameters));
|
|
5646
5767
|
}, void 0, { orgScoped: true }));
|
|
5647
5768
|
}
|
|
5648
5769
|
//#endregion
|
|
@@ -5761,7 +5882,7 @@ function registerAppCreateCommand(app) {
|
|
|
5761
5882
|
app.command("create").description("Create a custom org app").option("--name <name>", "App display name").option("--slug <slug>", "App slug segment (defaults from name)").option("--description <description>", "App description").option("--field <field>", "Credential field as key, key:secret, key:optional, or key:secret:optional (repeatable)", collectValues$1, []).option("--mcp <url>", "Create from an MCP server URL (auto-detect auth)").option("--openapi <url>", "Create from an OpenAPI spec URL (auto-detect auth)").option("--graphql <url>", "Create from a GraphQL endpoint URL (auto-detect auth)").option("--auth <kind>", "Override detected auth: oauth or api_key (MCP only)").option("--preview", "Show the request that would be created without creating").action((options) => runCliCommand("Create app failed", async () => {
|
|
5762
5883
|
const config = createCliConfig();
|
|
5763
5884
|
const client = createCliPlatformClient(config);
|
|
5764
|
-
await
|
|
5885
|
+
await resolveActiveOrganization(config);
|
|
5765
5886
|
const discovery = resolveDiscoverSource(options);
|
|
5766
5887
|
if (discovery) {
|
|
5767
5888
|
const result = await runAppCreateFromUrl(client, {
|
|
@@ -5837,7 +5958,7 @@ Examples:
|
|
|
5837
5958
|
`).action((appSlug, toolSlug, options) => runCliCommand("App execute failed", async () => {
|
|
5838
5959
|
const config = createCliConfig();
|
|
5839
5960
|
const client = createCliPlatformClient(config);
|
|
5840
|
-
await
|
|
5961
|
+
await resolveActiveOrganization(config);
|
|
5841
5962
|
const input = parseJsonOption(options.input, "--input");
|
|
5842
5963
|
const project = await resolveActiveProject(config, client);
|
|
5843
5964
|
const result = await runAppExecute(client, appSlug, toolSlug, {
|
|
@@ -5858,7 +5979,7 @@ function registerAppGetCommand(app) {
|
|
|
5858
5979
|
app.command("get").description("Get a Composio app from the live catalog").argument("<slug>", "App slug").action((slug) => runCliCommand("App get failed", async () => {
|
|
5859
5980
|
const config = createCliConfig();
|
|
5860
5981
|
const client = createCliPlatformClient(config);
|
|
5861
|
-
await
|
|
5982
|
+
await resolveActiveOrganization(config);
|
|
5862
5983
|
const result = await runAppShow(client, slug);
|
|
5863
5984
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
5864
5985
|
}, void 0, { orgScoped: true }));
|
|
@@ -5874,7 +5995,7 @@ function registerAppListCommand(app) {
|
|
|
5874
5995
|
app.command("list").description("List connectable apps in the active organization").action(() => runCliCommand("List apps failed", async () => {
|
|
5875
5996
|
const config = createCliConfig();
|
|
5876
5997
|
const client = createCliPlatformClient(config);
|
|
5877
|
-
await
|
|
5998
|
+
await resolveActiveOrganization(config);
|
|
5878
5999
|
const apps = await runAppList(client);
|
|
5879
6000
|
process.stdout.write(`${JSON.stringify(apps, null, 2)}\n`);
|
|
5880
6001
|
}, void 0, { orgScoped: true }));
|
|
@@ -5885,7 +6006,7 @@ function registerAppSearchCommand(app) {
|
|
|
5885
6006
|
app.command("search").description("Search the Composio app catalog (live)").argument("<query>", "Search query").option("--category <category>", "Filter by category").option("--limit <n>", "Page size", (value) => Number.parseInt(value, 10)).option("--cursor <cursor>", "Pagination cursor").action((query, options) => runCliCommand("App search failed", async () => {
|
|
5886
6007
|
const config = createCliConfig();
|
|
5887
6008
|
const client = createCliPlatformClient(config);
|
|
5888
|
-
await
|
|
6009
|
+
await resolveActiveOrganization(config);
|
|
5889
6010
|
const result = await runAppSearch(client, query, options);
|
|
5890
6011
|
process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
|
|
5891
6012
|
}, void 0, { orgScoped: true }));
|
|
@@ -5941,7 +6062,7 @@ function registerAppSyncCommand(app) {
|
|
|
5941
6062
|
app.command("sync").description("Sync a custom app credential template into src/apps/<name>/app.ts").argument("<slug>", "App slug, e.g. acme/internal-api").option("--dir <dir>", "Project root (defaults to cwd)").action((slug, options) => runCliCommand("Sync app failed", async () => {
|
|
5942
6063
|
const config = createCliConfig();
|
|
5943
6064
|
const client = createCliPlatformClient(config);
|
|
5944
|
-
await
|
|
6065
|
+
await resolveActiveOrganization(config);
|
|
5945
6066
|
const result = await runAppSync({
|
|
5946
6067
|
client,
|
|
5947
6068
|
slug,
|
|
@@ -5993,15 +6114,11 @@ async function runConnect(options) {
|
|
|
5993
6114
|
function registerConnectCommand(program) {
|
|
5994
6115
|
program.command("connect <slug>").description("Open the web app to connect an integration by catalog slug").option("--print-url", "Print the connect URL and exit without opening the browser").action((slug, options) => runCliCommand("Connect failed", async () => {
|
|
5995
6116
|
const config = createCliConfig();
|
|
5996
|
-
await
|
|
5997
|
-
const organizations = await listOrganizations(config);
|
|
5998
|
-
const activeOrganizationId = config.get("activeOrganizationId");
|
|
5999
|
-
const activeOrg = organizations.find((entry) => entry.organization.id === activeOrganizationId);
|
|
6000
|
-
if (!activeOrg) throw new Error("No active organization. Run `keystroke auth login` or `keystroke config use org`.");
|
|
6117
|
+
const membership = await resolveActiveOrganization(config);
|
|
6001
6118
|
await runConnect({
|
|
6002
6119
|
platform: createCliPlatformClient(config),
|
|
6003
6120
|
webUrl: getWebUrl(config),
|
|
6004
|
-
orgSlug:
|
|
6121
|
+
orgSlug: membership.organization.slug,
|
|
6005
6122
|
slug,
|
|
6006
6123
|
printUrl: options.printUrl
|
|
6007
6124
|
});
|
|
@@ -6470,7 +6587,7 @@ function resolveAuthLoginTargets(options, config) {
|
|
|
6470
6587
|
//#endregion
|
|
6471
6588
|
//#region src/commands/auth/login.ts
|
|
6472
6589
|
function registerAuthLoginCommand(auth) {
|
|
6473
|
-
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)").
|
|
6590
|
+
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)").action(async (options) => {
|
|
6474
6591
|
const config = createCliConfig();
|
|
6475
6592
|
const { webUrl, platformUrl } = resolveAuthLoginTargets(options, config);
|
|
6476
6593
|
config.set("webUrl", webUrl);
|
|
@@ -6483,12 +6600,8 @@ function registerAuthLoginCommand(auth) {
|
|
|
6483
6600
|
});
|
|
6484
6601
|
setAccessToken(platformUrl, result.accessToken);
|
|
6485
6602
|
const user = await getSessionWithBearer(platformUrl, result.accessToken);
|
|
6486
|
-
|
|
6487
|
-
|
|
6488
|
-
deviceOrganizationId: result.organizationId
|
|
6489
|
-
});
|
|
6490
|
-
if (user) process.stdout.write(`Logged in as ${user.name} (${user.email}) — organization ${membership.organization.name}\n`);
|
|
6491
|
-
else process.stdout.write(`Logged in to ${webUrl} — organization ${membership.organization.name}\n`);
|
|
6603
|
+
if (user) process.stdout.write(`Logged in as ${user.name} (${user.email})\n`);
|
|
6604
|
+
else process.stdout.write(`Logged in to ${webUrl}\n`);
|
|
6492
6605
|
} catch (error) {
|
|
6493
6606
|
process.stderr.write(`${formatCliError(error, "Login failed", {
|
|
6494
6607
|
webUrl,
|
|
@@ -6532,14 +6645,15 @@ function registerAuthStatusCommand(auth) {
|
|
|
6532
6645
|
try {
|
|
6533
6646
|
const user = await getSessionWithBearer(platformUrl, token);
|
|
6534
6647
|
const organizations = user ? await listOrganizations(config).catch(() => []) : [];
|
|
6535
|
-
const activeOrganizationId = config.get("activeOrganizationId");
|
|
6536
|
-
const activeOrganization = activeOrganizationId ? organizations.find((entry) => entry.organization.id === activeOrganizationId) : void 0;
|
|
6537
6648
|
process.stdout.write(`${JSON.stringify({
|
|
6538
6649
|
authenticated: user !== null,
|
|
6539
6650
|
webUrl,
|
|
6540
6651
|
user,
|
|
6541
|
-
|
|
6542
|
-
|
|
6652
|
+
organizations: organizations.map((entry) => ({
|
|
6653
|
+
slug: entry.organization.slug,
|
|
6654
|
+
name: entry.organization.name,
|
|
6655
|
+
role: entry.role
|
|
6656
|
+
}))
|
|
6543
6657
|
})}\n`);
|
|
6544
6658
|
if (!user) process.exitCode = 1;
|
|
6545
6659
|
} catch (error) {
|
|
@@ -6654,7 +6768,7 @@ function registerBuildCommand(program) {
|
|
|
6654
6768
|
try {
|
|
6655
6769
|
const root = resolveProjectRoot(options.dir);
|
|
6656
6770
|
ensureSdkCurrent(root);
|
|
6657
|
-
const { buildApp } = await import("./dist-
|
|
6771
|
+
const { buildApp } = await import("./dist-BnlTZTsD.mjs");
|
|
6658
6772
|
await buildApp({ root });
|
|
6659
6773
|
process.stdout.write(`Built ${root}\n`);
|
|
6660
6774
|
} catch (error) {
|
|
@@ -6777,7 +6891,7 @@ async function sleep(ms) {
|
|
|
6777
6891
|
}
|
|
6778
6892
|
async function buildDeployArchive(client, root, projectId, filter) {
|
|
6779
6893
|
if (filter?.length) {
|
|
6780
|
-
const { buildFilteredApp } = await import("./dist-
|
|
6894
|
+
const { buildFilteredApp } = await import("./dist-BnlTZTsD.mjs");
|
|
6781
6895
|
const filtered = await buildFilteredApp({
|
|
6782
6896
|
root,
|
|
6783
6897
|
filter,
|
|
@@ -6799,7 +6913,7 @@ async function buildDeployArchive(client, root, projectId, filter) {
|
|
|
6799
6913
|
sourceFiles: filtered.sourceFiles
|
|
6800
6914
|
};
|
|
6801
6915
|
}
|
|
6802
|
-
const { buildApp } = await import("./dist-
|
|
6916
|
+
const { buildApp } = await import("./dist-BnlTZTsD.mjs");
|
|
6803
6917
|
const { sourceFiles } = await buildApp({
|
|
6804
6918
|
root,
|
|
6805
6919
|
collectSources: true,
|
|
@@ -6817,11 +6931,8 @@ async function runDeploy(options) {
|
|
|
6817
6931
|
if (await runLint(root) !== 0) throw new Error("lint failed");
|
|
6818
6932
|
if (await runTypecheck(root) !== 0) throw new Error("typecheck failed");
|
|
6819
6933
|
const config = createCliConfig();
|
|
6934
|
+
await resolveActiveOrganization(config, root);
|
|
6820
6935
|
const client = createCliPlatformClient(config);
|
|
6821
|
-
await ensureLinkedOrganization(config, root);
|
|
6822
|
-
let active = await client.organizations.getActive();
|
|
6823
|
-
if (!active) active = await selectActiveOrganization(config);
|
|
6824
|
-
client.setActiveOrganizationId(active.organization.id);
|
|
6825
6936
|
const project = await client.projects.get(options.projectId);
|
|
6826
6937
|
const { archive, sourceFiles } = await buildDeployArchive(client, root, project.id, options.filter);
|
|
6827
6938
|
const created = await client.artifacts.create(project.id);
|
|
@@ -6859,7 +6970,7 @@ function registerDeployCommand(program) {
|
|
|
6859
6970
|
config = createCliConfig();
|
|
6860
6971
|
const root = resolveProjectRoot(options.dir);
|
|
6861
6972
|
const projectId = await resolveActiveProjectId(config, root);
|
|
6862
|
-
if (!projectId) throw
|
|
6973
|
+
if (!projectId) throw missingProjectRefError();
|
|
6863
6974
|
await runDeploy({
|
|
6864
6975
|
dir: options.dir,
|
|
6865
6976
|
projectId,
|
|
@@ -6924,7 +7035,7 @@ function runtimeChildEnv(parentEnv, overrides) {
|
|
|
6924
7035
|
//#region src/project/bootstrap-run.ts
|
|
6925
7036
|
/** Node args + env for `@keystrokehq/build` bootstrap (shared by start + dev). */
|
|
6926
7037
|
async function resolveBootstrapRun(options) {
|
|
6927
|
-
const { resolveRuntimeBuildArtifact } = await import("./dist-
|
|
7038
|
+
const { resolveRuntimeBuildArtifact } = await import("./dist-BnlTZTsD.mjs");
|
|
6928
7039
|
const loader = pathToFileURL(resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/runtime-loader.mjs")).href;
|
|
6929
7040
|
const bootstrap = resolveRuntimeBuildArtifact(options.runtimeNodeModules, "dist/standalone-bootstrap.mjs");
|
|
6930
7041
|
const args = [`--import=${loader}`];
|
|
@@ -7073,7 +7184,7 @@ async function runDev(options) {
|
|
|
7073
7184
|
process.on("SIGINT", shutdown);
|
|
7074
7185
|
process.on("SIGTERM", shutdown);
|
|
7075
7186
|
try {
|
|
7076
|
-
const { watchApp } = await import("./dist-
|
|
7187
|
+
const { watchApp } = await import("./dist-BnlTZTsD.mjs");
|
|
7077
7188
|
await watchApp({
|
|
7078
7189
|
root,
|
|
7079
7190
|
clean: false,
|
|
@@ -7651,8 +7762,6 @@ async function runOrganizationLeave(config) {
|
|
|
7651
7762
|
if (!user) throw new Error("Session expired. Run `keystroke auth login` again.");
|
|
7652
7763
|
await withActivePlatformClient(config, async (platform) => {
|
|
7653
7764
|
await platform.members.removeOrganizationMember(user.id);
|
|
7654
|
-
platform.setActiveOrganizationId(null);
|
|
7655
|
-
config.delete("activeOrganizationId");
|
|
7656
7765
|
process.stdout.write(`${JSON.stringify({ left: user.id }, null, 2)}\n`);
|
|
7657
7766
|
});
|
|
7658
7767
|
}
|
|
@@ -7736,13 +7845,13 @@ async function runProjectLink(config, projectRef, fromDir = process.cwd()) {
|
|
|
7736
7845
|
organization: membership.organization.slug
|
|
7737
7846
|
}, fromDir);
|
|
7738
7847
|
process.stdout.write(`Linked ${configPath} to ${membership.organization.slug}/${formatProjectLabel(project)}\nDeploy with: ${cliBinaryName()} deploy\n`);
|
|
7739
|
-
}, fromDir
|
|
7848
|
+
}, fromDir);
|
|
7740
7849
|
}
|
|
7741
7850
|
//#endregion
|
|
7742
7851
|
//#region src/commands/projects/run-project-members.ts
|
|
7743
7852
|
async function resolveMembersProject(platform) {
|
|
7744
7853
|
const ref = resolveActiveProjectRef();
|
|
7745
|
-
if (!ref) throw
|
|
7854
|
+
if (!ref) throw missingProjectRefError();
|
|
7746
7855
|
return resolveProjectRef(platform, ref);
|
|
7747
7856
|
}
|
|
7748
7857
|
async function runProjectMembersList(config) {
|
|
@@ -7849,7 +7958,7 @@ function registerProjectMembersCommand(project) {
|
|
|
7849
7958
|
//#region src/commands/projects/run-project-settings.ts
|
|
7850
7959
|
async function resolveSettingsProject(platform) {
|
|
7851
7960
|
const ref = resolveActiveProjectRef();
|
|
7852
|
-
if (!ref) throw
|
|
7961
|
+
if (!ref) throw missingProjectRefError();
|
|
7853
7962
|
return resolveProjectRef(platform, ref);
|
|
7854
7963
|
}
|
|
7855
7964
|
async function runProjectSettingsGet(config) {
|
|
@@ -7944,7 +8053,7 @@ function registerProjectsCommand(program) {
|
|
|
7944
8053
|
const config = createCliConfig();
|
|
7945
8054
|
try {
|
|
7946
8055
|
const projectRef = resolveActiveProjectRef();
|
|
7947
|
-
if (!projectRef) throw
|
|
8056
|
+
if (!projectRef) throw missingProjectRefError();
|
|
7948
8057
|
await runProjectDeploymentsList(config, { projectRef });
|
|
7949
8058
|
} catch (error) {
|
|
7950
8059
|
process.stderr.write(`${formatCliError(error, "List deployments failed", {
|
|
@@ -7958,7 +8067,7 @@ function registerProjectsCommand(program) {
|
|
|
7958
8067
|
const config = createCliConfig();
|
|
7959
8068
|
try {
|
|
7960
8069
|
const projectRef = resolveActiveProjectRef(options.dir);
|
|
7961
|
-
if (!projectRef) throw
|
|
8070
|
+
if (!projectRef) throw missingProjectRefError();
|
|
7962
8071
|
await runProjectLink(config, projectRef, options.dir);
|
|
7963
8072
|
} catch (error) {
|
|
7964
8073
|
process.stderr.write(`${formatCliError(error, "Link project failed", {
|
|
@@ -7987,7 +8096,7 @@ function registerProjectsCommand(program) {
|
|
|
7987
8096
|
const config = createCliConfig();
|
|
7988
8097
|
try {
|
|
7989
8098
|
const projectId = await resolveActiveProjectId(config);
|
|
7990
|
-
if (!projectId) throw
|
|
8099
|
+
if (!projectId) throw missingProjectRefError();
|
|
7991
8100
|
if (!options.name && options.description === void 0) throw new Error("At least one of --name or --description is required");
|
|
7992
8101
|
await runProjectUpdate(config, {
|
|
7993
8102
|
projectId,
|
|
@@ -8006,7 +8115,7 @@ function registerProjectsCommand(program) {
|
|
|
8006
8115
|
const config = createCliConfig();
|
|
8007
8116
|
try {
|
|
8008
8117
|
const projectId = await resolveActiveProjectId(config);
|
|
8009
|
-
if (!projectId) throw
|
|
8118
|
+
if (!projectId) throw missingProjectRefError();
|
|
8010
8119
|
if (!options.yes) throw new Error("Pass --yes to confirm project deletion");
|
|
8011
8120
|
await runProjectDelete(config, projectId);
|
|
8012
8121
|
} catch (error) {
|
|
@@ -8084,7 +8193,7 @@ function registerPullCommand(program) {
|
|
|
8084
8193
|
program.command("pull").description("Download the active deploy source snapshot into a local directory").option("--dir <path>", "Target directory", process.cwd()).option("--force", "Overwrite an existing local project tree").action(async (options) => runCliCommand("Pull failed", async () => {
|
|
8085
8194
|
const config = createCliConfig();
|
|
8086
8195
|
const projectId = await resolveActiveProjectId(config, options.dir);
|
|
8087
|
-
if (!projectId) throw
|
|
8196
|
+
if (!projectId) throw missingProjectRefError();
|
|
8088
8197
|
await runPull({
|
|
8089
8198
|
client: createCliPlatformClient(config),
|
|
8090
8199
|
projectId,
|
|
@@ -8106,7 +8215,7 @@ async function runStart(options) {
|
|
|
8106
8215
|
const apiPort = Number(new URL(serverUrl).port || 80);
|
|
8107
8216
|
const runtimeNodeModules = resolveCliRuntimeNodeModules(resolveCliRoot(import.meta.url));
|
|
8108
8217
|
ensureNativeDeps(runtimeNodeModules);
|
|
8109
|
-
const { buildApp } = await import("./dist-
|
|
8218
|
+
const { buildApp } = await import("./dist-BnlTZTsD.mjs");
|
|
8110
8219
|
await buildApp({
|
|
8111
8220
|
root,
|
|
8112
8221
|
clean: false
|
|
@@ -8341,7 +8450,7 @@ function registerWorkflowListCommand(workflow) {
|
|
|
8341
8450
|
workflow.command("list").description("List workflows in the active organization").option("--admin", "List all org resources (org owner or admin only)").action((options) => runCliCommand("List workflows failed", async () => {
|
|
8342
8451
|
const config = createCliConfig();
|
|
8343
8452
|
const client = createCliPlatformClient(config);
|
|
8344
|
-
await
|
|
8453
|
+
await resolveActiveOrganization(config);
|
|
8345
8454
|
if (options.admin) await requireAdminRole(config);
|
|
8346
8455
|
const projectId = await resolveActiveProjectId(config);
|
|
8347
8456
|
const result = await client.workflows.list({
|
|
@@ -8447,7 +8556,7 @@ function registerChannelPlatformsCommand(channel) {
|
|
|
8447
8556
|
channel.command("platforms").description("Browse gateway-enabled apps").command("list").description("List apps that support agent external channels").action(() => runCliCommand("List channel platforms failed", async () => {
|
|
8448
8557
|
const config = createCliConfig();
|
|
8449
8558
|
const client = createCliPlatformClient(config);
|
|
8450
|
-
await
|
|
8559
|
+
await resolveActiveOrganization(config);
|
|
8451
8560
|
const platforms = await runChannelPlatformsList(client);
|
|
8452
8561
|
process.stdout.write(`${JSON.stringify({ platforms }, null, 2)}\n`);
|
|
8453
8562
|
}, void 0, { orgScoped: true }));
|
|
@@ -8455,11 +8564,10 @@ function registerChannelPlatformsCommand(channel) {
|
|
|
8455
8564
|
//#endregion
|
|
8456
8565
|
//#region src/commands/channels/resolve-channel-project.ts
|
|
8457
8566
|
async function resolveChannelProjectId(config) {
|
|
8567
|
+
await resolveActiveOrganization(config);
|
|
8458
8568
|
const platform = createCliPlatformClient(config);
|
|
8459
|
-
await ensureLinkedOrganization(config);
|
|
8460
|
-
await ensureActiveOrganization(config);
|
|
8461
8569
|
const ref = resolveActiveProjectRef();
|
|
8462
|
-
if (!ref) throw
|
|
8570
|
+
if (!ref) throw missingProjectRefError();
|
|
8463
8571
|
return (await resolveProjectRef(platform, ref)).id;
|
|
8464
8572
|
}
|
|
8465
8573
|
//#endregion
|
|
@@ -8468,9 +8576,7 @@ function registerChannelAccountsCommand(channel) {
|
|
|
8468
8576
|
channel.command("accounts").description("List available workspace accounts for a platform").requiredOption("--platform <key>", "Platform key (slack)").action(async (options) => runCliCommand("List channel accounts failed", async () => {
|
|
8469
8577
|
const config = createCliConfig();
|
|
8470
8578
|
const projectId = await resolveChannelProjectId(config);
|
|
8471
|
-
const
|
|
8472
|
-
await ensureActiveOrganization(config);
|
|
8473
|
-
const accounts = await runChannelAccounts(client, projectId, options.platform);
|
|
8579
|
+
const accounts = await runChannelAccounts(createCliPlatformClient(config), projectId, options.platform);
|
|
8474
8580
|
process.stdout.write(`${JSON.stringify({ accounts }, null, 2)}\n`);
|
|
8475
8581
|
}));
|
|
8476
8582
|
}
|
|
@@ -8478,9 +8584,7 @@ function registerChannelListCommand(channel) {
|
|
|
8478
8584
|
channel.command("list").description("List channel bindings for an agent").requiredOption("--agent <id>", "Agent id").action(async (options) => runCliCommand("List agent channels failed", async () => {
|
|
8479
8585
|
const config = createCliConfig();
|
|
8480
8586
|
const projectId = await resolveChannelProjectId(config);
|
|
8481
|
-
const
|
|
8482
|
-
await ensureActiveOrganization(config);
|
|
8483
|
-
const connections = await runChannelList(client, projectId, options.agent);
|
|
8587
|
+
const connections = await runChannelList(createCliPlatformClient(config), projectId, options.agent);
|
|
8484
8588
|
process.stdout.write(`${JSON.stringify({ connections }, null, 2)}\n`);
|
|
8485
8589
|
}));
|
|
8486
8590
|
}
|
|
@@ -8488,9 +8592,7 @@ function registerChannelDirectoryCommand(channel) {
|
|
|
8488
8592
|
channel.command("directory").description("List channels available to bind from a platform directory").requiredOption("--platform <key>", "Platform key (slack)").requiredOption("--account <id>", "Workspace account id (team id)").action(async (options) => runCliCommand("List channel directory failed", async () => {
|
|
8489
8593
|
const config = createCliConfig();
|
|
8490
8594
|
const projectId = await resolveChannelProjectId(config);
|
|
8491
|
-
const
|
|
8492
|
-
await ensureActiveOrganization(config);
|
|
8493
|
-
const channels = await runChannelDirectory(client, projectId, options.platform, options.account);
|
|
8595
|
+
const channels = await runChannelDirectory(createCliPlatformClient(config), projectId, options.platform, options.account);
|
|
8494
8596
|
process.stdout.write(`${JSON.stringify({ channels }, null, 2)}\n`);
|
|
8495
8597
|
}));
|
|
8496
8598
|
}
|
|
@@ -8498,9 +8600,7 @@ function registerChannelBindCommand(channel) {
|
|
|
8498
8600
|
channel.command("bind").description("Bind an agent to a channel").argument("<agent>", "Agent id or slug").requiredOption("--platform <key>", "Platform key (slack)").requiredOption("--account <id>", "Workspace account id (team id)").requiredOption("--channel <id>", "Provider channel id").option("--channel-name <name>", "Provider channel name").option("--mode <mode>", "Listen mode (mention, all, dm)", "mention").action(async (agent, options) => runCliCommand("Bind channel failed", async () => {
|
|
8499
8601
|
const config = createCliConfig();
|
|
8500
8602
|
const projectId = await resolveChannelProjectId(config);
|
|
8501
|
-
const
|
|
8502
|
-
await ensureActiveOrganization(config);
|
|
8503
|
-
const connection = await runChannelBind(client, projectId, {
|
|
8603
|
+
const connection = await runChannelBind(createCliPlatformClient(config), projectId, {
|
|
8504
8604
|
agentId: agent,
|
|
8505
8605
|
platform: options.platform,
|
|
8506
8606
|
accountId: options.account,
|
|
@@ -8518,9 +8618,7 @@ function registerChannelUnbindCommand(channel) {
|
|
|
8518
8618
|
channel.command("unbind").description("Remove a channel binding from an agent").requiredOption("--agent <id>", "Agent id").requiredOption("--binding <id>", "Binding id").action(async (options) => runCliCommand("Unbind channel failed", async () => {
|
|
8519
8619
|
const config = createCliConfig();
|
|
8520
8620
|
const projectId = await resolveChannelProjectId(config);
|
|
8521
|
-
const
|
|
8522
|
-
await ensureActiveOrganization(config);
|
|
8523
|
-
const connection = await runChannelUnbind(client, projectId, {
|
|
8621
|
+
const connection = await runChannelUnbind(createCliPlatformClient(config), projectId, {
|
|
8524
8622
|
agentId: options.agent,
|
|
8525
8623
|
bindingId: options.binding
|
|
8526
8624
|
});
|
|
@@ -8532,7 +8630,6 @@ function registerChannelUpdateBindingCommand(channel) {
|
|
|
8532
8630
|
const config = createCliConfig();
|
|
8533
8631
|
const projectId = await resolveChannelProjectId(config);
|
|
8534
8632
|
const client = createCliPlatformClient(config);
|
|
8535
|
-
await ensureActiveOrganization(config);
|
|
8536
8633
|
const patch = {};
|
|
8537
8634
|
if (options.mode) patch.mode = options.mode;
|
|
8538
8635
|
if (options.threads !== void 0) patch.subscribeOnMention = options.threads;
|
|
@@ -8615,31 +8712,25 @@ function registerConfigCommand(program) {
|
|
|
8615
8712
|
webUrl: cliConfig.get("webUrl"),
|
|
8616
8713
|
platformUrl: getPlatformUrl(cliConfig),
|
|
8617
8714
|
localApiUrl: resolveLocalApiOrigin(process.cwd()),
|
|
8618
|
-
activeOrganizationId: cliConfig.get("activeOrganizationId"),
|
|
8619
8715
|
linkedProject: linked.project ?? null,
|
|
8620
8716
|
linkedOrganization: linked.organization ?? null,
|
|
8621
8717
|
apiTarget: getEffectiveApiTarget(cliConfig),
|
|
8622
8718
|
devSession: readDevSession(configDir) ?? null
|
|
8623
8719
|
}, null, 2)}\n`);
|
|
8624
8720
|
});
|
|
8625
|
-
config.command("use").description("Switch API target (local
|
|
8721
|
+
config.command("use").description("Switch API target (local or cloud)").argument("[mode]", "local or cloud").action(async (mode) => {
|
|
8626
8722
|
const cliConfig = createCliConfig();
|
|
8627
8723
|
if (!mode || mode === "local") {
|
|
8628
8724
|
cliConfig.set("apiTarget", "local");
|
|
8629
8725
|
process.stdout.write("Using local keystroke server\n");
|
|
8630
8726
|
return;
|
|
8631
8727
|
}
|
|
8632
|
-
if (mode === "org") {
|
|
8633
|
-
const membership = await selectActiveOrganization(cliConfig, { organizationRef: id });
|
|
8634
|
-
process.stdout.write(`Using organization ${membership.organization.name}\n`);
|
|
8635
|
-
return;
|
|
8636
|
-
}
|
|
8637
8728
|
if (mode === "cloud") {
|
|
8638
8729
|
cliConfig.set("apiTarget", "platform");
|
|
8639
8730
|
process.stdout.write("Using platform API\n");
|
|
8640
8731
|
return;
|
|
8641
8732
|
}
|
|
8642
|
-
throw new Error("Usage: keystroke config use [local|cloud
|
|
8733
|
+
throw new Error("Usage: keystroke config use [local|cloud]");
|
|
8643
8734
|
});
|
|
8644
8735
|
config.command("org").description("List organizations you belong to").action(async () => {
|
|
8645
8736
|
const organizations = await listOrganizations(createCliConfig());
|
|
@@ -8682,10 +8773,11 @@ async function syncAgentsGuide(command) {
|
|
|
8682
8773
|
//#endregion
|
|
8683
8774
|
//#region src/program.ts
|
|
8684
8775
|
function createProgram() {
|
|
8685
|
-
const program = new Command().name("keystroke").description("Build, run, and manage keystroke projects").version(readCliVersion()).option("--project <slug>", "Platform project slug (deploy target or one-off API target)").option("--local", "Force local keystroke server URL").hook("preAction", async (thisCommand, actionCommand) => {
|
|
8776
|
+
const program = new Command().name("keystroke").description("Build, run, and manage keystroke projects").version(readCliVersion()).option("--project <slug>", "Platform project slug (deploy target or one-off API target)").option("--organization <slug>", "Platform organization slug (org-scoped API target)").option("--local", "Force local keystroke server URL").hook("preAction", async (thisCommand, actionCommand) => {
|
|
8686
8777
|
const opts = thisCommand.opts();
|
|
8687
8778
|
setCliTargetOptions({
|
|
8688
8779
|
projectId: opts.project,
|
|
8780
|
+
organizationRef: opts.organization,
|
|
8689
8781
|
local: opts.local
|
|
8690
8782
|
});
|
|
8691
8783
|
await syncAgentsGuide(actionCommand);
|
|
@@ -8695,6 +8787,7 @@ function createProgram() {
|
|
|
8695
8787
|
registerConfigCommand(program);
|
|
8696
8788
|
registerOrganizationCommand(program);
|
|
8697
8789
|
registerApiKeyCommand(program);
|
|
8790
|
+
registerManagedServicesCommand(program);
|
|
8698
8791
|
registerProjectsCommand(program);
|
|
8699
8792
|
registerHistoryCommand(program);
|
|
8700
8793
|
registerCredentialsCommand(program);
|
|
@@ -8717,7 +8810,7 @@ function createProgram() {
|
|
|
8717
8810
|
return program;
|
|
8718
8811
|
}
|
|
8719
8812
|
async function runCli(argv) {
|
|
8720
|
-
const { maybeAutoUpdate } = await import("./maybe-auto-update-
|
|
8813
|
+
const { maybeAutoUpdate } = await import("./maybe-auto-update-KpKNhzFK.mjs");
|
|
8721
8814
|
await maybeAutoUpdate(argv);
|
|
8722
8815
|
createProgram().parse(argv);
|
|
8723
8816
|
}
|