@ekanos/cli 0.11.0 → 0.13.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 (57) hide show
  1. package/dist/apps-api.d.ts +3 -2
  2. package/dist/apps-api.js +1 -5
  3. package/dist/apps-api.js.map +1 -1
  4. package/dist/commands/agents-edit.js +1 -1
  5. package/dist/commands/agents-edit.js.map +1 -1
  6. package/dist/commands/apps.d.ts +19 -6
  7. package/dist/commands/apps.js +366 -43
  8. package/dist/commands/apps.js.map +1 -1
  9. package/dist/commands/knowledge.d.ts +37 -0
  10. package/dist/commands/knowledge.js +364 -0
  11. package/dist/commands/knowledge.js.map +1 -0
  12. package/dist/commands/routes.d.ts +23 -0
  13. package/dist/commands/routes.js +277 -0
  14. package/dist/commands/routes.js.map +1 -0
  15. package/dist/commands/sources.d.ts +4 -0
  16. package/dist/commands/sources.js +115 -1
  17. package/dist/commands/sources.js.map +1 -1
  18. package/dist/commands/team-agents-triggers.js +2 -1
  19. package/dist/commands/team-agents-triggers.js.map +1 -1
  20. package/dist/commands/teams-connect.d.ts +25 -0
  21. package/dist/commands/teams-connect.js +242 -0
  22. package/dist/commands/teams-connect.js.map +1 -0
  23. package/dist/commands/teams-onboard.d.ts +5 -2
  24. package/dist/commands/teams-onboard.js +12 -40
  25. package/dist/commands/teams-onboard.js.map +1 -1
  26. package/dist/commands/teams.d.ts +60 -5
  27. package/dist/commands/teams.js +141 -46
  28. package/dist/commands/teams.js.map +1 -1
  29. package/dist/connections-api.d.ts +125 -0
  30. package/dist/connections-api.js +156 -0
  31. package/dist/connections-api.js.map +1 -0
  32. package/dist/index.js +90 -6
  33. package/dist/index.js.map +1 -1
  34. package/dist/knowledge-api.d.ts +129 -0
  35. package/dist/knowledge-api.js +138 -0
  36. package/dist/knowledge-api.js.map +1 -0
  37. package/dist/routes-api.d.ts +105 -0
  38. package/dist/routes-api.js +147 -0
  39. package/dist/routes-api.js.map +1 -0
  40. package/dist/source-products-api.d.ts +59 -0
  41. package/dist/source-products-api.js +113 -0
  42. package/dist/source-products-api.js.map +1 -0
  43. package/dist/team-connect-api.d.ts +244 -0
  44. package/dist/team-connect-api.js +95 -0
  45. package/dist/team-connect-api.js.map +1 -0
  46. package/dist/teams-api.d.ts +1 -0
  47. package/dist/teams-api.js +1 -1
  48. package/dist/teams-api.js.map +1 -1
  49. package/package.json +2 -2
  50. package/templates/package.json.tmpl +4 -4
  51. package/templates/skills/build-agent/SKILL.md +18 -3
  52. package/templates/skills/build-agent/references/agent-json.md +29 -8
  53. package/templates/skills/build-agent/references/app-setup.md +2 -1
  54. package/templates/skills/build-agent/references/set-up-an-integration.md +76 -10
  55. package/templates/skills/build-agent/references/skills.md +7 -4
  56. package/templates/skills/build-agent/references/triggers.md +44 -15
  57. package/templates/skills/ekanos-platform/SKILL.md +40 -8
@@ -1 +1 @@
1
- {"version":3,"file":"team-agents-triggers.js","sourceRoot":"","sources":["../../src/commands/team-agents-triggers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type TeamAgentLink,\n type TeamAgentLinkAddRequest,\n TeamAgentLinkAddResultSchema,\n TeamAgentLinkListSchema,\n TeamAgentRowRemoveResultSchema,\n type TeamAgentTrigger,\n type TeamAgentTriggerAddRequest,\n TeamAgentTriggerAddResultSchema,\n TeamAgentTriggerListSchema,\n} from '@ekanos/integration-schema';\nimport type { z } from 'zod';\n\nimport type { CliContext } from '../context';\nimport { usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { call } from '../teams-api';\nimport { type TeamAgentRun, requireOperand, usageFor } from './team-agents';\n\n/**\n * `ekanos teams triggers list|add|remove` and `ekanos teams links\n * list|add|remove` — a team agent's triggers and outgoing links, set up by\n * the Source admin. When the template keeps an area, the host shows the\n * effective rows and refuses changes with the command that hands the area\n * to the team.\n */\n\nexport async function runTeamTriggers(\n ctx: CliContext,\n run: TeamAgentRun,\n): Promise<ExitCode> {\n const team = requireOperand(run.operands[0], 'team slug', 'triggers');\n const key = requireOperand(run.operands[1], 'agent key', 'triggers');\n const base = agentPath(team, key);\n\n switch (run.verb) {\n case 'list': {\n noExtra(run.operands, 2, 'triggers');\n const list = await send(\n run,\n TeamAgentTriggerListSchema,\n 'GET',\n `${base}/triggers`,\n );\n return ctx.succeed(\n { host: run.host, ...list },\n ctx.ui.result({\n title:\n list.triggers.length === 0\n ? `${list.agent.slug} on ${list.team.slug} has no triggers`\n : `Triggers of ${list.agent.slug} on ${list.team.slug}`,\n tone: list.triggers.length === 0 ? 'warn' : 'ok',\n rows: list.triggers.map((trigger) => [\n trigger.id,\n describeTrigger(trigger),\n ]),\n notes: list.teamOwned\n ? [\n '\"ekanos teams triggers add <team> <key> manual|schedule|webhook|event …\" adds one.',\n ]\n : [\n `These follow the template. To let the team change them: ekanos agents overrides ${key} enable triggers`,\n ],\n }),\n );\n }\n case 'add': {\n const body = triggerBody(run, team, key);\n const added = await send(\n run,\n TeamAgentTriggerAddResultSchema,\n 'POST',\n `${base}/triggers`,\n body,\n );\n const rows: Array<[string, string]> = [\n ['Trigger', added.trigger.id],\n ['Fires on', describeTrigger(added.trigger)],\n ];\n if (added.webhook) {\n rows.push(['URL', added.webhook.url]);\n rows.push(['Bearer token', added.webhook.token]);\n }\n return ctx.succeed(\n { host: run.host, ...added },\n ctx.ui.result({\n title: `Added a ${added.trigger.type} trigger to ${added.agent.slug} on ${added.team.slug}`,\n tone: added.webhook ? 'warn' : 'ok',\n rows,\n notes: added.webhook\n ? [\n 'The URL and token are shown once and cannot be read again. POST JSON to the URL with \"Authorization: Bearer <token>\".',\n ]\n : [],\n }),\n );\n }\n case 'remove': {\n const id = run.operands[2]?.trim();\n if (!id) {\n throw usageError(\n 'Name the trigger to remove.',\n `List them: ekanos teams triggers list ${team} ${key}`,\n );\n }\n noExtra(run.operands, 3, 'triggers');\n const removed = await send(\n run,\n TeamAgentRowRemoveResultSchema,\n 'DELETE',\n `${base}/triggers/${encodeURIComponent(id)}`,\n );\n return ctx.succeed(\n { host: run.host, ...removed },\n ctx.ui.result({\n title: `Removed trigger ${removed.removed} from ${removed.agent.slug}`,\n }),\n );\n }\n default:\n throw usageError(\n `Unknown teams triggers subcommand \"${run.verb}\".`,\n usageFor('triggers'),\n );\n }\n}\n\nexport async function runTeamLinks(\n ctx: CliContext,\n run: TeamAgentRun,\n): Promise<ExitCode> {\n const team = requireOperand(run.operands[0], 'team slug', 'links');\n const from = requireOperand(run.operands[1], 'agent key', 'links');\n const base = agentPath(team, from);\n\n switch (run.verb) {\n case 'list': {\n noExtra(run.operands, 2, 'links');\n const list = await send(\n run,\n TeamAgentLinkListSchema,\n 'GET',\n `${base}/links`,\n );\n return ctx.succeed(\n { host: run.host, ...list },\n ctx.ui.result({\n title:\n list.links.length === 0\n ? `${list.agent.slug} on ${list.team.slug} has no links`\n : `Links from ${list.agent.slug} on ${list.team.slug}`,\n tone: list.links.length === 0 ? 'warn' : 'ok',\n rows: list.links.map((link) => [link.id, describeLink(link)]),\n notes: list.teamOwned\n ? []\n : [\n `These follow the template. To let the team change them: ekanos agents overrides ${from} enable links`,\n ],\n }),\n );\n }\n case 'add': {\n const to = requireOperand(\n run.operands[2],\n 'agent key to link to',\n 'links',\n );\n noExtra(run.operands, 3, 'links');\n const kind = flag(run, 'kind');\n if (kind !== 'talk' && kind !== 'delegate') {\n throw usageError(\n 'Say what kind of link: --kind talk|delegate.',\n usageFor('links'),\n );\n }\n const mode = flag(run, 'mode');\n if (mode !== undefined && mode !== 'await' && mode !== 'handoff') {\n throw usageError('--mode is await or handoff.', usageFor('links'));\n }\n if (mode !== undefined && kind === 'talk') {\n throw usageError(\n 'Only a delegate link takes --mode.',\n usageFor('links'),\n );\n }\n const body: TeamAgentLinkAddRequest = {\n to,\n kind,\n ...(mode ? { mode } : {}),\n };\n const added = await send(\n run,\n TeamAgentLinkAddResultSchema,\n 'POST',\n `${base}/links`,\n body,\n );\n return ctx.succeed(\n { host: run.host, ...added },\n ctx.ui.result({\n title: `Linked ${added.agent.slug} → ${added.link.to.slug} on ${added.team.slug}`,\n rows: [\n ['Link', added.link.id],\n ['Kind', describeLink(added.link)],\n ],\n }),\n );\n }\n case 'remove': {\n const id = run.operands[2]?.trim();\n if (!id) {\n throw usageError(\n 'Name the link to remove.',\n `List them: ekanos teams links list ${team} ${from}`,\n );\n }\n noExtra(run.operands, 3, 'links');\n const removed = await send(\n run,\n TeamAgentRowRemoveResultSchema,\n 'DELETE',\n `${base}/links/${encodeURIComponent(id)}`,\n );\n return ctx.succeed(\n { host: run.host, ...removed },\n ctx.ui.result({\n title: `Removed link ${removed.removed} from ${removed.agent.slug}`,\n }),\n );\n }\n default:\n throw usageError(\n `Unknown teams links subcommand \"${run.verb}\".`,\n usageFor('links'),\n );\n }\n}\n\nfunction triggerBody(\n run: TeamAgentRun,\n team: string,\n key: string,\n): TeamAgentTriggerAddRequest {\n const type = run.operands[2]?.trim().toLowerCase();\n const prompt = flag(run, 'prompt') ?? '';\n switch (type) {\n case 'manual':\n noExtra(run.operands, 3, 'triggers');\n return { type: 'manual', promptTemplate: prompt };\n case 'schedule': {\n noExtra(run.operands, 3, 'triggers');\n const cron = flag(run, 'cron');\n if (!cron || !prompt) {\n throw usageError(\n 'A schedule needs --cron and --prompt.',\n `e.g. ekanos teams triggers add ${team} ${key} schedule --cron \"0 9 * * 1-5\" --timezone America/Los_Angeles --prompt \"Summarize yesterday's tickets\"`,\n );\n }\n return {\n type: 'schedule',\n scheduleCron: cron,\n timezone: flag(run, 'timezone') ?? 'UTC',\n promptTemplate: prompt,\n };\n }\n case 'webhook':\n noExtra(run.operands, 3, 'triggers');\n if (!prompt) {\n throw usageError(\n 'A webhook needs --prompt: what to do with each request.',\n `e.g. ekanos teams triggers add ${team} ${key} webhook --prompt \"Triage this alert: {{body.title}}\"`,\n );\n }\n return { type: 'webhook', promptTemplate: prompt };\n case 'event':\n case 'integration_event': {\n const eventId = run.operands[3]?.trim();\n if (!eventId) {\n throw usageError(\n 'Name the event, e.g. zendesk.ticket_created.',\n `e.g. ekanos teams triggers add ${team} ${key} event zendesk.ticket_created --filter '{\"priority\":[\"urgent\"]}'`,\n );\n }\n noExtra(run.operands, 4, 'triggers');\n return {\n type: 'integration_event',\n eventId,\n filter: parseFilter(flag(run, 'filter')),\n promptTemplate: prompt,\n };\n }\n case 'slack':\n case 'linear':\n throw usageError(\n `A ${type} trigger is connected in the app, where the team picks its workspace and channels.`,\n 'Open the agent in the app and add it under Triggers.',\n );\n default:\n throw usageError(\n type ? `Unknown trigger type \"${type}\".` : 'Name the trigger type.',\n usageFor('triggers'),\n );\n }\n}\n\nfunction parseFilter(\n raw: string | undefined,\n): Record<string, string | boolean | string[]> {\n if (!raw) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw usageError(\n '--filter must be a JSON object.',\n `e.g. --filter '{\"priority\":[\"urgent\",\"high\"]}'`,\n );\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw usageError(\n '--filter must be a JSON object.',\n `e.g. --filter '{\"priority\":[\"urgent\",\"high\"]}'`,\n );\n }\n const filter: Record<string, string | boolean | string[]> = {};\n for (const [name, value] of Object.entries(parsed)) {\n if (\n typeof value === 'string' ||\n typeof value === 'boolean' ||\n (Array.isArray(value) && value.every((item) => typeof item === 'string'))\n ) {\n filter[name] = value as string | boolean | string[];\n continue;\n }\n throw usageError(\n `--filter field \"${name}\" must be a string, a boolean or a list of strings.`,\n `e.g. --filter '{\"priority\":[\"urgent\",\"high\"]}'`,\n );\n }\n return filter;\n}\n\nfunction describeTrigger(trigger: TeamAgentTrigger): string {\n const what =\n trigger.type === 'schedule'\n ? `schedule ${trigger.scheduleCron ?? ''} (${trigger.timezone ?? 'UTC'})`\n : trigger.type === 'integration_event'\n ? `event ${trigger.eventId ?? ''}${trigger.filter && Object.keys(trigger.filter).length > 0 ? ` ${JSON.stringify(trigger.filter)}` : ''}`\n : trigger.type;\n const tags = [\n trigger.owner === 'template' ? 'from template' : 'team',\n trigger.active ? 'on' : 'off',\n ];\n return `${what} · ${tags.join(' · ')}`;\n}\n\nfunction describeLink(link: TeamAgentLink): string {\n const kind =\n link.kind === 'delegate' ? `delegate (${link.mode ?? 'await'})` : 'talk';\n const tags = [\n link.owner === 'template' ? 'from template' : 'team',\n ...(link.active ? [] : ['inactive']),\n ];\n return `${kind} → ${link.to.slug} · ${tags.join(' · ')}`;\n}\n\nfunction agentPath(team: string, key: string): string {\n return `/api/partner/teams/${encodeURIComponent(team)}/agents/${encodeURIComponent(key)}`;\n}\n\nfunction flag(run: TeamAgentRun, name: string): string | undefined {\n const value = run.args.flags?.[name];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction noExtra(\n operands: readonly string[],\n count: number,\n area: 'triggers' | 'links',\n) {\n const extra = operands[count];\n if (extra !== undefined) {\n throw usageError(`Unexpected argument \"${extra}\".`, usageFor(area));\n }\n}\n\nfunction send<T>(\n run: TeamAgentRun,\n schema: z.ZodType<T>,\n method: 'GET' | 'POST' | 'DELETE',\n path: string,\n body?: unknown,\n): Promise<T> {\n return run.client.call((token) =>\n call(run.host, token, schema, { method, path, source: run.source, body }),\n );\n}\n"]}
1
+ {"version":3,"file":"team-agents-triggers.js","sourceRoot":"","sources":["../../src/commands/team-agents-triggers.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type TeamAgentLink,\n type TeamAgentLinkAddRequest,\n TeamAgentLinkAddResultSchema,\n TeamAgentLinkListSchema,\n TeamAgentRowRemoveResultSchema,\n type TeamAgentTrigger,\n type TeamAgentTriggerAddRequest,\n TeamAgentTriggerAddResultSchema,\n TeamAgentTriggerListSchema,\n} from '@ekanos/integration-schema';\nimport type { z } from 'zod';\n\nimport type { CliContext } from '../context';\nimport { usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { call } from '../teams-api';\nimport { type TeamAgentRun, requireOperand, usageFor } from './team-agents';\n\n/**\n * `ekanos teams triggers list|add|remove` and `ekanos teams links\n * list|add|remove` — a team agent's triggers and outgoing links, set up by\n * the Source admin. When the template keeps an area, the host shows the\n * effective rows and refuses changes with the command that hands the area\n * to the team.\n */\n\nexport async function runTeamTriggers(\n ctx: CliContext,\n run: TeamAgentRun,\n): Promise<ExitCode> {\n const team = requireOperand(run.operands[0], 'team slug', 'triggers');\n const key = requireOperand(run.operands[1], 'agent key', 'triggers');\n const base = agentPath(team, key);\n\n switch (run.verb) {\n case 'list': {\n noExtra(run.operands, 2, 'triggers');\n const list = await send(\n run,\n TeamAgentTriggerListSchema,\n 'GET',\n `${base}/triggers`,\n );\n return ctx.succeed(\n { host: run.host, ...list },\n ctx.ui.result({\n title:\n list.triggers.length === 0\n ? `${list.agent.slug} on ${list.team.slug} has no triggers`\n : `Triggers of ${list.agent.slug} on ${list.team.slug}`,\n tone: list.triggers.length === 0 ? 'warn' : 'ok',\n rows: list.triggers.map((trigger) => [\n trigger.id,\n describeTrigger(trigger),\n ]),\n notes: list.teamOwned\n ? [\n '\"ekanos teams triggers add <team> <key> manual|schedule|webhook|event …\" adds one.',\n ]\n : [\n `These follow the template. To let the team change them: ekanos agents overrides ${key} enable triggers`,\n ],\n }),\n );\n }\n case 'add': {\n const body = triggerBody(run, team, key);\n const added = await send(\n run,\n TeamAgentTriggerAddResultSchema,\n 'POST',\n `${base}/triggers`,\n body,\n );\n const rows: Array<[string, string]> = [\n ['Trigger', added.trigger.id],\n ['Fires on', describeTrigger(added.trigger)],\n ];\n if (added.webhook) {\n rows.push(['URL', added.webhook.url]);\n rows.push(['Bearer token', added.webhook.token]);\n }\n return ctx.succeed(\n { host: run.host, ...added },\n ctx.ui.result({\n title: `Added a ${added.trigger.type} trigger to ${added.agent.slug} on ${added.team.slug}`,\n tone: added.webhook ? 'warn' : 'ok',\n rows,\n notes: added.webhook\n ? [\n 'The URL and token are shown once and cannot be read again. POST JSON to the URL with \"Authorization: Bearer <token>\".',\n ]\n : [],\n }),\n );\n }\n case 'remove': {\n const id = run.operands[2]?.trim();\n if (!id) {\n throw usageError(\n 'Name the trigger to remove.',\n `List them: ekanos teams triggers list ${team} ${key}`,\n );\n }\n noExtra(run.operands, 3, 'triggers');\n const removed = await send(\n run,\n TeamAgentRowRemoveResultSchema,\n 'DELETE',\n `${base}/triggers/${encodeURIComponent(id)}`,\n );\n return ctx.succeed(\n { host: run.host, ...removed },\n ctx.ui.result({\n title: `Removed trigger ${removed.removed} from ${removed.agent.slug}`,\n }),\n );\n }\n default:\n throw usageError(\n `Unknown teams triggers subcommand \"${run.verb}\".`,\n usageFor('triggers'),\n );\n }\n}\n\nexport async function runTeamLinks(\n ctx: CliContext,\n run: TeamAgentRun,\n): Promise<ExitCode> {\n const team = requireOperand(run.operands[0], 'team slug', 'links');\n const from = requireOperand(run.operands[1], 'agent key', 'links');\n const base = agentPath(team, from);\n\n switch (run.verb) {\n case 'list': {\n noExtra(run.operands, 2, 'links');\n const list = await send(\n run,\n TeamAgentLinkListSchema,\n 'GET',\n `${base}/links`,\n );\n return ctx.succeed(\n { host: run.host, ...list },\n ctx.ui.result({\n title:\n list.links.length === 0\n ? `${list.agent.slug} on ${list.team.slug} has no links`\n : `Links from ${list.agent.slug} on ${list.team.slug}`,\n tone: list.links.length === 0 ? 'warn' : 'ok',\n rows: list.links.map((link) => [link.id, describeLink(link)]),\n notes: list.teamOwned\n ? []\n : [\n `These follow the template. To let the team change them: ekanos agents overrides ${from} enable links`,\n ],\n }),\n );\n }\n case 'add': {\n const to = requireOperand(\n run.operands[2],\n 'agent key to link to',\n 'links',\n );\n noExtra(run.operands, 3, 'links');\n const kind = flag(run, 'kind');\n if (kind !== 'talk' && kind !== 'delegate') {\n throw usageError(\n 'Say what kind of link: --kind talk|delegate.',\n usageFor('links'),\n );\n }\n const mode = flag(run, 'mode');\n if (mode !== undefined && mode !== 'await' && mode !== 'handoff') {\n throw usageError('--mode is await or handoff.', usageFor('links'));\n }\n if (mode !== undefined && kind === 'talk') {\n throw usageError(\n 'Only a delegate link takes --mode.',\n usageFor('links'),\n );\n }\n const body: TeamAgentLinkAddRequest = {\n to,\n kind,\n ...(mode ? { mode } : {}),\n };\n const added = await send(\n run,\n TeamAgentLinkAddResultSchema,\n 'POST',\n `${base}/links`,\n body,\n );\n return ctx.succeed(\n { host: run.host, ...added },\n ctx.ui.result({\n title: `Linked ${added.agent.slug} → ${added.link.to.slug} on ${added.team.slug}`,\n rows: [\n ['Link', added.link.id],\n ['Kind', describeLink(added.link)],\n ],\n }),\n );\n }\n case 'remove': {\n const id = run.operands[2]?.trim();\n if (!id) {\n throw usageError(\n 'Name the link to remove.',\n `List them: ekanos teams links list ${team} ${from}`,\n );\n }\n noExtra(run.operands, 3, 'links');\n const removed = await send(\n run,\n TeamAgentRowRemoveResultSchema,\n 'DELETE',\n `${base}/links/${encodeURIComponent(id)}`,\n );\n return ctx.succeed(\n { host: run.host, ...removed },\n ctx.ui.result({\n title: `Removed link ${removed.removed} from ${removed.agent.slug}`,\n }),\n );\n }\n default:\n throw usageError(\n `Unknown teams links subcommand \"${run.verb}\".`,\n usageFor('links'),\n );\n }\n}\n\nfunction triggerBody(\n run: TeamAgentRun,\n team: string,\n key: string,\n): TeamAgentTriggerAddRequest {\n const type = run.operands[2]?.trim().toLowerCase();\n const prompt = flag(run, 'prompt') ?? '';\n switch (type) {\n case 'manual':\n noExtra(run.operands, 3, 'triggers');\n return { type: 'manual', promptTemplate: prompt };\n case 'schedule': {\n noExtra(run.operands, 3, 'triggers');\n const cron = flag(run, 'cron');\n if (!cron || !prompt) {\n throw usageError(\n 'A schedule needs --cron and --prompt.',\n `e.g. ekanos teams triggers add ${team} ${key} schedule --cron \"0 9 * * 1-5\" --timezone America/Los_Angeles --prompt \"Summarize yesterday's tickets\"`,\n );\n }\n return {\n type: 'schedule',\n scheduleCron: cron,\n timezone: flag(run, 'timezone') ?? 'UTC',\n promptTemplate: prompt,\n };\n }\n case 'webhook':\n noExtra(run.operands, 3, 'triggers');\n if (!prompt) {\n throw usageError(\n 'A webhook needs --prompt: what to do with each request.',\n `e.g. ekanos teams triggers add ${team} ${key} webhook --prompt \"Triage this alert: {{body.title}}\"`,\n );\n }\n return { type: 'webhook', promptTemplate: prompt };\n case 'event':\n case 'integration_event': {\n const eventId = run.operands[3]?.trim();\n if (!eventId) {\n throw usageError(\n 'Name the event, e.g. zendesk.ticket_created.',\n `e.g. ekanos teams triggers add ${team} ${key} event zendesk.ticket_created --filter '{\"priority\":[\"urgent\"]}'`,\n );\n }\n noExtra(run.operands, 4, 'triggers');\n return {\n type: 'integration_event',\n eventId,\n filter: parseFilter(flag(run, 'filter')),\n promptTemplate: prompt,\n };\n }\n case 'slack':\n throw usageError(\n 'A slack trigger is connected in the app, where the team picks its workspace and channels.',\n 'Open the agent in the app and add it under Triggers.',\n );\n case 'linear':\n throw usageError(\n 'A \"linear\" trigger is the Ekanos Agents app for Linear (@mentions and assignments only), connected in the app. The Linear integration\\'s own events are added here as event triggers.',\n `e.g. ekanos teams triggers add ${team} ${key} event linear.issue_labeled --filter '{\"labels\":[\"feedback\"]}' — \"ekanos catalog linear --json\" lists every agentEvents id.`,\n );\n default:\n throw usageError(\n type ? `Unknown trigger type \"${type}\".` : 'Name the trigger type.',\n usageFor('triggers'),\n );\n }\n}\n\nfunction parseFilter(\n raw: string | undefined,\n): Record<string, string | boolean | string[]> {\n if (!raw) return {};\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n throw usageError(\n '--filter must be a JSON object.',\n `e.g. --filter '{\"priority\":[\"urgent\",\"high\"]}'`,\n );\n }\n if (typeof parsed !== 'object' || parsed === null || Array.isArray(parsed)) {\n throw usageError(\n '--filter must be a JSON object.',\n `e.g. --filter '{\"priority\":[\"urgent\",\"high\"]}'`,\n );\n }\n const filter: Record<string, string | boolean | string[]> = {};\n for (const [name, value] of Object.entries(parsed)) {\n if (\n typeof value === 'string' ||\n typeof value === 'boolean' ||\n (Array.isArray(value) && value.every((item) => typeof item === 'string'))\n ) {\n filter[name] = value as string | boolean | string[];\n continue;\n }\n throw usageError(\n `--filter field \"${name}\" must be a string, a boolean or a list of strings.`,\n `e.g. --filter '{\"priority\":[\"urgent\",\"high\"]}'`,\n );\n }\n return filter;\n}\n\nfunction describeTrigger(trigger: TeamAgentTrigger): string {\n const what =\n trigger.type === 'schedule'\n ? `schedule ${trigger.scheduleCron ?? ''} (${trigger.timezone ?? 'UTC'})`\n : trigger.type === 'integration_event'\n ? `event ${trigger.eventId ?? ''}${trigger.filter && Object.keys(trigger.filter).length > 0 ? ` ${JSON.stringify(trigger.filter)}` : ''}`\n : trigger.type;\n const tags = [\n trigger.owner === 'template' ? 'from template' : 'team',\n trigger.active ? 'on' : 'off',\n ];\n return `${what} · ${tags.join(' · ')}`;\n}\n\nfunction describeLink(link: TeamAgentLink): string {\n const kind =\n link.kind === 'delegate' ? `delegate (${link.mode ?? 'await'})` : 'talk';\n const tags = [\n link.owner === 'template' ? 'from template' : 'team',\n ...(link.active ? [] : ['inactive']),\n ];\n return `${kind} → ${link.to.slug} · ${tags.join(' · ')}`;\n}\n\nfunction agentPath(team: string, key: string): string {\n return `/api/partner/teams/${encodeURIComponent(team)}/agents/${encodeURIComponent(key)}`;\n}\n\nfunction flag(run: TeamAgentRun, name: string): string | undefined {\n const value = run.args.flags?.[name];\n return typeof value === 'string' && value.trim() ? value.trim() : undefined;\n}\n\nfunction noExtra(\n operands: readonly string[],\n count: number,\n area: 'triggers' | 'links',\n) {\n const extra = operands[count];\n if (extra !== undefined) {\n throw usageError(`Unexpected argument \"${extra}\".`, usageFor(area));\n }\n}\n\nfunction send<T>(\n run: TeamAgentRun,\n schema: z.ZodType<T>,\n method: 'GET' | 'POST' | 'DELETE',\n path: string,\n body?: unknown,\n): Promise<T> {\n return run.client.call((token) =>\n call(run.host, token, schema, { method, path, source: run.source, body }),\n );\n}\n"]}
@@ -0,0 +1,25 @@
1
+ import type { CliContext } from '../context.js';
2
+ import type { ExitCode } from '../exit-codes.js';
3
+ import { type TeamsArgs, type TeamsClient } from './teams.js';
4
+ /**
5
+ * `teams connect <team> <product>` — connect a product for one team, doing
6
+ * whichever the integration needs (the host's plan decides, never the CLI):
7
+ *
8
+ * - works as shipped → says so; not self-serve or not enabled → refuses
9
+ * with the reason (and points at `sources products` for the latter);
10
+ * - form fields → asks them here (secrets hidden, never as arguments) and
11
+ * activates exactly as the app's form does;
12
+ * - OAuth → runs `teams app set` inline when the team's own app is needed
13
+ * first (Zendesk), then a one-time sign-in link for the member who
14
+ * consents: the caller when a member, else `--as <email>`. Opens it for
15
+ * the caller (unless `--no-open`), always prints it, and waits until the
16
+ * team is connected (unless `--no-wait`);
17
+ * - a form only the browser can fill → prints the team's page.
18
+ *
19
+ * `--link-only` keeps the old behaviour: the team's page and its status.
20
+ */
21
+ export declare function runTeamConnect(ctx: CliContext, args: TeamsArgs, client: TeamsClient, host: string, source: string, input: {
22
+ team: string;
23
+ product: string;
24
+ as?: string;
25
+ }): Promise<ExitCode>;
@@ -0,0 +1,242 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { invalidStateError, usageError, validationError } from '../errors.js';
3
+ import { showTeamConnect, startTeamConnect, } from '../team-connect-api.js';
4
+ import { showTeamIntegration } from '../teams-api.js';
5
+ import { promptHidden, promptLine } from './apps.js';
6
+ import { canPrompt, checklist, promptAndSaveTeamApp, } from './teams.js';
7
+ /**
8
+ * `teams connect <team> <product>` — connect a product for one team, doing
9
+ * whichever the integration needs (the host's plan decides, never the CLI):
10
+ *
11
+ * - works as shipped → says so; not self-serve or not enabled → refuses
12
+ * with the reason (and points at `sources products` for the latter);
13
+ * - form fields → asks them here (secrets hidden, never as arguments) and
14
+ * activates exactly as the app's form does;
15
+ * - OAuth → runs `teams app set` inline when the team's own app is needed
16
+ * first (Zendesk), then a one-time sign-in link for the member who
17
+ * consents: the caller when a member, else `--as <email>`. Opens it for
18
+ * the caller (unless `--no-open`), always prints it, and waits until the
19
+ * team is connected (unless `--no-wait`);
20
+ * - a form only the browser can fill → prints the team's page.
21
+ *
22
+ * `--link-only` keeps the old behaviour: the team's page and its status.
23
+ */
24
+ export async function runTeamConnect(ctx, args, client, host, source, input) {
25
+ var _a, _b, _c, _d;
26
+ const target = { source, team: input.team, product: input.product };
27
+ if (args.linkOnly)
28
+ return printLink(ctx, client, host, target);
29
+ const { plan } = await client.call((token) => showTeamConnect(host, token, target, input.as));
30
+ const name = plan.product.name;
31
+ switch (plan.mode) {
32
+ case 'not-entitled':
33
+ throw invalidStateError((_a = plan.reason) !== null && _a !== void 0 ? _a : `"${input.product}" is not enabled on ${plan.source.slug}.`, `A super-admin enables it for the Source first ("ekanos sources products" shows what ${plan.source.slug} has; "ekanos sources products enable ${input.product}" from a super-admin session, or /admin in the browser).`);
34
+ case 'not-self-serve':
35
+ throw invalidStateError((_b = plan.reason) !== null && _b !== void 0 ? _b : `${name} is not connected by a team.`, plan.product.kind === 'experience'
36
+ ? `"ekanos sources products --source ${plan.source.slug}" shows whether it is on for the Source.`
37
+ : 'It is turned on for the Source by Ekanos; there is nothing for the team to do.');
38
+ case 'unsupported':
39
+ throw invalidStateError((_c = plan.reason) !== null && _c !== void 0 ? _c : `${name} cannot be connected from here.`, `Open the team's page instead: ${plan.connectUrl}`);
40
+ case 'works-as-shipped':
41
+ return ctx.succeed({ host, plan, connected: true }, ctx.ui.result({
42
+ title: `${name} works as shipped for ${plan.team.slug}`,
43
+ rows: [['Status', 'nothing to connect']],
44
+ }));
45
+ case 'browser':
46
+ return ctx.succeed({ host, plan, connected: plan.connected }, ctx.ui.result({
47
+ title: plan.connected
48
+ ? `${plan.team.slug} has connected ${name}`
49
+ : `${name} connects in the app for ${plan.team.slug}`,
50
+ tone: plan.connected ? 'ok' : 'warn',
51
+ rows: [
52
+ ['Open', plan.connectUrl],
53
+ ['Status', statusOf(plan)],
54
+ ],
55
+ notes: plan.connected
56
+ ? []
57
+ : [
58
+ (_d = plan.reason) !== null && _d !== void 0 ? _d : `${name} connects through its own form in the app.`,
59
+ 'A team admin signs in there and clicks Connect.',
60
+ ],
61
+ }));
62
+ default:
63
+ break;
64
+ }
65
+ if (plan.connected) {
66
+ return ctx.succeed({ host, plan, connected: true }, ctx.ui.result({
67
+ title: `${plan.team.slug} has already connected ${name}`,
68
+ rows: [
69
+ ['Status', statusOf(plan)],
70
+ ['Team page', plan.connectUrl],
71
+ ],
72
+ notes: [
73
+ `"ekanos teams show ${plan.team.slug} ${plan.product.slug}" shows the full setup.`,
74
+ ],
75
+ }));
76
+ }
77
+ if (plan.mode === 'fields' || plan.mode === 'no-fields') {
78
+ return activate(ctx, args, client, host, target, plan);
79
+ }
80
+ return connectOAuth(ctx, args, client, host, target, plan, input.as);
81
+ }
82
+ async function activate(ctx, args, client, host, target, plan) {
83
+ var _a;
84
+ var _b, _c, _d, _e;
85
+ if (plan.scope === 'user' && !plan.member) {
86
+ throw invalidStateError((_b = plan.memberProblem) !== null && _b !== void 0 ? _b : `${plan.product.name} is a personal connection: each member connects their own.`, `A member connects it for themselves on the team's page: ${plan.connectUrl}`);
87
+ }
88
+ const fields = {};
89
+ if (plan.mode === 'fields') {
90
+ if (!canPrompt(ctx, args)) {
91
+ throw usageError(`${plan.product.name} needs its fields typed at a terminal (${plan.fields.map((field) => field.label).join(', ')}), never in a script or an agent run.`, `Run it yourself in your terminal: npx @ekanos/cli teams connect ${target.team} ${target.product} --source ${plan.source.slug}`);
92
+ }
93
+ ctx.log(`${plan.product.name} for ${plan.scope === 'user' ? 'you, in' : 'team'} ${plan.team.slug}: enter what the app's form asks. Secrets are hidden and never shown again.`);
94
+ for (const field of plan.fields) {
95
+ if (field.description)
96
+ ctx.log(` ${field.description}`);
97
+ const suffix = `${field.required ? '' : ' (optional — Enter skips)'}${field.sensitive ? ' (hidden)' : ''}: `;
98
+ const value = (await (field.sensitive
99
+ ? ((_c = args.askSecret) !== null && _c !== void 0 ? _c : promptHidden)
100
+ : ((_d = args.ask) !== null && _d !== void 0 ? _d : promptLine))(`${field.label}${suffix}`)).trim();
101
+ if (value)
102
+ fields[field.name] = value;
103
+ else if (field.required) {
104
+ throw validationError(`${field.label} is needed.`, `Run "ekanos teams connect ${target.team} ${target.product}" again.`);
105
+ }
106
+ }
107
+ }
108
+ const started = await client.call((token) => startTeamConnect(host, token, target, { fields }));
109
+ return ctx.succeed(Object.assign(Object.assign({ host }, started), { connected: started.plan.connected }), ctx.ui.result({
110
+ title: `Connected ${started.plan.product.name} for ${started.plan.team.slug}`,
111
+ rows: [
112
+ ['Status', statusOf(started.plan)],
113
+ [
114
+ 'For',
115
+ started.plan.scope === 'user'
116
+ ? `you (${(_e = (_a = started.plan.member) === null || _a === void 0 ? void 0 : _a.email) !== null && _e !== void 0 ? _e : 'your account'}) — a personal connection`
117
+ : 'the whole team',
118
+ ],
119
+ ['Team page', started.plan.connectUrl],
120
+ ],
121
+ }));
122
+ }
123
+ async function connectOAuth(ctx, args, client, host, target, plan, asEmail) {
124
+ var _a, _b, _c, _d, _e, _f;
125
+ if (!plan.member) {
126
+ throw invalidStateError((_a = plan.memberProblem) !== null && _a !== void 0 ? _a : 'No member of the team can sign in yet.', `Name a member of ${plan.team.slug} who signs in: ekanos teams connect ${target.team} ${target.product} --as <email>`);
127
+ }
128
+ if (plan.teamApp) {
129
+ const status = await client.call((token) => showTeamIntegration(host, token, target));
130
+ const app = (_b = status.teamApps.find((entry) => entry.connectionId === 'default')) !== null && _b !== void 0 ? _b : status.teamApps[0];
131
+ if (app && app.fields.some((field) => !field.set)) {
132
+ if (!canPrompt(ctx, args)) {
133
+ throw usageError(`${plan.product.name} needs ${plan.team.slug}'s own app first, entered at a terminal.`, `Run it yourself in your terminal: npx @ekanos/cli teams connect ${target.team} ${target.product} --source ${plan.source.slug}`);
134
+ }
135
+ ctx.log(`${plan.product.name} signs ${plan.team.slug} in through the team's own app. Set it up first:`);
136
+ await promptAndSaveTeamApp(ctx, args, client, host, target, status, app);
137
+ }
138
+ }
139
+ const started = await client.call((token) => startTeamConnect(host, token, target, asEmail ? { as: asEmail } : {}));
140
+ if (started.result !== 'consent') {
141
+ throw invalidStateError(`The host answered "${started.result}" where a sign-in link was expected.`, 'Run "ekanos upgrade" — the CLI and the host disagree on the connect contract.');
142
+ }
143
+ const member = (_c = started.plan.member) !== null && _c !== void 0 ? _c : plan.member;
144
+ const forCaller = member.isCaller;
145
+ const expires = started.expiresAt.replace('T', ' ').slice(0, 16);
146
+ ctx.log(forCaller
147
+ ? [
148
+ `Sign in to ${plan.product.name} as the account ${plan.team.slug} should use${plan.scope === 'user' ? ' (a personal connection: yours)' : ''}:`,
149
+ ` ${started.authorizeUrl}`,
150
+ ` (one-time link, valid until ${expires} UTC)`,
151
+ ].join('\n')
152
+ : [
153
+ `Send this link to ${(_d = member.email) !== null && _d !== void 0 ? _d : 'the member'} — they sign in to ${plan.product.name} for ${plan.team.slug}${plan.scope === 'user' ? ' (a personal connection: theirs)' : ''}:`,
154
+ ` ${started.authorizeUrl}`,
155
+ ` (one-time, for them only, valid until ${expires} UTC)`,
156
+ ].join('\n'));
157
+ // Only ever the caller's own browser: opening a link meant for another
158
+ // member would sign the caller's provider account in for them.
159
+ if (forCaller && !args.noOpen && !ctx.jsonMode) {
160
+ ((_e = args.openUrl) !== null && _e !== void 0 ? _e : openInBrowser)(started.authorizeUrl);
161
+ }
162
+ if (args.noWait || ctx.jsonMode) {
163
+ return ctx.succeed({
164
+ host,
165
+ plan: started.plan,
166
+ authorizeUrl: started.authorizeUrl,
167
+ expiresAt: started.expiresAt,
168
+ connected: false,
169
+ }, ctx.ui.hint(`Then check with "ekanos teams show ${target.team} ${target.product}".`));
170
+ }
171
+ ctx.log('Waiting for the sign-in to finish (Ctrl-C stops waiting; the link stays valid)…');
172
+ const deadline = Date.parse(started.expiresAt) || Date.now() + 10 * 60 * 1000;
173
+ while (Date.now() < deadline) {
174
+ await new Promise((resolve) => { var _a; return setTimeout(resolve, (_a = args.pollDelayMs) !== null && _a !== void 0 ? _a : 3000); });
175
+ const polled = await client.call((token) => showTeamConnect(host, token, target, asEmail));
176
+ if (polled.plan.connected) {
177
+ const status = await client.call((token) => showTeamIntegration(host, token, target));
178
+ return ctx.succeed({ host, plan: polled.plan, status, connected: true }, [
179
+ ctx.ui.result({
180
+ title: `Connected ${plan.product.name} for ${plan.team.slug}`,
181
+ rows: [
182
+ ['Signed in by', (_f = member.email) !== null && _f !== void 0 ? _f : member.userId],
183
+ ['Status', statusOf(polled.plan)],
184
+ ],
185
+ }),
186
+ checklist(status).join('\n'),
187
+ ].join('\n'));
188
+ }
189
+ }
190
+ throw validationError('The sign-in did not finish before the link expired.', `Run "ekanos teams connect ${target.team} ${target.product}${asEmail ? ` --as ${asEmail}` : ''}" again for a fresh link.`);
191
+ }
192
+ /** `--link-only`: the team's page and whether it is connected. */
193
+ async function printLink(ctx, client, host, target) {
194
+ var _a;
195
+ const status = await client.call((token) => showTeamIntegration(host, token, target));
196
+ if (!status.enabled) {
197
+ throw invalidStateError(`"${target.product}" is not enabled on ${status.source.slug}.`, `"ekanos sources products --source ${status.source.slug}" shows what this Source has; a super-admin enables a product for a Source.`);
198
+ }
199
+ const connected = status.activation !== null;
200
+ const rows = [
201
+ ['Open', status.connectUrl],
202
+ [
203
+ 'Status',
204
+ connected
205
+ ? `connected${((_a = status.activation) === null || _a === void 0 ? void 0 : _a.activatedAt) ? ` ${status.activation.activatedAt.slice(0, 10)}` : ''}`
206
+ : 'not connected',
207
+ ],
208
+ ];
209
+ return ctx.succeed(Object.assign({ host }, status), ctx.ui.result({
210
+ title: connected
211
+ ? `${status.team.slug} has connected ${status.product.name}`
212
+ : `Connect link for ${status.team.slug} · ${status.product.name}`,
213
+ tone: connected ? 'ok' : 'warn',
214
+ rows,
215
+ notes: [
216
+ 'A team member signs in there and clicks Connect.',
217
+ `"ekanos teams connect ${status.team.slug} ${status.product.slug}" (without --link-only) connects it from here.`,
218
+ ],
219
+ }));
220
+ }
221
+ function statusOf(plan) {
222
+ if (!plan.connected)
223
+ return 'not connected';
224
+ return `connected${plan.connectedAt ? ` ${plan.connectedAt.slice(0, 10)}` : ''}`;
225
+ }
226
+ /** Best effort: the link is always printed, so a failed open costs nothing. */
227
+ function openInBrowser(url) {
228
+ const [command, argv] = process.platform === 'darwin'
229
+ ? ['open', [url]]
230
+ : process.platform === 'win32'
231
+ ? ['cmd', ['/c', 'start', '""', url]]
232
+ : ['xdg-open', [url]];
233
+ try {
234
+ const child = spawn(command, argv, { detached: true, stdio: 'ignore' });
235
+ child.on('error', () => { });
236
+ child.unref();
237
+ }
238
+ catch (_a) {
239
+ // Printed above; nothing to do.
240
+ }
241
+ }
242
+ //# sourceMappingURL=teams-connect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teams-connect.js","sourceRoot":"","sources":["../../src/commands/teams-connect.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,oBAAoB,CAAC;AAG3C,OAAO,EAAE,iBAAiB,EAAE,UAAU,EAAE,eAAe,EAAE,MAAM,WAAW,CAAC;AAE3E,OAAO,EAEL,eAAe,EACf,gBAAgB,GACjB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,cAAc,CAAC;AAEnD,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAClD,OAAO,EAGL,SAAS,EACT,SAAS,EACT,oBAAoB,GACrB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;;GAgBG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAClC,GAAe,EACf,IAAe,EACf,MAAmB,EACnB,IAAY,EACZ,MAAc,EACd,KAAqD;;IAErD,MAAM,MAAM,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IAEpE,IAAI,IAAI,CAAC,QAAQ;QAAE,OAAO,SAAS,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IAE/D,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC3C,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,CAAC,CAC/C,CAAC;IACF,MAAM,IAAI,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,CAAC;IAE/B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;QAClB,KAAK,cAAc;YACjB,MAAM,iBAAiB,OACrB,IAAI,CAAC,MAAM,mCACT,IAAI,KAAK,CAAC,OAAO,uBAAuB,IAAI,CAAC,MAAM,CAAC,IAAI,GAAG,EAC7D,uFAAuF,IAAI,CAAC,MAAM,CAAC,IAAI,yCAAyC,KAAK,CAAC,OAAO,0DAA0D,CACxN,CAAC;QACJ,KAAK,gBAAgB;YACnB,MAAM,iBAAiB,OACrB,IAAI,CAAC,MAAM,mCAAI,GAAG,IAAI,8BAA8B,EACpD,IAAI,CAAC,OAAO,CAAC,IAAI,KAAK,YAAY;gBAChC,CAAC,CAAC,qCAAqC,IAAI,CAAC,MAAM,CAAC,IAAI,0CAA0C;gBACjG,CAAC,CAAC,gFAAgF,CACrF,CAAC;QACJ,KAAK,aAAa;YAChB,MAAM,iBAAiB,OACrB,IAAI,CAAC,MAAM,mCAAI,GAAG,IAAI,iCAAiC,EACvD,iCAAiC,IAAI,CAAC,UAAU,EAAE,CACnD,CAAC;QACJ,KAAK,kBAAkB;YACrB,OAAO,GAAG,CAAC,OAAO,CAChB,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAC/B,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;gBACZ,KAAK,EAAE,GAAG,IAAI,yBAAyB,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACvD,IAAI,EAAE,CAAC,CAAC,QAAQ,EAAE,oBAAoB,CAAC,CAAC;aACzC,CAAC,CACH,CAAC;QACJ,KAAK,SAAS;YACZ,OAAO,GAAG,CAAC,OAAO,CAChB,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,CAAC,SAAS,EAAE,EACzC,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;gBACZ,KAAK,EAAE,IAAI,CAAC,SAAS;oBACnB,CAAC,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,kBAAkB,IAAI,EAAE;oBAC3C,CAAC,CAAC,GAAG,IAAI,4BAA4B,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;gBACvD,IAAI,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;gBACpC,IAAI,EAAE;oBACJ,CAAC,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC;oBACzB,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;iBAC3B;gBACD,KAAK,EAAE,IAAI,CAAC,SAAS;oBACnB,CAAC,CAAC,EAAE;oBACJ,CAAC,CAAC;8BACE,IAAI,CAAC,MAAM,mCACT,GAAG,IAAI,4CAA4C;wBACrD,iDAAiD;qBAClD;aACN,CAAC,CACH,CAAC;QACJ;YACE,MAAM;IACV,CAAC;IAED,IAAI,IAAI,CAAC,SAAS,EAAE,CAAC;QACnB,OAAO,GAAG,CAAC,OAAO,CAChB,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,IAAI,EAAE,EAC/B,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;YACZ,KAAK,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,0BAA0B,IAAI,EAAE;YACxD,IAAI,EAAE;gBACJ,CAAC,QAAQ,EAAE,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC1B,CAAC,WAAW,EAAE,IAAI,CAAC,UAAU,CAAC;aAC/B;YACD,KAAK,EAAE;gBACL,sBAAsB,IAAI,CAAC,IAAI,CAAC,IAAI,IAAI,IAAI,CAAC,OAAO,CAAC,IAAI,yBAAyB;aACnF;SACF,CAAC,CACH,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,IAAI,IAAI,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;QACxD,OAAO,QAAQ,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,CAAC,CAAC;IACzD,CAAC;IACD,OAAO,YAAY,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;AACvE,CAAC;AAED,KAAK,UAAU,QAAQ,CACrB,GAAe,EACf,IAAe,EACf,MAAmB,EACnB,IAAY,EACZ,MAAyD,EACzD,IAAqB;;;IAErB,IAAI,IAAI,CAAC,KAAK,KAAK,MAAM,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QAC1C,MAAM,iBAAiB,OACrB,IAAI,CAAC,aAAa,mCAChB,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,4DAA4D,EAClF,2DAA2D,IAAI,CAAC,UAAU,EAAE,CAC7E,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,IAAI,IAAI,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC3B,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;YAC1B,MAAM,UAAU,CACd,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,0CAA0C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,uCAAuC,EACvJ,mEAAmE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,aAAa,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAChI,CAAC;QACJ,CAAC;QACD,GAAG,CAAC,GAAG,CACL,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,QAAQ,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,IAAI,6EAA6E,CACtK,CAAC;QACF,KAAK,MAAM,KAAK,IAAI,IAAI,CAAC,MAAM,EAAE,CAAC;YAChC,IAAI,KAAK,CAAC,WAAW;gBAAE,GAAG,CAAC,GAAG,CAAC,KAAK,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;YACzD,MAAM,MAAM,GAAG,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,2BAA2B,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC;YAC7G,MAAM,KAAK,GAAG,CACZ,MAAM,CACJ,KAAK,CAAC,SAAS;gBACb,CAAC,CAAC,OAAC,IAAI,CAAC,SAAS,mCAAI,YAAY,CAAC;gBAClC,CAAC,CAAC,OAAC,IAAI,CAAC,GAAG,mCAAI,UAAU,CAAC,CAC7B,CAAC,GAAG,KAAK,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC,CAC7B,CAAC,IAAI,EAAE,CAAC;YACT,IAAI,KAAK;gBAAE,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,KAAK,CAAC;iBACjC,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;gBACxB,MAAM,eAAe,CACnB,GAAG,KAAK,CAAC,KAAK,aAAa,EAC3B,6BAA6B,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,UAAU,CACrE,CAAC;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1C,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,CAAC,CAClD,CAAC;IACF,OAAO,GAAG,CAAC,OAAO,+BACd,IAAI,IAAK,OAAO,KAAE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,SAAS,KACrD,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,aAAa,OAAO,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,QAAQ,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;QAC7E,IAAI,EAAE;YACJ,CAAC,QAAQ,EAAE,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;YAClC;gBACE,KAAK;gBACL,OAAO,CAAC,IAAI,CAAC,KAAK,KAAK,MAAM;oBAC3B,CAAC,CAAC,QAAQ,MAAA,MAAA,OAAO,CAAC,IAAI,CAAC,MAAM,0CAAE,KAAK,mCAAI,cAAc,2BAA2B;oBACjF,CAAC,CAAC,gBAAgB;aACrB;YACD,CAAC,WAAW,EAAE,OAAO,CAAC,IAAI,CAAC,UAAU,CAAC;SACvC;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,GAAe,EACf,IAAe,EACf,MAAmB,EACnB,IAAY,EACZ,MAAyD,EACzD,IAAqB,EACrB,OAA2B;;IAE3B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,iBAAiB,OACrB,IAAI,CAAC,aAAa,mCAAI,wCAAwC,EAC9D,oBAAoB,IAAI,CAAC,IAAI,CAAC,IAAI,uCAAuC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,eAAe,CACtH,CAAC;IACJ,CAAC;IAED,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;QACjB,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACzC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CACzC,CAAC;QACF,MAAM,GAAG,SACP,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,YAAY,KAAK,SAAS,CAAC,mCACjE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC;QACrB,IAAI,GAAG,IAAI,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;YAClD,IAAI,CAAC,SAAS,CAAC,GAAG,EAAE,IAAI,CAAC,EAAE,CAAC;gBAC1B,MAAM,UAAU,CACd,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,0CAA0C,EACtF,mEAAmE,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,aAAa,IAAI,CAAC,MAAM,CAAC,IAAI,EAAE,CAChI,CAAC;YACJ,CAAC;YACD,GAAG,CAAC,GAAG,CACL,GAAG,IAAI,CAAC,OAAO,CAAC,IAAI,UAAU,IAAI,CAAC,IAAI,CAAC,IAAI,kDAAkD,CAC/F,CAAC;YACF,MAAM,oBAAoB,CAAC,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,CAAC,CAAC;QAC3E,CAAC;IACH,CAAC;IAED,MAAM,OAAO,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CAC1C,gBAAgB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC,CAAC,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACtE,CAAC;IACF,IAAI,OAAO,CAAC,MAAM,KAAK,SAAS,EAAE,CAAC;QACjC,MAAM,iBAAiB,CACrB,sBAAsB,OAAO,CAAC,MAAM,sCAAsC,EAC1E,+EAA+E,CAChF,CAAC;IACJ,CAAC;IAED,MAAM,MAAM,SAAG,OAAO,CAAC,IAAI,CAAC,MAAM,mCAAI,IAAI,CAAC,MAAM,CAAC;IAClD,MAAM,SAAS,GAAG,MAAM,CAAC,QAAQ,CAAC;IAClC,MAAM,OAAO,GAAG,OAAO,CAAC,SAAS,CAAC,OAAO,CAAC,GAAG,EAAE,GAAG,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;IACjE,GAAG,CAAC,GAAG,CACL,SAAS;QACP,CAAC,CAAC;YACE,cAAc,IAAI,CAAC,OAAO,CAAC,IAAI,mBAAmB,IAAI,CAAC,IAAI,CAAC,IAAI,cAAc,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,iCAAiC,CAAC,CAAC,CAAC,EAAE,GAAG;YAC/I,KAAK,OAAO,CAAC,YAAY,EAAE;YAC3B,iCAAiC,OAAO,OAAO;SAChD,CAAC,IAAI,CAAC,IAAI,CAAC;QACd,CAAC,CAAC;YACE,qBAAqB,MAAA,MAAM,CAAC,KAAK,mCAAI,YAAY,sBAAsB,IAAI,CAAC,OAAO,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC,KAAK,KAAK,MAAM,CAAC,CAAC,CAAC,kCAAkC,CAAC,CAAC,CAAC,EAAE,GAAG;YACnL,KAAK,OAAO,CAAC,YAAY,EAAE;YAC3B,2CAA2C,OAAO,OAAO;SAC1D,CAAC,IAAI,CAAC,IAAI,CAAC,CACjB,CAAC;IAEF,uEAAuE;IACvE,+DAA+D;IAC/D,IAAI,SAAS,IAAI,CAAC,IAAI,CAAC,MAAM,IAAI,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC;QAC/C,OAAC,IAAI,CAAC,OAAO,mCAAI,aAAa,CAAC,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,IAAI,GAAG,CAAC,QAAQ,EAAE,CAAC;QAChC,OAAO,GAAG,CAAC,OAAO,CAChB;YACE,IAAI;YACJ,IAAI,EAAE,OAAO,CAAC,IAAI;YAClB,YAAY,EAAE,OAAO,CAAC,YAAY;YAClC,SAAS,EAAE,OAAO,CAAC,SAAS;YAC5B,SAAS,EAAE,KAAK;SACjB,EACD,GAAG,CAAC,EAAE,CAAC,IAAI,CACT,sCAAsC,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,IAAI,CACxE,CACF,CAAC;IACJ,CAAC;IAED,GAAG,CAAC,GAAG,CACL,iFAAiF,CAClF,CAAC;IACF,MAAM,QAAQ,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,SAAS,CAAC,IAAI,IAAI,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC;IAC9E,OAAO,IAAI,CAAC,GAAG,EAAE,GAAG,QAAQ,EAAE,CAAC;QAC7B,MAAM,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,EAAE,kBAC5B,UAAU,CAAC,OAAO,QAAE,IAAI,CAAC,WAAW,mCAAI,IAAI,CAAC,GAAA,CAC9C,CAAC;QACF,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACzC,eAAe,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAC9C,CAAC;QACF,IAAI,MAAM,CAAC,IAAI,CAAC,SAAS,EAAE,CAAC;YAC1B,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACzC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CACzC,CAAC;YACF,OAAO,GAAG,CAAC,OAAO,CAChB,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,EAAE,EACpD;gBACE,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;oBACZ,KAAK,EAAE,aAAa,IAAI,CAAC,OAAO,CAAC,IAAI,QAAQ,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE;oBAC7D,IAAI,EAAE;wBACJ,CAAC,cAAc,QAAE,MAAM,CAAC,KAAK,mCAAI,MAAM,CAAC,MAAM,CAAC;wBAC/C,CAAC,QAAQ,EAAE,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;qBAClC;iBACF,CAAC;gBACF,SAAS,CAAC,MAAM,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC;aAC7B,CAAC,IAAI,CAAC,IAAI,CAAC,CACb,CAAC;QACJ,CAAC;IACH,CAAC;IACD,MAAM,eAAe,CACnB,qDAAqD,EACrD,6BAA6B,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,GAAG,OAAO,CAAC,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,CAAC,CAAC,EAAE,2BAA2B,CAC1H,CAAC;AACJ,CAAC;AAED,kEAAkE;AAClE,KAAK,UAAU,SAAS,CACtB,GAAe,EACf,MAAmB,EACnB,IAAY,EACZ,MAAyD;;IAEzD,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,IAAI,CAAC,CAAC,KAAK,EAAE,EAAE,CACzC,mBAAmB,CAAC,IAAI,EAAE,KAAK,EAAE,MAAM,CAAC,CACzC,CAAC;IACF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,MAAM,iBAAiB,CACrB,IAAI,MAAM,CAAC,OAAO,uBAAuB,MAAM,CAAC,MAAM,CAAC,IAAI,GAAG,EAC9D,qCAAqC,MAAM,CAAC,MAAM,CAAC,IAAI,6EAA6E,CACrI,CAAC;IACJ,CAAC;IACD,MAAM,SAAS,GAAG,MAAM,CAAC,UAAU,KAAK,IAAI,CAAC;IAC7C,MAAM,IAAI,GAAgB;QACxB,CAAC,MAAM,EAAE,MAAM,CAAC,UAAU,CAAC;QAC3B;YACE,QAAQ;YACR,SAAS;gBACP,CAAC,CAAC,YAAY,CAAA,MAAA,MAAM,CAAC,UAAU,0CAAE,WAAW,EAAC,CAAC,CAAC,IAAI,MAAM,CAAC,UAAU,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE;gBACtG,CAAC,CAAC,eAAe;SACpB;KACF,CAAC;IACF,OAAO,GAAG,CAAC,OAAO,iBACd,IAAI,IAAK,MAAM,GACjB,GAAG,CAAC,EAAE,CAAC,MAAM,CAAC;QACZ,KAAK,EAAE,SAAS;YACd,CAAC,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,IAAI,kBAAkB,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;YAC5D,CAAC,CAAC,oBAAoB,MAAM,CAAC,IAAI,CAAC,IAAI,MAAM,MAAM,CAAC,OAAO,CAAC,IAAI,EAAE;QACnE,IAAI,EAAE,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM;QAC/B,IAAI;QACJ,KAAK,EAAE;YACL,kDAAkD;YAClD,yBAAyB,MAAM,CAAC,IAAI,CAAC,IAAI,IAAI,MAAM,CAAC,OAAO,CAAC,IAAI,gDAAgD;SACjH;KACF,CAAC,CACH,CAAC;AACJ,CAAC;AAED,SAAS,QAAQ,CAAC,IAAqB;IACrC,IAAI,CAAC,IAAI,CAAC,SAAS;QAAE,OAAO,eAAe,CAAC;IAC5C,OAAO,YAAY,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC;AACnF,CAAC;AAED,+EAA+E;AAC/E,SAAS,aAAa,CAAC,GAAW;IAChC,MAAM,CAAC,OAAO,EAAE,IAAI,CAAC,GACnB,OAAO,CAAC,QAAQ,KAAK,QAAQ;QAC3B,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC,CAAC,OAAO,CAAC,QAAQ,KAAK,OAAO;YAC5B,CAAC,CAAC,CAAC,KAAK,EAAE,CAAC,IAAI,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,CAAC,CAAC;YACrC,CAAC,CAAC,CAAC,UAAU,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,IAAI,EAAE,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC;QACxE,KAAK,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;QAC5B,KAAK,CAAC,KAAK,EAAE,CAAC;IAChB,CAAC;eAAO,CAAC;QACP,gCAAgC;IAClC,CAAC;AACH,CAAC","sourcesContent":["import { spawn } from 'node:child_process';\n\nimport type { CliContext } from '../context';\nimport { invalidStateError, usageError, validationError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport {\n type TeamConnectPlan,\n showTeamConnect,\n startTeamConnect,\n} from '../team-connect-api';\nimport { showTeamIntegration } from '../teams-api';\nimport type { ResultRow } from '../ui';\nimport { promptHidden, promptLine } from './apps';\nimport {\n type TeamsArgs,\n type TeamsClient,\n canPrompt,\n checklist,\n promptAndSaveTeamApp,\n} from './teams';\n\n/**\n * `teams connect <team> <product>` — connect a product for one team, doing\n * whichever the integration needs (the host's plan decides, never the CLI):\n *\n * - works as shipped → says so; not self-serve or not enabled → refuses\n * with the reason (and points at `sources products` for the latter);\n * - form fields → asks them here (secrets hidden, never as arguments) and\n * activates exactly as the app's form does;\n * - OAuth → runs `teams app set` inline when the team's own app is needed\n * first (Zendesk), then a one-time sign-in link for the member who\n * consents: the caller when a member, else `--as <email>`. Opens it for\n * the caller (unless `--no-open`), always prints it, and waits until the\n * team is connected (unless `--no-wait`);\n * - a form only the browser can fill → prints the team's page.\n *\n * `--link-only` keeps the old behaviour: the team's page and its status.\n */\nexport async function runTeamConnect(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n source: string,\n input: { team: string; product: string; as?: string },\n): Promise<ExitCode> {\n const target = { source, team: input.team, product: input.product };\n\n if (args.linkOnly) return printLink(ctx, client, host, target);\n\n const { plan } = await client.call((token) =>\n showTeamConnect(host, token, target, input.as),\n );\n const name = plan.product.name;\n\n switch (plan.mode) {\n case 'not-entitled':\n throw invalidStateError(\n plan.reason ??\n `\"${input.product}\" is not enabled on ${plan.source.slug}.`,\n `A super-admin enables it for the Source first (\"ekanos sources products\" shows what ${plan.source.slug} has; \"ekanos sources products enable ${input.product}\" from a super-admin session, or /admin in the browser).`,\n );\n case 'not-self-serve':\n throw invalidStateError(\n plan.reason ?? `${name} is not connected by a team.`,\n plan.product.kind === 'experience'\n ? `\"ekanos sources products --source ${plan.source.slug}\" shows whether it is on for the Source.`\n : 'It is turned on for the Source by Ekanos; there is nothing for the team to do.',\n );\n case 'unsupported':\n throw invalidStateError(\n plan.reason ?? `${name} cannot be connected from here.`,\n `Open the team's page instead: ${plan.connectUrl}`,\n );\n case 'works-as-shipped':\n return ctx.succeed(\n { host, plan, connected: true },\n ctx.ui.result({\n title: `${name} works as shipped for ${plan.team.slug}`,\n rows: [['Status', 'nothing to connect']],\n }),\n );\n case 'browser':\n return ctx.succeed(\n { host, plan, connected: plan.connected },\n ctx.ui.result({\n title: plan.connected\n ? `${plan.team.slug} has connected ${name}`\n : `${name} connects in the app for ${plan.team.slug}`,\n tone: plan.connected ? 'ok' : 'warn',\n rows: [\n ['Open', plan.connectUrl],\n ['Status', statusOf(plan)],\n ],\n notes: plan.connected\n ? []\n : [\n plan.reason ??\n `${name} connects through its own form in the app.`,\n 'A team admin signs in there and clicks Connect.',\n ],\n }),\n );\n default:\n break;\n }\n\n if (plan.connected) {\n return ctx.succeed(\n { host, plan, connected: true },\n ctx.ui.result({\n title: `${plan.team.slug} has already connected ${name}`,\n rows: [\n ['Status', statusOf(plan)],\n ['Team page', plan.connectUrl],\n ],\n notes: [\n `\"ekanos teams show ${plan.team.slug} ${plan.product.slug}\" shows the full setup.`,\n ],\n }),\n );\n }\n\n if (plan.mode === 'fields' || plan.mode === 'no-fields') {\n return activate(ctx, args, client, host, target, plan);\n }\n return connectOAuth(ctx, args, client, host, target, plan, input.as);\n}\n\nasync function activate(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: { source: string; team: string; product: string },\n plan: TeamConnectPlan,\n): Promise<ExitCode> {\n if (plan.scope === 'user' && !plan.member) {\n throw invalidStateError(\n plan.memberProblem ??\n `${plan.product.name} is a personal connection: each member connects their own.`,\n `A member connects it for themselves on the team's page: ${plan.connectUrl}`,\n );\n }\n\n const fields: Record<string, string> = {};\n if (plan.mode === 'fields') {\n if (!canPrompt(ctx, args)) {\n throw usageError(\n `${plan.product.name} needs its fields typed at a terminal (${plan.fields.map((field) => field.label).join(', ')}), never in a script or an agent run.`,\n `Run it yourself in your terminal: npx @ekanos/cli teams connect ${target.team} ${target.product} --source ${plan.source.slug}`,\n );\n }\n ctx.log(\n `${plan.product.name} for ${plan.scope === 'user' ? 'you, in' : 'team'} ${plan.team.slug}: enter what the app's form asks. Secrets are hidden and never shown again.`,\n );\n for (const field of plan.fields) {\n if (field.description) ctx.log(` ${field.description}`);\n const suffix = `${field.required ? '' : ' (optional — Enter skips)'}${field.sensitive ? ' (hidden)' : ''}: `;\n const value = (\n await (\n field.sensitive\n ? (args.askSecret ?? promptHidden)\n : (args.ask ?? promptLine)\n )(`${field.label}${suffix}`)\n ).trim();\n if (value) fields[field.name] = value;\n else if (field.required) {\n throw validationError(\n `${field.label} is needed.`,\n `Run \"ekanos teams connect ${target.team} ${target.product}\" again.`,\n );\n }\n }\n }\n\n const started = await client.call((token) =>\n startTeamConnect(host, token, target, { fields }),\n );\n return ctx.succeed(\n { host, ...started, connected: started.plan.connected },\n ctx.ui.result({\n title: `Connected ${started.plan.product.name} for ${started.plan.team.slug}`,\n rows: [\n ['Status', statusOf(started.plan)],\n [\n 'For',\n started.plan.scope === 'user'\n ? `you (${started.plan.member?.email ?? 'your account'}) — a personal connection`\n : 'the whole team',\n ],\n ['Team page', started.plan.connectUrl],\n ],\n }),\n );\n}\n\nasync function connectOAuth(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: { source: string; team: string; product: string },\n plan: TeamConnectPlan,\n asEmail: string | undefined,\n): Promise<ExitCode> {\n if (!plan.member) {\n throw invalidStateError(\n plan.memberProblem ?? 'No member of the team can sign in yet.',\n `Name a member of ${plan.team.slug} who signs in: ekanos teams connect ${target.team} ${target.product} --as <email>`,\n );\n }\n\n if (plan.teamApp) {\n const status = await client.call((token) =>\n showTeamIntegration(host, token, target),\n );\n const app =\n status.teamApps.find((entry) => entry.connectionId === 'default') ??\n status.teamApps[0];\n if (app && app.fields.some((field) => !field.set)) {\n if (!canPrompt(ctx, args)) {\n throw usageError(\n `${plan.product.name} needs ${plan.team.slug}'s own app first, entered at a terminal.`,\n `Run it yourself in your terminal: npx @ekanos/cli teams connect ${target.team} ${target.product} --source ${plan.source.slug}`,\n );\n }\n ctx.log(\n `${plan.product.name} signs ${plan.team.slug} in through the team's own app. Set it up first:`,\n );\n await promptAndSaveTeamApp(ctx, args, client, host, target, status, app);\n }\n }\n\n const started = await client.call((token) =>\n startTeamConnect(host, token, target, asEmail ? { as: asEmail } : {}),\n );\n if (started.result !== 'consent') {\n throw invalidStateError(\n `The host answered \"${started.result}\" where a sign-in link was expected.`,\n 'Run \"ekanos upgrade\" — the CLI and the host disagree on the connect contract.',\n );\n }\n\n const member = started.plan.member ?? plan.member;\n const forCaller = member.isCaller;\n const expires = started.expiresAt.replace('T', ' ').slice(0, 16);\n ctx.log(\n forCaller\n ? [\n `Sign in to ${plan.product.name} as the account ${plan.team.slug} should use${plan.scope === 'user' ? ' (a personal connection: yours)' : ''}:`,\n ` ${started.authorizeUrl}`,\n ` (one-time link, valid until ${expires} UTC)`,\n ].join('\\n')\n : [\n `Send this link to ${member.email ?? 'the member'} — they sign in to ${plan.product.name} for ${plan.team.slug}${plan.scope === 'user' ? ' (a personal connection: theirs)' : ''}:`,\n ` ${started.authorizeUrl}`,\n ` (one-time, for them only, valid until ${expires} UTC)`,\n ].join('\\n'),\n );\n\n // Only ever the caller's own browser: opening a link meant for another\n // member would sign the caller's provider account in for them.\n if (forCaller && !args.noOpen && !ctx.jsonMode) {\n (args.openUrl ?? openInBrowser)(started.authorizeUrl);\n }\n\n if (args.noWait || ctx.jsonMode) {\n return ctx.succeed(\n {\n host,\n plan: started.plan,\n authorizeUrl: started.authorizeUrl,\n expiresAt: started.expiresAt,\n connected: false,\n },\n ctx.ui.hint(\n `Then check with \"ekanos teams show ${target.team} ${target.product}\".`,\n ),\n );\n }\n\n ctx.log(\n 'Waiting for the sign-in to finish (Ctrl-C stops waiting; the link stays valid)…',\n );\n const deadline = Date.parse(started.expiresAt) || Date.now() + 10 * 60 * 1000;\n while (Date.now() < deadline) {\n await new Promise((resolve) =>\n setTimeout(resolve, args.pollDelayMs ?? 3000),\n );\n const polled = await client.call((token) =>\n showTeamConnect(host, token, target, asEmail),\n );\n if (polled.plan.connected) {\n const status = await client.call((token) =>\n showTeamIntegration(host, token, target),\n );\n return ctx.succeed(\n { host, plan: polled.plan, status, connected: true },\n [\n ctx.ui.result({\n title: `Connected ${plan.product.name} for ${plan.team.slug}`,\n rows: [\n ['Signed in by', member.email ?? member.userId],\n ['Status', statusOf(polled.plan)],\n ],\n }),\n checklist(status).join('\\n'),\n ].join('\\n'),\n );\n }\n }\n throw validationError(\n 'The sign-in did not finish before the link expired.',\n `Run \"ekanos teams connect ${target.team} ${target.product}${asEmail ? ` --as ${asEmail}` : ''}\" again for a fresh link.`,\n );\n}\n\n/** `--link-only`: the team's page and whether it is connected. */\nasync function printLink(\n ctx: CliContext,\n client: TeamsClient,\n host: string,\n target: { source: string; team: string; product: string },\n): Promise<ExitCode> {\n const status = await client.call((token) =>\n showTeamIntegration(host, token, target),\n );\n if (!status.enabled) {\n throw invalidStateError(\n `\"${target.product}\" is not enabled on ${status.source.slug}.`,\n `\"ekanos sources products --source ${status.source.slug}\" shows what this Source has; a super-admin enables a product for a Source.`,\n );\n }\n const connected = status.activation !== null;\n const rows: ResultRow[] = [\n ['Open', status.connectUrl],\n [\n 'Status',\n connected\n ? `connected${status.activation?.activatedAt ? ` ${status.activation.activatedAt.slice(0, 10)}` : ''}`\n : 'not connected',\n ],\n ];\n return ctx.succeed(\n { host, ...status },\n ctx.ui.result({\n title: connected\n ? `${status.team.slug} has connected ${status.product.name}`\n : `Connect link for ${status.team.slug} · ${status.product.name}`,\n tone: connected ? 'ok' : 'warn',\n rows,\n notes: [\n 'A team member signs in there and clicks Connect.',\n `\"ekanos teams connect ${status.team.slug} ${status.product.slug}\" (without --link-only) connects it from here.`,\n ],\n }),\n );\n}\n\nfunction statusOf(plan: TeamConnectPlan): string {\n if (!plan.connected) return 'not connected';\n return `connected${plan.connectedAt ? ` ${plan.connectedAt.slice(0, 10)}` : ''}`;\n}\n\n/** Best effort: the link is always printed, so a failed open costs nothing. */\nfunction openInBrowser(url: string): void {\n const [command, argv] =\n process.platform === 'darwin'\n ? ['open', [url]]\n : process.platform === 'win32'\n ? ['cmd', ['/c', 'start', '\"\"', url]]\n : ['xdg-open', [url]];\n try {\n const child = spawn(command, argv, { detached: true, stdio: 'ignore' });\n child.on('error', () => {});\n child.unref();\n } catch {\n // Printed above; nothing to do.\n }\n}\n"]}
@@ -1,6 +1,6 @@
1
1
  import type { CliContext } from '../context.js';
2
2
  import type { ExitCode } from '../exit-codes.js';
3
- import type { TeamsClient } from './teams.js';
3
+ import type { TeamsArgs, TeamsClient } from './teams.js';
4
4
  /**
5
5
  * Onboarding a team from the terminal, for the Source admin: `teams create`,
6
6
  * `teams members list|invite|role|remove`, `teams roles list` and
@@ -14,6 +14,8 @@ export interface OnboardingFlags {
14
14
  slug?: string;
15
15
  owner?: string;
16
16
  role?: string;
17
+ /** `connect --as <member-email>`: the member who signs in. */
18
+ as?: string;
17
19
  yes: boolean;
18
20
  }
19
21
  export type OnboardingPlan = {
@@ -45,7 +47,8 @@ export type OnboardingPlan = {
45
47
  kind: 'connect';
46
48
  team: string;
47
49
  product: string;
50
+ as?: string;
48
51
  };
49
52
  export declare function isOnboardingSubcommand(value: string): value is OnboardingSubcommand;
50
53
  export declare function parseOnboarding(subcommand: OnboardingSubcommand, rest: readonly string[], flags: OnboardingFlags): OnboardingPlan;
51
- export declare function runOnboarding(ctx: CliContext, client: TeamsClient, host: string, source: string, plan: OnboardingPlan): Promise<ExitCode>;
54
+ export declare function runOnboarding(ctx: CliContext, args: TeamsArgs, client: TeamsClient, host: string, source: string, plan: OnboardingPlan): Promise<ExitCode>;
@@ -1,5 +1,6 @@
1
1
  import { invalidStateError, usageError } from '../errors.js';
2
- import { createTeam, inviteTeamMember, listTeamMembers, listTeamRoles, removeTeamMember, setTeamMemberRole, showTeamIntegration, } from '../teams-api.js';
2
+ import { createTeam, inviteTeamMember, listTeamMembers, listTeamRoles, removeTeamMember, setTeamMemberRole, } from '../teams-api.js';
3
+ import { runTeamConnect } from './teams-connect.js';
3
4
  /**
4
5
  * Onboarding a team from the terminal, for the Source admin: `teams create`,
5
6
  * `teams members list|invite|role|remove`, `teams roles list` and
@@ -35,11 +36,7 @@ export function parseOnboarding(subcommand, rest, flags) {
35
36
  if (subcommand === 'connect') {
36
37
  const [team, product, ...extra] = rest;
37
38
  noExtra(extra);
38
- return {
39
- kind: 'connect',
40
- team: slugOf(team, 'team'),
41
- product: slugOf(product, 'product'),
42
- };
39
+ return Object.assign({ kind: 'connect', team: slugOf(team, 'team'), product: slugOf(product, 'product') }, (flags.as === undefined ? {} : { as: emailOf(flags.as) }));
43
40
  }
44
41
  if (subcommand === 'roles') {
45
42
  const [verb, team, ...extra] = rest;
@@ -95,9 +92,8 @@ export function parseOnboarding(subcommand, rest, flags) {
95
92
  }
96
93
  return { kind: 'members-remove', team: teamSlug, email: address };
97
94
  }
98
- export async function runOnboarding(ctx, client, host, source, plan) {
99
- var _a;
100
- var _b, _c;
95
+ export async function runOnboarding(ctx, args, client, host, source, plan) {
96
+ var _a, _b;
101
97
  switch (plan.kind) {
102
98
  case 'create': {
103
99
  const created = await client.call((token) => createTeam(host, token, source, {
@@ -120,7 +116,7 @@ export async function runOnboarding(ctx, client, host, source, plan) {
120
116
  ],
121
117
  notes: [
122
118
  `Next: "ekanos teams members invite ${created.team.slug} <email> --role <role>" ("ekanos teams roles list ${created.team.slug}" lists the roles).`,
123
- `Then "ekanos teams connect ${created.team.slug} <product>" for the link a member opens to connect an integration.`,
119
+ `Then "ekanos teams connect ${created.team.slug} <product>" connects an integration for the team.`,
124
120
  ],
125
121
  }));
126
122
  }
@@ -165,7 +161,7 @@ export async function runOnboarding(ctx, client, host, source, plan) {
165
161
  ? `${changed.email} is already ${changed.after} on ${changed.team.slug}`
166
162
  : `${changed.email} is now ${changed.after} on ${changed.team.slug}`,
167
163
  rows: [
168
- ['Was', (_b = changed.before) !== null && _b !== void 0 ? _b : '—'],
164
+ ['Was', (_a = changed.before) !== null && _a !== void 0 ? _a : '—'],
169
165
  [
170
166
  'Applies to',
171
167
  changed.kind === 'member'
@@ -185,7 +181,7 @@ export async function runOnboarding(ctx, client, host, source, plan) {
185
181
  title: removed.kind === 'member'
186
182
  ? `Removed ${removed.email} from ${removed.team.slug}`
187
183
  : `Withdrew ${removed.email}'s invitation to ${removed.team.slug}`,
188
- rows: [['Role was', (_c = removed.before) !== null && _c !== void 0 ? _c : '—']],
184
+ rows: [['Role was', (_b = removed.before) !== null && _b !== void 0 ? _b : '—']],
189
185
  }));
190
186
  }
191
187
  case 'roles-list': {
@@ -201,36 +197,12 @@ export async function runOnboarding(ctx, client, host, source, plan) {
201
197
  ],
202
198
  }));
203
199
  }
204
- case 'connect': {
205
- const status = await client.call((token) => showTeamIntegration(host, token, {
206
- source,
200
+ case 'connect':
201
+ return runTeamConnect(ctx, args, client, host, source, {
207
202
  team: plan.team,
208
203
  product: plan.product,
209
- }));
210
- if (!status.enabled) {
211
- throw invalidStateError(`"${plan.product}" is not enabled on ${status.source.slug}.`, '"ekanos catalog" lists what this Source has; Ekanos enables a product for a Source.');
212
- }
213
- const connected = status.activation !== null;
214
- return ctx.succeed(Object.assign({ host }, status), ctx.ui.result({
215
- title: connected
216
- ? `${status.team.slug} has connected ${status.product.name}`
217
- : `Connect link for ${status.team.slug} · ${status.product.name}`,
218
- tone: connected ? 'ok' : 'warn',
219
- rows: [
220
- ['Open', status.connectUrl],
221
- [
222
- 'Status',
223
- connected
224
- ? `connected${((_a = status.activation) === null || _a === void 0 ? void 0 : _a.activatedAt) ? ` ${status.activation.activatedAt.slice(0, 10)}` : ''}`
225
- : 'not connected',
226
- ],
227
- ],
228
- notes: [
229
- 'A team member signs in there and clicks Connect: sign-in happens in their browser, never in a terminal.',
230
- `"ekanos teams show ${status.team.slug} ${status.product.slug}" shows the full setup checklist.`,
231
- ],
232
- }));
233
- }
204
+ as: plan.as,
205
+ });
234
206
  }
235
207
  }
236
208
  function noExtra(extra) {