@ekanos/cli 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +25 -8
  2. package/dist/agents-api.d.ts +11 -2
  3. package/dist/agents-api.js +39 -3
  4. package/dist/agents-api.js.map +1 -1
  5. package/dist/apps-api.js +2 -2
  6. package/dist/apps-api.js.map +1 -1
  7. package/dist/auth/ekanos-api.d.ts +16 -2
  8. package/dist/auth/ekanos-api.js +101 -15
  9. package/dist/auth/ekanos-api.js.map +1 -1
  10. package/dist/auth/host-trust.d.ts +46 -0
  11. package/dist/auth/host-trust.js +79 -0
  12. package/dist/auth/host-trust.js.map +1 -0
  13. package/dist/auth/session.d.ts +10 -1
  14. package/dist/auth/session.js +28 -28
  15. package/dist/auth/session.js.map +1 -1
  16. package/dist/commands/agents-edit.d.ts +6 -2
  17. package/dist/commands/agents-edit.js +57 -26
  18. package/dist/commands/agents-edit.js.map +1 -1
  19. package/dist/commands/agents.d.ts +13 -2
  20. package/dist/commands/agents.js +148 -36
  21. package/dist/commands/agents.js.map +1 -1
  22. package/dist/commands/apps.d.ts +2 -0
  23. package/dist/commands/apps.js +16 -12
  24. package/dist/commands/apps.js.map +1 -1
  25. package/dist/commands/catalog.js +7 -6
  26. package/dist/commands/catalog.js.map +1 -1
  27. package/dist/commands/knowledge.d.ts +19 -0
  28. package/dist/commands/knowledge.js +119 -27
  29. package/dist/commands/knowledge.js.map +1 -1
  30. package/dist/commands/login.d.ts +4 -0
  31. package/dist/commands/login.js +30 -2
  32. package/dist/commands/login.js.map +1 -1
  33. package/dist/commands/logout.d.ts +9 -1
  34. package/dist/commands/logout.js +56 -7
  35. package/dist/commands/logout.js.map +1 -1
  36. package/dist/commands/publish.js +3 -3
  37. package/dist/commands/publish.js.map +1 -1
  38. package/dist/commands/reviewers.d.ts +2 -0
  39. package/dist/commands/reviewers.js +7 -3
  40. package/dist/commands/reviewers.js.map +1 -1
  41. package/dist/commands/routes.d.ts +2 -0
  42. package/dist/commands/routes.js +42 -9
  43. package/dist/commands/routes.js.map +1 -1
  44. package/dist/commands/runs.d.ts +13 -2
  45. package/dist/commands/runs.js +96 -15
  46. package/dist/commands/runs.js.map +1 -1
  47. package/dist/commands/scope-notice.d.ts +21 -0
  48. package/dist/commands/scope-notice.js +35 -0
  49. package/dist/commands/scope-notice.js.map +1 -0
  50. package/dist/commands/skills.d.ts +7 -1
  51. package/dist/commands/skills.js +80 -24
  52. package/dist/commands/skills.js.map +1 -1
  53. package/dist/commands/sources.d.ts +1 -1
  54. package/dist/commands/sources.js +126 -12
  55. package/dist/commands/sources.js.map +1 -1
  56. package/dist/commands/status.js +5 -4
  57. package/dist/commands/status.js.map +1 -1
  58. package/dist/commands/team-agent-readiness.d.ts +59 -0
  59. package/dist/commands/team-agent-readiness.js +341 -0
  60. package/dist/commands/team-agent-readiness.js.map +1 -0
  61. package/dist/commands/team-agents-agents.d.ts +24 -3
  62. package/dist/commands/team-agents-agents.js +336 -35
  63. package/dist/commands/team-agents-agents.js.map +1 -1
  64. package/dist/commands/team-agents-mcp.js +32 -3
  65. package/dist/commands/team-agents-mcp.js.map +1 -1
  66. package/dist/commands/team-agents-triggers.js +230 -55
  67. package/dist/commands/team-agents-triggers.js.map +1 -1
  68. package/dist/commands/team-agents.d.ts +3 -1
  69. package/dist/commands/team-agents.js +27 -7
  70. package/dist/commands/team-agents.js.map +1 -1
  71. package/dist/commands/teams-channel-install.d.ts +24 -0
  72. package/dist/commands/teams-channel-install.js +94 -0
  73. package/dist/commands/teams-channel-install.js.map +1 -0
  74. package/dist/commands/teams-connect.d.ts +41 -0
  75. package/dist/commands/teams-connect.js +212 -57
  76. package/dist/commands/teams-connect.js.map +1 -1
  77. package/dist/commands/teams-events.d.ts +12 -0
  78. package/dist/commands/teams-events.js +138 -0
  79. package/dist/commands/teams-events.js.map +1 -0
  80. package/dist/commands/teams-onboard.d.ts +11 -3
  81. package/dist/commands/teams-onboard.js +60 -7
  82. package/dist/commands/teams-onboard.js.map +1 -1
  83. package/dist/commands/teams-overview.d.ts +11 -0
  84. package/dist/commands/teams-overview.js +160 -0
  85. package/dist/commands/teams-overview.js.map +1 -0
  86. package/dist/commands/teams-scope.d.ts +10 -0
  87. package/dist/commands/teams-scope.js +109 -0
  88. package/dist/commands/teams-scope.js.map +1 -0
  89. package/dist/commands/teams.d.ts +4 -2
  90. package/dist/commands/teams.js +113 -14
  91. package/dist/commands/teams.js.map +1 -1
  92. package/dist/commands/upgrade.js +12 -2
  93. package/dist/commands/upgrade.js.map +1 -1
  94. package/dist/commands/use.js +2 -2
  95. package/dist/commands/use.js.map +1 -1
  96. package/dist/commands/whoami.js +1 -1
  97. package/dist/commands/whoami.js.map +1 -1
  98. package/dist/connections-api.js +1 -1
  99. package/dist/connections-api.js.map +1 -1
  100. package/dist/delegate.js +11 -4
  101. package/dist/delegate.js.map +1 -1
  102. package/dist/harness-scaffold.js +12 -0
  103. package/dist/harness-scaffold.js.map +1 -1
  104. package/dist/index.d.ts +6 -0
  105. package/dist/index.js +683 -167
  106. package/dist/index.js.map +1 -1
  107. package/dist/knowledge-api.d.ts +46 -0
  108. package/dist/knowledge-api.js +32 -1
  109. package/dist/knowledge-api.js.map +1 -1
  110. package/dist/open-url.d.ts +16 -0
  111. package/dist/open-url.js +73 -0
  112. package/dist/open-url.js.map +1 -0
  113. package/dist/parse-argv.d.ts +2 -0
  114. package/dist/parse-argv.js.map +1 -1
  115. package/dist/publish-api.d.ts +2 -1
  116. package/dist/publish-api.js +4 -3
  117. package/dist/publish-api.js.map +1 -1
  118. package/dist/pull-write.d.ts +27 -0
  119. package/dist/pull-write.js +60 -0
  120. package/dist/pull-write.js.map +1 -0
  121. package/dist/routes-api.d.ts +3 -0
  122. package/dist/routes-api.js +9 -4
  123. package/dist/routes-api.js.map +1 -1
  124. package/dist/runs-api.d.ts +7 -1
  125. package/dist/runs-api.js +21 -6
  126. package/dist/runs-api.js.map +1 -1
  127. package/dist/safe-fs.d.ts +2 -0
  128. package/dist/safe-fs.js +12 -6
  129. package/dist/safe-fs.js.map +1 -1
  130. package/dist/secret-file.d.ts +17 -0
  131. package/dist/secret-file.js +69 -0
  132. package/dist/secret-file.js.map +1 -0
  133. package/dist/skills-api.d.ts +10 -2
  134. package/dist/skills-api.js +37 -2
  135. package/dist/skills-api.js.map +1 -1
  136. package/dist/source-products-api.d.ts +4 -0
  137. package/dist/source-products-api.js +14 -4
  138. package/dist/source-products-api.js.map +1 -1
  139. package/dist/source-target.js +2 -1
  140. package/dist/source-target.js.map +1 -1
  141. package/dist/sources-api.d.ts +2 -1
  142. package/dist/sources-api.js +3 -2
  143. package/dist/sources-api.js.map +1 -1
  144. package/dist/team-connect-api.d.ts +44 -2
  145. package/dist/team-connect-api.js +19 -7
  146. package/dist/team-connect-api.js.map +1 -1
  147. package/dist/teams-api.d.ts +41 -1
  148. package/dist/teams-api.js +97 -19
  149. package/dist/teams-api.js.map +1 -1
  150. package/dist/toolchain-api.d.ts +9 -0
  151. package/dist/toolchain-api.js +17 -2
  152. package/dist/toolchain-api.js.map +1 -1
  153. package/dist/toolchain-resolve.d.ts +3 -0
  154. package/dist/toolchain-resolve.js +15 -1
  155. package/dist/toolchain-resolve.js.map +1 -1
  156. package/dist/toolchain.d.ts +6 -0
  157. package/dist/toolchain.js +19 -0
  158. package/dist/toolchain.js.map +1 -1
  159. package/dist/update-notice.js +2 -1
  160. package/dist/update-notice.js.map +1 -1
  161. package/package.json +2 -2
  162. package/templates/AGENTS.md.tmpl +6 -1
  163. package/templates/claude-skill.md.tmpl +5 -0
  164. package/templates/package.json.tmpl +4 -4
  165. package/templates/skills/build-agent/SKILL.md +103 -17
  166. package/templates/skills/build-agent/references/agent-json.md +4 -2
  167. package/templates/skills/build-agent/references/rollout.md +27 -4
  168. package/templates/skills/build-agent/references/set-up-an-integration.md +55 -7
  169. package/templates/skills/build-agent/references/skills.md +20 -1
  170. package/templates/skills/build-agent/references/triggers.md +46 -11
  171. package/templates/skills/build-integration/references/widget-design.md +3 -3
  172. package/templates/skills/ekanos-platform/SKILL.md +43 -16
  173. package/templates/skills/polish-widgets/references/patterns.md +2 -2
@@ -1,4 +1,5 @@
1
1
  import { setProviderApp, showProviderApp, } from '../apps-api.js';
2
+ import { loginHint } from '../auth/host-trust.js';
2
3
  import { refreshStoredSession, requireSession, resolveAuthEnvironment, } from '../auth/session.js';
3
4
  import { deleteConnection, listConnections, showConnection, startConnection, } from '../connections-api.js';
4
5
  import { authRequiredError, invalidStateError, usageError, validationError, } from '../errors.js';
@@ -34,7 +35,7 @@ export async function runApps(ctx, args) {
34
35
  const env = resolveAuthEnvironment(ctx, args.host, args.env, {
35
36
  projectDir: args.dir,
36
37
  });
37
- const resolved = await resolveSourceTarget(env, requireSession(env.store, env.host), args);
38
+ const resolved = await resolveSourceTarget(env, requireSession(env), args);
38
39
  const client = new AppsClient(env, resolved.session);
39
40
  const source = resolved.source;
40
41
  if (subcommand === 'show') {
@@ -117,7 +118,7 @@ function summary(ctx, status) {
117
118
  : []),
118
119
  ...providerFieldRows(status),
119
120
  [
120
- 'Set up',
121
+ 'App ready',
121
122
  status.configured
122
123
  ? 'yes — teams can connect'
123
124
  : 'no — no team can connect yet',
@@ -213,7 +214,7 @@ async function runConnection(ctx, args, subcommand, product) {
213
214
  }
214
215
  const shown = await client.connection((token) => showConnection(env.host, token, source, product));
215
216
  if (shown.status === 'unsupported') {
216
- throw invalidStateError(shown.message, `Each team connects ${product} itself, from the team's Integrations page.`);
217
+ throw invalidStateError(shown.message, `Each team connects ${product} itself: "ekanos teams connect <team> ${product}".`);
217
218
  }
218
219
  if (shown.status !== 'ok') {
219
220
  throw invalidStateError('The host could not read the connection.', 'Retry shortly.');
@@ -288,7 +289,10 @@ async function askFields(ctx, args, current, product) {
288
289
  }
289
290
  async function disconnect(ctx, args, client, host, source, product) {
290
291
  var _a;
291
- if (canPrompt(ctx, args)) {
292
+ if (!args.yes && !canPrompt(ctx, args)) {
293
+ throw invalidStateError(`Disconnecting ${product} on ${source} stops it for every team's provided agents that use the Source connection, until someone connects it again.`, `Re-run with --yes: ekanos apps disconnect ${product} --source ${source} --yes`);
294
+ }
295
+ if (!args.yes) {
292
296
  const sure = await ((_a = args.confirm) !== null && _a !== void 0 ? _a : promptYesNo)(`Disconnect ${product} for every team's provided agents on ${source}? [y/N]`);
293
297
  if (!sure) {
294
298
  throw validationError('Nothing was changed.', `Run "ekanos apps show ${product}" to see the current state.`);
@@ -296,15 +300,15 @@ async function disconnect(ctx, args, client, host, source, product) {
296
300
  }
297
301
  const result = await client.connection((token) => deleteConnection(host, token, source, product));
298
302
  if (result.status === 'unsupported') {
299
- throw invalidStateError(result.message, `Each team connects ${product} itself, from the team's Integrations page.`);
303
+ throw invalidStateError(result.message, `Each team connects ${product} itself: "ekanos teams connect <team> ${product}".`);
300
304
  }
301
305
  if (result.status !== 'ok') {
302
306
  throw invalidStateError('The host could not disconnect.', 'Retry shortly.');
303
307
  }
304
308
  return ctx.succeed(Object.assign({ host, product }, result.data), ctx.ui.result({
305
309
  title: result.data.removed
306
- ? `Disconnected ${product} for ${source}`
307
- : `${product} was not connected for ${source}`,
310
+ ? `Disconnected the ${product} Source connection on ${source}`
311
+ : `${product} had no Source connection on ${source}`,
308
312
  rows: [
309
313
  [
310
314
  'Provided agents',
@@ -329,12 +333,12 @@ function connectionSummary(ctx, connection, meta) {
329
333
  ['Redirect URL', meta.callbackUrls],
330
334
  [
331
335
  'Used by',
332
- 'provided agents whose template says connections.<product>.owner: "source", in every team',
336
+ `provided agents whose template says connections.${connection.slug}.owner: "source", in every team`,
333
337
  ],
334
338
  ];
335
339
  return [
336
340
  ctx.ui.result({
337
- title: `${connection.name} — one connection for the whole Source`,
341
+ title: `${connection.name} — Source connection (one for every team's provided agents)`,
338
342
  rows,
339
343
  }),
340
344
  ...(connection.connected
@@ -348,7 +352,7 @@ async function openClient(ctx, args) {
348
352
  const env = resolveAuthEnvironment(ctx, args.host, args.env, {
349
353
  projectDir: args.dir,
350
354
  });
351
- const resolved = await resolveSourceTarget(env, requireSession(env.store, env.host), args);
355
+ const resolved = await resolveSourceTarget(env, requireSession(env), args);
352
356
  return {
353
357
  env,
354
358
  client: new AppsClient(env, resolved.session),
@@ -368,7 +372,7 @@ class AppsClient {
368
372
  }
369
373
  if (result.status === 'ok')
370
374
  return result.data;
371
- throw authRequiredError(`The session for ${this.env.host} could not authorize the apps call.`, `Run "ekanos login --host ${this.env.host}" and retry.`);
375
+ throw authRequiredError(`The session for ${this.env.host} could not authorize the apps call.`, loginHint(this.env));
372
376
  }
373
377
  /** As `call`, for the connections client, whose 409s are answers. */
374
378
  async connection(send) {
@@ -379,7 +383,7 @@ class AppsClient {
379
383
  }
380
384
  if (result.status !== 'unauthorized')
381
385
  return result;
382
- throw authRequiredError(`The session for ${this.env.host} could not authorize the connections call.`, `Run "ekanos login --host ${this.env.host}" and retry.`);
386
+ throw authRequiredError(`The session for ${this.env.host} could not authorize the connections call.`, loginHint(this.env));
383
387
  }
384
388
  }
385
389
  function canPrompt(ctx, args) {
@@ -1 +1 @@
1
- {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProviderAppStatus } from '@ekanos/integration-schema';\n\nimport {\n type AppsApiResult,\n setProviderApp,\n showProviderApp,\n} from '../apps-api';\nimport type { StoredSession } from '../auth/credential-store';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport {\n type ConnectionsApiResult,\n type SourceConnection,\n deleteConnection,\n listConnections,\n showConnection,\n startConnection,\n} from '../connections-api';\nimport type { CliContext } from '../context';\nimport {\n authRequiredError,\n invalidStateError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport type { ResultRow } from '../ui';\nimport { promptYesNo } from './publish';\n\nexport const APPS_SUBCOMMANDS = [\n 'show',\n 'set',\n 'list',\n 'connect',\n 'disconnect',\n] as const;\ntype AppsSubcommand = (typeof APPS_SUBCOMMANDS)[number];\n\nexport interface AppsArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n product?: string;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n /** Test seams for the questions `set` and `connect` ask. */\n ask?: (question: string) => Promise<string>;\n askSecret?: (question: string) => Promise<string>;\n confirm?: (question: string) => Promise<boolean>;\n /** Test seam: `connect`'s wait between status polls. */\n pollDelayMs?: number;\n /** `connect --no-wait`: print the URL and return without polling. */\n noWait?: boolean;\n}\n\n/**\n * `apps` — a Source's provider apps: the OAuth client an integration signs\n * every team in through (Linear's, say). `show` says whether the Source has\n * one and which callback URL to register; `set` takes the client id and\n * secret from the Source admin at the terminal — either on its own, Enter\n * keeping the saved one — never from a flag, a file or a non-interactive\n * run, so an agent driving the CLI never handles the secret.\n */\nexport async function runApps(\n ctx: CliContext,\n args: AppsArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n if (subcommand === 'list') return runList(ctx, args);\n const product = requireProduct(args.product, subcommand);\n if (subcommand === 'connect' || subcommand === 'disconnect') {\n return runConnection(ctx, args, subcommand, product);\n }\n\n if (subcommand === 'set' && !canPrompt(ctx, args)) {\n throw usageError(\n 'apps set takes the client secret at a terminal, never in a script or an agent run.',\n `Run it yourself in your terminal: npx @ekanos/cli apps set ${product}${args.source ? ` --source ${args.source}` : ''}`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(\n env,\n requireSession(env.store, env.host),\n args,\n );\n const client = new AppsClient(env, resolved.session);\n const source = resolved.source;\n\n if (subcommand === 'show') {\n return showApp(ctx, env.host, client, source, product);\n }\n\n const status = await client.call((token) =>\n showProviderApp(env.host, token, source, product),\n );\n\n ctx.log(walkthrough(status).join('\\n'));\n\n // Either credential on its own: Enter keeps what is saved. An older host\n // sends no `fields`; then `configured` says whether both are saved.\n const saved = (name: 'clientId' | 'clientSecret') =>\n status.fields?.find((field) => field.name === name) ?? {\n set: status.configured,\n value: null,\n };\n const savedId = saved('clientId');\n const savedSecret = saved('clientSecret');\n const clientId = (\n await (args.ask ?? promptLine)(\n savedId.set\n ? `Client ID (current: ${savedId.value ?? 'saved'} — Enter to keep): `\n : 'Client ID: ',\n )\n ).trim();\n const clientSecret = (\n await (args.askSecret ?? promptHidden)(\n savedSecret.set\n ? 'Client secret (saved — Enter to keep, hidden): '\n : 'Client secret (hidden): ',\n )\n ).trim();\n if (!clientId && !clientSecret) {\n throw validationError(\n 'Nothing was changed.',\n `Run \"ekanos apps show ${product}\" to see the current state.`,\n );\n }\n\n const result = await client.call((token) =>\n setProviderApp(env.host, token, {\n source,\n product,\n ...(clientId ? { clientId } : {}),\n ...(clientSecret ? { clientSecret } : {}),\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.replaced\n ? `Updated the ${result.product.name} app`\n : `Set up the ${result.product.name} app`,\n rows: [\n ['Source', result.source.slug],\n ...providerFieldRows(result),\n ['Teams can connect', result.configured ? 'yes' : 'not yet'],\n ['Callback URLs', callbackUrls(result)],\n ],\n }),\n );\n}\n\n/**\n * How to create the app: the integration's own steps (`oauth.setup`, with the\n * callback URL filled in) when it declares them, else the generic three.\n */\nexport function walkthrough(status: ProviderAppStatus): string[] {\n const name = status.product.name;\n const lines = [`${name} app for ${status.source.slug}`];\n if (status.setup?.consoleUrl) {\n lines.push(` Open: ${status.setup.consoleUrl}`);\n }\n const steps = status.setup?.steps.length\n ? [\n ...status.setup.steps,\n `Check the app lists exactly: ${callbackUrls(status).join(', ')}`,\n ]\n : [\n `In ${name}, create an OAuth app (or open the one you use).`,\n `Register exactly these callback URLs: ${callbackUrls(status).join(', ')}`,\n ];\n steps.push(\n \"Enter its client ID and secret below. The secret is stored in Ekanos's vault and never shown again.\",\n );\n lines.push(...steps.map((step, index) => ` ${index + 1}. ${step}`));\n if (status.setup?.guideUrl) lines.push(` Guide: ${status.setup.guideUrl}`);\n return lines;\n}\n\nfunction summary(ctx: CliContext, status: ProviderAppStatus): string {\n const rows: ResultRow[] = [\n ['Source', status.source.slug],\n ...(status.setup\n ? ([\n [\n 'How to create it',\n [\n ...(status.setup.consoleUrl\n ? [`Open ${status.setup.consoleUrl}`]\n : []),\n ...status.setup.steps.map(\n (step, index) => `${index + 1}. ${step}`,\n ),\n ],\n ],\n ] as const)\n : []),\n ...providerFieldRows(status),\n [\n 'Set up',\n status.configured\n ? 'yes — teams can connect'\n : 'no — no team can connect yet',\n ],\n ['Callback URLs', callbackUrls(status)],\n ];\n return [\n ctx.ui.result({ title: `${status.product.name} app`, rows }),\n ...(status.configured\n ? []\n : [\n ctx.ui.hint(\n `Run \"ekanos apps set ${status.product.slug}\" in your terminal to enter its credentials.`,\n ),\n ]),\n ].join('\\n');\n}\n\n/**\n * `apps show <product>`: the Source provider app, and — for an integration\n * that supports one — the Source connection (plan 241). A `teamApp`\n * integration (Zendesk) has no provider app but can have a Source\n * connection, so either half may be absent.\n */\nasync function showApp(\n ctx: CliContext,\n host: string,\n client: AppsClient,\n source: string,\n product: string,\n): Promise<ExitCode> {\n const [app, connection] = await Promise.all([\n client\n .call((token) => showProviderApp(host, token, source, product))\n .then(\n (status) => ({ ok: true as const, status }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n // A host without the connections routes (before plan 241), or one that\n // refuses, leaves `show` exactly as it was: the provider app alone.\n client\n .connection((token) => showConnection(host, token, source, product))\n .catch(() => ({ status: 'unavailable' as const })),\n ]);\n\n if (!app.ok && connection.status !== 'ok') throw app.error;\n\n const parts: string[] = [];\n if (app.ok) parts.push(summary(ctx, app.status));\n if (connection.status === 'ok') {\n parts.push(\n connectionSummary(ctx, connection.data.connection, {\n sourceSlug: connection.data.source.slug,\n callbackUrls: connection.data.callbackUrls,\n }),\n );\n }\n\n return ctx.succeed(\n {\n host,\n ...(app.ok ? app.status : {}),\n ...(connection.status === 'ok'\n ? {\n sourceConnection: connection.data.connection,\n sourceConnectionCallbackUrls: connection.data.callbackUrls,\n }\n : {}),\n },\n parts.join('\\n'),\n );\n}\n\n/** `apps list`: every integration the Source can connect once, with status. */\nasync function runList(ctx: CliContext, args: AppsArgs): Promise<ExitCode> {\n const { env, client, source } = await openClient(ctx, args);\n const result = await client.connection((token) =>\n listConnections(env.host, token, source),\n );\n if (result.status !== 'ok') {\n throw invalidStateError(\n 'The host could not list the connections.',\n 'Retry shortly.',\n );\n }\n const { connections } = result.data;\n const rows: ResultRow[] = connections.map((connection) => [\n `${connection.name} (${connection.slug})`,\n connectionState(connection),\n ]);\n return ctx.succeed(\n { host: env.host, ...result.data },\n connections.length === 0\n ? ctx.ui.hint(\n `No integration on ${result.data.source.slug} supports one connection for the whole Source yet.`,\n )\n : ctx.ui.result({\n title: `Source connections on ${result.data.source.slug}`,\n rows,\n }),\n );\n}\n\nfunction connectionState(connection: SourceConnection): string {\n if (connection.connected) {\n return [\n 'connected',\n connection.connectedAt ? ` ${connection.connectedAt}` : '',\n connection.connectedBy ? ` by ${connection.connectedBy}` : '',\n ].join('');\n }\n return connection.missing.length > 0\n ? `not connected — app fields missing: ${connection.missing.join(', ')}`\n : 'not connected';\n}\n\n/**\n * `apps connect <product>`: connect the integration ONCE for the whole Source,\n * for the Source's provided agents whose template says `owner: \"source\"`.\n * Asks for any missing app fields at the terminal (secrets hidden, never from\n * a flag), prints the provider's consent URL, then waits until the browser\n * finishes. `apps disconnect <product>` removes it.\n */\nasync function runConnection(\n ctx: CliContext,\n args: AppsArgs,\n subcommand: 'connect' | 'disconnect',\n product: string,\n): Promise<ExitCode> {\n const { env, client, source } = await openClient(ctx, args);\n\n if (subcommand === 'disconnect') {\n return disconnect(ctx, args, client, env.host, source, product);\n }\n\n const shown = await client.connection((token) =>\n showConnection(env.host, token, source, product),\n );\n if (shown.status === 'unsupported') {\n throw invalidStateError(\n shown.message,\n `Each team connects ${product} itself, from the team's Integrations page.`,\n );\n }\n if (shown.status !== 'ok') {\n throw invalidStateError(\n 'The host could not read the connection.',\n 'Retry shortly.',\n );\n }\n const current = shown.data.connection;\n\n if (current.app === 'fields') {\n ctx.log(\n [\n `${current.name} app for ${shown.data.source.slug} (one for the whole Source)`,\n ` Register this redirect URL in the app: ${shown.data.callbackUrls.join(', ')}`,\n ].join('\\n'),\n );\n }\n\n const fields = await askFields(ctx, args, current, product);\n\n const started = await client.connection((token) =>\n startConnection(env.host, token, {\n source,\n product,\n ...(Object.keys(fields).length > 0 ? { fields } : {}),\n }),\n );\n if (started.status === 'not-configured') {\n throw validationError(\n `${current.name} is not set up for the Source yet — missing: ${started.missing.join(', ')}.`,\n current.app === 'source-app'\n ? `Run \"ekanos apps set ${product}\" to enter the Source's app first.`\n : `Run \"ekanos apps connect ${product}\" again and fill every field.`,\n );\n }\n if (started.status !== 'ok') {\n throw invalidStateError(\n 'The host could not start the connection.',\n 'Retry shortly.',\n );\n }\n\n ctx.log(\n [\n `Open this link and approve ${current.name} as the account the Source's agents should act as:`,\n ` ${started.data.authorizeUrl}`,\n ].join('\\n'),\n );\n\n if (args.noWait || ctx.jsonMode) {\n return ctx.succeed(\n {\n host: env.host,\n product,\n authorizeUrl: started.data.authorizeUrl,\n callbackUrl: started.data.callbackUrl,\n connected: false,\n },\n ctx.ui.hint(`Then check with \"ekanos apps show ${product}\".`),\n );\n }\n\n const deadline = Date.now() + 10 * 60 * 1000;\n const before = current.connectedAt;\n while (Date.now() < deadline) {\n await new Promise((resolve) =>\n setTimeout(resolve, args.pollDelayMs ?? 3000),\n );\n const polled = await client.connection((token) =>\n showConnection(env.host, token, source, product),\n );\n if (\n polled.status === 'ok' &&\n polled.data.connection.connected &&\n polled.data.connection.connectedAt !== before\n ) {\n return ctx.succeed(\n { host: env.host, product, connection: polled.data.connection },\n connectionSummary(ctx, polled.data.connection, {\n sourceSlug: polled.data.source.slug,\n callbackUrls: polled.data.callbackUrls,\n }),\n );\n }\n }\n throw validationError(\n 'The connection did not finish within ten minutes.',\n `Run \"ekanos apps connect ${product}\" again for a fresh link.`,\n );\n}\n\nasync function askFields(\n ctx: CliContext,\n args: AppsArgs,\n current: SourceConnection,\n product: string,\n): Promise<Record<string, string>> {\n const toAsk = current.fields.filter(\n (field) => !field.set || current.missing.includes(field.name),\n );\n if (toAsk.length === 0) return {};\n if (!canPrompt(ctx, args)) {\n throw usageError(\n `${current.name} needs its app fields entered for the Source: ${toAsk.map((field) => field.label).join(', ')}.`,\n `Run it yourself in your terminal: npx @ekanos/cli apps connect ${product}${args.source ? ` --source ${args.source}` : ''}`,\n );\n }\n const fields: Record<string, string> = {};\n for (const field of toAsk) {\n const question = field.sensitive\n ? `${field.label} (hidden): `\n : `${field.label}: `;\n const value = (\n await (\n field.sensitive\n ? (args.askSecret ?? promptHidden)\n : (args.ask ?? promptLine)\n )(question)\n ).trim();\n if (value) fields[field.name] = value;\n }\n return fields;\n}\n\nasync function disconnect(\n ctx: CliContext,\n args: AppsArgs,\n client: AppsClient,\n host: string,\n source: string,\n product: string,\n): Promise<ExitCode> {\n if (canPrompt(ctx, args)) {\n const sure = await (args.confirm ?? promptYesNo)(\n `Disconnect ${product} for every team's provided agents on ${source}? [y/N]`,\n );\n if (!sure) {\n throw validationError(\n 'Nothing was changed.',\n `Run \"ekanos apps show ${product}\" to see the current state.`,\n );\n }\n }\n const result = await client.connection((token) =>\n deleteConnection(host, token, source, product),\n );\n if (result.status === 'unsupported') {\n throw invalidStateError(\n result.message,\n `Each team connects ${product} itself, from the team's Integrations page.`,\n );\n }\n if (result.status !== 'ok') {\n throw invalidStateError('The host could not disconnect.', 'Retry shortly.');\n }\n return ctx.succeed(\n { host, product, ...result.data },\n ctx.ui.result({\n title: result.data.removed\n ? `Disconnected ${product} for ${source}`\n : `${product} was not connected for ${source}`,\n rows: [\n [\n 'Provided agents',\n 'their tools for this product stop until you connect again',\n ],\n ],\n }),\n );\n}\n\nfunction connectionSummary(\n ctx: CliContext,\n connection: SourceConnection,\n meta: { sourceSlug: string; callbackUrls: string[] },\n): string {\n const rows: ResultRow[] = [\n ['Source', meta.sourceSlug],\n ['Connected', connectionState(connection)],\n ...(connection.scope ? ([['Scope', connection.scope]] as ResultRow[]) : []),\n ...(connection.fields.length > 0\n ? ([\n [\n 'App fields',\n connection.fields.map(\n (field) =>\n `${field.label}: ${field.set ? (field.value ?? 'set') : 'missing'}`,\n ),\n ],\n ] as ResultRow[])\n : []),\n ['Redirect URL', meta.callbackUrls],\n [\n 'Used by',\n 'provided agents whose template says connections.<product>.owner: \"source\", in every team',\n ],\n ];\n return [\n ctx.ui.result({\n title: `${connection.name} — one connection for the whole Source`,\n rows,\n }),\n ...(connection.connected\n ? []\n : [\n ctx.ui.hint(\n `Run \"ekanos apps connect ${connection.slug}\" in your terminal to connect it.`,\n ),\n ]),\n ].join('\\n');\n}\n\nasync function openClient(ctx: CliContext, args: AppsArgs) {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(\n env,\n requireSession(env.store, env.host),\n args,\n );\n return {\n env,\n client: new AppsClient(env, resolved.session),\n source: resolved.source,\n };\n}\n\nclass AppsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<AppsApiResult<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 apps call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n\n /** As `call`, for the connections client, whose 409s are answers. */\n async connection<T>(\n send: (accessToken: string) => Promise<ConnectionsApiResult<T>>,\n ): Promise<Exclude<ConnectionsApiResult<T>, { status: 'unauthorized' }>> {\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 !== 'unauthorized') return result;\n throw authRequiredError(\n `The session for ${this.env.host} could not authorize the connections call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n}\n\nfunction canPrompt(ctx: CliContext, args: AppsArgs): boolean {\n return !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n}\n\nfunction parseSubcommand(value: string | undefined): AppsSubcommand {\n const match = APPS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value ? `Unknown apps subcommand \"${value}\".` : 'apps needs a subcommand.',\n `Run one of: ${APPS_SUBCOMMANDS.map((name) => `ekanos apps ${name} <product>`).join(', ')}.`,\n );\n}\n\nfunction requireProduct(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 : `apps ${verb} needs a product.`,\n `Pass the product's slug, e.g. \"ekanos apps ${verb} linear\". \"ekanos catalog\" lists them.`,\n );\n}\n\nexport async function promptLine(question: string): Promise<string> {\n const readline = await import('node:readline/promises');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n try {\n return await rl.question(question);\n } finally {\n rl.close();\n }\n}\n\n/**\n * Read a line without echoing it: the secret never appears on screen or in\n * scrollback. The question is always printed; only the typed characters are\n * hidden (each shows as `*`, so a paste visibly landed).\n *\n * Raw mode by hand rather than readline: a terminal readline redraws its\n * line on `question()` — cursor to column 0, clear to the end of the screen —\n * which erased the question written before it, so the terminal sat on an\n * empty line and a hidden field looked skipped.\n */\nexport async function promptHidden(question: string): Promise<string> {\n const stdin = process.stdin;\n const stderr = process.stderr;\n stderr.write(question);\n\n if (!stdin.isTTY) {\n // Piped stdin echoes nothing: read one line as is.\n const readline = await import('node:readline/promises');\n const rl = readline.createInterface({ input: stdin, terminal: false });\n try {\n return await rl.question('');\n } finally {\n rl.close();\n stderr.write('\\n');\n }\n }\n\n return new Promise<string>((resolve) => {\n let value = '';\n let inEscape = false;\n const wasRaw = stdin.isRaw;\n const finish = () => {\n stdin.off('data', onData);\n stdin.setRawMode(wasRaw);\n stdin.pause();\n stderr.write('\\n');\n };\n const onData = (chunk: Buffer | string) => {\n for (const char of typeof chunk === 'string'\n ? chunk\n : chunk.toString('utf8')) {\n if (inEscape) {\n // An escape sequence (an arrow key) ends at its final letter.\n if (/[A-Za-z~]/.test(char)) inEscape = false;\n continue;\n }\n if (char === '\\u001b') {\n inEscape = true;\n continue;\n }\n if (char === '\\r' || char === '\\n' || char === '\\u0004') {\n finish();\n resolve(value);\n return;\n }\n if (char === '\\u0003') {\n // Ctrl-C: raw mode swallowed the signal, so leave as SIGINT would.\n finish();\n process.exit(130);\n }\n if (char === '\\u007f' || char === '\\b') {\n if (value.length > 0) {\n value = value.slice(0, -1);\n stderr.write('\\b \\b');\n }\n continue;\n }\n if (char === '\\u0015') {\n // Ctrl-U: clear what was typed.\n stderr.write('\\b \\b'.repeat(value.length));\n value = '';\n continue;\n }\n if (char < ' ') continue;\n value += char;\n stderr.write('*');\n }\n };\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on('data', onData);\n });\n}\n\n/** Each credential's state: the client id's value, the secret as saved or not. */\nfunction providerFieldRows(status: ProviderAppStatus): ResultRow[] {\n return (status.fields ?? []).map((field) => [\n field.label,\n !field.set\n ? 'not set'\n : field.sensitive\n ? 'saved'\n : (field.value ?? 'saved'),\n ]);\n}\n\n/** Every redirect URI to register; an older host sends only the one. */\nfunction callbackUrls(status: ProviderAppStatus): string[] {\n return status.callbackUrls?.length\n ? status.callbackUrls\n : [status.callbackUrl];\n}\n"]}
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"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","sourcesContent":["import type { ProviderAppStatus } from '@ekanos/integration-schema';\n\nimport {\n type AppsApiResult,\n setProviderApp,\n showProviderApp,\n} from '../apps-api';\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 {\n type ConnectionsApiResult,\n type SourceConnection,\n deleteConnection,\n listConnections,\n showConnection,\n startConnection,\n} from '../connections-api';\nimport type { CliContext } from '../context';\nimport {\n authRequiredError,\n invalidStateError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport type { ResultRow } from '../ui';\nimport { promptYesNo } from './publish';\n\nexport const APPS_SUBCOMMANDS = [\n 'show',\n 'set',\n 'list',\n 'connect',\n 'disconnect',\n] as const;\ntype AppsSubcommand = (typeof APPS_SUBCOMMANDS)[number];\n\nexport interface AppsArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n product?: string;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n /** Test seams for the questions `set` and `connect` ask. */\n ask?: (question: string) => Promise<string>;\n askSecret?: (question: string) => Promise<string>;\n confirm?: (question: string) => Promise<boolean>;\n /** Test seam: `connect`'s wait between status polls. */\n pollDelayMs?: number;\n /** `connect --no-wait`: print the URL and return without polling. */\n noWait?: boolean;\n /** `disconnect --yes`: confirm without the question (a script, an agent run). */\n yes?: boolean;\n}\n\n/**\n * `apps` — a Source's provider apps: the OAuth client an integration signs\n * every team in through (Linear's, say). `show` says whether the Source has\n * one and which callback URL to register; `set` takes the client id and\n * secret from the Source admin at the terminal — either on its own, Enter\n * keeping the saved one — never from a flag, a file or a non-interactive\n * run, so an agent driving the CLI never handles the secret.\n */\nexport async function runApps(\n ctx: CliContext,\n args: AppsArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n if (subcommand === 'list') return runList(ctx, args);\n const product = requireProduct(args.product, subcommand);\n if (subcommand === 'connect' || subcommand === 'disconnect') {\n return runConnection(ctx, args, subcommand, product);\n }\n\n if (subcommand === 'set' && !canPrompt(ctx, args)) {\n throw usageError(\n 'apps set takes the client secret at a terminal, never in a script or an agent run.',\n `Run it yourself in your terminal: npx @ekanos/cli apps set ${product}${args.source ? ` --source ${args.source}` : ''}`,\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), args);\n const client = new AppsClient(env, resolved.session);\n const source = resolved.source;\n\n if (subcommand === 'show') {\n return showApp(ctx, env.host, client, source, product);\n }\n\n const status = await client.call((token) =>\n showProviderApp(env.host, token, source, product),\n );\n\n ctx.log(walkthrough(status).join('\\n'));\n\n // Either credential on its own: Enter keeps what is saved. An older host\n // sends no `fields`; then `configured` says whether both are saved.\n const saved = (name: 'clientId' | 'clientSecret') =>\n status.fields?.find((field) => field.name === name) ?? {\n set: status.configured,\n value: null,\n };\n const savedId = saved('clientId');\n const savedSecret = saved('clientSecret');\n const clientId = (\n await (args.ask ?? promptLine)(\n savedId.set\n ? `Client ID (current: ${savedId.value ?? 'saved'} — Enter to keep): `\n : 'Client ID: ',\n )\n ).trim();\n const clientSecret = (\n await (args.askSecret ?? promptHidden)(\n savedSecret.set\n ? 'Client secret (saved — Enter to keep, hidden): '\n : 'Client secret (hidden): ',\n )\n ).trim();\n if (!clientId && !clientSecret) {\n throw validationError(\n 'Nothing was changed.',\n `Run \"ekanos apps show ${product}\" to see the current state.`,\n );\n }\n\n const result = await client.call((token) =>\n setProviderApp(env.host, token, {\n source,\n product,\n ...(clientId ? { clientId } : {}),\n ...(clientSecret ? { clientSecret } : {}),\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.replaced\n ? `Updated the ${result.product.name} app`\n : `Set up the ${result.product.name} app`,\n rows: [\n ['Source', result.source.slug],\n ...providerFieldRows(result),\n ['Teams can connect', result.configured ? 'yes' : 'not yet'],\n ['Callback URLs', callbackUrls(result)],\n ],\n }),\n );\n}\n\n/**\n * How to create the app: the integration's own steps (`oauth.setup`, with the\n * callback URL filled in) when it declares them, else the generic three.\n */\nexport function walkthrough(status: ProviderAppStatus): string[] {\n const name = status.product.name;\n const lines = [`${name} app for ${status.source.slug}`];\n if (status.setup?.consoleUrl) {\n lines.push(` Open: ${status.setup.consoleUrl}`);\n }\n const steps = status.setup?.steps.length\n ? [\n ...status.setup.steps,\n `Check the app lists exactly: ${callbackUrls(status).join(', ')}`,\n ]\n : [\n `In ${name}, create an OAuth app (or open the one you use).`,\n `Register exactly these callback URLs: ${callbackUrls(status).join(', ')}`,\n ];\n steps.push(\n \"Enter its client ID and secret below. The secret is stored in Ekanos's vault and never shown again.\",\n );\n lines.push(...steps.map((step, index) => ` ${index + 1}. ${step}`));\n if (status.setup?.guideUrl) lines.push(` Guide: ${status.setup.guideUrl}`);\n return lines;\n}\n\nfunction summary(ctx: CliContext, status: ProviderAppStatus): string {\n const rows: ResultRow[] = [\n ['Source', status.source.slug],\n ...(status.setup\n ? ([\n [\n 'How to create it',\n [\n ...(status.setup.consoleUrl\n ? [`Open ${status.setup.consoleUrl}`]\n : []),\n ...status.setup.steps.map(\n (step, index) => `${index + 1}. ${step}`,\n ),\n ],\n ],\n ] as const)\n : []),\n ...providerFieldRows(status),\n [\n 'App ready',\n status.configured\n ? 'yes — teams can connect'\n : 'no — no team can connect yet',\n ],\n ['Callback URLs', callbackUrls(status)],\n ];\n return [\n ctx.ui.result({ title: `${status.product.name} app`, rows }),\n ...(status.configured\n ? []\n : [\n ctx.ui.hint(\n `Run \"ekanos apps set ${status.product.slug}\" in your terminal to enter its credentials.`,\n ),\n ]),\n ].join('\\n');\n}\n\n/**\n * `apps show <product>`: the Source provider app, and — for an integration\n * that supports one — the Source connection (plan 241). A `teamApp`\n * integration (Zendesk) has no provider app but can have a Source\n * connection, so either half may be absent.\n */\nasync function showApp(\n ctx: CliContext,\n host: string,\n client: AppsClient,\n source: string,\n product: string,\n): Promise<ExitCode> {\n const [app, connection] = await Promise.all([\n client\n .call((token) => showProviderApp(host, token, source, product))\n .then(\n (status) => ({ ok: true as const, status }),\n (error: unknown) => ({ ok: false as const, error }),\n ),\n // A host without the connections routes (before plan 241), or one that\n // refuses, leaves `show` exactly as it was: the provider app alone.\n client\n .connection((token) => showConnection(host, token, source, product))\n .catch(() => ({ status: 'unavailable' as const })),\n ]);\n\n if (!app.ok && connection.status !== 'ok') throw app.error;\n\n const parts: string[] = [];\n if (app.ok) parts.push(summary(ctx, app.status));\n if (connection.status === 'ok') {\n parts.push(\n connectionSummary(ctx, connection.data.connection, {\n sourceSlug: connection.data.source.slug,\n callbackUrls: connection.data.callbackUrls,\n }),\n );\n }\n\n return ctx.succeed(\n {\n host,\n ...(app.ok ? app.status : {}),\n ...(connection.status === 'ok'\n ? {\n sourceConnection: connection.data.connection,\n sourceConnectionCallbackUrls: connection.data.callbackUrls,\n }\n : {}),\n },\n parts.join('\\n'),\n );\n}\n\n/** `apps list`: every integration the Source can connect once, with status. */\nasync function runList(ctx: CliContext, args: AppsArgs): Promise<ExitCode> {\n const { env, client, source } = await openClient(ctx, args);\n const result = await client.connection((token) =>\n listConnections(env.host, token, source),\n );\n if (result.status !== 'ok') {\n throw invalidStateError(\n 'The host could not list the connections.',\n 'Retry shortly.',\n );\n }\n const { connections } = result.data;\n const rows: ResultRow[] = connections.map((connection) => [\n `${connection.name} (${connection.slug})`,\n connectionState(connection),\n ]);\n return ctx.succeed(\n { host: env.host, ...result.data },\n connections.length === 0\n ? ctx.ui.hint(\n `No integration on ${result.data.source.slug} supports one connection for the whole Source yet.`,\n )\n : ctx.ui.result({\n title: `Source connections on ${result.data.source.slug}`,\n rows,\n }),\n );\n}\n\nfunction connectionState(connection: SourceConnection): string {\n if (connection.connected) {\n return [\n 'connected',\n connection.connectedAt ? ` ${connection.connectedAt}` : '',\n connection.connectedBy ? ` by ${connection.connectedBy}` : '',\n ].join('');\n }\n return connection.missing.length > 0\n ? `not connected — app fields missing: ${connection.missing.join(', ')}`\n : 'not connected';\n}\n\n/**\n * `apps connect <product>`: connect the integration ONCE for the whole Source,\n * for the Source's provided agents whose template says `owner: \"source\"`.\n * Asks for any missing app fields at the terminal (secrets hidden, never from\n * a flag), prints the provider's consent URL, then waits until the browser\n * finishes. `apps disconnect <product>` removes it.\n */\nasync function runConnection(\n ctx: CliContext,\n args: AppsArgs,\n subcommand: 'connect' | 'disconnect',\n product: string,\n): Promise<ExitCode> {\n const { env, client, source } = await openClient(ctx, args);\n\n if (subcommand === 'disconnect') {\n return disconnect(ctx, args, client, env.host, source, product);\n }\n\n const shown = await client.connection((token) =>\n showConnection(env.host, token, source, product),\n );\n if (shown.status === 'unsupported') {\n throw invalidStateError(\n shown.message,\n `Each team connects ${product} itself: \"ekanos teams connect <team> ${product}\".`,\n );\n }\n if (shown.status !== 'ok') {\n throw invalidStateError(\n 'The host could not read the connection.',\n 'Retry shortly.',\n );\n }\n const current = shown.data.connection;\n\n if (current.app === 'fields') {\n ctx.log(\n [\n `${current.name} app for ${shown.data.source.slug} (one for the whole Source)`,\n ` Register this redirect URL in the app: ${shown.data.callbackUrls.join(', ')}`,\n ].join('\\n'),\n );\n }\n\n const fields = await askFields(ctx, args, current, product);\n\n const started = await client.connection((token) =>\n startConnection(env.host, token, {\n source,\n product,\n ...(Object.keys(fields).length > 0 ? { fields } : {}),\n }),\n );\n if (started.status === 'not-configured') {\n throw validationError(\n `${current.name} is not set up for the Source yet — missing: ${started.missing.join(', ')}.`,\n current.app === 'source-app'\n ? `Run \"ekanos apps set ${product}\" to enter the Source's app first.`\n : `Run \"ekanos apps connect ${product}\" again and fill every field.`,\n );\n }\n if (started.status !== 'ok') {\n throw invalidStateError(\n 'The host could not start the connection.',\n 'Retry shortly.',\n );\n }\n\n ctx.log(\n [\n `Open this link and approve ${current.name} as the account the Source's agents should act as:`,\n ` ${started.data.authorizeUrl}`,\n ].join('\\n'),\n );\n\n if (args.noWait || ctx.jsonMode) {\n return ctx.succeed(\n {\n host: env.host,\n product,\n authorizeUrl: started.data.authorizeUrl,\n callbackUrl: started.data.callbackUrl,\n connected: false,\n },\n ctx.ui.hint(`Then check with \"ekanos apps show ${product}\".`),\n );\n }\n\n const deadline = Date.now() + 10 * 60 * 1000;\n const before = current.connectedAt;\n while (Date.now() < deadline) {\n await new Promise((resolve) =>\n setTimeout(resolve, args.pollDelayMs ?? 3000),\n );\n const polled = await client.connection((token) =>\n showConnection(env.host, token, source, product),\n );\n if (\n polled.status === 'ok' &&\n polled.data.connection.connected &&\n polled.data.connection.connectedAt !== before\n ) {\n return ctx.succeed(\n { host: env.host, product, connection: polled.data.connection },\n connectionSummary(ctx, polled.data.connection, {\n sourceSlug: polled.data.source.slug,\n callbackUrls: polled.data.callbackUrls,\n }),\n );\n }\n }\n throw validationError(\n 'The connection did not finish within ten minutes.',\n `Run \"ekanos apps connect ${product}\" again for a fresh link.`,\n );\n}\n\nasync function askFields(\n ctx: CliContext,\n args: AppsArgs,\n current: SourceConnection,\n product: string,\n): Promise<Record<string, string>> {\n const toAsk = current.fields.filter(\n (field) => !field.set || current.missing.includes(field.name),\n );\n if (toAsk.length === 0) return {};\n if (!canPrompt(ctx, args)) {\n throw usageError(\n `${current.name} needs its app fields entered for the Source: ${toAsk.map((field) => field.label).join(', ')}.`,\n `Run it yourself in your terminal: npx @ekanos/cli apps connect ${product}${args.source ? ` --source ${args.source}` : ''}`,\n );\n }\n const fields: Record<string, string> = {};\n for (const field of toAsk) {\n const question = field.sensitive\n ? `${field.label} (hidden): `\n : `${field.label}: `;\n const value = (\n await (\n field.sensitive\n ? (args.askSecret ?? promptHidden)\n : (args.ask ?? promptLine)\n )(question)\n ).trim();\n if (value) fields[field.name] = value;\n }\n return fields;\n}\n\nasync function disconnect(\n ctx: CliContext,\n args: AppsArgs,\n client: AppsClient,\n host: string,\n source: string,\n product: string,\n): Promise<ExitCode> {\n if (!args.yes && !canPrompt(ctx, args)) {\n throw invalidStateError(\n `Disconnecting ${product} on ${source} stops it for every team's provided agents that use the Source connection, until someone connects it again.`,\n `Re-run with --yes: ekanos apps disconnect ${product} --source ${source} --yes`,\n );\n }\n if (!args.yes) {\n const sure = await (args.confirm ?? promptYesNo)(\n `Disconnect ${product} for every team's provided agents on ${source}? [y/N]`,\n );\n if (!sure) {\n throw validationError(\n 'Nothing was changed.',\n `Run \"ekanos apps show ${product}\" to see the current state.`,\n );\n }\n }\n const result = await client.connection((token) =>\n deleteConnection(host, token, source, product),\n );\n if (result.status === 'unsupported') {\n throw invalidStateError(\n result.message,\n `Each team connects ${product} itself: \"ekanos teams connect <team> ${product}\".`,\n );\n }\n if (result.status !== 'ok') {\n throw invalidStateError('The host could not disconnect.', 'Retry shortly.');\n }\n return ctx.succeed(\n { host, product, ...result.data },\n ctx.ui.result({\n title: result.data.removed\n ? `Disconnected the ${product} Source connection on ${source}`\n : `${product} had no Source connection on ${source}`,\n rows: [\n [\n 'Provided agents',\n 'their tools for this product stop until you connect again',\n ],\n ],\n }),\n );\n}\n\nfunction connectionSummary(\n ctx: CliContext,\n connection: SourceConnection,\n meta: { sourceSlug: string; callbackUrls: string[] },\n): string {\n const rows: ResultRow[] = [\n ['Source', meta.sourceSlug],\n ['Connected', connectionState(connection)],\n ...(connection.scope ? ([['Scope', connection.scope]] as ResultRow[]) : []),\n ...(connection.fields.length > 0\n ? ([\n [\n 'App fields',\n connection.fields.map(\n (field) =>\n `${field.label}: ${field.set ? (field.value ?? 'set') : 'missing'}`,\n ),\n ],\n ] as ResultRow[])\n : []),\n ['Redirect URL', meta.callbackUrls],\n [\n 'Used by',\n `provided agents whose template says connections.${connection.slug}.owner: \"source\", in every team`,\n ],\n ];\n return [\n ctx.ui.result({\n title: `${connection.name} — Source connection (one for every team's provided agents)`,\n rows,\n }),\n ...(connection.connected\n ? []\n : [\n ctx.ui.hint(\n `Run \"ekanos apps connect ${connection.slug}\" in your terminal to connect it.`,\n ),\n ]),\n ].join('\\n');\n}\n\nasync function openClient(ctx: CliContext, args: AppsArgs) {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n return {\n env,\n client: new AppsClient(env, resolved.session),\n source: resolved.source,\n };\n}\n\nclass AppsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<AppsApiResult<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 apps call.`,\n loginHint(this.env),\n );\n }\n\n /** As `call`, for the connections client, whose 409s are answers. */\n async connection<T>(\n send: (accessToken: string) => Promise<ConnectionsApiResult<T>>,\n ): Promise<Exclude<ConnectionsApiResult<T>, { status: 'unauthorized' }>> {\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 !== 'unauthorized') return result;\n throw authRequiredError(\n `The session for ${this.env.host} could not authorize the connections call.`,\n loginHint(this.env),\n );\n }\n}\n\nfunction canPrompt(ctx: CliContext, args: AppsArgs): boolean {\n return !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n}\n\nfunction parseSubcommand(value: string | undefined): AppsSubcommand {\n const match = APPS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value ? `Unknown apps subcommand \"${value}\".` : 'apps needs a subcommand.',\n `Run one of: ${APPS_SUBCOMMANDS.map((name) => `ekanos apps ${name} <product>`).join(', ')}.`,\n );\n}\n\nfunction requireProduct(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 : `apps ${verb} needs a product.`,\n `Pass the product's slug, e.g. \"ekanos apps ${verb} linear\". \"ekanos catalog\" lists them.`,\n );\n}\n\nexport async function promptLine(question: string): Promise<string> {\n const readline = await import('node:readline/promises');\n const rl = readline.createInterface({\n input: process.stdin,\n output: process.stderr,\n });\n try {\n return await rl.question(question);\n } finally {\n rl.close();\n }\n}\n\n/**\n * Read a line without echoing it: the secret never appears on screen or in\n * scrollback. The question is always printed; only the typed characters are\n * hidden (each shows as `*`, so a paste visibly landed).\n *\n * Raw mode by hand rather than readline: a terminal readline redraws its\n * line on `question()` — cursor to column 0, clear to the end of the screen —\n * which erased the question written before it, so the terminal sat on an\n * empty line and a hidden field looked skipped.\n */\nexport async function promptHidden(question: string): Promise<string> {\n const stdin = process.stdin;\n const stderr = process.stderr;\n stderr.write(question);\n\n if (!stdin.isTTY) {\n // Piped stdin echoes nothing: read one line as is.\n const readline = await import('node:readline/promises');\n const rl = readline.createInterface({ input: stdin, terminal: false });\n try {\n return await rl.question('');\n } finally {\n rl.close();\n stderr.write('\\n');\n }\n }\n\n return new Promise<string>((resolve) => {\n let value = '';\n let inEscape = false;\n const wasRaw = stdin.isRaw;\n const finish = () => {\n stdin.off('data', onData);\n stdin.setRawMode(wasRaw);\n stdin.pause();\n stderr.write('\\n');\n };\n const onData = (chunk: Buffer | string) => {\n for (const char of typeof chunk === 'string'\n ? chunk\n : chunk.toString('utf8')) {\n if (inEscape) {\n // An escape sequence (an arrow key) ends at its final letter.\n if (/[A-Za-z~]/.test(char)) inEscape = false;\n continue;\n }\n if (char === '\\u001b') {\n inEscape = true;\n continue;\n }\n if (char === '\\r' || char === '\\n' || char === '\\u0004') {\n finish();\n resolve(value);\n return;\n }\n if (char === '\\u0003') {\n // Ctrl-C: raw mode swallowed the signal, so leave as SIGINT would.\n finish();\n process.exit(130);\n }\n if (char === '\\u007f' || char === '\\b') {\n if (value.length > 0) {\n value = value.slice(0, -1);\n stderr.write('\\b \\b');\n }\n continue;\n }\n if (char === '\\u0015') {\n // Ctrl-U: clear what was typed.\n stderr.write('\\b \\b'.repeat(value.length));\n value = '';\n continue;\n }\n if (char < ' ') continue;\n value += char;\n stderr.write('*');\n }\n };\n stdin.setRawMode(true);\n stdin.resume();\n stdin.on('data', onData);\n });\n}\n\n/** Each credential's state: the client id's value, the secret as saved or not. */\nfunction providerFieldRows(status: ProviderAppStatus): ResultRow[] {\n return (status.fields ?? []).map((field) => [\n field.label,\n !field.set\n ? 'not set'\n : field.sensitive\n ? 'saved'\n : (field.value ?? 'saved'),\n ]);\n}\n\n/** Every redirect URI to register; an older host sends only the one. */\nfunction callbackUrls(status: ProviderAppStatus): string[] {\n return status.callbackUrls?.length\n ? status.callbackUrls\n : [status.callbackUrl];\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { loginHint } from '../auth/host-trust.js';
1
2
  import { refreshStoredSession, requireSession, resolveAuthEnvironment, } from '../auth/session.js';
2
3
  import { fetchSourceCatalog, } from '../catalog-api.js';
3
4
  import { authRequiredError } from '../errors.js';
@@ -18,7 +19,7 @@ export async function runCatalog(ctx, args) {
18
19
  const env = resolveAuthEnvironment(ctx, args.host, args.env, {
19
20
  projectDir: args.dir,
20
21
  });
21
- let session = requireSession(env.store, env.host);
22
+ let session = requireSession(env);
22
23
  const resolved = await resolveSourceTarget(env, session, args);
23
24
  session = resolved.session;
24
25
  const query = { source: resolved.source, product: args.product };
@@ -27,20 +28,20 @@ export async function runCatalog(ctx, args) {
27
28
  session = await refreshStoredSession(env, session);
28
29
  result = await fetchSourceCatalog(env.host, session.accessToken, query);
29
30
  }
30
- const catalog = requireCatalog(result, env.host);
31
+ const catalog = requireCatalog(result, env);
31
32
  return ctx.succeed(Object.assign({ host: env.host }, catalog), withDocsHint(ctx.ui, args.dir, args.product
32
33
  ? productDetail(ctx.ui, catalog.products[0])
33
34
  : catalogSummary(ctx.ui, catalog)));
34
35
  }
35
- function requireCatalog(result, host) {
36
+ function requireCatalog(result, env) {
36
37
  if (result.status === 'ok')
37
38
  return result.catalog;
38
- throw authRequiredError(`The session for ${host} could not authorize the catalog read.`, `Run "ekanos login --host ${host}" and retry.`);
39
+ throw authRequiredError(`The session for ${env.host} could not authorize the catalog read.`, loginHint(env));
39
40
  }
40
41
  const AVAILABILITY_LABEL = {
41
42
  enabled: 'Enabled on this Source',
42
- 'turned-off': 'Granted but switched off',
43
- available: 'Available — ask Ekanos to enable',
43
+ 'turned-off': 'Not enabled — granted, but switched off',
44
+ available: 'Not enabled — only a super-admin enables it',
44
45
  };
45
46
  function catalogSummary(ui, catalog) {
46
47
  const blocks = ['enabled', 'turned-off', 'available']
@@ -1 +1 @@
1
- {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CatalogProduct, SourceCatalog } from '@ekanos/integration-schema';\n\nimport {\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport {\n type FetchSourceCatalogResult,\n fetchSourceCatalog,\n} from '../catalog-api';\nimport type { CliContext } from '../context';\nimport { authRequiredError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport { type Ui, pluralize } from '../ui';\nimport { withDocsHint } from './agents-init';\n\nexport interface CatalogArgs {\n host?: string;\n source?: string;\n /** One product's detail, when given. */\n product?: string;\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `catalog` — what the Source can already do (plan 239.0). Lists every\n * product the Source can use, with its tools, agent events and the steps\n * left to set it up; `ekanos catalog <product>` shows one in full.\n *\n * Read before building: an agent migration asks it first, so a capability\n * the Source already has is set up rather than rebuilt. Works outside a\n * project — the Source comes from `--source`, else `ekanos.json`, else the\n * caller's only seat.\n */\nexport async function runCatalog(\n ctx: CliContext,\n args: CatalogArgs,\n): Promise<ExitCode> {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n let session = requireSession(env.store, env.host);\n\n const resolved = await resolveSourceTarget(env, session, args);\n session = resolved.session;\n\n const query = { source: resolved.source, product: args.product };\n let result = await fetchSourceCatalog(env.host, session.accessToken, query);\n if (result.status === 'unauthorized') {\n session = await refreshStoredSession(env, session);\n result = await fetchSourceCatalog(env.host, session.accessToken, query);\n }\n const catalog = requireCatalog(result, env.host);\n\n return ctx.succeed(\n { host: env.host, ...catalog },\n withDocsHint(\n ctx.ui,\n args.dir,\n args.product\n ? productDetail(ctx.ui, catalog.products[0]!)\n : catalogSummary(ctx.ui, catalog),\n ),\n );\n}\n\nfunction requireCatalog(\n result: FetchSourceCatalogResult,\n host: string,\n): SourceCatalog {\n if (result.status === 'ok') return result.catalog;\n throw authRequiredError(\n `The session for ${host} could not authorize the catalog read.`,\n `Run \"ekanos login --host ${host}\" and retry.`,\n );\n}\n\nconst AVAILABILITY_LABEL = {\n enabled: 'Enabled on this Source',\n 'turned-off': 'Granted but switched off',\n available: 'Available — ask Ekanos to enable',\n} as const;\n\nfunction catalogSummary(ui: Ui, catalog: SourceCatalog): string {\n const blocks = (['enabled', 'turned-off', 'available'] as const)\n .map((availability) => {\n const products = catalog.products.filter(\n (product) => product.availability === availability,\n );\n if (products.length === 0) return null;\n return ui.result({\n title: `${AVAILABILITY_LABEL[availability]} (${products.length})`,\n tone: availability === 'enabled' ? 'ok' : 'warn',\n rows: products.map((product): [string, string] => [\n product.slug,\n [product.name, describeShape(product), openSteps(product)]\n .filter(Boolean)\n .join(' · '),\n ]),\n });\n })\n .filter((block): block is string => block !== null);\n\n return [\n ...blocks,\n ui.hint(\n `${pluralize(catalog.products.length, 'product')} on ${catalog.source.slug}. ` +\n `\"ekanos catalog <product>\" shows tools, agent events and setup steps.`,\n ),\n ].join('\\n\\n');\n}\n\nfunction productDetail(ui: Ui, product: CatalogProduct): string {\n const rows: [string, string | string[]][] = [\n ['What', product.summary ?? '—'],\n [\n 'Kind',\n product.kind === 'experience' ? 'Ekanos Experience' : 'Integration',\n ],\n ['Status', AVAILABILITY_LABEL[product.availability]],\n ];\n if (product.connectedTeams !== null) {\n rows.push(['Teams connected', String(product.connectedTeams)]);\n }\n if (product.tools.length > 0) {\n rows.push([\n 'Tools',\n product.tools.map(\n (tool) =>\n `${tool.name} (${tool.effect}${tool.sensitivity === 'undeclared' ? '' : `, ${tool.sensitivity}`})`,\n ),\n ]);\n }\n if (product.agentEvents.length > 0) {\n rows.push([\n 'Agent triggers',\n product.agentEvents.map((event) => `${event.id} — ${event.label}`),\n ]);\n }\n if (product.agentReplyTool) {\n rows.push(['Replies with', product.agentReplyTool]);\n }\n rows.push([\n 'Setup',\n product.setupSteps.flatMap((step, index) => [\n `${index + 1}. [${step.state}] ${step.title} (${step.actor}) — ${step.detail}` +\n (step.guideUrl ? ` ${step.guideUrl}` : ''),\n ...(step.consoleUrl ? [` Open ${step.consoleUrl}`] : []),\n ...(step.instructions ?? []).map(\n (line, lineIndex) =>\n ` ${String.fromCharCode(97 + lineIndex)}. ${line}`,\n ),\n ]),\n ]);\n\n return ui.result({ title: `${product.name} (${product.slug})`, rows });\n}\n\nfunction describeShape(product: CatalogProduct): string {\n const parts = [\n product.tools.length > 0 ? pluralize(product.tools.length, 'tool') : null,\n product.agentEvents.length > 0\n ? pluralize(product.agentEvents.length, 'agent trigger')\n : null,\n ].filter(Boolean);\n return parts.join(', ');\n}\n\nfunction openSteps(product: CatalogProduct): string {\n const open = product.setupSteps.filter((step) => step.state === 'todo');\n return open.length === 0 ? '' : `${pluralize(open.length, 'step')} left`;\n}\n"]}
1
+ {"version":3,"file":"catalog.js","sourceRoot":"","sources":["../../src/commands/catalog.ts"],"names":[],"mappings":"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","sourcesContent":["import type { CatalogProduct, SourceCatalog } from '@ekanos/integration-schema';\n\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport {\n type FetchSourceCatalogResult,\n fetchSourceCatalog,\n} from '../catalog-api';\nimport type { CliContext } from '../context';\nimport { authRequiredError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport { type Ui, pluralize } from '../ui';\nimport { withDocsHint } from './agents-init';\n\nexport interface CatalogArgs {\n host?: string;\n source?: string;\n /** One product's detail, when given. */\n product?: string;\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `catalog` — what the Source can already do (plan 239.0). Lists every\n * product the Source can use, with its tools, agent events and the steps\n * left to set it up; `ekanos catalog <product>` shows one in full.\n *\n * Read before building: an agent migration asks it first, so a capability\n * the Source already has is set up rather than rebuilt. Works outside a\n * project — the Source comes from `--source`, else `ekanos.json`, else the\n * caller's only seat.\n */\nexport async function runCatalog(\n ctx: CliContext,\n args: CatalogArgs,\n): Promise<ExitCode> {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n let session = requireSession(env);\n\n const resolved = await resolveSourceTarget(env, session, args);\n session = resolved.session;\n\n const query = { source: resolved.source, product: args.product };\n let result = await fetchSourceCatalog(env.host, session.accessToken, query);\n if (result.status === 'unauthorized') {\n session = await refreshStoredSession(env, session);\n result = await fetchSourceCatalog(env.host, session.accessToken, query);\n }\n const catalog = requireCatalog(result, env);\n\n return ctx.succeed(\n { host: env.host, ...catalog },\n withDocsHint(\n ctx.ui,\n args.dir,\n args.product\n ? productDetail(ctx.ui, catalog.products[0]!)\n : catalogSummary(ctx.ui, catalog),\n ),\n );\n}\n\nfunction requireCatalog(\n result: FetchSourceCatalogResult,\n env: AuthEnvironment,\n): SourceCatalog {\n if (result.status === 'ok') return result.catalog;\n throw authRequiredError(\n `The session for ${env.host} could not authorize the catalog read.`,\n loginHint(env),\n );\n}\n\nconst AVAILABILITY_LABEL = {\n enabled: 'Enabled on this Source',\n 'turned-off': 'Not enabled — granted, but switched off',\n available: 'Not enabled — only a super-admin enables it',\n} as const;\n\nfunction catalogSummary(ui: Ui, catalog: SourceCatalog): string {\n const blocks = (['enabled', 'turned-off', 'available'] as const)\n .map((availability) => {\n const products = catalog.products.filter(\n (product) => product.availability === availability,\n );\n if (products.length === 0) return null;\n return ui.result({\n title: `${AVAILABILITY_LABEL[availability]} (${products.length})`,\n tone: availability === 'enabled' ? 'ok' : 'warn',\n rows: products.map((product): [string, string] => [\n product.slug,\n [product.name, describeShape(product), openSteps(product)]\n .filter(Boolean)\n .join(' · '),\n ]),\n });\n })\n .filter((block): block is string => block !== null);\n\n return [\n ...blocks,\n ui.hint(\n `${pluralize(catalog.products.length, 'product')} on ${catalog.source.slug}. ` +\n `\"ekanos catalog <product>\" shows tools, agent events and setup steps.`,\n ),\n ].join('\\n\\n');\n}\n\nfunction productDetail(ui: Ui, product: CatalogProduct): string {\n const rows: [string, string | string[]][] = [\n ['What', product.summary ?? '—'],\n [\n 'Kind',\n product.kind === 'experience' ? 'Ekanos Experience' : 'Integration',\n ],\n ['Status', AVAILABILITY_LABEL[product.availability]],\n ];\n if (product.connectedTeams !== null) {\n rows.push(['Teams connected', String(product.connectedTeams)]);\n }\n if (product.tools.length > 0) {\n rows.push([\n 'Tools',\n product.tools.map(\n (tool) =>\n `${tool.name} (${tool.effect}${tool.sensitivity === 'undeclared' ? '' : `, ${tool.sensitivity}`})`,\n ),\n ]);\n }\n if (product.agentEvents.length > 0) {\n rows.push([\n 'Agent triggers',\n product.agentEvents.map((event) => `${event.id} — ${event.label}`),\n ]);\n }\n if (product.agentReplyTool) {\n rows.push(['Replies with', product.agentReplyTool]);\n }\n rows.push([\n 'Setup',\n product.setupSteps.flatMap((step, index) => [\n `${index + 1}. [${step.state}] ${step.title} (${step.actor}) — ${step.detail}` +\n (step.guideUrl ? ` ${step.guideUrl}` : ''),\n ...(step.consoleUrl ? [` Open ${step.consoleUrl}`] : []),\n ...(step.instructions ?? []).map(\n (line, lineIndex) =>\n ` ${String.fromCharCode(97 + lineIndex)}. ${line}`,\n ),\n ]),\n ]);\n\n return ui.result({ title: `${product.name} (${product.slug})`, rows });\n}\n\nfunction describeShape(product: CatalogProduct): string {\n const parts = [\n product.tools.length > 0 ? pluralize(product.tools.length, 'tool') : null,\n product.agentEvents.length > 0\n ? pluralize(product.agentEvents.length, 'agent trigger')\n : null,\n ].filter(Boolean);\n return parts.join(', ');\n}\n\nfunction openSteps(product: CatalogProduct): string {\n const open = product.setupSteps.filter((step) => step.state === 'todo');\n return open.length === 0 ? '' : `${pluralize(open.length, 'step')} left`;\n}\n"]}
@@ -12,8 +12,20 @@ export interface KnowledgeArgs {
12
12
  team?: string;
13
13
  /** `pull`: where to write (default `knowledge/<team|general>`). */
14
14
  out?: string;
15
+ /** `pull`: overwrite local files that differ from the host's. */
16
+ force?: boolean;
17
+ /**
18
+ * `push --prune`: also delete the articles an earlier push of this folder
19
+ * made whose files are gone. Never an article written in the app, and
20
+ * never one edited there since the push.
21
+ */
22
+ prune?: boolean;
23
+ /** `push --prune`: delete without asking (a script or agent run). */
24
+ yes?: boolean;
15
25
  dir: string;
16
26
  env: Record<string, string | undefined>;
27
+ stdinIsTTY?: boolean;
28
+ confirm?: (question: string) => Promise<boolean>;
17
29
  }
18
30
  /**
19
31
  * `knowledge` — a Source's Knowledge base (plan 244): the General collection
@@ -24,6 +36,13 @@ export interface KnowledgeArgs {
24
36
  * agents do: that team's articles plus General.
25
37
  */
26
38
  export declare function runKnowledge(ctx: CliContext, args: KnowledgeArgs): Promise<ExitCode>;
39
+ /**
40
+ * Which folder a push came from, as the host records it on each article
41
+ * (`synced_from`): the path as named from the project directory, so pushing
42
+ * the same folder from the same place is the same origin. `--prune` only
43
+ * ever removes articles of that origin.
44
+ */
45
+ export declare function knowledgeOrigin(target: string, cwd: string): string;
27
46
  /** Mirrors the host's `knowledgeSlug`: a file's path without `.md`. */
28
47
  export declare function knowledgeSlugFromPath(relative: string): string;
29
48
  /**