@ekanos/cli 0.21.0 → 0.22.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apps-api.js +1 -1
- package/dist/apps-api.js.map +1 -1
- package/dist/commands/names.js +2 -2
- package/dist/commands/names.js.map +1 -1
- package/dist/commands/publish.js +1 -1
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/sources.js +2 -2
- package/dist/commands/sources.js.map +1 -1
- package/dist/commands/team-agent-readiness.js +1 -1
- package/dist/commands/team-agent-readiness.js.map +1 -1
- package/dist/commands/teams-channel-install.js +1 -1
- package/dist/commands/teams-channel-install.js.map +1 -1
- package/dist/commands/teams-connect.js +2 -2
- package/dist/commands/teams-connect.js.map +1 -1
- package/dist/commands/teams.js +2 -2
- package/dist/commands/teams.js.map +1 -1
- package/dist/commands/use.js +1 -1
- package/dist/commands/use.js.map +1 -1
- package/dist/connections-api.js +1 -1
- package/dist/connections-api.js.map +1 -1
- package/dist/experience/definition-checks.js +1 -1
- package/dist/experience/definition-checks.js.map +1 -1
- package/dist/experience/definition-shape.d.ts +4 -1
- package/dist/experience/definition-shape.js.map +1 -1
- package/dist/generated/fa-free-names.d.ts +2 -2
- package/dist/generated/fa-free-names.js +5 -5
- package/dist/generated/fa-free-names.js.map +1 -1
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/publish-api.js +1 -2
- package/dist/publish-api.js.map +1 -1
- package/dist/runs-api.js +1 -1
- package/dist/runs-api.js.map +1 -1
- package/dist/schema-skew.js.map +1 -1
- package/dist/secret-form.js +1 -1
- package/dist/secret-form.js.map +1 -1
- package/dist/source-products-api.js +1 -1
- package/dist/source-products-api.js.map +1 -1
- package/dist/teams-api.js +2 -2
- package/dist/teams-api.js.map +1 -1
- package/dist/workflows-api.js +1 -1
- package/dist/workflows-api.js.map +1 -1
- package/package.json +2 -2
- package/templates/AGENTS.md.tmpl +24 -8
- package/templates/experience/AGENTS.md.tmpl +3 -1
- package/templates/experience/package.json.tmpl +4 -4
- package/templates/experience/src/widgets/hello-widget.tsx.tmpl +3 -1
- package/templates/package.json.tmpl +4 -4
- package/templates/skills/build-integration/SKILL.md +2 -1
- package/templates/skills/build-integration/references/api-wiring.md +4 -2
package/dist/apps-api.js
CHANGED
|
@@ -42,7 +42,7 @@ async function call(host, accessToken, schema, product, init) {
|
|
|
42
42
|
}
|
|
43
43
|
if (response.status === 404) {
|
|
44
44
|
throw notFoundError(message !== null && message !== void 0 ? message : `"${product}" was not found.`, code === 'PRODUCT_NOT_ENTITLED'
|
|
45
|
-
? `"ekanos sources products" shows what this Source has; only
|
|
45
|
+
? `"ekanos sources products" shows what this Source has; only Ekanos enables a product for a Source.`
|
|
46
46
|
: 'Run "ekanos sources" to list the sources you hold a seat on.');
|
|
47
47
|
}
|
|
48
48
|
if (response.status === 409 && code === 'NO_PROVIDER_APP') {
|
package/dist/apps-api.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apps-api.js","sourceRoot":"","sources":["../src/apps-api.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"apps-api.js","sourceRoot":"","sources":["../src/apps-api.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type ProviderAppSetResult,\n ProviderAppSetResultSchema,\n type ProviderAppStatus,\n ProviderAppStatusSchema,\n} from '@ekanos/integration-schema';\nimport type { z } from 'zod';\n\nimport { request } from './auth/ekanos-api';\nimport {\n authRequiredError,\n forbiddenError,\n invalidStateError,\n networkError,\n notFoundError,\n usageError,\n} from './errors';\n\n/**\n * The CLI's client for a Source's provider apps — the OAuth client an\n * integration signs every team in through.\n *\n * GET /api/partner/apps/<product>?source=<slug|id> → { ok, data: ProviderAppStatus }\n * PUT /api/partner/apps/<product> { source, clientId, clientSecret }\n * → { ok, data: ProviderAppStatus & { replaced } }\n *\n * → 401 / 3xx refresh once and retry\n * → 403 { code: \"SOURCE_ADMIN_REQUIRED\" | \"MFA_REQUIRED\" | \"FORBIDDEN\" }\n * → 404 { code: \"PRODUCT_NOT_ENTITLED\" | \"SOURCE_NOT_FOUND\" }\n * → 409 { code: \"NO_PROVIDER_APP\" }\n */\n\nexport type AppsApiResult<T> =\n | { status: 'ok'; data: T }\n | { status: 'unauthorized' };\n\nexport function showProviderApp(\n host: string,\n accessToken: string,\n source: string,\n product: string,\n): Promise<AppsApiResult<ProviderAppStatus>> {\n return call(host, accessToken, ProviderAppStatusSchema, product, {\n method: 'GET',\n path: `${route(product)}?${new URLSearchParams({ source })}`,\n });\n}\n\nexport function setProviderApp(\n host: string,\n accessToken: string,\n body: {\n source: string;\n product: string;\n /** Either or both: one left out keeps what is stored. */\n clientId?: string;\n clientSecret?: string;\n },\n): Promise<AppsApiResult<ProviderAppSetResult>> {\n return call(host, accessToken, ProviderAppSetResultSchema, body.product, {\n method: 'PUT',\n path: route(body.product),\n body: {\n source: body.source,\n ...(body.clientId ? { clientId: body.clientId } : {}),\n ...(body.clientSecret ? { clientSecret: body.clientSecret } : {}),\n },\n });\n}\n\nfunction route(product: string): string {\n return `/api/partner/apps/${encodeURIComponent(product)}`;\n}\n\nasync function call<T>(\n host: string,\n accessToken: string,\n schema: z.ZodType<T>,\n product: string,\n init: { method: 'GET' | 'PUT'; path: string; body?: unknown },\n): Promise<AppsApiResult<T>> {\n const response = await request(`${host}${init.path}`, {\n method: init.method,\n headers: {\n accept: 'application/json',\n authorization: `Bearer ${accessToken}`,\n ...(init.body === undefined\n ? {}\n : { 'content-type': 'application/json' }),\n },\n body: init.body === undefined ? undefined : JSON.stringify(init.body),\n });\n\n if (\n response.status === 401 ||\n (response.status >= 300 && response.status < 400)\n ) {\n return { status: 'unauthorized' };\n }\n\n const body = await readOptionalJson(response);\n const code = typeof body.code === 'string' ? body.code : null;\n const message =\n typeof body.error === 'string' && body.error ? body.error : null;\n\n if (response.status === 403 && code === 'MFA_REQUIRED') {\n throw authRequiredError(\n message ?? `${host} requires multi-factor authentication.`,\n 'Complete MFA in the browser, then run \"ekanos login\" again.',\n );\n }\n if (response.status === 403) {\n throw forbiddenError(\n message ?? 'Not permitted on this Source.',\n code === 'SOURCE_ADMIN_REQUIRED'\n ? \"Only a Source admin manages the Source's apps. Ask one to run it.\"\n : 'Run \"ekanos sources\" to list the sources you hold a seat on.',\n );\n }\n if (response.status === 404) {\n throw notFoundError(\n message ?? `\"${product}\" was not found.`,\n code === 'PRODUCT_NOT_ENTITLED'\n ? `\"ekanos sources products\" shows what this Source has; only Ekanos enables a product for a Source.`\n : 'Run \"ekanos sources\" to list the sources you hold a seat on.',\n );\n }\n if (response.status === 409 && code === 'NO_PROVIDER_APP') {\n throw invalidStateError(\n message ?? `\"${product}\" has no app for the Source to set up.`,\n `Each team connects ${product} with its own app: \"ekanos teams app set <team> ${product}\", then \"ekanos teams connect <team> ${product}\". \"ekanos catalog ${product}\" shows its setup steps.`,\n );\n }\n if (response.status === 400) {\n throw usageError(\n message ?? 'The host refused the request.',\n 'See \"ekanos apps --help\".',\n );\n }\n if (!response.ok) {\n throw networkError(\n `${host}${init.path.split('?')[0]} responded ${response.status}.`,\n response.status >= 500\n ? 'The Ekanos deployment returned a server error. Retry shortly.'\n : 'Confirm the host runs a build that includes the apps routes.',\n );\n }\n\n const parsed = schema.safeParse(body.data);\n if (!parsed.success) {\n throw networkError(\n `${host}/api/partner/apps answered in a shape this CLI does not read.`,\n 'Run \"ekanos upgrade\" — the CLI and the host disagree on the apps contract.',\n );\n }\n return { status: 'ok', data: parsed.data };\n}\n\nasync function readOptionalJson(\n response: Response,\n): Promise<Record<string, unknown>> {\n try {\n const parsed: unknown = await response.json();\n return typeof parsed === 'object' && parsed !== null\n ? (parsed as Record<string, unknown>)\n : {};\n } catch {\n return {};\n }\n}\n"]}
|
package/dist/commands/names.js
CHANGED
|
@@ -42,7 +42,7 @@ export async function runNames(ctx, args) {
|
|
|
42
42
|
['Source', source],
|
|
43
43
|
],
|
|
44
44
|
notes: [
|
|
45
|
-
'
|
|
45
|
+
'Ekanos decides it. Check with "ekanos names status ' +
|
|
46
46
|
`${claim.slug}".`,
|
|
47
47
|
'Until it is approved, publish restricted: the package is named under your Source namespace.',
|
|
48
48
|
],
|
|
@@ -69,7 +69,7 @@ function statusTitle(status) {
|
|
|
69
69
|
case 'none':
|
|
70
70
|
return `No claim for ${status.slug}`;
|
|
71
71
|
case 'requested':
|
|
72
|
-
return `The claim for ${status.slug} is waiting for
|
|
72
|
+
return `The claim for ${status.slug} is waiting for Ekanos`;
|
|
73
73
|
case 'approved':
|
|
74
74
|
return `${status.slug} is an approved global name`;
|
|
75
75
|
case 'rejected':
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/commands/names.ts"],"names":[],"mappings":"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","sourcesContent":["import { SLUG_PATTERN } from '@ekanos/integration-schema';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport { authRequiredError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport {\n type NameClaimStatus,\n type NamesApiResult,\n getNameClaim,\n requestNameClaim,\n} from '../names-api';\nimport { resolveSourceTarget } from '../source-target';\n\nexport const NAMES_SUBCOMMANDS = ['claim', 'status'] as const;\ntype NamesSubcommand = (typeof NAMES_SUBCOMMANDS)[number];\n\nconst USAGE =\n 'Run one of: ekanos names claim <slug> [--reason <text>] [--source <slug>], ekanos names status <slug> [--source <slug>].';\n\nexport interface NamesArgs {\n host?: string;\n source?: string;\n /** `claim <slug>`, `status <slug>`. */\n positionals: readonly string[];\n reason?: string;\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `names` - a global package name is approved by a super admin. `claim`\n * requests one for a slug; `status` says where the request stands. A package\n * that is not global needs no claim: it is named under the Source's own\n * namespace.\n */\nexport async function runNames(\n ctx: CliContext,\n args: NamesArgs,\n): Promise<ExitCode> {\n const [rawSubcommand, rawSlug, ...extra] = args.positionals;\n const subcommand = parseSubcommand(rawSubcommand);\n if (extra.length > 0) {\n throw usageError(`Unexpected argument \"${extra[0]}\".`, USAGE);\n }\n if (subcommand === 'status' && args.reason !== undefined) {\n throw usageError('names status takes no --reason.', USAGE);\n }\n const slug = requireSlug(rawSlug, subcommand);\n const reason = args.reason?.trim() || undefined;\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const call = withOneRefresh(env, resolved.session);\n const source = resolved.source;\n\n if (subcommand === 'claim') {\n const claim = await call((token) =>\n requestNameClaim(env.host, token, {\n source,\n slug,\n ...(reason ? { reason } : {}),\n }),\n );\n\n return ctx.succeed(\n { host: env.host, source, ...claim },\n ctx.ui.result({\n title: `Requested the global name ${claim.slug}`,\n tone: 'ok',\n rows: [\n ['Name', claim.slug],\n ['Status', claim.status],\n ['Source', source],\n ],\n notes: [\n 'A super admin decides it. Check with \"ekanos names status ' +\n `${claim.slug}\".`,\n 'Until it is approved, publish restricted: the package is named under your Source namespace.',\n ],\n }),\n );\n }\n\n const status = await call((token) =>\n getNameClaim(env.host, token, source, slug),\n );\n\n return ctx.succeed(\n { host: env.host, source, ...status },\n ctx.ui.result({\n title: statusTitle(status),\n tone: status.status === 'approved' ? 'ok' : 'warn',\n rows: [\n ['Name', status.slug],\n ['Status', status.status],\n ...(status.requestedAt\n ? [['Requested', status.requestedAt] as const]\n : []),\n ...(status.decidedAt ? [['Decided', status.decidedAt] as const] : []),\n ...(status.reason ? [['Reason', status.reason] as const] : []),\n ],\n notes: statusNotes(status),\n }),\n );\n}\n\nfunction statusTitle(status: NameClaimStatus): string {\n switch (status.status) {\n case 'none':\n return `No claim for ${status.slug}`;\n case 'requested':\n return `The claim for ${status.slug} is waiting for a super admin`;\n case 'approved':\n return `${status.slug} is an approved global name`;\n case 'rejected':\n return `The claim for ${status.slug} was rejected`;\n }\n}\n\nfunction statusNotes(status: NameClaimStatus): string[] {\n switch (status.status) {\n case 'none':\n return [`Request it: \"ekanos names claim ${status.slug}\".`];\n case 'requested':\n return ['Publish restricted in the meantime.'];\n case 'approved':\n return ['Publish with availability.mode \"global\" in ekanos.json.'];\n case 'rejected':\n return [\n 'Publish restricted under your Source namespace, or claim a different name.',\n ];\n }\n}\n\nfunction withOneRefresh(env: AuthEnvironment, initial: StoredSession) {\n let session = initial;\n\n return async <T>(\n send: (accessToken: string) => Promise<NamesApiResult<T>>,\n ): Promise<T> => {\n let result = await send(session.accessToken);\n if (result.status === 'unauthorized') {\n session = await refreshStoredSession(env, session);\n result = await send(session.accessToken);\n }\n if (result.status === 'ok') return result.data;\n throw authRequiredError(\n `The session for ${env.host} could not authorize the names call.`,\n loginHint(env),\n );\n };\n}\n\nfunction parseSubcommand(value: string | undefined): NamesSubcommand {\n const match = NAMES_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown names subcommand \"${value}\".`\n : 'names needs a subcommand.',\n USAGE,\n );\n}\n\nfunction requireSlug(\n value: string | undefined,\n subcommand: NamesSubcommand,\n): string {\n const slug = value?.trim().toLowerCase();\n if (slug && SLUG_PATTERN.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a package slug (kebab-case, no namespace).`\n : 'Name the package slug.',\n `e.g. \"ekanos names ${subcommand} google-drive\". ekanos.json keeps the bare slug.`,\n );\n}\n"]}
|
|
1
|
+
{"version":3,"file":"names.js","sourceRoot":"","sources":["../../src/commands/names.ts"],"names":[],"mappings":"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","sourcesContent":["import { SLUG_PATTERN } from '@ekanos/integration-schema';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport { authRequiredError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport {\n type NameClaimStatus,\n type NamesApiResult,\n getNameClaim,\n requestNameClaim,\n} from '../names-api';\nimport { resolveSourceTarget } from '../source-target';\n\nexport const NAMES_SUBCOMMANDS = ['claim', 'status'] as const;\ntype NamesSubcommand = (typeof NAMES_SUBCOMMANDS)[number];\n\nconst USAGE =\n 'Run one of: ekanos names claim <slug> [--reason <text>] [--source <slug>], ekanos names status <slug> [--source <slug>].';\n\nexport interface NamesArgs {\n host?: string;\n source?: string;\n /** `claim <slug>`, `status <slug>`. */\n positionals: readonly string[];\n reason?: string;\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `names` - a global package name is approved by a super admin. `claim`\n * requests one for a slug; `status` says where the request stands. A package\n * that is not global needs no claim: it is named under the Source's own\n * namespace.\n */\nexport async function runNames(\n ctx: CliContext,\n args: NamesArgs,\n): Promise<ExitCode> {\n const [rawSubcommand, rawSlug, ...extra] = args.positionals;\n const subcommand = parseSubcommand(rawSubcommand);\n if (extra.length > 0) {\n throw usageError(`Unexpected argument \"${extra[0]}\".`, USAGE);\n }\n if (subcommand === 'status' && args.reason !== undefined) {\n throw usageError('names status takes no --reason.', USAGE);\n }\n const slug = requireSlug(rawSlug, subcommand);\n const reason = args.reason?.trim() || undefined;\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const call = withOneRefresh(env, resolved.session);\n const source = resolved.source;\n\n if (subcommand === 'claim') {\n const claim = await call((token) =>\n requestNameClaim(env.host, token, {\n source,\n slug,\n ...(reason ? { reason } : {}),\n }),\n );\n\n return ctx.succeed(\n { host: env.host, source, ...claim },\n ctx.ui.result({\n title: `Requested the global name ${claim.slug}`,\n tone: 'ok',\n rows: [\n ['Name', claim.slug],\n ['Status', claim.status],\n ['Source', source],\n ],\n notes: [\n 'Ekanos decides it. Check with \"ekanos names status ' +\n `${claim.slug}\".`,\n 'Until it is approved, publish restricted: the package is named under your Source namespace.',\n ],\n }),\n );\n }\n\n const status = await call((token) =>\n getNameClaim(env.host, token, source, slug),\n );\n\n return ctx.succeed(\n { host: env.host, source, ...status },\n ctx.ui.result({\n title: statusTitle(status),\n tone: status.status === 'approved' ? 'ok' : 'warn',\n rows: [\n ['Name', status.slug],\n ['Status', status.status],\n ...(status.requestedAt\n ? [['Requested', status.requestedAt] as const]\n : []),\n ...(status.decidedAt ? [['Decided', status.decidedAt] as const] : []),\n ...(status.reason ? [['Reason', status.reason] as const] : []),\n ],\n notes: statusNotes(status),\n }),\n );\n}\n\nfunction statusTitle(status: NameClaimStatus): string {\n switch (status.status) {\n case 'none':\n return `No claim for ${status.slug}`;\n case 'requested':\n return `The claim for ${status.slug} is waiting for Ekanos`;\n case 'approved':\n return `${status.slug} is an approved global name`;\n case 'rejected':\n return `The claim for ${status.slug} was rejected`;\n }\n}\n\nfunction statusNotes(status: NameClaimStatus): string[] {\n switch (status.status) {\n case 'none':\n return [`Request it: \"ekanos names claim ${status.slug}\".`];\n case 'requested':\n return ['Publish restricted in the meantime.'];\n case 'approved':\n return ['Publish with availability.mode \"global\" in ekanos.json.'];\n case 'rejected':\n return [\n 'Publish restricted under your Source namespace, or claim a different name.',\n ];\n }\n}\n\nfunction withOneRefresh(env: AuthEnvironment, initial: StoredSession) {\n let session = initial;\n\n return async <T>(\n send: (accessToken: string) => Promise<NamesApiResult<T>>,\n ): Promise<T> => {\n let result = await send(session.accessToken);\n if (result.status === 'unauthorized') {\n session = await refreshStoredSession(env, session);\n result = await send(session.accessToken);\n }\n if (result.status === 'ok') return result.data;\n throw authRequiredError(\n `The session for ${env.host} could not authorize the names call.`,\n loginHint(env),\n );\n };\n}\n\nfunction parseSubcommand(value: string | undefined): NamesSubcommand {\n const match = NAMES_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown names subcommand \"${value}\".`\n : 'names needs a subcommand.',\n USAGE,\n );\n}\n\nfunction requireSlug(\n value: string | undefined,\n subcommand: NamesSubcommand,\n): string {\n const slug = value?.trim().toLowerCase();\n if (slug && SLUG_PATTERN.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a package slug (kebab-case, no namespace).`\n : 'Name the package slug.',\n `e.g. \"ekanos names ${subcommand} google-drive\". ekanos.json keeps the bare slug.`,\n );\n}\n"]}
|
package/dist/commands/publish.js
CHANGED
|
@@ -346,7 +346,7 @@ export async function verifyPublishTarget(ctx, env, session, args) {
|
|
|
346
346
|
}
|
|
347
347
|
function seatsHint(sources, host) {
|
|
348
348
|
if (sources.length === 0) {
|
|
349
|
-
return (`You hold no seats on any source on ${host}. Ask
|
|
349
|
+
return (`You hold no seats on any source on ${host}. Ask Ekanos ` +
|
|
350
350
|
`to grant your account the developer seat on the intended source.`);
|
|
351
351
|
}
|
|
352
352
|
return (`You hold a seat on: ${describeSeats(sources)}. Pass "--source <slug>" ` +
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Finding } from '@ekanos/integration-schema';\nimport { findRepoRoot } from '@ekanos/integration-schema/repo';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport {\n CliError,\n forbiddenError,\n gateFailedError,\n preconditionError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { readProjectKind } from '../experience/project';\nimport { runExperiencePublish } from '../experience/publish';\nimport { renderFindings } from '../findings-renderer';\nimport { type SlugLookup, lookupSlug } from '../names-api';\nimport { packProject } from '../pack';\nimport { type LoadedProject, loadProject, serializeProject } from '../project';\nimport {\n MAX_MANIFEST_BYTES,\n globalNameUnapprovedError,\n stillUnauthorized,\n submitArchive,\n} from '../publish-api';\nimport { runRepoPublish } from '../repo/publish';\nimport { assertSchemaNotSkewed } from '../schema-skew';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { shortHost } from '../ui';\nimport { announceUpdate, checkForUpdate } from '../update-notice';\nimport { collectAllFindings } from '../validate-findings';\n\n/**\n * Checks that are WARN in plain `ekanos validate` but must refuse a\n * `publish` outright: a project that will fail the gate is not allowed to\n * upload and find that out from the gate instead of from itself.\n * `project.host-compiler-rules` (see `project-checks.ts`) is WARN-severity\n * everywhere else on purpose — it reads a partner's local tsconfig, not the\n * gate's own verdict, so it must not block plain validate on a false\n * positive — but at the publish gate, \"this WILL fail the gate\" is exactly\n * the thing a submission preflight exists to refuse. A list, not a second\n * check, so the underlying rule and its message/hint stay defined in exactly\n * one place.\n */\nconst PUBLISH_ERROR_ESCALATIONS: readonly string[] = [\n 'project.host-compiler-rules',\n];\n\n/**\n * Escalate the checks in `PUBLISH_ERROR_ESCALATIONS` from `warn` to `error`\n * for THIS publish run only — `validate`'s own output (and the underlying\n * finding objects elsewhere) is never touched.\n */\nexport function escalateForPublish(findings: Finding[]): Finding[] {\n return findings.map((finding) =>\n finding.severity === 'warn' &&\n PUBLISH_ERROR_ESCALATIONS.includes(finding.check)\n ? { ...finding, severity: 'error' }\n : finding,\n );\n}\n\nexport interface PublishArgs {\n host?: string;\n /** Ekanos source slug. Falls back to ekanos.json's \"source\" field. */\n source?: string;\n /** Project directory (contains ekanos.json). Defaults to cwd. */\n dir: string;\n /**\n * Skips the interactive confirm when the source resolved IMPLICITLY (from\n * ekanos.json) and the caller holds more than one developer seat. Has no\n * effect when `--source` was passed this invocation (explicit is already\n * consent) or when the caller holds exactly one seat (nothing to\n * disambiguate).\n */\n yes: boolean;\n env: Record<string, string | undefined>;\n /**\n * Whether stdin is a real interactive terminal — the SECOND condition (with\n * human/non-JSON mode) required before publish will ever prompt. Defaults\n * to `process.stdin.isTTY === true`. Injectable so tests can exercise the\n * confirm branch without a real TTY.\n */\n stdinIsTTY?: boolean;\n /**\n * Injectable y/N prompt, for tests. Defaults to a real readline prompt over\n * stdin/stderr. Never invoked unless BOTH human mode and a real stdin TTY\n * are in play — see `canPrompt` in `verifyPublishTarget`.\n */\n confirm?: (question: string) => Promise<boolean>;\n /** Experiences only: build and pack, publish nothing. In a repo: every package. */\n dryRun?: boolean;\n /** Repo only: the packages to publish, by name. */\n packages?: readonly string[];\n /** Repo only: publish every package. */\n all?: boolean;\n}\n\n/** Where the resolved source slug came from — governs the confirmation rules below. */\nexport interface SourceResolution {\n source: string;\n /** True iff `--source` was passed THIS invocation. */\n explicit: boolean;\n}\n\n/**\n * `publish` — pack the project and submit it to an Ekanos deployment.\n *\n * The submission gate is the SAME findings pass `validate` runs (one\n * implementation, `validate-findings.ts`): any error-severity finding refuses\n * the publish with GATE_FAILED (exit 10) and the findings in `data`, so an\n * agent can branch on the code and fix-then-retry without re-running validate.\n *\n * Authorization is server-side — the dev seat on the target source — and the\n * stored session is refreshed once on a 401, mirroring `whoami`. On the first\n * successful publish the chosen source slug is persisted into `ekanos.json`\n * so later publishes need no `--source`.\n */\nexport async function runPublish(\n ctx: CliContext,\n args: PublishArgs,\n): Promise<ExitCode> {\n // Inside a repo, `publish` plans the packages: a same-repo integration is\n // ordered first rather than refused as an override.\n const repoRoot = findRepoRoot(path.resolve(args.dir));\n if (repoRoot) {\n return runRepoPublish(ctx, {\n repoRoot,\n cwd: path.resolve(args.dir),\n names: args.packages ?? [],\n all: args.all === true,\n publish: args,\n });\n }\n if ((args.packages?.length ?? 0) > 0 || args.all) {\n throw usageError(\n 'Package names and --all are for a repo.',\n 'Run this from a repo (see \"ekanos init --kind repo\"), or drop the names to publish this project.',\n );\n }\n\n // An experience is published (dry-run only, for now) by its own pipeline,\n // before any login: overrides and the gate refuse it first.\n if (readProjectKind(path.resolve(args.dir)) === 'experience') {\n return runExperiencePublish(ctx, {\n dir: args.dir,\n dryRun: args.dryRun === true,\n env: args.env,\n host: args.host,\n source: args.source,\n yes: args.yes,\n stdinIsTTY: args.stdinIsTTY,\n confirm: args.confirm,\n });\n }\n\n const prepared = await prepareIntegrationSubmission(ctx, args);\n const { loaded, version, slug } = prepared;\n\n ctx.log(`Validating ${slug} before publishing…`);\n\n const findings = escalateForPublish(await collectAllFindings(loaded));\n const errorCount = findings.filter((f) => f.severity === 'error').length;\n\n if (errorCount > 0) {\n // Same rule as `validate`: render the shared findings block to stderr\n // BEFORE the envelope settles, human mode only. JSON mode carries the\n // identical findings in `data.findings` and must stay byte-identical.\n // Closing order is findings block -> short summary (via `ctx.fail`'s\n // `findingsSummary` option) -> next action.\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.err(\n `${ctx.ui.glyphs.err} Refusing to publish: ${errorCount} finding` +\n `${errorCount === 1 ? '' : 's'}.`,\n ),\n );\n renderFindings(ctx, findings, { cwd: loaded.projectDir });\n }\n\n const exitCode = ctx.fail(\n gateFailedError(\n `Refusing to publish: ${errorCount} validation finding` +\n `${errorCount === 1 ? '' : 's'}.`,\n 'Resolve the error-severity findings in data.findings (they are ' +\n 'exactly what \"ekanos validate\" reports), then re-run ' +\n '\"ekanos publish\".',\n ),\n { slug, version, findings },\n !ctx.jsonMode\n ? { findingsSummary: { command: 'ekanos publish', errorCount } }\n : undefined,\n );\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.nextAction(\n 'ekanos validate',\n 'fix the error-severity findings above, then re-run \"ekanos publish\"',\n ),\n );\n }\n\n return exitCode;\n }\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.ok(\n `${ctx.ui.glyphs.ok} validated ${slug} — no error-severity findings.`,\n ),\n );\n }\n\n const submitted = await submitPrepared(ctx, args, prepared);\n\n return ctx.succeed(submitted.data, submitted.human);\n}\n\nexport interface SubmittedIntegration {\n data: Record<string, unknown>;\n human: string;\n}\n\n/**\n * Confirm the target, pack and submit one gated integration. The caller has\n * already passed the gate; this is the only part of `publish` that talks to\n * the host.\n */\nexport async function submitPrepared(\n ctx: CliContext,\n args: PublishArgs,\n prepared: PreparedSubmission,\n): Promise<SubmittedIntegration> {\n const { loaded, skew, notice, env, version, slug, resolution } = prepared;\n\n // The 100%-certainty mechanism: confirm the resolved source is one the\n // caller actually holds a seat on — and, when it was resolved IMPLICITLY\n // from ekanos.json with more than one seat in play, that a human (or an\n // explicit --yes) actually intends this target — BEFORE anything is packed\n // or sent over the wire.\n const verified = await verifyPublishTarget(ctx, env, resolution.session, {\n source: resolution.source,\n explicit: resolution.explicit,\n slug,\n version,\n yes: args.yes,\n stdinIsTTY: args.stdinIsTTY ?? process.stdin.isTTY === true,\n confirm: args.confirm ?? promptYesNo,\n });\n\n const source = verified.sourceSeat.slug;\n const availability = loaded.project.availability?.mode;\n\n // Say the full name the host will use, and refuse an unapproved global\n // name, before anything is packed.\n const lookup = await preflightName(\n ctx,\n env,\n verified.session,\n source,\n slug,\n availability,\n );\n\n ctx.log(`Packing ${slug}@${version}…`);\n\n const packed = packProject(loaded.projectDir);\n const manifest = buildManifest(loaded, packed.files);\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.ok(\n `${ctx.ui.glyphs.ok} packed ${slug}@${version} (${packed.files.length} files).`,\n ),\n );\n }\n\n ctx.log(`Submitting to ${env.host} (source \"${source}\")…`);\n\n const receipt = await submitWithOneRefresh(env, verified.session, {\n source,\n slug,\n version,\n manifest,\n archive: packed.archive,\n ...(availability ? { availability } : {}),\n });\n\n const displayName =\n receipt.displayName ?? lookup?.displayName ?? receipt.slug;\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.ok(\n `${ctx.ui.glyphs.ok} submitted ${displayName}@${receipt.version} ` +\n `(state \"${receipt.state}\").`,\n ),\n );\n }\n\n const persisted = persistProjectFields(loaded, source, env.host);\n\n const persistedNote = [\n ...(persisted.source ? [`\"source\": \"${source}\"`] : []),\n ...(persisted.host ? [`\"host\": \"${env.host}\"`] : []),\n ];\n\n return {\n data: {\n host: env.host,\n source: {\n id: verified.sourceSeat.id,\n slug: verified.sourceSeat.slug,\n name: verified.sourceSeat.name,\n },\n slug: receipt.slug,\n namespace: receipt.namespace ?? lookup?.namespace ?? null,\n displayName,\n version: receipt.version,\n submissionId: receipt.submissionId,\n state: receipt.state,\n archiveSha256: receipt.archiveSha256,\n files: packed.files,\n sourcePersisted: persisted.source,\n hostPersisted: persisted.host,\n hostOverride: persisted.hostOverride,\n ...(skew.status === 'project-older'\n ? {\n schemaSkew: {\n status: skew.status,\n cliSchemaVersion: skew.cliSchemaVersion,\n projectSchemaVersion: skew.projectSchemaVersion,\n },\n }\n : {}),\n ...(notice ? { toolchain: notice } : {}),\n },\n human: ctx.ui.result({\n title: 'Submitted',\n rows: [\n ['Integration', `${displayName}@${receipt.version}`],\n ['State', receipt.state],\n ['Source', source],\n ['Host', shortHost(env.host)],\n ...(persistedNote.length > 0\n ? [\n [\n 'Saved',\n `${persistedNote.join(' and ')} to ekanos.json`,\n ] as const,\n ]\n : []),\n ],\n notes: persisted.hostOverride\n ? [\n `This publish went to ${env.host}, but ekanos.json keeps \"host\": ` +\n `\"${persisted.hostOverride}\" — a one-off override never replaces ` +\n 'the saved host; edit ekanos.json to change it.',\n ]\n : [],\n }),\n };\n}\n\n/**\n * Ask the host what it will call this slug for the Source, before packing.\n * An unapproved global name stops the publish here. Any other answer - an\n * older host without the route, a server error, a shape this CLI does not\n * read - is not a reason to stop: the submission itself is authoritative, and\n * the bare slug stands in for the name.\n */\nasync function preflightName(\n ctx: CliContext,\n env: AuthEnvironment,\n session: StoredSession,\n source: string,\n slug: string,\n availability: 'global' | 'restricted' | undefined,\n): Promise<SlugLookup | null> {\n let lookup: SlugLookup | null = null;\n\n try {\n let result = await lookupSlug(\n env.host,\n session.accessToken,\n source,\n slug,\n availability,\n );\n if (result.status === 'unauthorized') {\n const refreshed = await refreshStoredSession(env, session);\n result = await lookupSlug(\n env.host,\n refreshed.accessToken,\n source,\n slug,\n availability,\n );\n }\n if (result.status === 'ok') lookup = result.lookup;\n } catch (error) {\n if (!(error instanceof CliError)) throw error;\n ctx.log(\n `Could not pre-check the name of ${slug} (${error.message}); continuing.`,\n );\n }\n\n if (lookup?.status === 'global_unapproved') {\n throw globalNameUnapprovedError(slug);\n }\n\n if (lookup?.displayName && !ctx.jsonMode) {\n ctx.log(`Publishing as ${lookup.displayName}.`);\n }\n\n return lookup;\n}\n\nexport interface PreparedSubmission {\n env: AuthEnvironment;\n session: StoredSession;\n loaded: LoadedProject;\n skew: ReturnType<typeof assertSchemaNotSkewed>;\n notice: Awaited<ReturnType<typeof checkForUpdate>>;\n resolution: SourceResolution & { session: StoredSession };\n version: string;\n slug: string;\n}\n\n/**\n * Everything `publish` does before it gates a project: sign-in, load, schema\n * skew, toolchain check, source resolution. Shared by the single-project verb\n * and the repo verb (which gates every package before submitting any).\n */\nexport async function prepareIntegrationSubmission(\n ctx: CliContext,\n args: PublishArgs,\n): Promise<PreparedSubmission> {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const session = requireSession(env);\n\n const loaded = loadProject(args.dir);\n\n // Fail fast, before anything else: a project whose schema is newer than\n // this CLI bundles cannot be trusted to validate correctly, so publishing\n // it — the one verb whose findings gate is meant to be authoritative —\n // must refuse before packing or submitting anything. See `schema-skew.ts`.\n const skew = assertSchemaNotSkewed(ctx, loaded.projectDir);\n\n const notice = await checkForUpdate({\n env: args.env,\n host: env.host,\n session,\n });\n announceUpdate(ctx, notice);\n\n // The host would reject a build from a CLI it has declared unsupported\n // anyway (see the wire contract in `toolchain-api.ts`) — refuse here with a\n // hint naming the fix, rather than let the submission round-trip fail with\n // whatever generic error the host happens to answer with.\n if (notice?.status === 'unsupported') {\n throw preconditionError(\n `@ekanos/cli ${notice.current.cli} is below ${env.host}'s minimum ` +\n `supported version (needs at least ${notice.target.cli}).`,\n 'Run \"ekanos upgrade\" before publishing — the host will refuse this ' +\n 'submission from an unsupported CLI regardless.',\n );\n }\n\n const resolution = await resolveSourceSlug(env, session, args.source, loaded);\n const version = readProjectVersion(loaded.projectDir);\n const slug = loaded.primary.slug;\n\n return { env, session, loaded, skew, notice, resolution, version, slug };\n}\n\n/**\n * The publish-target verification gate.\n *\n * FORBIDDEN (exit 5) whenever the resolved source is not among the caller's\n * seats — regardless of whether it came from `--source` or ekanos.json.\n * Beyond that, the confirmation rules branch on how the source was resolved:\n *\n * - `--source` THIS invocation: explicit is consent. Proceed.\n * - ekanos.json, exactly one seat held (which must be the match, or the\n * FORBIDDEN check above would have already fired): proceed, but say so —\n * there is nothing to disambiguate, but the target should never be silent.\n * - ekanos.json, multiple seats held: the ambiguous case this mechanism\n * exists for. Only when BOTH human (non-JSON) mode AND stdin is a real\n * TTY does it print the target and require an explicit y/N confirm\n * (`--yes` skips it) — see `canPrompt` below for why stdin matters, not\n * just stdout. Every other combination (JSON mode, or human mode with a\n * closed/non-interactive stdin) NEVER prompts — it proceeds only with\n * `--yes`, otherwise VALIDATION (exit 3) with the seat list, naming\n * `--source`, `--yes` and `ekanos use`.\n */\nexport async function verifyPublishTarget(\n ctx: CliContext,\n env: AuthEnvironment,\n session: StoredSession,\n args: SourceResolution & {\n slug: string;\n version: string;\n yes: boolean;\n /** Real interactivity signal for stdin — see `canPrompt` below. */\n stdinIsTTY: boolean;\n confirm: (question: string) => Promise<boolean>;\n },\n): Promise<{ sourceSeat: SourceSeat; session: StoredSession }> {\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env);\n }\n\n const seat = result.sources.find((s) => s.slug === args.source);\n\n if (!seat) {\n throw forbiddenError(\n `This account does not hold a seat on source \"${args.source}\" on ${env.host}.`,\n seatsHint(result.sources, env.host),\n );\n }\n\n if (args.explicit) {\n return { sourceSeat: seat, session: result.session };\n }\n\n if (result.sources.length === 1) {\n ctx.log(\n `Publishing to ${seat.name ?? seat.slug} (${seat.slug}) — your only ` +\n `developer seat.`,\n );\n return { sourceSeat: seat, session: result.session };\n }\n\n // Implicit source, multiple seats: the ambiguous case.\n //\n // `ctx.jsonMode` alone is NOT enough to decide whether an interactive\n // confirm is safe: `--no-json` forces human mode even when stdout is\n // piped, and neither `--no-json` nor a bare human run says anything about\n // stdin. Prompting `readline`'s `.question()` against a closed/non-TTY\n // stdin (a cron job, a wrapper script piping stdout but not attached to a\n // terminal) never resolves — the process hangs instead of exiting with a\n // clean code. So an actual prompt requires BOTH: human mode AND a real\n // stdin TTY. Anything else — JSON mode, or human mode with non-interactive\n // stdin — falls through to the same non-prompting `--yes`-or-refuse rule.\n const canPrompt = !ctx.jsonMode && args.stdinIsTTY;\n\n if (canPrompt) {\n ctx.log(\n `Publishing ${args.slug}@${args.version} to SOURCE ${seat.name ?? seat.slug} ` +\n `(${seat.slug}) on ${env.host}`,\n );\n\n if (!args.yes) {\n const confirmed = await args.confirm('Proceed? [y/N]');\n\n if (!confirmed) {\n throw validationError(\n `Publish to \"${seat.slug}\" was not confirmed.`,\n multiSeatHint(result.sources),\n );\n }\n }\n\n return { sourceSeat: seat, session: result.session };\n }\n\n if (args.yes) {\n return { sourceSeat: seat, session: result.session };\n }\n\n throw validationError(\n `Ambiguous publish target: this account holds ${result.sources.length} ` +\n `developer seats and the source was resolved from ekanos.json, not ` +\n `an explicit flag.`,\n multiSeatHint(result.sources),\n );\n}\n\nfunction seatsHint(sources: SourceSeat[], host: string): string {\n if (sources.length === 0) {\n return (\n `You hold no seats on any source on ${host}. Ask an Ekanos super-admin ` +\n `to grant your account the developer seat on the intended source.`\n );\n }\n\n return (\n `You hold a seat on: ${describeSeats(sources)}. Pass \"--source <slug>\" ` +\n `naming one of these, or run \"ekanos use <slug>\" to set the project's ` +\n `default.`\n );\n}\n\nfunction multiSeatHint(sources: SourceSeat[]): string {\n return (\n `You hold seats on: ${describeSeats(sources)}. Pass \"--source <slug>\" ` +\n `to name the target explicitly, add \"--yes\" to confirm the target ` +\n `already in ekanos.json non-interactively, or run \"ekanos use <slug>\" ` +\n `to change the project's default.`\n );\n}\n\nfunction describeSeats(sources: SourceSeat[]): string {\n return sources.map((s) => `${s.slug} (${s.roles.join(', ')})`).join(', ');\n}\n\n/**\n * The real, non-test y/N prompt. Reads a line from stdin and writes the\n * question to stderr, so it never touches stdout — the one stream the JSON\n * envelope invariant depends on. Only reachable when `verifyPublishTarget`'s\n * `canPrompt` is true — human mode AND a real stdin TTY — so this never\n * blocks on a closed or non-interactive stdin.\n */\n/**\n * Exported so `upgrade` can reuse the exact same y/N prompt rather than\n * writing a second one — see `canPrompt` above for the stdin-TTY gating this\n * is only ever invoked behind.\n */\nexport async function promptYesNo(question: string): Promise<boolean> {\n const readline = await import('node:readline/promises');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n try {\n const answer = await rl.question(`${question} `);\n return /^y(es)?$/i.test(answer.trim());\n } finally {\n rl.close();\n }\n}\n\nexport async function submitWithOneRefresh(\n env: ReturnType<typeof resolveAuthEnvironment>,\n session: StoredSession,\n payload: Parameters<typeof submitArchive>[2],\n) {\n const first = await submitArchive(env.host, session.accessToken, payload);\n\n if (first.status === 'ok') return first.receipt;\n\n // The access token no longer authenticates — an ordinary event, not an\n // error. One refresh, one retry; a second 401 is authoritative.\n const refreshed = await refreshStoredSession(env, session);\n const second = await submitArchive(env.host, refreshed.accessToken, payload);\n\n if (second.status === 'ok') return second.receipt;\n\n return stillUnauthorized(env);\n}\n\n/**\n * Resolve the source slug (flag → ekanos.json) and whether it was given\n * EXPLICITLY this invocation — the fact `verifyPublishTarget` uses to decide\n * whether a confirmation is even in play. `flag !== undefined` (rather than\n * \"non-empty after trim\") is deliberate: an explicit `--source` that is\n * effectively empty is still a caller who typed the flag, not one who\n * fell through to ekanos.json.\n */\nexport async function resolveSourceSlug(\n env: AuthEnvironment,\n session: StoredSession,\n flag: string | undefined,\n /** Anything that carries the project's saved `source`: an integration project or an experience's ekanos.json. */\n loaded: { project: { source?: string } },\n): Promise<SourceResolution & { session: StoredSession }> {\n const explicit = flag !== undefined;\n const raw = flag ?? loaded.project.source;\n\n if (!raw || raw.trim().length === 0) {\n return noSourceError(env, session);\n }\n\n return { source: raw.trim(), explicit, session };\n}\n\n/**\n * The no-source validation error, enriched with the caller's seat list when\n * it can be fetched — best-effort, since a session is guaranteed to exist\n * here (publish already called `requireSession`) but the fetch itself can\n * still fail (network, MFA, a down deployment). A failure to enrich must\n * never mask or replace the primary \"no source given\" error.\n */\nasync function noSourceError(\n env: AuthEnvironment,\n session: StoredSession,\n): Promise<never> {\n let seatsNote = '';\n\n try {\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'ok') {\n seatsNote =\n result.sources.length > 0\n ? ` You hold a seat on: ${describeSeats(result.sources)}.`\n : ' You hold no seats on any source on this host yet.';\n }\n } catch {\n // Best-effort — the primary error below stands on its own.\n }\n\n throw validationError(\n 'No Ekanos source given for the submission.',\n 'Pass \"--source <slug>\" (your operator names the source), or set ' +\n '\"source\": \"<slug>\" in ekanos.json. A successful publish saves it ' +\n `there for you.${seatsNote}`,\n );\n}\n\n/**\n * Persist the chosen source AND host into ekanos.json after a SUCCESSFUL\n * publish, so the next publish — and every other host-taking verb — needs no\n * flag. Returns what was written. A write failure is reported but never fails\n * the command — the submission already landed.\n *\n * `publish` is the only verb that writes ekanos.json: it is the one verb that\n * proves the (host, source) pair actually works, and it always runs inside a\n * project. `login` deliberately never writes — it is routinely run outside\n * one, and the credential store's sole-host fallback covers it.\n *\n * `host` persists on FIRST WRITE ONLY. It decides where every future verb\n * sends the bearer token and the source archive, so a one-off `--host`\n * override (a staging test, say) must not silently become the project's\n * sticky default; when the override differs from the stored host, the stored\n * value is kept and the difference is called out in the result instead.\n * Changing it is an explicit edit of ekanos.json. `source` keeps the simpler\n * always-update semantics — it is scoped BY the host, and updating it is the\n * documented way to repoint a project.\n */\nexport function persistProjectFields(\n loaded: LoadedProject,\n source: string,\n host: string,\n): { source: boolean; host: boolean; hostOverride: string | null } {\n const wants = {\n source: loaded.project.source !== source,\n host: loaded.project.host === undefined,\n };\n\n const hostOverride =\n loaded.project.host !== undefined && loaded.project.host !== host\n ? loaded.project.host\n : null;\n\n if (!wants.source && !wants.host) {\n return { source: false, host: false, hostOverride };\n }\n\n try {\n fs.writeFileSync(\n loaded.configPath,\n serializeProject({\n ...loaded.project,\n source,\n host: wants.host ? host : loaded.project.host,\n }),\n );\n\n return { ...wants, hostOverride };\n } catch {\n // Diagnostics-only: the publish succeeded; a read-only ekanos.json just\n // means the next publish needs the flags again.\n return { source: false, host: false, hostOverride };\n }\n}\n\n/**\n * How many packed paths the manifest embeds before switching to a truncated\n * list plus a `filesTruncated` total. The manifest is metadata — the archive\n * itself is the payload — and the server caps it at MAX_MANIFEST_BYTES, so a\n * many-small-files project must not be able to blow the cap with its file\n * list alone.\n */\nconst MANIFEST_FILE_LIST_CAP = 200;\n\n/**\n * The submission manifest: the parsed ekanos.json, the integration entries,\n * and (a bounded prefix of) the packed file list. Refuses to build one over\n * the server's byte cap — a clear VALIDATION error here beats the server's\n * generic 400 after a 4 MiB upload.\n */\nexport function buildManifest(loaded: LoadedProject, files: string[]): string {\n const manifest = JSON.stringify({\n project: loaded.project,\n integrations: loaded.integrations.map((i) => ({\n slug: i.slug,\n entry: i.entry,\n })),\n files: files.slice(0, MANIFEST_FILE_LIST_CAP),\n ...(files.length > MANIFEST_FILE_LIST_CAP\n ? { filesTruncated: files.length }\n : {}),\n });\n\n const bytes = Buffer.byteLength(manifest, 'utf8');\n\n if (bytes > MAX_MANIFEST_BYTES) {\n throw validationError(\n `The submission manifest is ${bytes} bytes, over the ` +\n `${MAX_MANIFEST_BYTES}-byte server cap.`,\n 'The manifest embeds your ekanos.json — trim oversized fields there ' +\n '(sourceGlobs is the usual culprit), then re-run \"ekanos publish\".',\n );\n }\n\n return manifest;\n}\n\nconst SEMVER_PATTERN =\n /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\n\n/**\n * The submitted version is the project's own `package.json#version` — one\n * source of truth, the same field npm would publish.\n */\nexport function readProjectVersion(projectDir: string): string {\n const manifestPath = path.join(projectDir, 'package.json');\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\n } catch (error) {\n throw preconditionError(\n `Could not read ${manifestPath}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n `Ensure the project has a valid package.json — its \"version\" field is ` +\n `what gets submitted.`,\n );\n }\n\n const version =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { version?: unknown }).version\n : undefined;\n\n if (typeof version !== 'string' || !SEMVER_PATTERN.test(version)) {\n throw validationError(\n `package.json \"version\" is ${\n typeof version === 'string' ? `\"${version}\"` : 'missing'\n }, which is not a semver version.`,\n `Set \"version\" in ${manifestPath} to a semver string like \"0.1.0\", ` +\n `then re-run \"ekanos publish\".`,\n );\n }\n\n return version;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"publish.js","sourceRoot":"","sources":["../../src/commands/publish.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Finding } from '@ekanos/integration-schema';\nimport { findRepoRoot } from '@ekanos/integration-schema/repo';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport {\n CliError,\n forbiddenError,\n gateFailedError,\n preconditionError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { readProjectKind } from '../experience/project';\nimport { runExperiencePublish } from '../experience/publish';\nimport { renderFindings } from '../findings-renderer';\nimport { type SlugLookup, lookupSlug } from '../names-api';\nimport { packProject } from '../pack';\nimport { type LoadedProject, loadProject, serializeProject } from '../project';\nimport {\n MAX_MANIFEST_BYTES,\n globalNameUnapprovedError,\n stillUnauthorized,\n submitArchive,\n} from '../publish-api';\nimport { runRepoPublish } from '../repo/publish';\nimport { assertSchemaNotSkewed } from '../schema-skew';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { shortHost } from '../ui';\nimport { announceUpdate, checkForUpdate } from '../update-notice';\nimport { collectAllFindings } from '../validate-findings';\n\n/**\n * Checks that are WARN in plain `ekanos validate` but must refuse a\n * `publish` outright: a project that will fail the gate is not allowed to\n * upload and find that out from the gate instead of from itself.\n * `project.host-compiler-rules` (see `project-checks.ts`) is WARN-severity\n * everywhere else on purpose — it reads a partner's local tsconfig, not the\n * gate's own verdict, so it must not block plain validate on a false\n * positive — but at the publish gate, \"this WILL fail the gate\" is exactly\n * the thing a submission preflight exists to refuse. A list, not a second\n * check, so the underlying rule and its message/hint stay defined in exactly\n * one place.\n */\nconst PUBLISH_ERROR_ESCALATIONS: readonly string[] = [\n 'project.host-compiler-rules',\n];\n\n/**\n * Escalate the checks in `PUBLISH_ERROR_ESCALATIONS` from `warn` to `error`\n * for THIS publish run only — `validate`'s own output (and the underlying\n * finding objects elsewhere) is never touched.\n */\nexport function escalateForPublish(findings: Finding[]): Finding[] {\n return findings.map((finding) =>\n finding.severity === 'warn' &&\n PUBLISH_ERROR_ESCALATIONS.includes(finding.check)\n ? { ...finding, severity: 'error' }\n : finding,\n );\n}\n\nexport interface PublishArgs {\n host?: string;\n /** Ekanos source slug. Falls back to ekanos.json's \"source\" field. */\n source?: string;\n /** Project directory (contains ekanos.json). Defaults to cwd. */\n dir: string;\n /**\n * Skips the interactive confirm when the source resolved IMPLICITLY (from\n * ekanos.json) and the caller holds more than one developer seat. Has no\n * effect when `--source` was passed this invocation (explicit is already\n * consent) or when the caller holds exactly one seat (nothing to\n * disambiguate).\n */\n yes: boolean;\n env: Record<string, string | undefined>;\n /**\n * Whether stdin is a real interactive terminal — the SECOND condition (with\n * human/non-JSON mode) required before publish will ever prompt. Defaults\n * to `process.stdin.isTTY === true`. Injectable so tests can exercise the\n * confirm branch without a real TTY.\n */\n stdinIsTTY?: boolean;\n /**\n * Injectable y/N prompt, for tests. Defaults to a real readline prompt over\n * stdin/stderr. Never invoked unless BOTH human mode and a real stdin TTY\n * are in play — see `canPrompt` in `verifyPublishTarget`.\n */\n confirm?: (question: string) => Promise<boolean>;\n /** Experiences only: build and pack, publish nothing. In a repo: every package. */\n dryRun?: boolean;\n /** Repo only: the packages to publish, by name. */\n packages?: readonly string[];\n /** Repo only: publish every package. */\n all?: boolean;\n}\n\n/** Where the resolved source slug came from — governs the confirmation rules below. */\nexport interface SourceResolution {\n source: string;\n /** True iff `--source` was passed THIS invocation. */\n explicit: boolean;\n}\n\n/**\n * `publish` — pack the project and submit it to an Ekanos deployment.\n *\n * The submission gate is the SAME findings pass `validate` runs (one\n * implementation, `validate-findings.ts`): any error-severity finding refuses\n * the publish with GATE_FAILED (exit 10) and the findings in `data`, so an\n * agent can branch on the code and fix-then-retry without re-running validate.\n *\n * Authorization is server-side — the dev seat on the target source — and the\n * stored session is refreshed once on a 401, mirroring `whoami`. On the first\n * successful publish the chosen source slug is persisted into `ekanos.json`\n * so later publishes need no `--source`.\n */\nexport async function runPublish(\n ctx: CliContext,\n args: PublishArgs,\n): Promise<ExitCode> {\n // Inside a repo, `publish` plans the packages: a same-repo integration is\n // ordered first rather than refused as an override.\n const repoRoot = findRepoRoot(path.resolve(args.dir));\n if (repoRoot) {\n return runRepoPublish(ctx, {\n repoRoot,\n cwd: path.resolve(args.dir),\n names: args.packages ?? [],\n all: args.all === true,\n publish: args,\n });\n }\n if ((args.packages?.length ?? 0) > 0 || args.all) {\n throw usageError(\n 'Package names and --all are for a repo.',\n 'Run this from a repo (see \"ekanos init --kind repo\"), or drop the names to publish this project.',\n );\n }\n\n // An experience is published (dry-run only, for now) by its own pipeline,\n // before any login: overrides and the gate refuse it first.\n if (readProjectKind(path.resolve(args.dir)) === 'experience') {\n return runExperiencePublish(ctx, {\n dir: args.dir,\n dryRun: args.dryRun === true,\n env: args.env,\n host: args.host,\n source: args.source,\n yes: args.yes,\n stdinIsTTY: args.stdinIsTTY,\n confirm: args.confirm,\n });\n }\n\n const prepared = await prepareIntegrationSubmission(ctx, args);\n const { loaded, version, slug } = prepared;\n\n ctx.log(`Validating ${slug} before publishing…`);\n\n const findings = escalateForPublish(await collectAllFindings(loaded));\n const errorCount = findings.filter((f) => f.severity === 'error').length;\n\n if (errorCount > 0) {\n // Same rule as `validate`: render the shared findings block to stderr\n // BEFORE the envelope settles, human mode only. JSON mode carries the\n // identical findings in `data.findings` and must stay byte-identical.\n // Closing order is findings block -> short summary (via `ctx.fail`'s\n // `findingsSummary` option) -> next action.\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.err(\n `${ctx.ui.glyphs.err} Refusing to publish: ${errorCount} finding` +\n `${errorCount === 1 ? '' : 's'}.`,\n ),\n );\n renderFindings(ctx, findings, { cwd: loaded.projectDir });\n }\n\n const exitCode = ctx.fail(\n gateFailedError(\n `Refusing to publish: ${errorCount} validation finding` +\n `${errorCount === 1 ? '' : 's'}.`,\n 'Resolve the error-severity findings in data.findings (they are ' +\n 'exactly what \"ekanos validate\" reports), then re-run ' +\n '\"ekanos publish\".',\n ),\n { slug, version, findings },\n !ctx.jsonMode\n ? { findingsSummary: { command: 'ekanos publish', errorCount } }\n : undefined,\n );\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.nextAction(\n 'ekanos validate',\n 'fix the error-severity findings above, then re-run \"ekanos publish\"',\n ),\n );\n }\n\n return exitCode;\n }\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.ok(\n `${ctx.ui.glyphs.ok} validated ${slug} — no error-severity findings.`,\n ),\n );\n }\n\n const submitted = await submitPrepared(ctx, args, prepared);\n\n return ctx.succeed(submitted.data, submitted.human);\n}\n\nexport interface SubmittedIntegration {\n data: Record<string, unknown>;\n human: string;\n}\n\n/**\n * Confirm the target, pack and submit one gated integration. The caller has\n * already passed the gate; this is the only part of `publish` that talks to\n * the host.\n */\nexport async function submitPrepared(\n ctx: CliContext,\n args: PublishArgs,\n prepared: PreparedSubmission,\n): Promise<SubmittedIntegration> {\n const { loaded, skew, notice, env, version, slug, resolution } = prepared;\n\n // The 100%-certainty mechanism: confirm the resolved source is one the\n // caller actually holds a seat on — and, when it was resolved IMPLICITLY\n // from ekanos.json with more than one seat in play, that a human (or an\n // explicit --yes) actually intends this target — BEFORE anything is packed\n // or sent over the wire.\n const verified = await verifyPublishTarget(ctx, env, resolution.session, {\n source: resolution.source,\n explicit: resolution.explicit,\n slug,\n version,\n yes: args.yes,\n stdinIsTTY: args.stdinIsTTY ?? process.stdin.isTTY === true,\n confirm: args.confirm ?? promptYesNo,\n });\n\n const source = verified.sourceSeat.slug;\n const availability = loaded.project.availability?.mode;\n\n // Say the full name the host will use, and refuse an unapproved global\n // name, before anything is packed.\n const lookup = await preflightName(\n ctx,\n env,\n verified.session,\n source,\n slug,\n availability,\n );\n\n ctx.log(`Packing ${slug}@${version}…`);\n\n const packed = packProject(loaded.projectDir);\n const manifest = buildManifest(loaded, packed.files);\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.ok(\n `${ctx.ui.glyphs.ok} packed ${slug}@${version} (${packed.files.length} files).`,\n ),\n );\n }\n\n ctx.log(`Submitting to ${env.host} (source \"${source}\")…`);\n\n const receipt = await submitWithOneRefresh(env, verified.session, {\n source,\n slug,\n version,\n manifest,\n archive: packed.archive,\n ...(availability ? { availability } : {}),\n });\n\n const displayName =\n receipt.displayName ?? lookup?.displayName ?? receipt.slug;\n\n if (!ctx.jsonMode) {\n ctx.log(\n ctx.ui.ok(\n `${ctx.ui.glyphs.ok} submitted ${displayName}@${receipt.version} ` +\n `(state \"${receipt.state}\").`,\n ),\n );\n }\n\n const persisted = persistProjectFields(loaded, source, env.host);\n\n const persistedNote = [\n ...(persisted.source ? [`\"source\": \"${source}\"`] : []),\n ...(persisted.host ? [`\"host\": \"${env.host}\"`] : []),\n ];\n\n return {\n data: {\n host: env.host,\n source: {\n id: verified.sourceSeat.id,\n slug: verified.sourceSeat.slug,\n name: verified.sourceSeat.name,\n },\n slug: receipt.slug,\n namespace: receipt.namespace ?? lookup?.namespace ?? null,\n displayName,\n version: receipt.version,\n submissionId: receipt.submissionId,\n state: receipt.state,\n archiveSha256: receipt.archiveSha256,\n files: packed.files,\n sourcePersisted: persisted.source,\n hostPersisted: persisted.host,\n hostOverride: persisted.hostOverride,\n ...(skew.status === 'project-older'\n ? {\n schemaSkew: {\n status: skew.status,\n cliSchemaVersion: skew.cliSchemaVersion,\n projectSchemaVersion: skew.projectSchemaVersion,\n },\n }\n : {}),\n ...(notice ? { toolchain: notice } : {}),\n },\n human: ctx.ui.result({\n title: 'Submitted',\n rows: [\n ['Integration', `${displayName}@${receipt.version}`],\n ['State', receipt.state],\n ['Source', source],\n ['Host', shortHost(env.host)],\n ...(persistedNote.length > 0\n ? [\n [\n 'Saved',\n `${persistedNote.join(' and ')} to ekanos.json`,\n ] as const,\n ]\n : []),\n ],\n notes: persisted.hostOverride\n ? [\n `This publish went to ${env.host}, but ekanos.json keeps \"host\": ` +\n `\"${persisted.hostOverride}\" — a one-off override never replaces ` +\n 'the saved host; edit ekanos.json to change it.',\n ]\n : [],\n }),\n };\n}\n\n/**\n * Ask the host what it will call this slug for the Source, before packing.\n * An unapproved global name stops the publish here. Any other answer - an\n * older host without the route, a server error, a shape this CLI does not\n * read - is not a reason to stop: the submission itself is authoritative, and\n * the bare slug stands in for the name.\n */\nasync function preflightName(\n ctx: CliContext,\n env: AuthEnvironment,\n session: StoredSession,\n source: string,\n slug: string,\n availability: 'global' | 'restricted' | undefined,\n): Promise<SlugLookup | null> {\n let lookup: SlugLookup | null = null;\n\n try {\n let result = await lookupSlug(\n env.host,\n session.accessToken,\n source,\n slug,\n availability,\n );\n if (result.status === 'unauthorized') {\n const refreshed = await refreshStoredSession(env, session);\n result = await lookupSlug(\n env.host,\n refreshed.accessToken,\n source,\n slug,\n availability,\n );\n }\n if (result.status === 'ok') lookup = result.lookup;\n } catch (error) {\n if (!(error instanceof CliError)) throw error;\n ctx.log(\n `Could not pre-check the name of ${slug} (${error.message}); continuing.`,\n );\n }\n\n if (lookup?.status === 'global_unapproved') {\n throw globalNameUnapprovedError(slug);\n }\n\n if (lookup?.displayName && !ctx.jsonMode) {\n ctx.log(`Publishing as ${lookup.displayName}.`);\n }\n\n return lookup;\n}\n\nexport interface PreparedSubmission {\n env: AuthEnvironment;\n session: StoredSession;\n loaded: LoadedProject;\n skew: ReturnType<typeof assertSchemaNotSkewed>;\n notice: Awaited<ReturnType<typeof checkForUpdate>>;\n resolution: SourceResolution & { session: StoredSession };\n version: string;\n slug: string;\n}\n\n/**\n * Everything `publish` does before it gates a project: sign-in, load, schema\n * skew, toolchain check, source resolution. Shared by the single-project verb\n * and the repo verb (which gates every package before submitting any).\n */\nexport async function prepareIntegrationSubmission(\n ctx: CliContext,\n args: PublishArgs,\n): Promise<PreparedSubmission> {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const session = requireSession(env);\n\n const loaded = loadProject(args.dir);\n\n // Fail fast, before anything else: a project whose schema is newer than\n // this CLI bundles cannot be trusted to validate correctly, so publishing\n // it — the one verb whose findings gate is meant to be authoritative —\n // must refuse before packing or submitting anything. See `schema-skew.ts`.\n const skew = assertSchemaNotSkewed(ctx, loaded.projectDir);\n\n const notice = await checkForUpdate({\n env: args.env,\n host: env.host,\n session,\n });\n announceUpdate(ctx, notice);\n\n // The host would reject a build from a CLI it has declared unsupported\n // anyway (see the wire contract in `toolchain-api.ts`) — refuse here with a\n // hint naming the fix, rather than let the submission round-trip fail with\n // whatever generic error the host happens to answer with.\n if (notice?.status === 'unsupported') {\n throw preconditionError(\n `@ekanos/cli ${notice.current.cli} is below ${env.host}'s minimum ` +\n `supported version (needs at least ${notice.target.cli}).`,\n 'Run \"ekanos upgrade\" before publishing — the host will refuse this ' +\n 'submission from an unsupported CLI regardless.',\n );\n }\n\n const resolution = await resolveSourceSlug(env, session, args.source, loaded);\n const version = readProjectVersion(loaded.projectDir);\n const slug = loaded.primary.slug;\n\n return { env, session, loaded, skew, notice, resolution, version, slug };\n}\n\n/**\n * The publish-target verification gate.\n *\n * FORBIDDEN (exit 5) whenever the resolved source is not among the caller's\n * seats — regardless of whether it came from `--source` or ekanos.json.\n * Beyond that, the confirmation rules branch on how the source was resolved:\n *\n * - `--source` THIS invocation: explicit is consent. Proceed.\n * - ekanos.json, exactly one seat held (which must be the match, or the\n * FORBIDDEN check above would have already fired): proceed, but say so —\n * there is nothing to disambiguate, but the target should never be silent.\n * - ekanos.json, multiple seats held: the ambiguous case this mechanism\n * exists for. Only when BOTH human (non-JSON) mode AND stdin is a real\n * TTY does it print the target and require an explicit y/N confirm\n * (`--yes` skips it) — see `canPrompt` below for why stdin matters, not\n * just stdout. Every other combination (JSON mode, or human mode with a\n * closed/non-interactive stdin) NEVER prompts — it proceeds only with\n * `--yes`, otherwise VALIDATION (exit 3) with the seat list, naming\n * `--source`, `--yes` and `ekanos use`.\n */\nexport async function verifyPublishTarget(\n ctx: CliContext,\n env: AuthEnvironment,\n session: StoredSession,\n args: SourceResolution & {\n slug: string;\n version: string;\n yes: boolean;\n /** Real interactivity signal for stdin — see `canPrompt` below. */\n stdinIsTTY: boolean;\n confirm: (question: string) => Promise<boolean>;\n },\n): Promise<{ sourceSeat: SourceSeat; session: StoredSession }> {\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env);\n }\n\n const seat = result.sources.find((s) => s.slug === args.source);\n\n if (!seat) {\n throw forbiddenError(\n `This account does not hold a seat on source \"${args.source}\" on ${env.host}.`,\n seatsHint(result.sources, env.host),\n );\n }\n\n if (args.explicit) {\n return { sourceSeat: seat, session: result.session };\n }\n\n if (result.sources.length === 1) {\n ctx.log(\n `Publishing to ${seat.name ?? seat.slug} (${seat.slug}) — your only ` +\n `developer seat.`,\n );\n return { sourceSeat: seat, session: result.session };\n }\n\n // Implicit source, multiple seats: the ambiguous case.\n //\n // `ctx.jsonMode` alone is NOT enough to decide whether an interactive\n // confirm is safe: `--no-json` forces human mode even when stdout is\n // piped, and neither `--no-json` nor a bare human run says anything about\n // stdin. Prompting `readline`'s `.question()` against a closed/non-TTY\n // stdin (a cron job, a wrapper script piping stdout but not attached to a\n // terminal) never resolves — the process hangs instead of exiting with a\n // clean code. So an actual prompt requires BOTH: human mode AND a real\n // stdin TTY. Anything else — JSON mode, or human mode with non-interactive\n // stdin — falls through to the same non-prompting `--yes`-or-refuse rule.\n const canPrompt = !ctx.jsonMode && args.stdinIsTTY;\n\n if (canPrompt) {\n ctx.log(\n `Publishing ${args.slug}@${args.version} to SOURCE ${seat.name ?? seat.slug} ` +\n `(${seat.slug}) on ${env.host}`,\n );\n\n if (!args.yes) {\n const confirmed = await args.confirm('Proceed? [y/N]');\n\n if (!confirmed) {\n throw validationError(\n `Publish to \"${seat.slug}\" was not confirmed.`,\n multiSeatHint(result.sources),\n );\n }\n }\n\n return { sourceSeat: seat, session: result.session };\n }\n\n if (args.yes) {\n return { sourceSeat: seat, session: result.session };\n }\n\n throw validationError(\n `Ambiguous publish target: this account holds ${result.sources.length} ` +\n `developer seats and the source was resolved from ekanos.json, not ` +\n `an explicit flag.`,\n multiSeatHint(result.sources),\n );\n}\n\nfunction seatsHint(sources: SourceSeat[], host: string): string {\n if (sources.length === 0) {\n return (\n `You hold no seats on any source on ${host}. Ask Ekanos ` +\n `to grant your account the developer seat on the intended source.`\n );\n }\n\n return (\n `You hold a seat on: ${describeSeats(sources)}. Pass \"--source <slug>\" ` +\n `naming one of these, or run \"ekanos use <slug>\" to set the project's ` +\n `default.`\n );\n}\n\nfunction multiSeatHint(sources: SourceSeat[]): string {\n return (\n `You hold seats on: ${describeSeats(sources)}. Pass \"--source <slug>\" ` +\n `to name the target explicitly, add \"--yes\" to confirm the target ` +\n `already in ekanos.json non-interactively, or run \"ekanos use <slug>\" ` +\n `to change the project's default.`\n );\n}\n\nfunction describeSeats(sources: SourceSeat[]): string {\n return sources.map((s) => `${s.slug} (${s.roles.join(', ')})`).join(', ');\n}\n\n/**\n * The real, non-test y/N prompt. Reads a line from stdin and writes the\n * question to stderr, so it never touches stdout — the one stream the JSON\n * envelope invariant depends on. Only reachable when `verifyPublishTarget`'s\n * `canPrompt` is true — human mode AND a real stdin TTY — so this never\n * blocks on a closed or non-interactive stdin.\n */\n/**\n * Exported so `upgrade` can reuse the exact same y/N prompt rather than\n * writing a second one — see `canPrompt` above for the stdin-TTY gating this\n * is only ever invoked behind.\n */\nexport async function promptYesNo(question: string): Promise<boolean> {\n const readline = await import('node:readline/promises');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n\n try {\n const answer = await rl.question(`${question} `);\n return /^y(es)?$/i.test(answer.trim());\n } finally {\n rl.close();\n }\n}\n\nexport async function submitWithOneRefresh(\n env: ReturnType<typeof resolveAuthEnvironment>,\n session: StoredSession,\n payload: Parameters<typeof submitArchive>[2],\n) {\n const first = await submitArchive(env.host, session.accessToken, payload);\n\n if (first.status === 'ok') return first.receipt;\n\n // The access token no longer authenticates — an ordinary event, not an\n // error. One refresh, one retry; a second 401 is authoritative.\n const refreshed = await refreshStoredSession(env, session);\n const second = await submitArchive(env.host, refreshed.accessToken, payload);\n\n if (second.status === 'ok') return second.receipt;\n\n return stillUnauthorized(env);\n}\n\n/**\n * Resolve the source slug (flag → ekanos.json) and whether it was given\n * EXPLICITLY this invocation — the fact `verifyPublishTarget` uses to decide\n * whether a confirmation is even in play. `flag !== undefined` (rather than\n * \"non-empty after trim\") is deliberate: an explicit `--source` that is\n * effectively empty is still a caller who typed the flag, not one who\n * fell through to ekanos.json.\n */\nexport async function resolveSourceSlug(\n env: AuthEnvironment,\n session: StoredSession,\n flag: string | undefined,\n /** Anything that carries the project's saved `source`: an integration project or an experience's ekanos.json. */\n loaded: { project: { source?: string } },\n): Promise<SourceResolution & { session: StoredSession }> {\n const explicit = flag !== undefined;\n const raw = flag ?? loaded.project.source;\n\n if (!raw || raw.trim().length === 0) {\n return noSourceError(env, session);\n }\n\n return { source: raw.trim(), explicit, session };\n}\n\n/**\n * The no-source validation error, enriched with the caller's seat list when\n * it can be fetched — best-effort, since a session is guaranteed to exist\n * here (publish already called `requireSession`) but the fetch itself can\n * still fail (network, MFA, a down deployment). A failure to enrich must\n * never mask or replace the primary \"no source given\" error.\n */\nasync function noSourceError(\n env: AuthEnvironment,\n session: StoredSession,\n): Promise<never> {\n let seatsNote = '';\n\n try {\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'ok') {\n seatsNote =\n result.sources.length > 0\n ? ` You hold a seat on: ${describeSeats(result.sources)}.`\n : ' You hold no seats on any source on this host yet.';\n }\n } catch {\n // Best-effort — the primary error below stands on its own.\n }\n\n throw validationError(\n 'No Ekanos source given for the submission.',\n 'Pass \"--source <slug>\" (your operator names the source), or set ' +\n '\"source\": \"<slug>\" in ekanos.json. A successful publish saves it ' +\n `there for you.${seatsNote}`,\n );\n}\n\n/**\n * Persist the chosen source AND host into ekanos.json after a SUCCESSFUL\n * publish, so the next publish — and every other host-taking verb — needs no\n * flag. Returns what was written. A write failure is reported but never fails\n * the command — the submission already landed.\n *\n * `publish` is the only verb that writes ekanos.json: it is the one verb that\n * proves the (host, source) pair actually works, and it always runs inside a\n * project. `login` deliberately never writes — it is routinely run outside\n * one, and the credential store's sole-host fallback covers it.\n *\n * `host` persists on FIRST WRITE ONLY. It decides where every future verb\n * sends the bearer token and the source archive, so a one-off `--host`\n * override (a staging test, say) must not silently become the project's\n * sticky default; when the override differs from the stored host, the stored\n * value is kept and the difference is called out in the result instead.\n * Changing it is an explicit edit of ekanos.json. `source` keeps the simpler\n * always-update semantics — it is scoped BY the host, and updating it is the\n * documented way to repoint a project.\n */\nexport function persistProjectFields(\n loaded: LoadedProject,\n source: string,\n host: string,\n): { source: boolean; host: boolean; hostOverride: string | null } {\n const wants = {\n source: loaded.project.source !== source,\n host: loaded.project.host === undefined,\n };\n\n const hostOverride =\n loaded.project.host !== undefined && loaded.project.host !== host\n ? loaded.project.host\n : null;\n\n if (!wants.source && !wants.host) {\n return { source: false, host: false, hostOverride };\n }\n\n try {\n fs.writeFileSync(\n loaded.configPath,\n serializeProject({\n ...loaded.project,\n source,\n host: wants.host ? host : loaded.project.host,\n }),\n );\n\n return { ...wants, hostOverride };\n } catch {\n // Diagnostics-only: the publish succeeded; a read-only ekanos.json just\n // means the next publish needs the flags again.\n return { source: false, host: false, hostOverride };\n }\n}\n\n/**\n * How many packed paths the manifest embeds before switching to a truncated\n * list plus a `filesTruncated` total. The manifest is metadata — the archive\n * itself is the payload — and the server caps it at MAX_MANIFEST_BYTES, so a\n * many-small-files project must not be able to blow the cap with its file\n * list alone.\n */\nconst MANIFEST_FILE_LIST_CAP = 200;\n\n/**\n * The submission manifest: the parsed ekanos.json, the integration entries,\n * and (a bounded prefix of) the packed file list. Refuses to build one over\n * the server's byte cap — a clear VALIDATION error here beats the server's\n * generic 400 after a 4 MiB upload.\n */\nexport function buildManifest(loaded: LoadedProject, files: string[]): string {\n const manifest = JSON.stringify({\n project: loaded.project,\n integrations: loaded.integrations.map((i) => ({\n slug: i.slug,\n entry: i.entry,\n })),\n files: files.slice(0, MANIFEST_FILE_LIST_CAP),\n ...(files.length > MANIFEST_FILE_LIST_CAP\n ? { filesTruncated: files.length }\n : {}),\n });\n\n const bytes = Buffer.byteLength(manifest, 'utf8');\n\n if (bytes > MAX_MANIFEST_BYTES) {\n throw validationError(\n `The submission manifest is ${bytes} bytes, over the ` +\n `${MAX_MANIFEST_BYTES}-byte server cap.`,\n 'The manifest embeds your ekanos.json — trim oversized fields there ' +\n '(sourceGlobs is the usual culprit), then re-run \"ekanos publish\".',\n );\n }\n\n return manifest;\n}\n\nconst SEMVER_PATTERN =\n /^\\d+\\.\\d+\\.\\d+(?:-[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?(?:\\+[0-9A-Za-z-]+(?:\\.[0-9A-Za-z-]+)*)?$/;\n\n/**\n * The submitted version is the project's own `package.json#version` — one\n * source of truth, the same field npm would publish.\n */\nexport function readProjectVersion(projectDir: string): string {\n const manifestPath = path.join(projectDir, 'package.json');\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(fs.readFileSync(manifestPath, 'utf8'));\n } catch (error) {\n throw preconditionError(\n `Could not read ${manifestPath}: ${\n error instanceof Error ? error.message : String(error)\n }`,\n `Ensure the project has a valid package.json — its \"version\" field is ` +\n `what gets submitted.`,\n );\n }\n\n const version =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { version?: unknown }).version\n : undefined;\n\n if (typeof version !== 'string' || !SEMVER_PATTERN.test(version)) {\n throw validationError(\n `package.json \"version\" is ${\n typeof version === 'string' ? `\"${version}\"` : 'missing'\n }, which is not a semver version.`,\n `Set \"version\" in ${manifestPath} to a semver string like \"0.1.0\", ` +\n `then re-run \"ekanos publish\".`,\n );\n }\n\n return version;\n}\n"]}
|
package/dist/commands/sources.js
CHANGED
|
@@ -171,8 +171,8 @@ async function runProducts(ctx, args, rest) {
|
|
|
171
171
|
list.canEnable
|
|
172
172
|
? '"ekanos sources products enable|disable <product>" switches one.'
|
|
173
173
|
: list.canEnableOwned
|
|
174
|
-
? '"ekanos sources products enable|disable <product>" switches one built by this Source; any other
|
|
175
|
-
: '
|
|
174
|
+
? '"ekanos sources products enable|disable <product>" switches one built by this Source; Ekanos enables any other.'
|
|
175
|
+
: 'Ekanos enables them.',
|
|
176
176
|
'"ekanos teams connect <team> <product>" connects an enabled integration for a team.',
|
|
177
177
|
],
|
|
178
178
|
}),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport { authRequiredError, invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { hostPredatesFeatures, productGroup } from '../product-kinds';\nimport { EKANOS_CONFIG_FILENAME } from '../project';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport {\n type SourceProduct,\n type SourceProductsApiResult,\n listSourceProducts,\n setSourceProduct,\n} from '../source-products-api';\nimport { resolveSourceTarget } from '../source-target';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { listProductScopes, setScopeProduct } from '../teams-api';\nimport { type Ui, pluralize, shortHost } from '../ui';\nimport { scopeDeprecationNotice } from './scope-notice';\nimport { runSourcePeople, runSourceRoles } from './sources-roles';\n\nexport interface SourcesArgs {\n host?: string;\n /** `products [enable|disable <product>]`, `scopes [add|remove <scope> <product>]`; none lists the sources. */\n positionals?: readonly string[];\n source?: string;\n yes?: boolean;\n /** `roles` and `people`: their flags (`--level`, `--permission`, `--search` …). */\n flags?: Record<string, string | boolean | string[]>;\n /** `roles delete` asks at a terminal; the test seams for it. */\n stdinIsTTY?: boolean;\n ask?: (question: string) => Promise<string>;\n /** Where a project's ekanos.json may sit — its `source` field, if any, is the marker. */\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `sources` — list every source the caller holds a developer or admin seat\n * on, the read half of the publish-target-verification story.\n *\n * The list itself is the mechanism that makes `publish` safe: a partner (or\n * an agent acting for one) can always answer \"which sources can I possibly\n * publish to?\" before running `ekanos use` or passing `--source`.\n */\nexport async function runSources(\n ctx: CliContext,\n args: SourcesArgs,\n): Promise<ExitCode> {\n const [subcommand, ...rest] = args.positionals ?? [];\n if (subcommand !== undefined) {\n if (subcommand === 'scopes') return runScopes(ctx, args, rest);\n if (subcommand === 'roles') return runSourceRoles(ctx, args, rest);\n if (subcommand === 'people') return runSourcePeople(ctx, args, rest);\n if (subcommand !== 'products') {\n throw usageError(\n `Unknown sources subcommand \"${subcommand}\".`,\n 'Run \"ekanos sources\" to list your sources, \"ekanos sources products [enable|disable <product>]\", \"ekanos sources scopes [add|remove <scope> <product>]\", \"ekanos sources roles [list|create|update|delete <role>]\" or \"ekanos sources people\".',\n );\n }\n return runProducts(ctx, args, rest);\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const session = requireSession(env);\n\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env);\n }\n\n const activeSource = readActiveSource(args.dir);\n\n return ctx.succeed(\n { host: env.host, sources: result.sources, activeSource },\n humanSummary(ctx.ui, env.host, result.sources, activeSource),\n );\n}\n\n/**\n * Best-effort, lenient read of ekanos.json's `source` field — mirrors\n * `readProjectHost` in `auth/session.ts`. A missing, unparseable, or\n * sourceless ekanos.json (or no project at all) simply means \"no active\n * source to mark\", never an error: `sources` must answer outside a project\n * too.\n */\nexport function readActiveSource(dir: string): string | null {\n const configPath = path.join(dir, EKANOS_CONFIG_FILENAME);\n\n let raw: string;\n try {\n raw = fs.readFileSync(configPath, 'utf8');\n } catch {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const source =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { source?: unknown }).source\n : undefined;\n\n return typeof source === 'string' && source.trim().length > 0\n ? source.trim()\n : null;\n}\n\n/** Why a product is not enabled, by the lever that would enable it — the words `catalog` uses. */\nconst NOT_ENABLED_BECAUSE: Record<SourceProduct['lever'], string> = {\n flag: 'its Flag is off',\n plan: 'no active plan',\n entitlement: 'not granted',\n};\n\nfunction humanSummary(\n ui: Ui,\n host: string,\n sources: SourceSeat[],\n activeSource: string | null,\n): string {\n if (sources.length === 0) {\n return ui.result({\n // Read by any signed-in account, a team member's too: no word here\n // may imply the host serves more than one customer.\n title: 'No partner seats',\n tone: 'warn',\n rows: [['Host', shortHost(host)]],\n notes: ['This account has no partner seats on this host.'],\n });\n }\n\n const orphaned =\n activeSource && !sources.some((s) => s.slug === activeSource);\n\n return ui.result({\n title: `${pluralize(sources.length, 'source')} on ${shortHost(host)}`,\n rows: sources.map((source): [string, string] => [\n source.slug,\n [\n source.name ?? '(unnamed)',\n source.roles.join(', '),\n ...(source.slug === activeSource ? [ui.accent('this project')] : []),\n ].join(' · '),\n ]),\n notes: orphaned\n ? [\n `This project's ekanos.json points at \"${activeSource}\", which is not in the list above.`,\n ]\n : [],\n });\n}\n\n/**\n * `sources products` — the catalog as one Source has it: every product, its\n * kind (Feature or Integration), and whether it is enabled for the Source.\n * `enable|disable <product>` switch one through the levers `/admin` uses\n * (`attachProductToSource` / `detachProductFromSource` for an Integration,\n * the Feature lever for a Feature). A Source admin switches the\n * integrations their Source built (`owned`); anything else is a super-admin\n * grant, which an `ekanos login` session never carries, so from the terminal\n * that write answers with where to do it.\n */\nasync function runProducts(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawProduct, ...extra] = rest;\n if (extra.length > 0) {\n throw usageError(\n `Unexpected argument \"${extra[0]}\".`,\n 'Run \"ekanos sources products [enable|disable <product>] [--source <slug>]\".',\n );\n }\n if (verb !== undefined && verb !== 'enable' && verb !== 'disable') {\n throw usageError(\n `Unknown sources products subcommand \"${verb}\".`,\n 'Run \"ekanos sources products\", \"ekanos sources products enable <product>\" or \"ekanos sources products disable <product> --yes\".',\n );\n }\n const product = verb ? productSlug(rawProduct, verb) : null;\n if (verb === 'disable' && !args.yes) {\n throw invalidStateError(\n `Disabling ${product} removes it from the Source: its plans, widget settings, Source credentials and workspaces go with it.`,\n `Re-run with --yes: ekanos sources products disable ${product} --yes`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), {\n source: args.source,\n dir: args.dir,\n });\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product) {\n const list = await client.call((token) =>\n listSourceProducts(env.host, token, resolved.source),\n );\n const legacyHost = hostPredatesFeatures(list.products);\n const byKind = (kind: 'feature' | 'experience' | 'integration') =>\n list.products\n .filter((entry) => productGroup(entry, legacyHost) === kind)\n .map((entry): [string, string] => [\n entry.slug,\n `${entry.enabled ? '✓ enabled' : `✗ not enabled (${NOT_ENABLED_BECAUSE[entry.lever]})`} · ${entry.name}${entry.owned ? ' · built by this Source' : ''}${entry.registered ? '' : ' · no package on this host'}`,\n ]);\n return ctx.succeed(\n { host: env.host, ...list },\n [\n ctx.ui.result({\n title: `Features on ${list.source.slug}`,\n rows: byKind('feature'),\n }),\n ...(byKind('experience').length > 0\n ? [\n ctx.ui.result({\n title: `Experiences on ${list.source.slug}`,\n rows: byKind('experience'),\n }),\n ]\n : []),\n ctx.ui.result({\n title: `Integrations on ${list.source.slug}`,\n rows: byKind('integration'),\n notes: [\n list.canEnable\n ? '\"ekanos sources products enable|disable <product>\" switches one.'\n : list.canEnableOwned\n ? '\"ekanos sources products enable|disable <product>\" switches one built by this Source; any other is a super-admin grant, made in the browser at /admin/sources → the Source → Products.'\n : 'Enabling one is a super-admin grant, made in the browser at /admin/sources → the Source → Products.',\n '\"ekanos teams connect <team> <product>\" connects an enabled integration for a team.',\n ],\n }),\n ].join('\\n'),\n );\n }\n\n const enabled = verb === 'enable';\n const result = await client.call((token) =>\n setSourceProduct(env.host, token, {\n source: resolved.source,\n product,\n enabled,\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${enabled ? 'Enabled' : 'Disabled'} ${result.product.name} for ${result.source.slug}`\n : `${result.product.name} was already ${enabled ? 'enabled' : 'off'} for ${result.source.slug}`,\n rows: [\n ['Kind', result.product.kind],\n [\n 'Switched by',\n result.product.lever === 'flag'\n ? 'its Flag'\n : result.product.lever === 'plan'\n ? 'its plan'\n : 'the entitlement',\n ],\n ],\n notes:\n enabled && result.product.kind === 'integration'\n ? [\n `Next: \"ekanos teams connect <team> ${result.product.slug}\" connects it for a team.`,\n ]\n : [],\n }),\n );\n}\n\n/**\n * `sources scopes` — the Source's product scopes, for its Source admin: each\n * scope's products and how many teams hold it. Once a Source has a scope,\n * each team sees in the app only its scopes' products. `add|remove <scope>\n * <product>` changes one scope (by name or id) through what\n * `/admin/sources/[id]/scopes` uses; a product can only be added if\n * the Source has it. Taking one out hides it from every team on the scope\n * that no other of its scopes shows it to, so that needs `--yes`.\n */\nasync function runScopes(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawScope, rawProduct, ...extra] = rest;\n const usage =\n 'Run \"ekanos sources scopes\", \"ekanos sources scopes add <scope> <product>\" or \"ekanos sources scopes remove <scope> <product> --yes\".';\n if (verb !== undefined && verb !== 'add' && verb !== 'remove') {\n throw usageError(`Unknown sources scopes subcommand \"${verb}\".`, usage);\n }\n if (extra.length > 0) {\n throw usageError(`Unexpected argument \"${extra[0]}\".`, usage);\n }\n const scope = rawScope?.trim();\n if (verb && !scope) {\n throw usageError(\n `sources scopes ${verb} needs a scope and a product.`,\n usage,\n );\n }\n const product = verb ? scopeProductSlug(rawProduct, verb) : null;\n if (verb === 'remove' && !args.yes) {\n throw invalidStateError(\n `Taking ${product} out of ${scope} hides it, in the app, from every team on ${scope} that no other of its scopes shows it to.`,\n `Re-run with --yes: ekanos sources scopes remove ${quoteArg(scope!)} ${product} --yes`,\n );\n }\n\n ctx.warn(\n scopeDeprecationNotice(\n verb ? `audiences set ${scope} --products …` : 'audiences list',\n ),\n );\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), {\n source: args.source,\n dir: args.dir,\n });\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product || !scope) {\n const list = await client.call((token) =>\n listProductScopes(env.host, token, resolved.source),\n );\n if (list.scopes.length === 0) {\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `No product scopes on ${list.source.slug}`,\n rows: [['Teams see', 'every product the Source has']],\n notes: [\n 'Scopes are created at /admin/sources → the Source → Product scopes.',\n ],\n }),\n );\n }\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `Product scopes on ${list.source.slug}`,\n rows: list.scopes.map((entry): [string, string[]] => [\n entry.name,\n [\n `${pluralize(entry.teamCount, 'team')}${entry.isDefault ? ' · given to every new team' : ''}`,\n entry.products.length > 0\n ? entry.products.map((item) => item.slug).join(', ')\n : 'no products',\n ],\n ]),\n notes: [\n 'A team sees in the app only the products of the scopes it holds.',\n '\"ekanos sources scopes add <scope> <product>\" shows a product to every team on a scope; \"ekanos teams scope show|set <team>\" reads or changes which scopes a team holds.',\n ],\n }),\n );\n }\n\n const included = verb === 'add';\n const result = await client.call((token) =>\n setScopeProduct(\n env.host,\n token,\n { source: resolved.source, scope, product },\n included,\n ),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${included ? 'Added' : 'Took'} ${result.product.name} ${included ? 'to' : 'out of'} ${result.scope.name}`\n : `${result.product.name} was already ${included ? 'in' : 'not in'} ${result.scope.name}`,\n tone: !included && result.changed ? 'warn' : 'ok',\n rows: [\n ['Teams on it', String(result.scope.teamCount)],\n [\n 'Products',\n result.scope.products.length > 0\n ? result.scope.products.map((item) => item.slug).join(', ')\n : 'none',\n ],\n ],\n notes: [\n included\n ? `Every team on ${result.scope.name} sees ${result.product.slug} in the app now.`\n : `Teams on ${result.scope.name} see ${result.product.slug} only if another of their scopes has it.`,\n ],\n }),\n );\n}\n\nfunction scopeProductSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources scopes ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources scopes add Bronze linear\".',\n );\n}\n\nfunction quoteArg(value: string): string {\n return /^[A-Za-z0-9._-]+$/.test(value) ? value : `\"${value}\"`;\n}\n\nfunction productSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources products ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources products enable agents\".',\n );\n}\n\nclass ProductsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<SourceProductsApiResult<T>>,\n ): Promise<T> {\n let result = await send(this.session.accessToken);\n if (result.status === 'unauthorized') {\n this.session = await refreshStoredSession(this.env, this.session);\n result = await send(this.session.accessToken);\n }\n if (result.status === 'ok') return result.data;\n throw authRequiredError(\n `The session for ${this.env.host} could not authorize the sources call.`,\n loginHint(this.env),\n );\n }\n}\n"]}
|
|
1
|
+
{"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport { authRequiredError, invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { hostPredatesFeatures, productGroup } from '../product-kinds';\nimport { EKANOS_CONFIG_FILENAME } from '../project';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport {\n type SourceProduct,\n type SourceProductsApiResult,\n listSourceProducts,\n setSourceProduct,\n} from '../source-products-api';\nimport { resolveSourceTarget } from '../source-target';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { listProductScopes, setScopeProduct } from '../teams-api';\nimport { type Ui, pluralize, shortHost } from '../ui';\nimport { scopeDeprecationNotice } from './scope-notice';\nimport { runSourcePeople, runSourceRoles } from './sources-roles';\n\nexport interface SourcesArgs {\n host?: string;\n /** `products [enable|disable <product>]`, `scopes [add|remove <scope> <product>]`; none lists the sources. */\n positionals?: readonly string[];\n source?: string;\n yes?: boolean;\n /** `roles` and `people`: their flags (`--level`, `--permission`, `--search` …). */\n flags?: Record<string, string | boolean | string[]>;\n /** `roles delete` asks at a terminal; the test seams for it. */\n stdinIsTTY?: boolean;\n ask?: (question: string) => Promise<string>;\n /** Where a project's ekanos.json may sit — its `source` field, if any, is the marker. */\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `sources` — list every source the caller holds a developer or admin seat\n * on, the read half of the publish-target-verification story.\n *\n * The list itself is the mechanism that makes `publish` safe: a partner (or\n * an agent acting for one) can always answer \"which sources can I possibly\n * publish to?\" before running `ekanos use` or passing `--source`.\n */\nexport async function runSources(\n ctx: CliContext,\n args: SourcesArgs,\n): Promise<ExitCode> {\n const [subcommand, ...rest] = args.positionals ?? [];\n if (subcommand !== undefined) {\n if (subcommand === 'scopes') return runScopes(ctx, args, rest);\n if (subcommand === 'roles') return runSourceRoles(ctx, args, rest);\n if (subcommand === 'people') return runSourcePeople(ctx, args, rest);\n if (subcommand !== 'products') {\n throw usageError(\n `Unknown sources subcommand \"${subcommand}\".`,\n 'Run \"ekanos sources\" to list your sources, \"ekanos sources products [enable|disable <product>]\", \"ekanos sources scopes [add|remove <scope> <product>]\", \"ekanos sources roles [list|create|update|delete <role>]\" or \"ekanos sources people\".',\n );\n }\n return runProducts(ctx, args, rest);\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const session = requireSession(env);\n\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env);\n }\n\n const activeSource = readActiveSource(args.dir);\n\n return ctx.succeed(\n { host: env.host, sources: result.sources, activeSource },\n humanSummary(ctx.ui, env.host, result.sources, activeSource),\n );\n}\n\n/**\n * Best-effort, lenient read of ekanos.json's `source` field — mirrors\n * `readProjectHost` in `auth/session.ts`. A missing, unparseable, or\n * sourceless ekanos.json (or no project at all) simply means \"no active\n * source to mark\", never an error: `sources` must answer outside a project\n * too.\n */\nexport function readActiveSource(dir: string): string | null {\n const configPath = path.join(dir, EKANOS_CONFIG_FILENAME);\n\n let raw: string;\n try {\n raw = fs.readFileSync(configPath, 'utf8');\n } catch {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const source =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { source?: unknown }).source\n : undefined;\n\n return typeof source === 'string' && source.trim().length > 0\n ? source.trim()\n : null;\n}\n\n/** Why a product is not enabled, by the lever that would enable it — the words `catalog` uses. */\nconst NOT_ENABLED_BECAUSE: Record<SourceProduct['lever'], string> = {\n flag: 'its Flag is off',\n plan: 'no active plan',\n entitlement: 'not granted',\n};\n\nfunction humanSummary(\n ui: Ui,\n host: string,\n sources: SourceSeat[],\n activeSource: string | null,\n): string {\n if (sources.length === 0) {\n return ui.result({\n // Read by any signed-in account, a team member's too: no word here\n // may imply the host serves more than one customer.\n title: 'No partner seats',\n tone: 'warn',\n rows: [['Host', shortHost(host)]],\n notes: ['This account has no partner seats on this host.'],\n });\n }\n\n const orphaned =\n activeSource && !sources.some((s) => s.slug === activeSource);\n\n return ui.result({\n title: `${pluralize(sources.length, 'source')} on ${shortHost(host)}`,\n rows: sources.map((source): [string, string] => [\n source.slug,\n [\n source.name ?? '(unnamed)',\n source.roles.join(', '),\n ...(source.slug === activeSource ? [ui.accent('this project')] : []),\n ].join(' · '),\n ]),\n notes: orphaned\n ? [\n `This project's ekanos.json points at \"${activeSource}\", which is not in the list above.`,\n ]\n : [],\n });\n}\n\n/**\n * `sources products` — the catalog as one Source has it: every product, its\n * kind (Feature or Integration), and whether it is enabled for the Source.\n * `enable|disable <product>` switch one through the levers `/admin` uses\n * (`attachProductToSource` / `detachProductFromSource` for an Integration,\n * the Feature lever for a Feature). A Source admin switches the\n * integrations their Source built (`owned`); anything else is a super-admin\n * grant, which an `ekanos login` session never carries, so from the terminal\n * that write answers with where to do it.\n */\nasync function runProducts(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawProduct, ...extra] = rest;\n if (extra.length > 0) {\n throw usageError(\n `Unexpected argument \"${extra[0]}\".`,\n 'Run \"ekanos sources products [enable|disable <product>] [--source <slug>]\".',\n );\n }\n if (verb !== undefined && verb !== 'enable' && verb !== 'disable') {\n throw usageError(\n `Unknown sources products subcommand \"${verb}\".`,\n 'Run \"ekanos sources products\", \"ekanos sources products enable <product>\" or \"ekanos sources products disable <product> --yes\".',\n );\n }\n const product = verb ? productSlug(rawProduct, verb) : null;\n if (verb === 'disable' && !args.yes) {\n throw invalidStateError(\n `Disabling ${product} removes it from the Source: its plans, widget settings, Source credentials and workspaces go with it.`,\n `Re-run with --yes: ekanos sources products disable ${product} --yes`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), {\n source: args.source,\n dir: args.dir,\n });\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product) {\n const list = await client.call((token) =>\n listSourceProducts(env.host, token, resolved.source),\n );\n const legacyHost = hostPredatesFeatures(list.products);\n const byKind = (kind: 'feature' | 'experience' | 'integration') =>\n list.products\n .filter((entry) => productGroup(entry, legacyHost) === kind)\n .map((entry): [string, string] => [\n entry.slug,\n `${entry.enabled ? '✓ enabled' : `✗ not enabled (${NOT_ENABLED_BECAUSE[entry.lever]})`} · ${entry.name}${entry.owned ? ' · built by this Source' : ''}${entry.registered ? '' : ' · no package on this host'}`,\n ]);\n return ctx.succeed(\n { host: env.host, ...list },\n [\n ctx.ui.result({\n title: `Features on ${list.source.slug}`,\n rows: byKind('feature'),\n }),\n ...(byKind('experience').length > 0\n ? [\n ctx.ui.result({\n title: `Experiences on ${list.source.slug}`,\n rows: byKind('experience'),\n }),\n ]\n : []),\n ctx.ui.result({\n title: `Integrations on ${list.source.slug}`,\n rows: byKind('integration'),\n notes: [\n list.canEnable\n ? '\"ekanos sources products enable|disable <product>\" switches one.'\n : list.canEnableOwned\n ? '\"ekanos sources products enable|disable <product>\" switches one built by this Source; Ekanos enables any other.'\n : 'Ekanos enables them.',\n '\"ekanos teams connect <team> <product>\" connects an enabled integration for a team.',\n ],\n }),\n ].join('\\n'),\n );\n }\n\n const enabled = verb === 'enable';\n const result = await client.call((token) =>\n setSourceProduct(env.host, token, {\n source: resolved.source,\n product,\n enabled,\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${enabled ? 'Enabled' : 'Disabled'} ${result.product.name} for ${result.source.slug}`\n : `${result.product.name} was already ${enabled ? 'enabled' : 'off'} for ${result.source.slug}`,\n rows: [\n ['Kind', result.product.kind],\n [\n 'Switched by',\n result.product.lever === 'flag'\n ? 'its Flag'\n : result.product.lever === 'plan'\n ? 'its plan'\n : 'the entitlement',\n ],\n ],\n notes:\n enabled && result.product.kind === 'integration'\n ? [\n `Next: \"ekanos teams connect <team> ${result.product.slug}\" connects it for a team.`,\n ]\n : [],\n }),\n );\n}\n\n/**\n * `sources scopes` — the Source's product scopes, for its Source admin: each\n * scope's products and how many teams hold it. Once a Source has a scope,\n * each team sees in the app only its scopes' products. `add|remove <scope>\n * <product>` changes one scope (by name or id) through what\n * `/admin/sources/[id]/scopes` uses; a product can only be added if\n * the Source has it. Taking one out hides it from every team on the scope\n * that no other of its scopes shows it to, so that needs `--yes`.\n */\nasync function runScopes(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawScope, rawProduct, ...extra] = rest;\n const usage =\n 'Run \"ekanos sources scopes\", \"ekanos sources scopes add <scope> <product>\" or \"ekanos sources scopes remove <scope> <product> --yes\".';\n if (verb !== undefined && verb !== 'add' && verb !== 'remove') {\n throw usageError(`Unknown sources scopes subcommand \"${verb}\".`, usage);\n }\n if (extra.length > 0) {\n throw usageError(`Unexpected argument \"${extra[0]}\".`, usage);\n }\n const scope = rawScope?.trim();\n if (verb && !scope) {\n throw usageError(\n `sources scopes ${verb} needs a scope and a product.`,\n usage,\n );\n }\n const product = verb ? scopeProductSlug(rawProduct, verb) : null;\n if (verb === 'remove' && !args.yes) {\n throw invalidStateError(\n `Taking ${product} out of ${scope} hides it, in the app, from every team on ${scope} that no other of its scopes shows it to.`,\n `Re-run with --yes: ekanos sources scopes remove ${quoteArg(scope!)} ${product} --yes`,\n );\n }\n\n ctx.warn(\n scopeDeprecationNotice(\n verb ? `audiences set ${scope} --products …` : 'audiences list',\n ),\n );\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), {\n source: args.source,\n dir: args.dir,\n });\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product || !scope) {\n const list = await client.call((token) =>\n listProductScopes(env.host, token, resolved.source),\n );\n if (list.scopes.length === 0) {\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `No product scopes on ${list.source.slug}`,\n rows: [['Teams see', 'every product the Source has']],\n notes: [\n 'Scopes are created at /admin/sources → the Source → Product scopes.',\n ],\n }),\n );\n }\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `Product scopes on ${list.source.slug}`,\n rows: list.scopes.map((entry): [string, string[]] => [\n entry.name,\n [\n `${pluralize(entry.teamCount, 'team')}${entry.isDefault ? ' · given to every new team' : ''}`,\n entry.products.length > 0\n ? entry.products.map((item) => item.slug).join(', ')\n : 'no products',\n ],\n ]),\n notes: [\n 'A team sees in the app only the products of the scopes it holds.',\n '\"ekanos sources scopes add <scope> <product>\" shows a product to every team on a scope; \"ekanos teams scope show|set <team>\" reads or changes which scopes a team holds.',\n ],\n }),\n );\n }\n\n const included = verb === 'add';\n const result = await client.call((token) =>\n setScopeProduct(\n env.host,\n token,\n { source: resolved.source, scope, product },\n included,\n ),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${included ? 'Added' : 'Took'} ${result.product.name} ${included ? 'to' : 'out of'} ${result.scope.name}`\n : `${result.product.name} was already ${included ? 'in' : 'not in'} ${result.scope.name}`,\n tone: !included && result.changed ? 'warn' : 'ok',\n rows: [\n ['Teams on it', String(result.scope.teamCount)],\n [\n 'Products',\n result.scope.products.length > 0\n ? result.scope.products.map((item) => item.slug).join(', ')\n : 'none',\n ],\n ],\n notes: [\n included\n ? `Every team on ${result.scope.name} sees ${result.product.slug} in the app now.`\n : `Teams on ${result.scope.name} see ${result.product.slug} only if another of their scopes has it.`,\n ],\n }),\n );\n}\n\nfunction scopeProductSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources scopes ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources scopes add Bronze linear\".',\n );\n}\n\nfunction quoteArg(value: string): string {\n return /^[A-Za-z0-9._-]+$/.test(value) ? value : `\"${value}\"`;\n}\n\nfunction productSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources products ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources products enable agents\".',\n );\n}\n\nclass ProductsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<SourceProductsApiResult<T>>,\n ): Promise<T> {\n let result = await send(this.session.accessToken);\n if (result.status === 'unauthorized') {\n this.session = await refreshStoredSession(this.env, this.session);\n result = await send(this.session.accessToken);\n }\n if (result.status === 'ok') return result.data;\n throw authRequiredError(\n `The session for ${this.env.host} could not authorize the sources call.`,\n loginHint(this.env),\n );\n }\n}\n"]}
|
|
@@ -108,7 +108,7 @@ export function requirementFix(item, team, source) {
|
|
|
108
108
|
case 'source_not_connected':
|
|
109
109
|
return `${cli()} apps connect ${item.key} --source ${source}`;
|
|
110
110
|
case 'source_not_entitled':
|
|
111
|
-
return `
|
|
111
|
+
return `Ekanos enables it for the Source (${cli()} sources products --source ${source})`;
|
|
112
112
|
case 'source_unsupported':
|
|
113
113
|
return `set connections.${item.key}.owner to "team" in agent.json, then ${cli()} agents apply`;
|
|
114
114
|
default:
|