@ekanos/cli 0.12.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 (47) 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 +13 -4
  7. package/dist/commands/apps.js +117 -39
  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/sources.d.ts +4 -0
  13. package/dist/commands/sources.js +115 -1
  14. package/dist/commands/sources.js.map +1 -1
  15. package/dist/commands/team-agents-triggers.js +2 -1
  16. package/dist/commands/team-agents-triggers.js.map +1 -1
  17. package/dist/commands/teams-connect.d.ts +25 -0
  18. package/dist/commands/teams-connect.js +242 -0
  19. package/dist/commands/teams-connect.js.map +1 -0
  20. package/dist/commands/teams-onboard.d.ts +5 -2
  21. package/dist/commands/teams-onboard.js +12 -40
  22. package/dist/commands/teams-onboard.js.map +1 -1
  23. package/dist/commands/teams.d.ts +60 -5
  24. package/dist/commands/teams.js +141 -46
  25. package/dist/commands/teams.js.map +1 -1
  26. package/dist/index.js +62 -6
  27. package/dist/index.js.map +1 -1
  28. package/dist/knowledge-api.d.ts +129 -0
  29. package/dist/knowledge-api.js +138 -0
  30. package/dist/knowledge-api.js.map +1 -0
  31. package/dist/source-products-api.d.ts +59 -0
  32. package/dist/source-products-api.js +113 -0
  33. package/dist/source-products-api.js.map +1 -0
  34. package/dist/team-connect-api.d.ts +244 -0
  35. package/dist/team-connect-api.js +95 -0
  36. package/dist/team-connect-api.js.map +1 -0
  37. package/dist/teams-api.d.ts +1 -0
  38. package/dist/teams-api.js +1 -1
  39. package/dist/teams-api.js.map +1 -1
  40. package/package.json +2 -2
  41. package/templates/package.json.tmpl +4 -4
  42. package/templates/skills/build-agent/SKILL.md +14 -1
  43. package/templates/skills/build-agent/references/agent-json.md +22 -6
  44. package/templates/skills/build-agent/references/app-setup.md +2 -1
  45. package/templates/skills/build-agent/references/set-up-an-integration.md +19 -8
  46. package/templates/skills/build-agent/references/triggers.md +44 -15
  47. package/templates/skills/ekanos-platform/SKILL.md +32 -6
@@ -0,0 +1 @@
1
+ {"version":3,"file":"knowledge.js","sourceRoot":"","sources":["../../src/commands/knowledge.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\nimport type { z } from 'zod';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport {\n authRequiredError,\n notFoundError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport {\n KNOWLEDGE_PUSH_BATCH,\n type KnowledgeApiResult,\n type KnowledgeArticle,\n KnowledgeListSchema,\n type KnowledgePushArticle,\n type KnowledgePushResult,\n KnowledgePushSchema,\n KnowledgeSearchSchema,\n knowledgeCall,\n} from '../knowledge-api';\nimport { classifyPath } from '../safe-fs';\nimport { resolveSourceTarget } from '../source-target';\nimport { pluralize } from '../ui';\n\nexport const KNOWLEDGE_SUBCOMMANDS = [\n 'list',\n 'push',\n 'search',\n 'pull',\n] as const;\ntype KnowledgeSubcommand = (typeof KNOWLEDGE_SUBCOMMANDS)[number];\n\nexport interface KnowledgeArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n /** `push <dir>`, `search <query>`. */\n target?: string;\n /** A team's slug: that team's collection instead of the Source's General one. */\n team?: string;\n /** `pull`: where to write (default `knowledge/<team|general>`). */\n out?: string;\n dir: string;\n env: Record<string, string | undefined>;\n}\n\nconst USAGE =\n 'Run one of: ekanos knowledge list [--team <slug>] | push <dir> [--team <slug>] | search <query> --team <slug> | pull [--team <slug>] [--out <dir>].';\n\n/**\n * `knowledge` — a Source's Knowledge base (plan 244): the General collection\n * every team reads, and with `--team` one team's own collection. `push`\n * turns a folder of markdown files into articles — one per `.md`, keyed by\n * its path, so pushing the same folder again only changes what changed —\n * and `pull` writes them back the same way. `search` runs as a team's\n * agents do: that team's articles plus General.\n */\nexport async function runKnowledge(\n ctx: CliContext,\n args: KnowledgeArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n const team = args.team?.trim() || undefined;\n\n // Read the folder before any network call, so a bad one fails fast.\n const files =\n subcommand === 'push'\n ? readKnowledgeFolder(requireTarget(args.target, 'push'), args.dir)\n : null;\n if (subcommand === 'search') {\n requireTarget(args.target, 'search');\n if (!team) {\n throw usageError(\n 'knowledge search needs --team <slug>.',\n 'Search runs as that team’s agents see it: its articles plus the General collection.',\n );\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 KnowledgeClient(env, resolved.session);\n const source = resolved.source;\n const send = <T>(\n schema: z.ZodType<T>,\n init: Parameters<typeof knowledgeCall>[3],\n ) => client.call((token) => knowledgeCall(env.host, token, schema, init));\n const where = (slug: string) => (team ? `team ${team}` : `${slug} General`);\n\n switch (subcommand) {\n case 'list': {\n const list = await send(KnowledgeListSchema, {\n method: 'GET',\n query: { source, team },\n });\n if (list.articles.length === 0) {\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `No Knowledge articles in ${where(list.source.slug)} yet`,\n tone: 'warn',\n notes: [\n `\"ekanos knowledge push <dir>${team ? ` --team ${team}` : ''}\" stores a folder of .md files.`,\n ],\n }),\n );\n }\n return ctx.succeed(\n { host: env.host, ...list },\n [\n ctx.ui.bold(\n `${pluralize(list.articles.length, 'article')} in ${where(list.source.slug)}`,\n ),\n ctx.ui.table(\n ['Slug', 'Title', 'Tags', 'Version', 'Updated'],\n list.articles.map((article) => [\n article.slug,\n article.title,\n article.tags.join(', '),\n `v${article.version}`,\n article.updatedAt.slice(0, 10),\n ]),\n ),\n ].join('\\n'),\n );\n }\n\n case 'search': {\n const query = args.target!;\n const found = await send(KnowledgeSearchSchema, {\n method: 'GET',\n path: '/search',\n query: { source, team, q: query },\n });\n if (found.results.length === 0) {\n return ctx.succeed(\n { host: env.host, ...found },\n ctx.ui.result({\n title: `Nothing in team ${team}'s Knowledge matches \"${query}\"`,\n tone: 'warn',\n notes: ['Try fewer or different words.'],\n }),\n );\n }\n return ctx.succeed(\n { host: env.host, ...found },\n ctx.ui.result({\n title: `${found.results.length === 1 ? '1 match' : `${found.results.length} matches`} for \"${query}\" in team ${team}`,\n rows: found.results.map((hit) => [\n `${hit.title} (${hit.collection === 'general' ? 'General' : 'team'})`,\n [hit.snippet.replace(/\\s+/g, ' '), ctx.ui.dim(hit.slug)],\n ]),\n }),\n );\n }\n\n case 'push': {\n const articles = files!;\n const results: KnowledgePushResult[] = [];\n let pushed: { source: { slug: string } } | null = null;\n for (\n let start = 0;\n start < articles.length;\n start += KNOWLEDGE_PUSH_BATCH\n ) {\n const batch = articles.slice(start, start + KNOWLEDGE_PUSH_BATCH);\n const response = await send(KnowledgePushSchema, {\n method: 'POST',\n query: {},\n body: {\n source,\n ...(team ? { team } : {}),\n articles: batch.map(({ file: _file, ...article }) => article),\n },\n });\n pushed = response;\n results.push(...response.results);\n }\n const count = (status: KnowledgePushResult['status']) =>\n results.filter((result) => result.status === status).length;\n const refused = results.filter((result) => result.status === 'refused');\n return ctx.succeed(\n { host: env.host, team: team ?? null, results },\n ctx.ui.result({\n title: `Pushed ${pluralize(results.length, 'article')} to ${where(pushed?.source.slug ?? source)}`,\n tone: refused.length > 0 ? 'warn' : 'ok',\n rows: [\n ['Created', String(count('created'))],\n ['Updated', String(count('updated'))],\n ['Unchanged', String(count('unchanged'))],\n ...(refused.length > 0\n ? ([\n [\n 'Refused',\n refused.map(\n (result) => `${result.slug}: ${result.message ?? ''}`,\n ),\n ],\n ] as const)\n : []),\n ],\n notes: [\n team\n ? `Team ${team}'s agents with search_knowledge find these now.`\n : 'Every team on the Source reads the General collection.',\n ],\n }),\n );\n }\n\n case 'pull': {\n const list = await send(KnowledgeListSchema, {\n method: 'GET',\n query: { source, team, body: '1' },\n });\n const outDir = path.resolve(\n args.dir,\n args.out ?? path.join('knowledge', team ?? 'general'),\n );\n const written = writeKnowledgeFolder(outDir, list.articles);\n return ctx.succeed(\n { host: env.host, team: team ?? null, dir: outDir, files: written },\n ctx.ui.result({\n title: `Pulled ${pluralize(written.length, 'article')} from ${where(list.source.slug)}`,\n rows: [['Into', outDir]],\n notes: [\n `Edit, then \"ekanos knowledge push ${path.relative(args.dir, outDir) || '.'}${team ? ` --team ${team}` : ''}\".`,\n ],\n }),\n );\n }\n }\n}\n\n/** Every call refreshes the session once on a 401, then gives up. */\nclass KnowledgeClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<KnowledgeApiResult<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 knowledge call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n}\n\n/** Mirrors the host's `knowledgeSlug`: a file's path without `.md`. */\nexport function knowledgeSlugFromPath(relative: string): string {\n return relative\n .trim()\n .toLowerCase()\n .replace(/\\\\/g, '/')\n .replace(/\\.(md|markdown|mdx)$/, '')\n .normalize('NFKD')\n .replace(/[̀-ͯ]/g, '')\n .replace(/[^a-z0-9._/-]+/g, '-')\n .replace(/\\/+/g, '/')\n .replace(/-{2,}/g, '-')\n .split('/')\n .map((part) => part.replace(/^[-.]+|[-.]+$/g, ''))\n .filter(Boolean)\n .join('/')\n .slice(0, 200);\n}\n\nconst IGNORED = new Set(['node_modules', '.git']);\nconst MARKDOWN = /\\.(md|markdown|mdx)$/i;\nconst BODY_MAX = 200_000;\n\n/**\n * Every markdown file under `target`, as articles. The title is the\n * frontmatter `title:`, else the first `# heading` (taken out of the body so\n * it is not shown twice), else the file name; tags are the frontmatter\n * `tags:` (`[a, b]`, `a, b` or a `- a` list).\n */\nexport function readKnowledgeFolder(\n target: string,\n cwd: string,\n): (KnowledgePushArticle & { file: string })[] {\n const root = path.resolve(cwd, target);\n const kind = classifyPath(root);\n if (kind !== 'directory' && kind !== 'file') {\n throw notFoundError(\n `No folder or file at ${root}.`,\n 'Pass a folder of .md files, e.g. \"ekanos knowledge push ./knowledge\".',\n );\n }\n\n const found: string[] = [];\n const walk = (dir: string) => {\n for (const name of fs.readdirSync(dir).sort()) {\n if (IGNORED.has(name) || name.startsWith('.')) continue;\n const full = path.join(dir, name);\n const entry = classifyPath(full);\n if (entry === 'directory') walk(full);\n else if (entry === 'file' && MARKDOWN.test(name)) found.push(full);\n }\n };\n if (kind === 'file') found.push(root);\n else walk(root);\n\n if (found.length === 0) {\n throw validationError(\n `No .md files under ${root}.`,\n 'Each markdown file becomes one article.',\n );\n }\n\n const base = kind === 'file' ? path.dirname(root) : root;\n const seen = new Map<string, string>();\n return found.map((file) => {\n const relative = path.relative(base, file).split(path.sep).join('/');\n const markdown = fs.readFileSync(file, 'utf8');\n const { fields, tags, body } = splitFrontmatter(markdown);\n const slug = knowledgeSlugFromPath(fields.slug || relative);\n if (!slug) {\n throw validationError(\n `${file}: no usable slug.`,\n 'Rename the file with letters or digits.',\n );\n }\n const clash = seen.get(slug);\n if (clash) {\n throw validationError(\n `${file} and ${clash} both become \"${slug}\".`,\n 'Rename one of them.',\n );\n }\n seen.set(slug, file);\n\n const heading = fields.title\n ? null\n : body.match(/^[ \\t]*#[ \\t]+(.+?)[ \\t]*#*[ \\t]*$/m);\n const title = (\n fields.title ||\n heading?.[1] ||\n path.basename(file).replace(MARKDOWN, '').replace(/[-_]+/g, ' ')\n )\n .trim()\n .slice(0, 300);\n const text = (heading ? body.replace(heading[0], '') : body).replace(\n /^\\s*\\n/,\n '',\n );\n if (text.length > BODY_MAX) {\n throw validationError(\n `${file} is longer than ${BODY_MAX.toLocaleString()} characters.`,\n 'Split it into smaller articles.',\n );\n }\n return {\n file,\n slug,\n title: title || slug,\n body: text,\n ...(tags.length > 0 ? { tags: tags.slice(0, 30) } : {}),\n };\n });\n}\n\nfunction writeKnowledgeFolder(\n outDir: string,\n articles: KnowledgeArticle[],\n): string[] {\n const written: string[] = [];\n for (const article of articles) {\n const target = path.resolve(outDir, ...`${article.slug}.md`.split('/'));\n if (!target.startsWith(outDir + path.sep)) {\n throw validationError(\n `Refusing to write ${article.slug} outside ${outDir}.`,\n 'The host sent a slug that leaves the folder.',\n );\n }\n const kind = classifyPath(target);\n if (kind !== 'missing' && kind !== 'file') {\n throw validationError(\n `Refusing to write through ${target} (${kind}).`,\n 'Remove it, or pass --out <dir>.',\n );\n }\n const frontmatter = [\n '---',\n `title: ${JSON.stringify(article.title)}`,\n ...(article.tags.length > 0\n ? [\n `tags: [${article.tags.map((tag) => JSON.stringify(tag)).join(', ')}]`,\n ]\n : []),\n '---',\n '',\n ].join('\\n');\n fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.writeFileSync(target, frontmatter + (article.body ?? ''));\n written.push(target);\n }\n return written;\n}\n\nconst FRONTMATTER = /^?---[ \\t]*\\r?\\n([\\s\\S]*?)\\r?\\n---[ \\t]*(?:\\r?\\n|$)/;\n\n/** Top-level `title`, `slug` and `tags` only. */\nfunction splitFrontmatter(markdown: string): {\n fields: Record<string, string>;\n tags: string[];\n body: string;\n} {\n const match = markdown.match(FRONTMATTER);\n if (!match) return { fields: {}, tags: [], body: markdown };\n const fields: Record<string, string> = {};\n const tags: string[] = [];\n const lines = match[1]!.split(/\\r?\\n/);\n for (let index = 0; index < lines.length; index += 1) {\n const pair = lines[index]!.match(/^([A-Za-z0-9_-]+):[ \\t]*(.*)$/);\n if (!pair) continue;\n const key = pair[1]!.toLowerCase();\n const value = pair[2]!.trim();\n if (key === 'tags') {\n if (value) {\n tags.push(...value.replace(/^\\[|\\]$/g, '').split(','));\n }\n while (\n index + 1 < lines.length &&\n /^[ \\t]*-[ \\t]+/.test(lines[index + 1]!)\n ) {\n tags.push(lines[index + 1]!.replace(/^[ \\t]*-[ \\t]+/, ''));\n index += 1;\n }\n continue;\n }\n fields[key] = unquote(value);\n }\n return {\n fields,\n tags: [...new Set(tags.map((tag) => unquote(tag.trim())).filter(Boolean))],\n body: markdown.slice(match[0].length),\n };\n}\n\nfunction unquote(value: string): string {\n if (value.length >= 2 && value.startsWith('\"') && value.endsWith('\"')) {\n try {\n const parsed: unknown = JSON.parse(value);\n if (typeof parsed === 'string') return parsed;\n } catch {\n // Not JSON-escaped: strip the quotes below.\n }\n }\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n return value.slice(1, -1);\n }\n return value;\n}\n\nfunction parseSubcommand(value: string | undefined): KnowledgeSubcommand {\n const match = KNOWLEDGE_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown knowledge subcommand \"${value}\".`\n : 'knowledge needs a subcommand.',\n USAGE,\n );\n}\n\nfunction requireTarget(value: string | undefined, verb: 'push' | 'search') {\n if (value?.trim()) return value;\n throw usageError(\n verb === 'push'\n ? 'knowledge push needs a folder of .md files.'\n : 'knowledge search needs a query.',\n verb === 'push'\n ? 'e.g. \"ekanos knowledge push ./knowledge --team first-bank\".'\n : 'e.g. \"ekanos knowledge search \\\\\"wire cutoff\\\\\" --team first-bank\".',\n );\n}\n"]}
@@ -2,6 +2,10 @@ import type { CliContext } from '../context.js';
2
2
  import type { ExitCode } from '../exit-codes.js';
3
3
  export interface SourcesArgs {
4
4
  host?: string;
5
+ /** `products [enable|disable <product>]`; none lists the sources. */
6
+ positionals?: readonly string[];
7
+ source?: string;
8
+ yes?: boolean;
5
9
  /** Where a project's ekanos.json may sit — its `source` field, if any, is the marker. */
6
10
  dir: string;
7
11
  env: Record<string, string | undefined>;
@@ -1,8 +1,11 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
- import { requireSession, resolveAuthEnvironment } from '../auth/session.js';
3
+ import { refreshStoredSession, requireSession, resolveAuthEnvironment, } from '../auth/session.js';
4
+ import { authRequiredError, invalidStateError, usageError } from '../errors.js';
4
5
  import { EKANOS_CONFIG_FILENAME } from '../project.js';
5
6
  import { fetchSeatsWithOneRefresh } from '../seats.js';
7
+ import { listSourceProducts, setSourceProduct, } from '../source-products-api.js';
8
+ import { resolveSourceTarget } from '../source-target.js';
6
9
  import { stillUnauthorizedSourceSeats } from '../sources-api.js';
7
10
  import { pluralize, shortHost } from '../ui.js';
8
11
  /**
@@ -14,6 +17,14 @@ import { pluralize, shortHost } from '../ui.js';
14
17
  * publish to?" before running `ekanos use` or passing `--source`.
15
18
  */
16
19
  export async function runSources(ctx, args) {
20
+ var _a;
21
+ const [subcommand, ...rest] = (_a = args.positionals) !== null && _a !== void 0 ? _a : [];
22
+ if (subcommand !== undefined) {
23
+ if (subcommand !== 'products') {
24
+ throw usageError(`Unknown sources subcommand "${subcommand}".`, 'Run "ekanos sources" to list your sources, or "ekanos sources products [enable|disable <product>]".');
25
+ }
26
+ return runProducts(ctx, args, rest);
27
+ }
17
28
  const env = resolveAuthEnvironment(ctx, args.host, args.env, {
18
29
  projectDir: args.dir,
19
30
  });
@@ -82,4 +93,107 @@ function humanSummary(ui, host, sources, activeSource) {
82
93
  : [],
83
94
  });
84
95
  }
96
+ /**
97
+ * `sources products` — the catalog as one Source has it: every product, its
98
+ * kind (Experience or Integration), and whether it is enabled for the Source.
99
+ * `enable|disable <product>` switch one through the levers `/admin` uses
100
+ * (`attachProductToSource` / `detachProductFromSource` for an Integration,
101
+ * the Experience lever for an Experience). That is a super-admin grant: the
102
+ * host refuses a Source admin, and an `ekanos login` session never carries
103
+ * super-admin, so from the terminal the write answers with where to do it.
104
+ */
105
+ async function runProducts(ctx, args, rest) {
106
+ const [verb, rawProduct, ...extra] = rest;
107
+ if (extra.length > 0) {
108
+ throw usageError(`Unexpected argument "${extra[0]}".`, 'Run "ekanos sources products [enable|disable <product>] [--source <slug>]".');
109
+ }
110
+ if (verb !== undefined && verb !== 'enable' && verb !== 'disable') {
111
+ throw usageError(`Unknown sources products subcommand "${verb}".`, 'Run "ekanos sources products", "ekanos sources products enable <product>" or "ekanos sources products disable <product> --yes".');
112
+ }
113
+ const product = verb ? productSlug(rawProduct, verb) : null;
114
+ if (verb === 'disable' && !args.yes) {
115
+ throw invalidStateError(`Disabling ${product} removes it from the Source: its plans, widget settings, Source credentials and workspaces go with it.`, `Re-run with --yes: ekanos sources products disable ${product} --yes`);
116
+ }
117
+ const env = resolveAuthEnvironment(ctx, args.host, args.env, {
118
+ projectDir: args.dir,
119
+ });
120
+ const resolved = await resolveSourceTarget(env, requireSession(env.store, env.host), { source: args.source, dir: args.dir });
121
+ const client = new ProductsClient(env, resolved.session);
122
+ if (!verb || !product) {
123
+ const list = await client.call((token) => listSourceProducts(env.host, token, resolved.source));
124
+ const byKind = (kind) => list.products
125
+ .filter((entry) => entry.kind === kind)
126
+ .map((entry) => [
127
+ entry.slug,
128
+ `${entry.enabled ? '✓ enabled' : '✗ off'} · ${entry.name}${entry.registered ? '' : ' · no package on this host'}`,
129
+ ]);
130
+ return ctx.succeed(Object.assign({ host: env.host }, list), [
131
+ ctx.ui.result({
132
+ title: `Experiences on ${list.source.slug}`,
133
+ rows: byKind('experience'),
134
+ }),
135
+ ctx.ui.result({
136
+ title: `Integrations on ${list.source.slug}`,
137
+ rows: byKind('integration'),
138
+ notes: [
139
+ list.canEnable
140
+ ? '"ekanos sources products enable|disable <product>" switches one.'
141
+ : 'Enabling one is a super-admin grant, made in the browser at /admin/sources → the Source → Products.',
142
+ '"ekanos teams connect <team> <product>" connects an enabled integration for a team.',
143
+ ],
144
+ }),
145
+ ].join('\n'));
146
+ }
147
+ const enabled = verb === 'enable';
148
+ const result = await client.call((token) => setSourceProduct(env.host, token, {
149
+ source: resolved.source,
150
+ product,
151
+ enabled,
152
+ }));
153
+ return ctx.succeed(Object.assign({ host: env.host }, result), ctx.ui.result({
154
+ title: result.changed
155
+ ? `${enabled ? 'Enabled' : 'Disabled'} ${result.product.name} for ${result.source.slug}`
156
+ : `${result.product.name} was already ${enabled ? 'enabled' : 'off'} for ${result.source.slug}`,
157
+ rows: [
158
+ ['Kind', result.product.kind],
159
+ [
160
+ 'Switched by',
161
+ result.product.lever === 'flag'
162
+ ? 'its Flag'
163
+ : result.product.lever === 'plan'
164
+ ? 'its plan'
165
+ : 'the entitlement',
166
+ ],
167
+ ],
168
+ notes: enabled && result.product.kind === 'integration'
169
+ ? [
170
+ `Next: "ekanos teams connect <team> ${result.product.slug}" connects it for a team.`,
171
+ ]
172
+ : [],
173
+ }));
174
+ }
175
+ function productSlug(value, verb) {
176
+ const slug = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
177
+ if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug))
178
+ return slug;
179
+ throw usageError(value
180
+ ? `"${value}" is not a product slug.`
181
+ : `sources products ${verb} needs a product.`, '"ekanos sources products" lists them, e.g. "ekanos sources products enable agents".');
182
+ }
183
+ class ProductsClient {
184
+ constructor(env, session) {
185
+ this.env = env;
186
+ this.session = session;
187
+ }
188
+ async call(send) {
189
+ let result = await send(this.session.accessToken);
190
+ if (result.status === 'unauthorized') {
191
+ this.session = await refreshStoredSession(this.env, this.session);
192
+ result = await send(this.session.accessToken);
193
+ }
194
+ if (result.status === 'ok')
195
+ return result.data;
196
+ throw authRequiredError(`The session for ${this.env.host} could not authorize the sources call.`, `Run "ekanos login --host ${this.env.host}" and retry.`);
197
+ }
198
+ }
85
199
  //# sourceMappingURL=sources.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport { requireSession, resolveAuthEnvironment } from '../auth/session';\nimport type { CliContext } from '../context';\nimport type { ExitCode } from '../exit-codes';\nimport { EKANOS_CONFIG_FILENAME } from '../project';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { type Ui, pluralize, shortHost } from '../ui';\n\nexport interface SourcesArgs {\n host?: string;\n /** Where a project's ekanos.json may sit — its `source` field, if any, is the marker. */\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `sources` — list every source the caller holds a developer or admin seat\n * on, the read half of the publish-target-verification story.\n *\n * The list itself is the mechanism that makes `publish` safe: a partner (or\n * an agent acting for one) can always answer \"which sources can I possibly\n * publish to?\" before running `ekanos use` or passing `--source`.\n */\nexport async function runSources(\n ctx: CliContext,\n args: SourcesArgs,\n): Promise<ExitCode> {\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const session = requireSession(env.store, env.host);\n\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env.host);\n }\n\n const activeSource = readActiveSource(args.dir);\n\n return ctx.succeed(\n { host: env.host, sources: result.sources, activeSource },\n humanSummary(ctx.ui, env.host, result.sources, activeSource),\n );\n}\n\n/**\n * Best-effort, lenient read of ekanos.json's `source` field — mirrors\n * `readProjectHost` in `auth/session.ts`. A missing, unparseable, or\n * sourceless ekanos.json (or no project at all) simply means \"no active\n * source to mark\", never an error: `sources` must answer outside a project\n * too.\n */\nexport function readActiveSource(dir: string): string | null {\n const configPath = path.join(dir, EKANOS_CONFIG_FILENAME);\n\n let raw: string;\n try {\n raw = fs.readFileSync(configPath, 'utf8');\n } catch {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const source =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { source?: unknown }).source\n : undefined;\n\n return typeof source === 'string' && source.trim().length > 0\n ? source.trim()\n : null;\n}\n\nfunction humanSummary(\n ui: Ui,\n host: string,\n sources: SourceSeat[],\n activeSource: string | null,\n): string {\n if (sources.length === 0) {\n return ui.result({\n title: 'No sources',\n tone: 'warn',\n rows: [['Host', shortHost(host)]],\n notes: ['This account holds no developer seats on this host.'],\n });\n }\n\n const orphaned =\n activeSource && !sources.some((s) => s.slug === activeSource);\n\n return ui.result({\n title: `${pluralize(sources.length, 'source')} on ${shortHost(host)}`,\n rows: sources.map((source): [string, string] => [\n source.slug,\n [\n source.name ?? '(unnamed)',\n source.roles.join(', '),\n ...(source.slug === activeSource ? [ui.accent('this project')] : []),\n ].join(' · '),\n ]),\n notes: orphaned\n ? [\n `This project's ekanos.json points at \"${activeSource}\", which is not in the list above.`,\n ]\n : [],\n });\n}\n"]}
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport { authRequiredError, invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { EKANOS_CONFIG_FILENAME } from '../project';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport {\n type SourceProduct,\n type SourceProductsApiResult,\n listSourceProducts,\n setSourceProduct,\n} from '../source-products-api';\nimport { resolveSourceTarget } from '../source-target';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { type Ui, pluralize, shortHost } from '../ui';\n\nexport interface SourcesArgs {\n host?: string;\n /** `products [enable|disable <product>]`; none lists the sources. */\n positionals?: readonly string[];\n source?: string;\n yes?: boolean;\n /** Where a project's ekanos.json may sit — its `source` field, if any, is the marker. */\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `sources` — list every source the caller holds a developer or admin seat\n * on, the read half of the publish-target-verification story.\n *\n * The list itself is the mechanism that makes `publish` safe: a partner (or\n * an agent acting for one) can always answer \"which sources can I possibly\n * publish to?\" before running `ekanos use` or passing `--source`.\n */\nexport async function runSources(\n ctx: CliContext,\n args: SourcesArgs,\n): Promise<ExitCode> {\n const [subcommand, ...rest] = args.positionals ?? [];\n if (subcommand !== undefined) {\n if (subcommand !== 'products') {\n throw usageError(\n `Unknown sources subcommand \"${subcommand}\".`,\n 'Run \"ekanos sources\" to list your sources, or \"ekanos sources products [enable|disable <product>]\".',\n );\n }\n return runProducts(ctx, args, rest);\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const session = requireSession(env.store, env.host);\n\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env.host);\n }\n\n const activeSource = readActiveSource(args.dir);\n\n return ctx.succeed(\n { host: env.host, sources: result.sources, activeSource },\n humanSummary(ctx.ui, env.host, result.sources, activeSource),\n );\n}\n\n/**\n * Best-effort, lenient read of ekanos.json's `source` field — mirrors\n * `readProjectHost` in `auth/session.ts`. A missing, unparseable, or\n * sourceless ekanos.json (or no project at all) simply means \"no active\n * source to mark\", never an error: `sources` must answer outside a project\n * too.\n */\nexport function readActiveSource(dir: string): string | null {\n const configPath = path.join(dir, EKANOS_CONFIG_FILENAME);\n\n let raw: string;\n try {\n raw = fs.readFileSync(configPath, 'utf8');\n } catch {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const source =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { source?: unknown }).source\n : undefined;\n\n return typeof source === 'string' && source.trim().length > 0\n ? source.trim()\n : null;\n}\n\nfunction humanSummary(\n ui: Ui,\n host: string,\n sources: SourceSeat[],\n activeSource: string | null,\n): string {\n if (sources.length === 0) {\n return ui.result({\n title: 'No sources',\n tone: 'warn',\n rows: [['Host', shortHost(host)]],\n notes: ['This account holds no developer seats on this host.'],\n });\n }\n\n const orphaned =\n activeSource && !sources.some((s) => s.slug === activeSource);\n\n return ui.result({\n title: `${pluralize(sources.length, 'source')} on ${shortHost(host)}`,\n rows: sources.map((source): [string, string] => [\n source.slug,\n [\n source.name ?? '(unnamed)',\n source.roles.join(', '),\n ...(source.slug === activeSource ? [ui.accent('this project')] : []),\n ].join(' · '),\n ]),\n notes: orphaned\n ? [\n `This project's ekanos.json points at \"${activeSource}\", which is not in the list above.`,\n ]\n : [],\n });\n}\n\n/**\n * `sources products` — the catalog as one Source has it: every product, its\n * kind (Experience or Integration), and whether it is enabled for the Source.\n * `enable|disable <product>` switch one through the levers `/admin` uses\n * (`attachProductToSource` / `detachProductFromSource` for an Integration,\n * the Experience lever for an Experience). That is a super-admin grant: the\n * host refuses a Source admin, and an `ekanos login` session never carries\n * super-admin, so from the terminal the write answers with where to do it.\n */\nasync function runProducts(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawProduct, ...extra] = rest;\n if (extra.length > 0) {\n throw usageError(\n `Unexpected argument \"${extra[0]}\".`,\n 'Run \"ekanos sources products [enable|disable <product>] [--source <slug>]\".',\n );\n }\n if (verb !== undefined && verb !== 'enable' && verb !== 'disable') {\n throw usageError(\n `Unknown sources products subcommand \"${verb}\".`,\n 'Run \"ekanos sources products\", \"ekanos sources products enable <product>\" or \"ekanos sources products disable <product> --yes\".',\n );\n }\n const product = verb ? productSlug(rawProduct, verb) : null;\n if (verb === 'disable' && !args.yes) {\n throw invalidStateError(\n `Disabling ${product} removes it from the Source: its plans, widget settings, Source credentials and workspaces go with it.`,\n `Re-run with --yes: ekanos sources products disable ${product} --yes`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(\n env,\n requireSession(env.store, env.host),\n { source: args.source, dir: args.dir },\n );\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product) {\n const list = await client.call((token) =>\n listSourceProducts(env.host, token, resolved.source),\n );\n const byKind = (kind: SourceProduct['kind']) =>\n list.products\n .filter((entry) => entry.kind === kind)\n .map((entry): [string, string] => [\n entry.slug,\n `${entry.enabled ? '✓ enabled' : '✗ off'} · ${entry.name}${entry.registered ? '' : ' · no package on this host'}`,\n ]);\n return ctx.succeed(\n { host: env.host, ...list },\n [\n ctx.ui.result({\n title: `Experiences on ${list.source.slug}`,\n rows: byKind('experience'),\n }),\n ctx.ui.result({\n title: `Integrations on ${list.source.slug}`,\n rows: byKind('integration'),\n notes: [\n list.canEnable\n ? '\"ekanos sources products enable|disable <product>\" switches one.'\n : 'Enabling one is a super-admin grant, made in the browser at /admin/sources → the Source → Products.',\n '\"ekanos teams connect <team> <product>\" connects an enabled integration for a team.',\n ],\n }),\n ].join('\\n'),\n );\n }\n\n const enabled = verb === 'enable';\n const result = await client.call((token) =>\n setSourceProduct(env.host, token, {\n source: resolved.source,\n product,\n enabled,\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${enabled ? 'Enabled' : 'Disabled'} ${result.product.name} for ${result.source.slug}`\n : `${result.product.name} was already ${enabled ? 'enabled' : 'off'} for ${result.source.slug}`,\n rows: [\n ['Kind', result.product.kind],\n [\n 'Switched by',\n result.product.lever === 'flag'\n ? 'its Flag'\n : result.product.lever === 'plan'\n ? 'its plan'\n : 'the entitlement',\n ],\n ],\n notes:\n enabled && result.product.kind === 'integration'\n ? [\n `Next: \"ekanos teams connect <team> ${result.product.slug}\" connects it for a team.`,\n ]\n : [],\n }),\n );\n}\n\nfunction productSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources products ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources products enable agents\".',\n );\n}\n\nclass ProductsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<SourceProductsApiResult<T>>,\n ): Promise<T> {\n let result = await send(this.session.accessToken);\n if (result.status === 'unauthorized') {\n this.session = await refreshStoredSession(this.env, this.session);\n result = await send(this.session.accessToken);\n }\n if (result.status === 'ok') return result.data;\n throw authRequiredError(\n `The session for ${this.env.host} could not authorize the sources call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n}\n"]}
@@ -178,8 +178,9 @@ function triggerBody(run, team, key) {
178
178
  };
179
179
  }
180
180
  case 'slack':
181
+ throw usageError('A slack trigger is connected in the app, where the team picks its workspace and channels.', 'Open the agent in the app and add it under Triggers.');
181
182
  case 'linear':
182
- throw usageError(`A ${type} trigger is connected in the app, where the team picks its workspace and channels.`, 'Open the agent in the app and add it under Triggers.');
183
+ throw usageError('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.', `e.g. ekanos teams triggers add ${team} ${key} event linear.issue_labeled --filter '{"labels":["feedback"]}' — "ekanos catalog linear --json" lists every agentEvents id.`);
183
184
  default:
184
185
  throw usageError(type ? `Unknown trigger type "${type}".` : 'Name the trigger type.', usageFor('triggers'));
185
186
  }
@@ -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>;