@kora-platform/cli 0.7.0-rc1 → 0.8.0-rc1

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.
Files changed (38) hide show
  1. package/README.md +21 -0
  2. package/dist/api-client.d.ts +250 -93
  3. package/dist/api-client.js +187 -163
  4. package/dist/api-types.d.ts +280 -162
  5. package/dist/artifact-api-client.d.ts +28 -1
  6. package/dist/artifact-api-client.js +33 -0
  7. package/dist/artifact-commands.d.ts +5 -0
  8. package/dist/artifact-commands.js +172 -1
  9. package/dist/audit-commands.d.ts +12 -0
  10. package/dist/audit-commands.js +74 -0
  11. package/dist/auth-commands.d.ts +1 -0
  12. package/dist/auth-commands.js +116 -29
  13. package/dist/command-builders.d.ts +1 -0
  14. package/dist/command-builders.js +1 -0
  15. package/dist/command-groups.js +10 -12
  16. package/dist/command-registry.js +548 -243
  17. package/dist/commands.js +652 -602
  18. package/dist/environment-context.d.ts +9 -0
  19. package/dist/environment-context.js +32 -0
  20. package/dist/{integration-commands.d.ts → extension-commands.d.ts} +3 -2
  21. package/dist/extension-commands.js +446 -0
  22. package/dist/files.d.ts +33 -0
  23. package/dist/files.js +247 -12
  24. package/dist/format.d.ts +5 -0
  25. package/dist/format.js +78 -1
  26. package/dist/runner.js +14 -5
  27. package/dist/schema-registry-data.d.ts +272 -569
  28. package/dist/schema-registry-data.js +307 -700
  29. package/dist/session.d.ts +1 -0
  30. package/dist/transport.d.ts +10 -0
  31. package/dist/transport.js +22 -0
  32. package/dist/types.d.ts +2 -1
  33. package/dist/workspace-source.d.ts +1 -0
  34. package/dist/workspace-source.js +13 -0
  35. package/package.json +2 -1
  36. package/dist/integration-api-client.d.ts +0 -29
  37. package/dist/integration-api-client.js +0 -50
  38. package/dist/integration-commands.js +0 -208
@@ -3,7 +3,8 @@ import { basename, resolve } from "node:path";
3
3
  import { TextDecoder } from "node:util";
4
4
  import { genericProblem, usageProblem } from "./cli-errors.js";
5
5
  import { readOptionalNumberFlag, readOptionalStringFlag, readRequiredStringFlag } from "./command-flags.js";
6
- import { renderSuccess, renderTable } from "./format.js";
6
+ import { renderKeyValue, renderSuccess, renderTable } from "./format.js";
7
+ import { confirmDestructive } from "./interaction.js";
7
8
  export async function executeArtifactUpload(parsed, context, api, resolveOrgScope) {
8
9
  const { org, session } = await resolveOrgScope(parsed, context, api);
9
10
  const pathValue = readRequiredArg(parsed, "path");
@@ -40,6 +41,27 @@ export async function executeArtifactList(parsed, context, api, resolveOrgScope)
40
41
  meta: { command: "artifact list", orgId: org.id }
41
42
  };
42
43
  }
44
+ export async function executeArtifactInventory(parsed, context, api, resolveOrgScope) {
45
+ const { org, session } = await resolveOrgScope(parsed, context, api);
46
+ const data = await api.listArtifacts(session, org.id, readArtifactInventoryFilters(parsed));
47
+ return {
48
+ data,
49
+ human: renderArtifactInventory(data.artifacts),
50
+ kind: "runtime_artifact_inventory",
51
+ meta: { command: "artifact inventory", orgId: org.id }
52
+ };
53
+ }
54
+ export async function executeArtifactInspect(parsed, context, api, resolveOrgScope) {
55
+ const { org, session } = await resolveOrgScope(parsed, context, api);
56
+ const artifactId = readRequiredArg(parsed, "artifact-id");
57
+ const data = await api.getArtifactDetail(session, org.id, artifactId);
58
+ return {
59
+ data,
60
+ human: renderArtifactDetail(data),
61
+ kind: "runtime_artifact_inspect",
62
+ meta: { command: "artifact inspect", orgId: org.id }
63
+ };
64
+ }
43
65
  export async function executeArtifactDownload(parsed, context, api, resolveOrgScope) {
44
66
  const { org, session } = await resolveOrgScope(parsed, context, api);
45
67
  const artifactId = readRequiredArg(parsed, "artifact-id");
@@ -94,6 +116,40 @@ export async function executeArtifactRead(parsed, context, api, resolveOrgScope)
94
116
  meta: { command: "artifact read", orgId: org.id }
95
117
  };
96
118
  }
119
+ export async function executeArtifactArchive(parsed, context, api, resolveOrgScope) {
120
+ const { org, session } = await resolveOrgScope(parsed, context, api);
121
+ const artifactId = readRequiredArg(parsed, "artifact-id");
122
+ const data = await api.archiveArtifact(session, org.id, artifactId);
123
+ return {
124
+ data,
125
+ human: renderSuccess(`Archived artifact ${data.artifact.name} (${data.artifact.artifactId}).`),
126
+ kind: "runtime_artifact_archive",
127
+ meta: { command: "artifact archive", orgId: org.id }
128
+ };
129
+ }
130
+ export async function executeArtifactRestore(parsed, context, api, resolveOrgScope) {
131
+ const { org, session } = await resolveOrgScope(parsed, context, api);
132
+ const artifactId = readRequiredArg(parsed, "artifact-id");
133
+ const data = await api.restoreArtifact(session, org.id, artifactId);
134
+ return {
135
+ data,
136
+ human: renderSuccess(`Restored artifact ${data.artifact.name} (${data.artifact.artifactId}).`),
137
+ kind: "runtime_artifact_restore",
138
+ meta: { command: "artifact restore", orgId: org.id }
139
+ };
140
+ }
141
+ export async function executeArtifactPurge(parsed, context, api, resolveOrgScope) {
142
+ const { org, session } = await resolveOrgScope(parsed, context, api);
143
+ const artifactId = readRequiredArg(parsed, "artifact-id");
144
+ await confirmDestructive(parsed, context, `Purge bytes for artifact ${artifactId}?`);
145
+ const data = await api.purgeArtifact(session, org.id, artifactId);
146
+ return {
147
+ data,
148
+ human: renderSuccess(`Purged artifact ${data.artifact.name} (${data.artifact.artifactId}); byte deletion is ${data.artifact.byteDeletionStatus}.`),
149
+ kind: "runtime_artifact_purge",
150
+ meta: { command: "artifact purge", orgId: org.id }
151
+ };
152
+ }
97
153
  function readRequiredArg(parsed, name) {
98
154
  const value = parsed.args[name];
99
155
  if (!value) {
@@ -108,6 +164,108 @@ function readArtifactReadMaxBytes(parsed) {
108
164
  }
109
165
  return maxBytes;
110
166
  }
167
+ function readArtifactInventoryLimit(parsed) {
168
+ const limit = readOptionalNumberFlag(parsed, "limit");
169
+ if (limit === undefined) {
170
+ return undefined;
171
+ }
172
+ if (!Number.isInteger(limit) || limit <= 0 || limit > 500) {
173
+ throw usageProblem("--limit must be an integer between 1 and 500.", parsed.definition.id);
174
+ }
175
+ return limit;
176
+ }
177
+ function readArtifactInventoryFilters(parsed) {
178
+ const producerType = readOptionalStringFlag(parsed, "producer-type");
179
+ const associationRole = readOptionalStringFlag(parsed, "association-role");
180
+ const associationKind = readOptionalStringFlag(parsed, "association-kind");
181
+ const runId = readOptionalStringFlag(parsed, "run-id");
182
+ const workflowId = readOptionalStringFlag(parsed, "workflow-id");
183
+ const workflowNodeTestId = readOptionalStringFlag(parsed, "workflow-node-test-id");
184
+ const nodeId = readOptionalStringFlag(parsed, "node-id");
185
+ const mediaType = readOptionalStringFlag(parsed, "media-type");
186
+ const lifecycleStatus = readOptionalArtifactLifecycleFilter(parsed);
187
+ const createdAfter = readOptionalStringFlag(parsed, "created-after");
188
+ const createdBefore = readOptionalStringFlag(parsed, "created-before");
189
+ const limit = readArtifactInventoryLimit(parsed);
190
+ return {
191
+ ...(producerType ? { producerType } : {}),
192
+ ...(associationRole ? { associationRole } : {}),
193
+ ...(associationKind ? { associationKind } : {}),
194
+ ...(runId ? { runId } : {}),
195
+ ...(workflowId ? { workflowId } : {}),
196
+ ...(workflowNodeTestId ? { workflowNodeTestId } : {}),
197
+ ...(nodeId ? { nodeId } : {}),
198
+ ...(mediaType ? { mediaType } : {}),
199
+ ...(lifecycleStatus ? { lifecycleStatus } : {}),
200
+ ...(createdAfter ? { createdAfter } : {}),
201
+ ...(createdBefore ? { createdBefore } : {}),
202
+ ...(limit !== undefined ? { limit } : {})
203
+ };
204
+ }
205
+ function renderArtifactInventory(records) {
206
+ return renderTable(records.map((record) => ({
207
+ artifactId: record.artifact.artifactId,
208
+ byteDeletionStatus: record.artifact.byteDeletionStatus,
209
+ inputUsageCount: record.associationSummary.inputUsageCount,
210
+ lifecycleStatus: record.artifact.lifecycleStatus,
211
+ name: record.artifact.name,
212
+ origin: formatArtifactAssociationOrigin(record.originAssociation),
213
+ outputOriginCount: record.associationSummary.outputOriginCount,
214
+ producerType: record.artifact.producerType,
215
+ reviewUsageCount: record.associationSummary.reviewUsageCount
216
+ })), [
217
+ { key: "artifactId", label: "Artifact" },
218
+ { key: "name", label: "Name" },
219
+ { key: "lifecycleStatus", label: "Lifecycle" },
220
+ { key: "byteDeletionStatus", label: "Bytes" },
221
+ { key: "producerType", label: "Producer" },
222
+ { key: "origin", label: "Origin" },
223
+ { key: "inputUsageCount", label: "Inputs" },
224
+ { key: "outputOriginCount", label: "Outputs" },
225
+ { key: "reviewUsageCount", label: "Reviews" }
226
+ ]);
227
+ }
228
+ function renderArtifactDetail(input) {
229
+ const summary = renderKeyValue([
230
+ { label: "Artifact", value: input.artifact.artifactId },
231
+ { label: "Name", value: input.artifact.name },
232
+ { label: "Lifecycle", value: input.artifact.lifecycleStatus },
233
+ { label: "Bytes", value: input.artifact.byteDeletionStatus },
234
+ { label: "Producer", value: input.artifact.producerType },
235
+ { label: "Media type", value: input.artifact.mediaType ?? "" },
236
+ { label: "Size bytes", value: input.artifact.sizeBytes },
237
+ { label: "Scan", value: input.artifact.scanStatus },
238
+ { label: "Created", value: input.artifact.createdAt },
239
+ { label: "Archived", value: input.artifact.archivedAt ?? "" },
240
+ { label: "Purged", value: input.artifact.purgedAt ?? "" },
241
+ { label: "Bytes deleted", value: input.artifact.bytesDeletedAt ?? "" }
242
+ ]);
243
+ const associations = renderTable(input.associations.map((association) => ({
244
+ associatedAt: association.associatedAt,
245
+ associationKind: association.associationKind,
246
+ nodeId: association.nodeId ?? "",
247
+ origin: formatArtifactAssociationOrigin(association),
248
+ role: association.role,
249
+ })), [
250
+ { key: "associationKind", label: "Kind" },
251
+ { key: "role", label: "Role" },
252
+ { key: "origin", label: "Origin" },
253
+ { key: "nodeId", label: "Node" },
254
+ { key: "associatedAt", label: "Associated" }
255
+ ]);
256
+ return `${summary}\n\nAssociations:\n${associations}`;
257
+ }
258
+ function formatArtifactAssociationOrigin(association) {
259
+ if (!association) {
260
+ return "";
261
+ }
262
+ if (association.workflowNodeTestId) {
263
+ return association.workflowName
264
+ ? `${association.workflowName}/${association.workflowNodeTestId}`
265
+ : association.workflowNodeTestId;
266
+ }
267
+ return association.workflowRunId ?? association.workflowId ?? "";
268
+ }
111
269
  function isInlineArtifactMediaType(contentType) {
112
270
  const normalized = contentType.split(";", 1)[0]?.trim().toLowerCase() ?? "";
113
271
  if (normalized === "text/html" ||
@@ -124,3 +282,16 @@ function isInlineArtifactMediaType(contentType) {
124
282
  function readArtifactContentType(headers) {
125
283
  return headers.get("content-type") ?? "application/octet-stream";
126
284
  }
285
+ function readOptionalArtifactLifecycleFilter(parsed) {
286
+ const lifecycleStatus = readOptionalStringFlag(parsed, "lifecycle-status");
287
+ if (!lifecycleStatus) {
288
+ return undefined;
289
+ }
290
+ if (lifecycleStatus !== "active" &&
291
+ lifecycleStatus !== "archived" &&
292
+ lifecycleStatus !== "purged" &&
293
+ lifecycleStatus !== "all") {
294
+ throw usageProblem("--lifecycle-status must be one of active, archived, purged, or all.", parsed.definition.id);
295
+ }
296
+ return lifecycleStatus;
297
+ }
@@ -0,0 +1,12 @@
1
+ import type { createPlatformApiClient } from "./api-client.js";
2
+ import type { CommandExecutionContext, ExecutedCommand } from "./command-types.js";
3
+ import type { ParsedCommand } from "./runner.js";
4
+ import type { CliSessionState } from "./session.js";
5
+ type ResolveOrgScope = (parsed: ParsedCommand, context: CommandExecutionContext, api: ReturnType<typeof createPlatformApiClient>) => Promise<{
6
+ org: {
7
+ id: string;
8
+ };
9
+ session: CliSessionState;
10
+ }>;
11
+ export declare function executeAudit(parsed: ParsedCommand, context: CommandExecutionContext, api: ReturnType<typeof createPlatformApiClient>, resolveOrgScope: ResolveOrgScope): Promise<ExecutedCommand>;
12
+ export {};
@@ -0,0 +1,74 @@
1
+ import { usageProblem, genericProblem } from "./cli-errors.js";
2
+ import { readOptionalNumberFlag, readOptionalStringFlag } from "./command-flags.js";
3
+ import { renderPrettyJson, renderTable } from "./format.js";
4
+ export async function executeAudit(parsed, context, api, resolveOrgScope) {
5
+ const { org, session } = await resolveOrgScope(parsed, context, api);
6
+ switch (parsed.definition.id) {
7
+ case "audit.list": {
8
+ const action = readOptionalStringFlag(parsed, "action");
9
+ const actorId = readOptionalStringFlag(parsed, "actor");
10
+ const category = readOptionalStringFlag(parsed, "category");
11
+ const from = readOptionalStringFlag(parsed, "from");
12
+ const limit = readOptionalNumberFlag(parsed, "limit");
13
+ const outcome = readOptionalStringFlag(parsed, "outcome");
14
+ const resourceId = readOptionalStringFlag(parsed, "resource-id");
15
+ const resourceType = readOptionalStringFlag(parsed, "resource-type");
16
+ const to = readOptionalStringFlag(parsed, "to");
17
+ const data = await api.listAuditEvents(session, org.id, {
18
+ ...(action ? { action } : {}),
19
+ ...(actorId ? { actorId } : {}),
20
+ ...(category ? { category } : {}),
21
+ ...(from ? { from } : {}),
22
+ ...(limit !== undefined ? { limit } : {}),
23
+ ...(outcome ? { outcome } : {}),
24
+ ...(resourceId ? { resourceId } : {}),
25
+ ...(resourceType ? { resourceType } : {}),
26
+ ...(to ? { to } : {})
27
+ });
28
+ return {
29
+ data,
30
+ human: renderTable(data.events.map(formatAuditEventRow), [
31
+ { key: "occurredAt", label: "Occurred" },
32
+ { key: "outcome", label: "Outcome" },
33
+ { key: "category", label: "Category" },
34
+ { key: "action", label: "Action" },
35
+ { key: "actorId", label: "Actor" },
36
+ { key: "resource", label: "Resource" },
37
+ { key: "id", label: "Event" }
38
+ ]),
39
+ kind: "audit_event_list",
40
+ meta: { command: parsed.definition.path.join(" "), orgId: org.id }
41
+ };
42
+ }
43
+ case "audit.get": {
44
+ const data = await api.getAuditEvent(session, org.id, readRequiredArg(parsed, "event-id"));
45
+ return {
46
+ data,
47
+ human: renderPrettyJson(data.event),
48
+ kind: "audit_event_get",
49
+ meta: { command: parsed.definition.path.join(" "), orgId: org.id }
50
+ };
51
+ }
52
+ default:
53
+ throw genericProblem(`Unhandled audit command ${parsed.definition.id}.`, parsed.definition.id);
54
+ }
55
+ }
56
+ function formatAuditEventRow(event) {
57
+ return {
58
+ ...event,
59
+ resource: formatAuditResource(event)
60
+ };
61
+ }
62
+ function formatAuditResource(event) {
63
+ if (event.resourceType && event.resourceId) {
64
+ return `${event.resourceType}:${event.resourceId}`;
65
+ }
66
+ return event.resourceType ?? event.resourceId ?? "";
67
+ }
68
+ function readRequiredArg(parsed, name) {
69
+ const value = parsed.args[name];
70
+ if (!value) {
71
+ throw usageProblem(`Missing required argument <${name}>.`, parsed.definition.id);
72
+ }
73
+ return value;
74
+ }
@@ -2,5 +2,6 @@ import type { createPlatformApiClient } from "./api-client.js";
2
2
  import type { CommandExecutionContext, ExecutedCommand } from "./command-types.js";
3
3
  import type { ParsedCommand } from "./runner.js";
4
4
  export declare function executeAuthLogin(parsed: ParsedCommand, context: CommandExecutionContext, api: ReturnType<typeof createPlatformApiClient>): Promise<ExecutedCommand>;
5
+ export declare function executeAuthSignup(parsed: ParsedCommand, context: CommandExecutionContext, api: ReturnType<typeof createPlatformApiClient>): Promise<ExecutedCommand>;
5
6
  export declare function executeAuthLogout(context: CommandExecutionContext, api: ReturnType<typeof createPlatformApiClient>): Promise<ExecutedCommand>;
6
7
  export declare function executeAuthWhoami(context: CommandExecutionContext, api: ReturnType<typeof createPlatformApiClient>): Promise<ExecutedCommand>;
@@ -1,4 +1,5 @@
1
1
  import { authProblem, toProblem } from "./cli-errors.js";
2
+ import { readOptionalStringFlag } from "./command-flags.js";
2
3
  import { writeCliConfig, readCliConfig, findRepoConfigPath } from "./config.js";
3
4
  import { renderKeyValue, renderSuccess } from "./format.js";
4
5
  import { chooseOrganization, ensureInteractive } from "./interaction.js";
@@ -11,12 +12,8 @@ export async function executeAuthLogin(parsed, context, api) {
11
12
  }
12
13
  : context;
13
14
  ensureInteractive(prompts, "auth login");
14
- const persistedGlobalConfig = await readCliConfig(context.configPath);
15
- const repoConfigPath = await findRepoConfigPath(context.cwd);
16
- const repoConfig = repoConfigPath ? await readCliConfig(repoConfigPath) : {};
17
- const envBaseUrl = context.env.KORA_BASE_URL;
18
- const configuredBaseUrl = envBaseUrl ?? repoConfig.baseUrl ?? persistedGlobalConfig.baseUrl;
19
- const baseUrl = configuredBaseUrl ?? await promptText("Platform base URL: ", prompts);
15
+ const resolvedBaseUrl = await resolveAuthBaseUrl(parsed, context, prompts);
16
+ const { baseUrl } = resolvedBaseUrl;
20
17
  const authSettings = await readAuthSettingsOrDefault(api, baseUrl);
21
18
  const oidcLoginUrl = buildOidcStartUrl(baseUrl);
22
19
  if (authSettings.oidcEnabled && !authSettings.localEnabled) {
@@ -45,30 +42,16 @@ export async function executeAuthLogin(parsed, context, api) {
45
42
  const email = await promptText("Email: ", prompts);
46
43
  const password = await promptPassword("Password: ", prompts);
47
44
  const session = await api.login({ baseUrl, email, password });
48
- const organizations = (await api.listOrganizations(session)).organizations;
49
- const activeOrg = organizations.length === 1
50
- ? organizations[0] ?? null
51
- : organizations.length > 1
52
- ? await chooseOrganization(organizations, prompts, parsed)
53
- : null;
54
- const latestSession = await readLatestSessionForWrite(context.sessionStore, session);
55
- const sessionForWrite = isSameSessionIdentity(latestSession, session) ? latestSession : session;
56
- const nextSession = {
57
- ...sessionForWrite,
58
- activeOrg: activeOrg
59
- ? {
60
- id: activeOrg.id,
61
- name: activeOrg.name,
62
- role: activeOrg.role,
63
- slug: activeOrg.slug,
64
- status: activeOrg.status
65
- }
66
- : null
67
- };
68
- await context.sessionStore.write(nextSession);
69
- if (!envBaseUrl && !repoConfig.baseUrl) {
45
+ const nextSession = await writeSessionWithSelectedOrg({
46
+ api,
47
+ context,
48
+ parsed,
49
+ prompts,
50
+ session
51
+ });
52
+ if (resolvedBaseUrl.shouldPersistGlobalBaseUrl) {
70
53
  await writeCliConfig(context.configPath, {
71
- ...persistedGlobalConfig,
54
+ ...resolvedBaseUrl.persistedGlobalConfig,
72
55
  baseUrl
73
56
  });
74
57
  }
@@ -87,6 +70,110 @@ export async function executeAuthLogin(parsed, context, api) {
87
70
  }
88
71
  };
89
72
  }
73
+ export async function executeAuthSignup(parsed, context, api) {
74
+ const prompts = parsed.json
75
+ ? {
76
+ ...context,
77
+ stdout: context.stderr
78
+ }
79
+ : context;
80
+ ensureInteractive(prompts, "auth signup");
81
+ const resolvedBaseUrl = await resolveAuthBaseUrl(parsed, context, prompts);
82
+ const { baseUrl } = resolvedBaseUrl;
83
+ const authSettings = await readAuthSettingsOrDefault(api, baseUrl);
84
+ const oidcLoginUrl = buildOidcStartUrl(baseUrl);
85
+ if (!authSettings.localEnabled) {
86
+ return {
87
+ data: {
88
+ loginUrl: oidcLoginUrl,
89
+ mode: authSettings.mode
90
+ },
91
+ human: [
92
+ "Local account signup is disabled for this deployment.",
93
+ `Open this URL in a browser: ${oidcLoginUrl}`,
94
+ "Account creation is managed by SSO for this deployment."
95
+ ].join("\n"),
96
+ kind: "access_auth_signup_sso_required",
97
+ meta: {
98
+ command: "auth signup",
99
+ orgId: null
100
+ }
101
+ };
102
+ }
103
+ if (authSettings.oidcEnabled) {
104
+ prompts.stdout.write(`SSO is also available at: ${oidcLoginUrl}\n`);
105
+ prompts.stdout.write("Continuing with local account signup.\n");
106
+ }
107
+ const name = await promptText("Name: ", prompts);
108
+ const email = await promptText("Email: ", prompts);
109
+ const password = await promptPassword("Password: ", prompts);
110
+ const session = await api.signup({ baseUrl, email, name, password });
111
+ const nextSession = await writeSessionWithSelectedOrg({
112
+ api,
113
+ context,
114
+ parsed,
115
+ prompts,
116
+ session
117
+ });
118
+ if (resolvedBaseUrl.shouldPersistGlobalBaseUrl) {
119
+ await writeCliConfig(context.configPath, {
120
+ ...resolvedBaseUrl.persistedGlobalConfig,
121
+ baseUrl
122
+ });
123
+ }
124
+ return {
125
+ data: {
126
+ activeOrg: nextSession.activeOrg,
127
+ user: nextSession.user
128
+ },
129
+ human: renderSuccess(nextSession.activeOrg
130
+ ? `Signed up as ${nextSession.user.email}. Active org: ${nextSession.activeOrg.slug}.`
131
+ : `Signed up as ${nextSession.user.email}.`),
132
+ kind: "access_auth_signup",
133
+ meta: {
134
+ command: "auth signup",
135
+ orgId: nextSession.activeOrg?.id ?? null
136
+ }
137
+ };
138
+ }
139
+ async function resolveAuthBaseUrl(parsed, context, prompts) {
140
+ const persistedGlobalConfig = await readCliConfig(context.configPath);
141
+ const repoConfigPath = await findRepoConfigPath(context.cwd);
142
+ const repoConfig = repoConfigPath ? await readCliConfig(repoConfigPath) : {};
143
+ const flagBaseUrl = readOptionalStringFlag(parsed, "base-url");
144
+ const envBaseUrl = context.env.KORA_BASE_URL;
145
+ const configuredBaseUrl = flagBaseUrl ?? envBaseUrl ?? repoConfig.baseUrl ?? persistedGlobalConfig.baseUrl;
146
+ const baseUrl = configuredBaseUrl ?? await promptText("Platform base URL: ", prompts);
147
+ return {
148
+ baseUrl,
149
+ persistedGlobalConfig,
150
+ shouldPersistGlobalBaseUrl: !flagBaseUrl && !envBaseUrl && !repoConfig.baseUrl
151
+ };
152
+ }
153
+ async function writeSessionWithSelectedOrg(input) {
154
+ const organizations = (await input.api.listOrganizations(input.session)).organizations;
155
+ const activeOrg = organizations.length === 1
156
+ ? organizations[0] ?? null
157
+ : organizations.length > 1
158
+ ? await chooseOrganization(organizations, input.prompts, input.parsed)
159
+ : null;
160
+ const latestSession = await readLatestSessionForWrite(input.context.sessionStore, input.session);
161
+ const sessionForWrite = isSameSessionIdentity(latestSession, input.session) ? latestSession : input.session;
162
+ const nextSession = {
163
+ ...sessionForWrite,
164
+ activeOrg: activeOrg
165
+ ? {
166
+ id: activeOrg.id,
167
+ name: activeOrg.name,
168
+ role: activeOrg.role,
169
+ slug: activeOrg.slug,
170
+ status: activeOrg.status
171
+ }
172
+ : null
173
+ };
174
+ await input.context.sessionStore.write(nextSession);
175
+ return nextSession;
176
+ }
90
177
  async function readAuthSettingsOrDefault(api, baseUrl) {
91
178
  try {
92
179
  return await api.getAuthSettings(baseUrl);
@@ -3,6 +3,7 @@ export declare function arg(name: string, description: string, required?: boolea
3
3
  export declare function flag(name: string, description: string, input?: {
4
4
  acceptsValue?: boolean;
5
5
  defaultValue?: boolean | number | string;
6
+ hiddenWhenCommandFiltered?: boolean;
6
7
  knownValues?: string[];
7
8
  repeatable?: boolean;
8
9
  required?: boolean;
@@ -10,6 +10,7 @@ export function flag(name, description, input = {}) {
10
10
  acceptsValue: input.acceptsValue ?? false,
11
11
  ...(input.defaultValue !== undefined ? { defaultValue: input.defaultValue } : {}),
12
12
  description,
13
+ ...(input.hiddenWhenCommandFiltered ? { hiddenWhenCommandFiltered: true } : {}),
13
14
  ...(input.knownValues ? { knownValues: input.knownValues } : {}),
14
15
  name,
15
16
  ...(input.repeatable ? { repeatable: true } : {}),
@@ -5,29 +5,27 @@ const COMMAND_GROUP_DESCRIPTIONS = new Map([
5
5
  ["access members", "Organization member inspection and membership lifecycle."],
6
6
  ["activity", "Recent workflow, agent, person, and capability activity."],
7
7
  ["admin", "Platform-admin lifecycle controls."],
8
- ["artifact", "Managed workflow artifact upload and inspection."],
8
+ ["artifact", "Managed runtime artifact upload and inspection."],
9
+ ["audit", "Organization admin audit event inspection."],
9
10
  ["auth", "Current identity and login session management."],
10
- ["chat", "Chat session inspection, draft state, and draft application."],
11
+ ["chat", "Chat session health and history inspection."],
11
12
  ["completion", "Shell completion and completion helpers."],
12
- ["env", "Runtime variables for the active organization."],
13
- ["integrations", "Backend-discovered integration catalog, diagnostics, and CLI-safe actions."],
14
- ["mcp", "Organization-managed MCP servers."],
15
- ["skills", "Organization-managed skill packages."],
13
+ ["deployment", "Environment deployment inspection."],
14
+ ["env", "Runtime variables for an environment."],
15
+ ["environment", "Deployment environments and environment actions."],
16
+ ["extensions", "Extension package, install, and built-in lifecycle."],
17
+ ["extensions built-ins", "Kora-provided built-in extension catalog and installation."],
16
18
  ["secrets", "Organization secret definitions."],
17
- ["org", "Organization selection, settings, import, and bundle inspection."],
18
- ["org bundle", "Current organization bundle inspection."],
19
+ ["org", "Organization selection and settings."],
19
20
  ["org settings", "Applied organization settings."],
20
21
  ["org-model", "Modeled people, roles, agents, assignments, capabilities, operations, and related inventory."],
21
22
  ["org-model agents", "Modeled agents in the executable organization model."],
22
23
  ["org-model assignments", "Role and capability assignments in the executable organization model."],
23
24
  ["org-model capabilities", "Modeled capabilities in the executable organization model."],
24
- ["org-model connectors", "Modeled connectors in the executable organization model."],
25
- ["org-model mcp-servers", "Modeled MCP servers in the executable organization model."],
26
25
  ["org-model operations", "Modeled operations in the executable organization model."],
27
26
  ["org-model people", "Modeled people in the executable organization model."],
28
27
  ["org-model roles", "Modeled roles in the executable organization model."],
29
- ["release", "Draft changes, releases, and deployment inspection."],
30
- ["release deployment", "Deployment inspection for a release."],
28
+ ["release", "Release artifacts and deployment readiness."],
31
29
  ["run", "Workflow run inspection and run control."],
32
30
  ["schema", "Product and resource schemas."],
33
31
  ["task", "Task and inbox inspection plus task completion."],