@ekanos/cli 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (173) hide show
  1. package/README.md +25 -8
  2. package/dist/agents-api.d.ts +11 -2
  3. package/dist/agents-api.js +39 -3
  4. package/dist/agents-api.js.map +1 -1
  5. package/dist/apps-api.js +2 -2
  6. package/dist/apps-api.js.map +1 -1
  7. package/dist/auth/ekanos-api.d.ts +16 -2
  8. package/dist/auth/ekanos-api.js +101 -15
  9. package/dist/auth/ekanos-api.js.map +1 -1
  10. package/dist/auth/host-trust.d.ts +46 -0
  11. package/dist/auth/host-trust.js +79 -0
  12. package/dist/auth/host-trust.js.map +1 -0
  13. package/dist/auth/session.d.ts +10 -1
  14. package/dist/auth/session.js +28 -28
  15. package/dist/auth/session.js.map +1 -1
  16. package/dist/commands/agents-edit.d.ts +6 -2
  17. package/dist/commands/agents-edit.js +57 -26
  18. package/dist/commands/agents-edit.js.map +1 -1
  19. package/dist/commands/agents.d.ts +13 -2
  20. package/dist/commands/agents.js +148 -36
  21. package/dist/commands/agents.js.map +1 -1
  22. package/dist/commands/apps.d.ts +2 -0
  23. package/dist/commands/apps.js +16 -12
  24. package/dist/commands/apps.js.map +1 -1
  25. package/dist/commands/catalog.js +7 -6
  26. package/dist/commands/catalog.js.map +1 -1
  27. package/dist/commands/knowledge.d.ts +19 -0
  28. package/dist/commands/knowledge.js +119 -27
  29. package/dist/commands/knowledge.js.map +1 -1
  30. package/dist/commands/login.d.ts +4 -0
  31. package/dist/commands/login.js +30 -2
  32. package/dist/commands/login.js.map +1 -1
  33. package/dist/commands/logout.d.ts +9 -1
  34. package/dist/commands/logout.js +56 -7
  35. package/dist/commands/logout.js.map +1 -1
  36. package/dist/commands/publish.js +3 -3
  37. package/dist/commands/publish.js.map +1 -1
  38. package/dist/commands/reviewers.d.ts +2 -0
  39. package/dist/commands/reviewers.js +7 -3
  40. package/dist/commands/reviewers.js.map +1 -1
  41. package/dist/commands/routes.d.ts +2 -0
  42. package/dist/commands/routes.js +42 -9
  43. package/dist/commands/routes.js.map +1 -1
  44. package/dist/commands/runs.d.ts +13 -2
  45. package/dist/commands/runs.js +96 -15
  46. package/dist/commands/runs.js.map +1 -1
  47. package/dist/commands/scope-notice.d.ts +21 -0
  48. package/dist/commands/scope-notice.js +35 -0
  49. package/dist/commands/scope-notice.js.map +1 -0
  50. package/dist/commands/skills.d.ts +7 -1
  51. package/dist/commands/skills.js +80 -24
  52. package/dist/commands/skills.js.map +1 -1
  53. package/dist/commands/sources.d.ts +1 -1
  54. package/dist/commands/sources.js +126 -12
  55. package/dist/commands/sources.js.map +1 -1
  56. package/dist/commands/status.js +5 -4
  57. package/dist/commands/status.js.map +1 -1
  58. package/dist/commands/team-agent-readiness.d.ts +59 -0
  59. package/dist/commands/team-agent-readiness.js +341 -0
  60. package/dist/commands/team-agent-readiness.js.map +1 -0
  61. package/dist/commands/team-agents-agents.d.ts +24 -3
  62. package/dist/commands/team-agents-agents.js +336 -35
  63. package/dist/commands/team-agents-agents.js.map +1 -1
  64. package/dist/commands/team-agents-mcp.js +32 -3
  65. package/dist/commands/team-agents-mcp.js.map +1 -1
  66. package/dist/commands/team-agents-triggers.js +230 -55
  67. package/dist/commands/team-agents-triggers.js.map +1 -1
  68. package/dist/commands/team-agents.d.ts +3 -1
  69. package/dist/commands/team-agents.js +27 -7
  70. package/dist/commands/team-agents.js.map +1 -1
  71. package/dist/commands/teams-channel-install.d.ts +24 -0
  72. package/dist/commands/teams-channel-install.js +94 -0
  73. package/dist/commands/teams-channel-install.js.map +1 -0
  74. package/dist/commands/teams-connect.d.ts +41 -0
  75. package/dist/commands/teams-connect.js +212 -57
  76. package/dist/commands/teams-connect.js.map +1 -1
  77. package/dist/commands/teams-events.d.ts +12 -0
  78. package/dist/commands/teams-events.js +138 -0
  79. package/dist/commands/teams-events.js.map +1 -0
  80. package/dist/commands/teams-onboard.d.ts +11 -3
  81. package/dist/commands/teams-onboard.js +60 -7
  82. package/dist/commands/teams-onboard.js.map +1 -1
  83. package/dist/commands/teams-overview.d.ts +11 -0
  84. package/dist/commands/teams-overview.js +160 -0
  85. package/dist/commands/teams-overview.js.map +1 -0
  86. package/dist/commands/teams-scope.d.ts +10 -0
  87. package/dist/commands/teams-scope.js +109 -0
  88. package/dist/commands/teams-scope.js.map +1 -0
  89. package/dist/commands/teams.d.ts +4 -2
  90. package/dist/commands/teams.js +113 -14
  91. package/dist/commands/teams.js.map +1 -1
  92. package/dist/commands/upgrade.js +12 -2
  93. package/dist/commands/upgrade.js.map +1 -1
  94. package/dist/commands/use.js +2 -2
  95. package/dist/commands/use.js.map +1 -1
  96. package/dist/commands/whoami.js +1 -1
  97. package/dist/commands/whoami.js.map +1 -1
  98. package/dist/connections-api.js +1 -1
  99. package/dist/connections-api.js.map +1 -1
  100. package/dist/delegate.js +11 -4
  101. package/dist/delegate.js.map +1 -1
  102. package/dist/harness-scaffold.js +12 -0
  103. package/dist/harness-scaffold.js.map +1 -1
  104. package/dist/index.d.ts +6 -0
  105. package/dist/index.js +683 -167
  106. package/dist/index.js.map +1 -1
  107. package/dist/knowledge-api.d.ts +46 -0
  108. package/dist/knowledge-api.js +32 -1
  109. package/dist/knowledge-api.js.map +1 -1
  110. package/dist/open-url.d.ts +16 -0
  111. package/dist/open-url.js +73 -0
  112. package/dist/open-url.js.map +1 -0
  113. package/dist/parse-argv.d.ts +2 -0
  114. package/dist/parse-argv.js.map +1 -1
  115. package/dist/publish-api.d.ts +2 -1
  116. package/dist/publish-api.js +4 -3
  117. package/dist/publish-api.js.map +1 -1
  118. package/dist/pull-write.d.ts +27 -0
  119. package/dist/pull-write.js +60 -0
  120. package/dist/pull-write.js.map +1 -0
  121. package/dist/routes-api.d.ts +3 -0
  122. package/dist/routes-api.js +9 -4
  123. package/dist/routes-api.js.map +1 -1
  124. package/dist/runs-api.d.ts +7 -1
  125. package/dist/runs-api.js +21 -6
  126. package/dist/runs-api.js.map +1 -1
  127. package/dist/safe-fs.d.ts +2 -0
  128. package/dist/safe-fs.js +12 -6
  129. package/dist/safe-fs.js.map +1 -1
  130. package/dist/secret-file.d.ts +17 -0
  131. package/dist/secret-file.js +69 -0
  132. package/dist/secret-file.js.map +1 -0
  133. package/dist/skills-api.d.ts +10 -2
  134. package/dist/skills-api.js +37 -2
  135. package/dist/skills-api.js.map +1 -1
  136. package/dist/source-products-api.d.ts +4 -0
  137. package/dist/source-products-api.js +14 -4
  138. package/dist/source-products-api.js.map +1 -1
  139. package/dist/source-target.js +2 -1
  140. package/dist/source-target.js.map +1 -1
  141. package/dist/sources-api.d.ts +2 -1
  142. package/dist/sources-api.js +3 -2
  143. package/dist/sources-api.js.map +1 -1
  144. package/dist/team-connect-api.d.ts +44 -2
  145. package/dist/team-connect-api.js +19 -7
  146. package/dist/team-connect-api.js.map +1 -1
  147. package/dist/teams-api.d.ts +41 -1
  148. package/dist/teams-api.js +97 -19
  149. package/dist/teams-api.js.map +1 -1
  150. package/dist/toolchain-api.d.ts +9 -0
  151. package/dist/toolchain-api.js +17 -2
  152. package/dist/toolchain-api.js.map +1 -1
  153. package/dist/toolchain-resolve.d.ts +3 -0
  154. package/dist/toolchain-resolve.js +15 -1
  155. package/dist/toolchain-resolve.js.map +1 -1
  156. package/dist/toolchain.d.ts +6 -0
  157. package/dist/toolchain.js +19 -0
  158. package/dist/toolchain.js.map +1 -1
  159. package/dist/update-notice.js +2 -1
  160. package/dist/update-notice.js.map +1 -1
  161. package/package.json +2 -2
  162. package/templates/AGENTS.md.tmpl +6 -1
  163. package/templates/claude-skill.md.tmpl +5 -0
  164. package/templates/package.json.tmpl +4 -4
  165. package/templates/skills/build-agent/SKILL.md +103 -17
  166. package/templates/skills/build-agent/references/agent-json.md +4 -2
  167. package/templates/skills/build-agent/references/rollout.md +27 -4
  168. package/templates/skills/build-agent/references/set-up-an-integration.md +55 -7
  169. package/templates/skills/build-agent/references/skills.md +20 -1
  170. package/templates/skills/build-agent/references/triggers.md +46 -11
  171. package/templates/skills/build-integration/references/widget-design.md +3 -3
  172. package/templates/skills/ekanos-platform/SKILL.md +43 -16
  173. package/templates/skills/polish-widgets/references/patterns.md +2 -2
@@ -1 +1 @@
1
- {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SOURCE_SKILL_ENTRY_FILE,\n SOURCE_SKILL_LIMITS,\n type SourceSkillFile,\n type SourceSkillPushRequest,\n type SourceSkillPushResult,\n type SourceSkillShow,\n SourceSkillSlugSchema,\n type SourceSkillSummary,\n} from '@ekanos/integration-schema';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport {\n authRequiredError,\n notFoundError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { classifyPath } from '../safe-fs';\nimport {\n type SkillsApiResult,\n listSkills,\n pushSkill,\n showSkill,\n} from '../skills-api';\nimport { resolveSourceTarget } from '../source-target';\nimport { type ResultRow, type Ui, pluralize } from '../ui';\n\nexport const SKILLS_SUBCOMMANDS = ['list', 'show', 'push', 'pull'] as const;\n\ntype SkillsSubcommand = (typeof SKILLS_SUBCOMMANDS)[number];\n\n/** Where an agent directory keeps the skills it uses: `agents/<key>/skills/<slug>/SKILL.md`. */\nexport const AGENT_SKILLS_DIR = 'skills';\n\nexport interface SkillsArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n /** A skill slug, or for `push` a skill folder. */\n target?: string;\n /** A team's slug: that team's own skills instead of the Source's. */\n team?: string;\n /** `pull`: where to write the folder (default `skills/<slug>`). */\n out?: string;\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `skills` — the Source's skills, held by Ekanos in its skill store. A skill\n * is a folder: `SKILL.md` plus any `references/` and `assets/`. `push`\n * stores it as the skill's next version (created on first push, nothing\n * stored when it is unchanged), live for every team at once — or with\n * `--team`, as that one team's own skill. `pull` writes the folder back.\n */\nexport async function runSkills(\n ctx: CliContext,\n args: SkillsArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n\n // Read the folder before any network call, so a bad one fails fast.\n const folder =\n subcommand === 'push'\n ? readSkillFolder(requirePath(args.target), args.dir)\n : null;\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 SkillsClient(env, resolved.session);\n const source = resolved.source;\n const team = args.team?.trim() || undefined;\n\n switch (subcommand) {\n case 'list': {\n const list = await client.call((token) =>\n listSkills(env.host, token, source, team),\n );\n return ctx.succeed(\n { host: env.host, ...list },\n listSummary(ctx.ui, list.skills, team ?? list.source.slug),\n );\n }\n case 'show': {\n const slug = requireSlug(args.target, 'show');\n const shown = await client.call((token) =>\n showSkill(env.host, token, source, slug, team),\n );\n return ctx.succeed(\n {\n host: env.host,\n ...shown,\n // The listing, not every byte: `pull` is for contents.\n files: shown.files.map(({ content: _content, ...file }) => file),\n },\n skillDetail(ctx.ui, shown),\n );\n }\n case 'pull': {\n const slug = requireSlug(args.target, 'pull');\n const shown = await client.call((token) =>\n showSkill(env.host, token, source, slug, team),\n );\n const outDir = path.resolve(\n args.dir,\n args.out ?? path.join(AGENT_SKILLS_DIR, slug),\n );\n const written = writeSkillFolder(outDir, shown.files);\n return ctx.succeed(\n {\n host: env.host,\n slug,\n version: shown.skill.version,\n dir: outDir,\n files: written,\n },\n ctx.ui.result({\n title: `Pulled ${slug}${shown.skill.version ? ` v${shown.skill.version}` : ''}`,\n rows: [\n ['Into', outDir],\n ['Files', shown.files.map((file) => file.path)],\n ],\n notes: [\n `Edit, then \"ekanos skills push ${path.relative(args.dir, outDir) || '.'}${team ? ` --team ${team}` : ''}\".`,\n ],\n }),\n );\n }\n case 'push': {\n const result = await pushSkillFolder(client, env.host, {\n source,\n team,\n folder: folder!,\n });\n return ctx.succeed(\n { host: env.host, ...result },\n pushSummary(ctx.ui, result),\n );\n }\n }\n}\n\n/** Every call refreshes the session once on a 401, then gives up. */\nexport class SkillsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<SkillsApiResult<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 skills call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n}\n\nexport function pushSkillFolder(\n client: SkillsClient,\n host: string,\n input: { source: string; team?: string; folder: SkillFolder },\n): Promise<SourceSkillPushResult> {\n const body: SourceSkillPushRequest = {\n source: input.source,\n ...(input.team ? { team: input.team } : {}),\n slug: input.folder.slug,\n name: input.folder.name,\n description: input.folder.description,\n files: input.folder.files,\n };\n return client.call((token) => pushSkill(host, token, body));\n}\n\nexport interface SkillFolder {\n dir: string;\n slug: string;\n name: string;\n description: string;\n files: SourceSkillFile[];\n}\n\n/** Never sent: VCS and OS litter. */\nconst IGNORED = new Set(['.git', '.DS_Store', 'node_modules', 'Thumbs.db']);\n\n/**\n * Read a skill folder: `SKILL.md` and every other file under it. The slug is\n * the frontmatter `name` when it is slug-shaped (Claude Code's own rule is\n * that it matches the folder), else the folder's name; the description is\n * the frontmatter's, else the first paragraph.\n */\nexport function readSkillFolder(target: string, cwd: string): SkillFolder {\n const dir = path.resolve(cwd, target);\n const entry = path.join(dir, SOURCE_SKILL_ENTRY_FILE);\n if (classifyPath(dir) !== 'directory' || classifyPath(entry) !== 'file') {\n throw notFoundError(\n `No ${SOURCE_SKILL_ENTRY_FILE} in ${dir}.`,\n `A skill is a folder holding ${SOURCE_SKILL_ENTRY_FILE} (plus optional references/ and assets/).`,\n );\n }\n\n const files: SourceSkillFile[] = [];\n let total = 0;\n const walk = (current: string) => {\n for (const name of fs.readdirSync(current).sort()) {\n if (IGNORED.has(name) || name.startsWith('.')) continue;\n const full = path.join(current, name);\n const kind = classifyPath(full);\n if (kind === 'directory' && current === dir && name === 'scripts') {\n throw validationError(\n `${full}: executable skills (scripts/) cannot be pushed from the CLI yet.`,\n 'They need the in-app review flow. Move what the agent must know into SKILL.md or references/.',\n );\n }\n if (kind === 'directory') {\n walk(full);\n continue;\n }\n if (kind !== 'file') continue; // symlinks and devices stay home\n const bytes = fs.readFileSync(full);\n total += bytes.byteLength;\n if (bytes.byteLength > SOURCE_SKILL_LIMITS.fileBytes) {\n throw validationError(\n `${full} is larger than ${SOURCE_SKILL_LIMITS.fileBytes / 1024} KB.`,\n 'Skills hold instructions and small references; keep big data elsewhere.',\n );\n }\n files.push({\n path: path.relative(dir, full).split(path.sep).join('/'),\n ...encodeBytes(bytes),\n });\n }\n };\n walk(dir);\n\n if (files.length > SOURCE_SKILL_LIMITS.files) {\n throw validationError(\n `${dir} holds ${files.length} files; a skill holds at most ${SOURCE_SKILL_LIMITS.files}.`,\n 'Trim the folder and push again.',\n );\n }\n if (total > SOURCE_SKILL_LIMITS.totalBytes) {\n throw validationError(\n `${dir} is larger than ${SOURCE_SKILL_LIMITS.totalBytes / 1024 / 1024} MB.`,\n 'Trim the folder and push again.',\n );\n }\n\n const markdown = fs.readFileSync(entry, 'utf8');\n const { fields, body } = splitFrontmatter(markdown);\n const fromName = SourceSkillSlugSchema.safeParse(fields.name ?? '');\n const fromDir = SourceSkillSlugSchema.safeParse(path.basename(dir));\n const slug = fromName.success\n ? fromName.data\n : fromDir.success\n ? fromDir.data\n : null;\n if (!slug) {\n throw validationError(\n `No usable skill slug for ${dir}.`,\n 'Name the folder (or the frontmatter \"name:\") in lowercase-with-hyphens, e.g. \"refund-policy\".',\n );\n }\n\n const description = clip(\n fields.description?.trim() || firstParagraph(body),\n SOURCE_SKILL_LIMITS.descriptionLength,\n );\n if (!description) {\n throw validationError(\n `${entry} has no description.`,\n 'Add \"description:\" to its frontmatter — it is how an agent decides to load the skill.',\n );\n }\n if (!body.trim()) {\n throw validationError(\n `${entry} has no instructions after its frontmatter.`,\n 'The body of SKILL.md is what the agent reads.',\n );\n }\n\n return {\n dir,\n slug,\n name: clip(fields.name?.trim() || slug, SOURCE_SKILL_LIMITS.nameLength),\n description,\n files,\n };\n}\n\n/** The skill folders beside an agent: `<agentDir>/skills/<slug>/SKILL.md`. */\nexport function findAgentSkillFolders(agentDir: string): string[] {\n const root = path.join(agentDir, AGENT_SKILLS_DIR);\n if (classifyPath(root) !== 'directory') return [];\n return fs\n .readdirSync(root)\n .sort()\n .map((name) => path.join(root, name))\n .filter(\n (dir) =>\n classifyPath(dir) === 'directory' &&\n classifyPath(path.join(dir, SOURCE_SKILL_ENTRY_FILE)) === 'file',\n );\n}\n\nfunction writeSkillFolder(\n outDir: string,\n files: SourceSkillShow['files'],\n): string[] {\n const written: string[] = [];\n for (const file of files) {\n const target = path.resolve(outDir, ...file.path.split('/'));\n if (!target.startsWith(outDir + path.sep)) {\n throw validationError(\n `Refusing to write ${file.path} outside ${outDir}.`,\n 'The host sent a path 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 fs.mkdirSync(path.dirname(target), { recursive: true });\n fs.writeFileSync(\n target,\n Buffer.from(file.content, file.encoding === 'base64' ? 'base64' : 'utf8'),\n );\n written.push(target);\n }\n return written;\n}\n\nfunction encodeBytes(\n bytes: Buffer,\n): Pick<SourceSkillFile, 'encoding' | 'content'> {\n try {\n return {\n encoding: 'utf8',\n content: new TextDecoder('utf-8', { fatal: true }).decode(bytes),\n };\n } catch {\n return { encoding: 'base64', content: bytes.toString('base64') };\n }\n}\n\nconst FRONTMATTER = /^?---[ \\t]*\\r?\\n([\\s\\S]*?)\\r?\\n---[ \\t]*(?:\\r?\\n|$)/;\n\n/** Top-level `key: value` pairs only — `name` and `description` are all that is read. */\nfunction splitFrontmatter(markdown: string): {\n fields: Record<string, string>;\n body: string;\n} {\n const match = markdown.match(FRONTMATTER);\n if (!match) return { fields: {}, body: markdown };\n const fields: Record<string, 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 let value = pair[2]!.trim();\n const continued: string[] = [];\n while (index + 1 < lines.length && /^[ \\t]+\\S/.test(lines[index + 1]!)) {\n continued.push(lines[index + 1]!.trim());\n index += 1;\n }\n if (/^[>|][+-]?$/.test(value)) value = '';\n value = [value, ...continued].filter(Boolean).join(' ');\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n fields[pair[1]!] = value;\n }\n return { fields, body: markdown.slice(match[0].length) };\n}\n\nfunction firstParagraph(body: string): string {\n for (const block of body.split(/\\r?\\n[ \\t]*\\r?\\n/)) {\n const text = block\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(\n (line) => line && !/^(#{1,6}\\s|[-*+]\\s|\\d+\\.\\s|>|\\||```)/.test(line),\n )\n .join(' ');\n if (text) return text;\n }\n return '';\n}\n\nfunction clip(text: string, max: number) {\n return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;\n}\n\nfunction parseSubcommand(value: string | undefined): SkillsSubcommand {\n const match = SKILLS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown skills subcommand \"${value}\".`\n : 'skills needs a subcommand.',\n `Run one of: ${SKILLS_SUBCOMMANDS.map((name) => `ekanos skills ${name}`).join(', ')}.`,\n );\n}\n\nfunction requireSlug(value: string | undefined, verb: string): string {\n const parsed = SourceSkillSlugSchema.safeParse(value ?? '');\n if (parsed.success) return parsed.data;\n throw usageError(\n value\n ? `\"${value}\" is not a skill slug.`\n : `skills ${verb} needs a skill slug.`,\n `Pass the slug, e.g. \"ekanos skills ${verb} refund-policy\". \"ekanos skills list\" shows them.`,\n );\n}\n\nfunction requirePath(value: string | undefined): string {\n if (value) return value;\n throw usageError(\n 'skills push needs a skill folder.',\n `Pass the folder holding ${SOURCE_SKILL_ENTRY_FILE}, e.g. \"ekanos skills push agents/support/skills/refund-policy\".`,\n );\n}\n\nconst LEVEL_LABEL = {\n platform: 'platform (read-only)',\n source: 'every team',\n team: 'team only',\n} as const;\n\nfunction listSummary(\n ui: Ui,\n skills: SourceSkillSummary[],\n where: string,\n): string {\n if (skills.length === 0) {\n return ui.result({\n title: `No skills on ${where} yet`,\n tone: 'warn',\n notes: ['\"ekanos skills push <dir>\" stores the first one.'],\n });\n }\n return [\n ui.result({\n title: `${pluralize(skills.length, 'skill')} on ${where}`,\n rows: skills.map((skill): ResultRow => [\n skill.slug,\n [\n skill.name === skill.slug ? null : skill.name,\n LEVEL_LABEL[skill.level],\n skill.version ? `v${skill.version}` : null,\n skill.fileCount > 1 ? pluralize(skill.fileCount, 'file') : null,\n skill.kind === 'executable' ? 'executable' : null,\n ]\n .filter(Boolean)\n .join(' · '),\n ]),\n }),\n ui.hint('\"ekanos skills show <slug>\" shows one; \"pull\" writes it out.'),\n ].join('\\n\\n');\n}\n\nfunction skillDetail(ui: Ui, shown: SourceSkillShow): string {\n const { skill } = shown;\n return ui.result({\n title: `${skill.name} (${skill.slug})`,\n rows: [\n [\n 'Level',\n skill.team ? `team ${skill.team.slug}` : LEVEL_LABEL[skill.level],\n ],\n ['Description', skill.description],\n ['Version', skill.version ? `v${skill.version}` : 'none published'],\n [\n 'Files',\n shown.files.map(\n (file) => `${file.path} (${formatBytes(file.sizeBytes)})`,\n ),\n ],\n [\n 'History',\n shown.versions.map(\n (version) =>\n `v${version.version}` +\n (version.publishedAt\n ? ` published ${version.publishedAt.slice(0, 10)}`\n : ''),\n ),\n ],\n ],\n });\n}\n\nconst OUTCOME_TITLE = {\n created: 'Created',\n updated: 'Stored a new version of',\n unchanged: 'Unchanged:',\n} as const;\n\nexport function pushSummary(ui: Ui, result: SourceSkillPushResult): string {\n const { skill, changes } = result;\n const rows: ResultRow[] = [\n [\n 'Level',\n skill.team ? `team ${skill.team.slug}` : LEVEL_LABEL[skill.level],\n ],\n ['Version', skill.version ? `v${skill.version}` : 'none'],\n ];\n if (result.outcome === 'created') {\n rows.push(['Files', changes.added]);\n } else {\n if (changes.added.length > 0) rows.push(['Added', changes.added]);\n if (changes.changed.length > 0) rows.push(['Changed', changes.changed]);\n if (changes.removed.length > 0) rows.push(['Removed', changes.removed]);\n if (changes.metadata) rows.push(['Name/description', 'changed']);\n }\n return ui.result({\n title: `${OUTCOME_TITLE[result.outcome]} ${skill.slug}`,\n tone: result.outcome === 'unchanged' ? 'warn' : 'ok',\n rows,\n notes:\n result.outcome === 'unchanged'\n ? ['The folder matches the published version; nothing was stored.']\n : skill.level === 'source'\n ? [\n 'Live now: every agent that names this skill reads the new version.',\n ]\n : [],\n });\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n return `${(bytes / 1024).toFixed(1)} KB`;\n}\n"]}
1
+ {"version":3,"file":"skills.js","sourceRoot":"","sources":["../../src/commands/skills.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n SOURCE_SKILL_ENTRY_FILE,\n SOURCE_SKILL_LIMITS,\n type SourceSkillArchiveResult,\n type SourceSkillFile,\n type SourceSkillPushRequest,\n type SourceSkillPushResult,\n type SourceSkillShow,\n SourceSkillSlugSchema,\n type SourceSkillSummary,\n} from '@ekanos/integration-schema';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport {\n authRequiredError,\n invalidStateError,\n notFoundError,\n usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { writePulledFiles } from '../pull-write';\nimport { classifyPath } from '../safe-fs';\nimport {\n type SkillsApiResult,\n archiveSkill,\n listSkills,\n pushSkill,\n showSkill,\n} from '../skills-api';\nimport { resolveSourceTarget } from '../source-target';\nimport { type ResultRow, type Ui, pluralize } from '../ui';\nimport { promptYesNo } from './publish';\n\nexport const SKILLS_SUBCOMMANDS = [\n 'list',\n 'show',\n 'push',\n 'pull',\n 'archive',\n 'unarchive',\n] as const;\n\ntype SkillsSubcommand = (typeof SKILLS_SUBCOMMANDS)[number];\n\n/** Where an agent directory keeps the skills it uses: `agents/<key>/skills/<slug>/SKILL.md`. */\nexport const AGENT_SKILLS_DIR = 'skills';\n\nexport interface SkillsArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n /** A skill slug, or for `push` a skill folder. */\n target?: string;\n /** A team's slug: that team's own skills instead of the Source's. */\n team?: string;\n /** `pull`: where to write the folder (default `skills/<slug>`). */\n out?: string;\n /** `pull`: overwrite local files that differ from the host's. */\n force?: boolean;\n /** `archive`: confirm without asking. */\n yes?: boolean;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n confirm?: (question: string) => Promise<boolean>;\n}\n\n/**\n * `skills` — the Source's skills, held by Ekanos in its skill store. A skill\n * is a folder: `SKILL.md` plus any `references/` and `assets/`. `push`\n * stores it as the skill's next version (created on first push, nothing\n * stored when it is unchanged), live for every team at once — or with\n * `--team`, as that one team's own skill. `pull` writes the folder back.\n */\nexport async function runSkills(\n ctx: CliContext,\n args: SkillsArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n\n // Read the folder before any network call, so a bad one fails fast.\n const folder =\n subcommand === 'push'\n ? readSkillFolder(requirePath(args.target), args.dir)\n : null;\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const client = new SkillsClient(env, resolved.session);\n const source = resolved.source;\n const team = args.team?.trim() || undefined;\n\n switch (subcommand) {\n case 'list': {\n const list = await client.call((token) =>\n listSkills(env.host, token, source, team),\n );\n return ctx.succeed(\n { host: env.host, ...list },\n listSummary(ctx.ui, list.skills, team ?? list.source.slug),\n );\n }\n case 'show': {\n const slug = requireSlug(args.target, 'show');\n const shown = await client.call((token) =>\n showSkill(env.host, token, source, slug, team),\n );\n return ctx.succeed(\n {\n host: env.host,\n ...shown,\n // The listing, not every byte: `pull` is for contents.\n files: shown.files.map(({ content: _content, ...file }) => file),\n },\n skillDetail(ctx.ui, shown),\n );\n }\n case 'pull': {\n const slug = requireSlug(args.target, 'pull');\n const shown = await client.call((token) =>\n showSkill(env.host, token, source, slug, team),\n );\n const outDir = path.resolve(\n args.dir,\n args.out ?? path.join(AGENT_SKILLS_DIR, slug),\n );\n const written = writePulledFiles({\n projectDir: args.dir,\n outDir,\n files: shown.files.map((file) => ({\n path: file.path,\n contents: Buffer.from(\n file.content,\n file.encoding === 'base64' ? 'base64' : 'utf8',\n ),\n })),\n force: args.force === true,\n rerun: `ekanos skills pull ${slug}${team ? ` --team ${team}` : ''}`,\n });\n return ctx.succeed(\n {\n host: env.host,\n slug,\n version: shown.skill.version,\n dir: outDir,\n files: written,\n },\n ctx.ui.result({\n title: `Pulled ${slug}${shown.skill.version ? ` v${shown.skill.version}` : ''}`,\n rows: [\n ['Into', outDir],\n ['Files', shown.files.map((file) => file.path)],\n ],\n notes: [\n `Edit, then \"ekanos skills push ${path.relative(args.dir, outDir) || '.'}${team ? ` --team ${team}` : ''}\".`,\n ],\n }),\n );\n }\n case 'archive':\n case 'unarchive': {\n const slug = requireSlug(args.target, subcommand);\n if (subcommand === 'archive') {\n await confirmArchive(ctx, args, {\n slug,\n where: team ?? source,\n source,\n team,\n });\n }\n const result = await client.call((token) =>\n archiveSkill(env.host, token, subcommand, { source, slug, team }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n archiveSummary(ctx.ui, result, subcommand, team),\n );\n }\n case 'push': {\n const result = await pushSkillFolder(client, env.host, {\n source,\n team,\n folder: folder!,\n });\n return ctx.succeed(\n { host: env.host, ...result },\n pushSummary(ctx.ui, result),\n );\n }\n }\n}\n\n/**\n * Archiving takes a skill away from every agent that could name it. A human\n * run asks first; a scripted or JSON run needs `--yes`.\n */\nasync function confirmArchive(\n ctx: CliContext,\n args: SkillsArgs,\n target: { slug: string; where: string; source: string; team?: string },\n) {\n if (args.yes) return;\n const canPrompt =\n !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n if (!canPrompt) {\n throw invalidStateError(\n `Archiving ${target.slug} on ${target.where} means no agent can name it, and it cannot be pushed, until it is unarchived.`,\n `Re-run with --yes: ekanos skills archive ${target.slug}${target.team ? ` --team ${target.team}` : ''} --source ${target.source} --yes`,\n );\n }\n const confirmed = await (args.confirm ?? promptYesNo)(\n `Archive ${target.slug} on ${target.where}? No agent can name it until \"ekanos skills unarchive ${target.slug}\". [y/N]`,\n );\n if (!confirmed) {\n throw validationError(\n `Archiving ${target.slug} was not confirmed.`,\n 'Nothing was changed.',\n );\n }\n}\n\nfunction archiveSummary(\n ui: Ui,\n result: SourceSkillArchiveResult,\n action: 'archive' | 'unarchive',\n team: string | undefined,\n): string {\n const { skill } = result;\n const flag = team ? ` --team ${team}` : '';\n if (result.outcome === 'unchanged') {\n return ui.result({\n title: `Unchanged: ${skill.slug} is already ${action === 'archive' ? 'archived' : 'active'}`,\n tone: 'warn',\n });\n }\n return ui.result({\n title: `${result.outcome === 'archived' ? 'Archived' : 'Unarchived'}: ${skill.slug}`,\n rows: skill.version ? [['Version', `v${skill.version}`]] : [],\n notes: [\n result.outcome === 'archived'\n ? `No agent can name it now. \"ekanos skills unarchive ${skill.slug}${flag}\" brings it back.`\n : 'Agents can name it again.',\n ],\n });\n}\n\n/** Every call refreshes the session once on a 401, then gives up. */\nexport class SkillsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<SkillsApiResult<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 skills call.`,\n loginHint(this.env),\n );\n }\n}\n\nexport function pushSkillFolder(\n client: SkillsClient,\n host: string,\n input: { source: string; team?: string; folder: SkillFolder },\n): Promise<SourceSkillPushResult> {\n const body: SourceSkillPushRequest = {\n source: input.source,\n ...(input.team ? { team: input.team } : {}),\n slug: input.folder.slug,\n name: input.folder.name,\n description: input.folder.description,\n files: input.folder.files,\n };\n return client.call((token) => pushSkill(host, token, body));\n}\n\nexport interface SkillFolder {\n dir: string;\n slug: string;\n name: string;\n description: string;\n files: SourceSkillFile[];\n}\n\n/** Never sent: VCS and OS litter. */\nconst IGNORED = new Set(['.git', '.DS_Store', 'node_modules', 'Thumbs.db']);\n\n/**\n * Read a skill folder: `SKILL.md` and every other file under it. The slug is\n * the frontmatter `name` when it is slug-shaped (Claude Code's own rule is\n * that it matches the folder), else the folder's name; the description is\n * the frontmatter's, else the first paragraph.\n */\nexport function readSkillFolder(target: string, cwd: string): SkillFolder {\n const dir = path.resolve(cwd, target);\n const entry = path.join(dir, SOURCE_SKILL_ENTRY_FILE);\n if (classifyPath(dir) !== 'directory' || classifyPath(entry) !== 'file') {\n throw notFoundError(\n `No ${SOURCE_SKILL_ENTRY_FILE} in ${dir}.`,\n `A skill is a folder holding ${SOURCE_SKILL_ENTRY_FILE} (plus optional references/ and assets/).`,\n );\n }\n\n const files: SourceSkillFile[] = [];\n let total = 0;\n const walk = (current: string) => {\n for (const name of fs.readdirSync(current).sort()) {\n if (IGNORED.has(name) || name.startsWith('.')) continue;\n const full = path.join(current, name);\n const kind = classifyPath(full);\n if (kind === 'directory' && current === dir && name === 'scripts') {\n throw validationError(\n `${full}: executable skills (scripts/) cannot be pushed from the CLI yet.`,\n 'They need the in-app review flow. Move what the agent must know into SKILL.md or references/.',\n );\n }\n if (kind === 'directory') {\n walk(full);\n continue;\n }\n if (kind !== 'file') continue; // symlinks and devices stay home\n const bytes = fs.readFileSync(full);\n total += bytes.byteLength;\n if (bytes.byteLength > SOURCE_SKILL_LIMITS.fileBytes) {\n throw validationError(\n `${full} is larger than ${SOURCE_SKILL_LIMITS.fileBytes / 1024} KB.`,\n 'Skills hold instructions and small references; keep big data elsewhere.',\n );\n }\n files.push({\n path: path.relative(dir, full).split(path.sep).join('/'),\n ...encodeBytes(bytes),\n });\n }\n };\n walk(dir);\n\n if (files.length > SOURCE_SKILL_LIMITS.files) {\n throw validationError(\n `${dir} holds ${files.length} files; a skill holds at most ${SOURCE_SKILL_LIMITS.files}.`,\n 'Trim the folder and push again.',\n );\n }\n if (total > SOURCE_SKILL_LIMITS.totalBytes) {\n throw validationError(\n `${dir} is larger than ${SOURCE_SKILL_LIMITS.totalBytes / 1024 / 1024} MB.`,\n 'Trim the folder and push again.',\n );\n }\n\n const markdown = fs.readFileSync(entry, 'utf8');\n const { fields, body } = splitFrontmatter(markdown);\n const fromName = SourceSkillSlugSchema.safeParse(fields.name ?? '');\n const fromDir = SourceSkillSlugSchema.safeParse(path.basename(dir));\n const slug = fromName.success\n ? fromName.data\n : fromDir.success\n ? fromDir.data\n : null;\n if (!slug) {\n throw validationError(\n `No usable skill slug for ${dir}.`,\n 'Name the folder (or the frontmatter \"name:\") in lowercase-with-hyphens, e.g. \"refund-policy\".',\n );\n }\n\n const description = clip(\n fields.description?.trim() || firstParagraph(body),\n SOURCE_SKILL_LIMITS.descriptionLength,\n );\n if (!description) {\n throw validationError(\n `${entry} has no description.`,\n 'Add \"description:\" to its frontmatter — it is how an agent decides to load the skill.',\n );\n }\n if (!body.trim()) {\n throw validationError(\n `${entry} has no instructions after its frontmatter.`,\n 'The body of SKILL.md is what the agent reads.',\n );\n }\n\n return {\n dir,\n slug,\n name: clip(fields.name?.trim() || slug, SOURCE_SKILL_LIMITS.nameLength),\n description,\n files,\n };\n}\n\n/** The skill folders beside an agent: `<agentDir>/skills/<slug>/SKILL.md`. */\nexport function findAgentSkillFolders(agentDir: string): string[] {\n const root = path.join(agentDir, AGENT_SKILLS_DIR);\n if (classifyPath(root) !== 'directory') return [];\n return fs\n .readdirSync(root)\n .sort()\n .map((name) => path.join(root, name))\n .filter(\n (dir) =>\n classifyPath(dir) === 'directory' &&\n classifyPath(path.join(dir, SOURCE_SKILL_ENTRY_FILE)) === 'file',\n );\n}\n\nfunction encodeBytes(\n bytes: Buffer,\n): Pick<SourceSkillFile, 'encoding' | 'content'> {\n try {\n return {\n encoding: 'utf8',\n content: new TextDecoder('utf-8', { fatal: true }).decode(bytes),\n };\n } catch {\n return { encoding: 'base64', content: bytes.toString('base64') };\n }\n}\n\nconst FRONTMATTER = /^?---[ \\t]*\\r?\\n([\\s\\S]*?)\\r?\\n---[ \\t]*(?:\\r?\\n|$)/;\n\n/** Top-level `key: value` pairs only — `name` and `description` are all that is read. */\nfunction splitFrontmatter(markdown: string): {\n fields: Record<string, string>;\n body: string;\n} {\n const match = markdown.match(FRONTMATTER);\n if (!match) return { fields: {}, body: markdown };\n const fields: Record<string, 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 let value = pair[2]!.trim();\n const continued: string[] = [];\n while (index + 1 < lines.length && /^[ \\t]+\\S/.test(lines[index + 1]!)) {\n continued.push(lines[index + 1]!.trim());\n index += 1;\n }\n if (/^[>|][+-]?$/.test(value)) value = '';\n value = [value, ...continued].filter(Boolean).join(' ');\n if (\n value.length >= 2 &&\n ((value.startsWith('\"') && value.endsWith('\"')) ||\n (value.startsWith(\"'\") && value.endsWith(\"'\")))\n ) {\n value = value.slice(1, -1);\n }\n fields[pair[1]!] = value;\n }\n return { fields, body: markdown.slice(match[0].length) };\n}\n\nfunction firstParagraph(body: string): string {\n for (const block of body.split(/\\r?\\n[ \\t]*\\r?\\n/)) {\n const text = block\n .split(/\\r?\\n/)\n .map((line) => line.trim())\n .filter(\n (line) => line && !/^(#{1,6}\\s|[-*+]\\s|\\d+\\.\\s|>|\\||```)/.test(line),\n )\n .join(' ');\n if (text) return text;\n }\n return '';\n}\n\nfunction clip(text: string, max: number) {\n return text.length > max ? `${text.slice(0, max - 1).trimEnd()}…` : text;\n}\n\nfunction parseSubcommand(value: string | undefined): SkillsSubcommand {\n const match = SKILLS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown skills subcommand \"${value}\".`\n : 'skills needs a subcommand.',\n `Run one of: ${SKILLS_SUBCOMMANDS.map((name) => `ekanos skills ${name}`).join(', ')}.`,\n );\n}\n\nfunction requireSlug(value: string | undefined, verb: string): string {\n const parsed = SourceSkillSlugSchema.safeParse(value ?? '');\n if (parsed.success) return parsed.data;\n throw usageError(\n value\n ? `\"${value}\" is not a skill slug.`\n : `skills ${verb} needs a skill slug.`,\n `Pass the slug, e.g. \"ekanos skills ${verb} refund-policy\". \"ekanos skills list\" shows them.`,\n );\n}\n\nfunction requirePath(value: string | undefined): string {\n if (value) return value;\n throw usageError(\n 'skills push needs a skill folder.',\n `Pass the folder holding ${SOURCE_SKILL_ENTRY_FILE}, e.g. \"ekanos skills push agents/support/skills/refund-policy\".`,\n );\n}\n\nconst LEVEL_LABEL = {\n platform: 'platform (read-only)',\n source: 'every team',\n team: 'team only',\n} as const;\n\nfunction listSummary(\n ui: Ui,\n skills: SourceSkillSummary[],\n where: string,\n): string {\n if (skills.length === 0) {\n return ui.result({\n title: `No skills on ${where} yet`,\n tone: 'warn',\n notes: ['\"ekanos skills push <dir>\" stores the first one.'],\n });\n }\n return [\n ui.result({\n title: `${pluralize(skills.length, 'skill')} on ${where}`,\n rows: skills.map((skill): ResultRow => [\n skill.slug,\n [\n skill.name === skill.slug ? null : skill.name,\n LEVEL_LABEL[skill.level],\n skill.version ? `v${skill.version}` : null,\n skill.fileCount > 1 ? pluralize(skill.fileCount, 'file') : null,\n skill.kind === 'executable' ? 'executable' : null,\n ]\n .filter(Boolean)\n .join(' · '),\n ]),\n }),\n ui.hint('\"ekanos skills show <slug>\" shows one; \"pull\" writes it out.'),\n ].join('\\n\\n');\n}\n\nfunction skillDetail(ui: Ui, shown: SourceSkillShow): string {\n const { skill } = shown;\n return ui.result({\n title: `${skill.name} (${skill.slug})`,\n rows: [\n [\n 'Level',\n skill.team ? `team ${skill.team.slug}` : LEVEL_LABEL[skill.level],\n ],\n ['Description', skill.description],\n ['Version', skill.version ? `v${skill.version}` : 'none published'],\n [\n 'Files',\n shown.files.map(\n (file) => `${file.path} (${formatBytes(file.sizeBytes)})`,\n ),\n ],\n [\n 'History',\n shown.versions.map(\n (version) =>\n `v${version.version}` +\n (version.publishedAt\n ? ` published ${version.publishedAt.slice(0, 10)}`\n : ''),\n ),\n ],\n ],\n });\n}\n\nconst OUTCOME_TITLE = {\n created: 'Created',\n updated: 'Stored a new version of',\n unchanged: 'Unchanged:',\n} as const;\n\nexport function pushSummary(ui: Ui, result: SourceSkillPushResult): string {\n const { skill, changes } = result;\n const rows: ResultRow[] = [\n [\n 'Level',\n skill.team ? `team ${skill.team.slug}` : LEVEL_LABEL[skill.level],\n ],\n ['Version', skill.version ? `v${skill.version}` : 'none'],\n ];\n if (result.outcome === 'created') {\n rows.push(['Files', changes.added]);\n } else {\n if (changes.added.length > 0) rows.push(['Added', changes.added]);\n if (changes.changed.length > 0) rows.push(['Changed', changes.changed]);\n if (changes.removed.length > 0) rows.push(['Removed', changes.removed]);\n if (changes.metadata) rows.push(['Name/description', 'changed']);\n }\n return ui.result({\n title: `${OUTCOME_TITLE[result.outcome]} ${skill.slug}`,\n tone: result.outcome === 'unchanged' ? 'warn' : 'ok',\n rows,\n notes:\n result.outcome === 'unchanged'\n ? ['The folder matches the published version; nothing was stored.']\n : skill.level === 'source'\n ? [\n 'Live now: every agent that names this skill reads the new version.',\n ]\n : skill.team && result.outcome === 'created'\n ? [\n `A provided agent reads it once attached, where its template allows team skills: ekanos teams agents skills ${skill.team.slug} <agent-key> add ${skill.slug}`,\n ]\n : [],\n });\n}\n\nfunction formatBytes(bytes: number): string {\n if (bytes < 1024) return `${bytes} B`;\n return `${(bytes / 1024).toFixed(1)} KB`;\n}\n"]}
@@ -2,7 +2,7 @@ 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. */
5
+ /** `products [enable|disable <product>]`, `scopes [add|remove <scope> <product>]`; none lists the sources. */
6
6
  positionals?: readonly string[];
7
7
  source?: string;
8
8
  yes?: boolean;
@@ -1,5 +1,6 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
+ import { loginHint } from '../auth/host-trust.js';
3
4
  import { refreshStoredSession, requireSession, resolveAuthEnvironment, } from '../auth/session.js';
4
5
  import { authRequiredError, invalidStateError, usageError } from '../errors.js';
5
6
  import { EKANOS_CONFIG_FILENAME } from '../project.js';
@@ -7,6 +8,7 @@ import { fetchSeatsWithOneRefresh } from '../seats.js';
7
8
  import { listSourceProducts, setSourceProduct, } from '../source-products-api.js';
8
9
  import { resolveSourceTarget } from '../source-target.js';
9
10
  import { stillUnauthorizedSourceSeats } from '../sources-api.js';
11
+ import { listProductScopes, setScopeProduct } from '../teams-api.js';
10
12
  import { pluralize, shortHost } from '../ui.js';
11
13
  /**
12
14
  * `sources` — list every source the caller holds a developer or admin seat
@@ -20,18 +22,20 @@ export async function runSources(ctx, args) {
20
22
  var _a;
21
23
  const [subcommand, ...rest] = (_a = args.positionals) !== null && _a !== void 0 ? _a : [];
22
24
  if (subcommand !== undefined) {
25
+ if (subcommand === 'scopes')
26
+ return runScopes(ctx, args, rest);
23
27
  if (subcommand !== 'products') {
24
- throw usageError(`Unknown sources subcommand "${subcommand}".`, 'Run "ekanos sources" to list your sources, or "ekanos sources products [enable|disable <product>]".');
28
+ throw usageError(`Unknown sources subcommand "${subcommand}".`, 'Run "ekanos sources" to list your sources, "ekanos sources products [enable|disable <product>]" or "ekanos sources scopes [add|remove <scope> <product>]".');
25
29
  }
26
30
  return runProducts(ctx, args, rest);
27
31
  }
28
32
  const env = resolveAuthEnvironment(ctx, args.host, args.env, {
29
33
  projectDir: args.dir,
30
34
  });
31
- const session = requireSession(env.store, env.host);
35
+ const session = requireSession(env);
32
36
  const result = await fetchSeatsWithOneRefresh(env, session);
33
37
  if (result.status === 'unauthorized') {
34
- stillUnauthorizedSourceSeats(env.host);
38
+ stillUnauthorizedSourceSeats(env);
35
39
  }
36
40
  const activeSource = readActiveSource(args.dir);
37
41
  return ctx.succeed({ host: env.host, sources: result.sources, activeSource }, humanSummary(ctx.ui, env.host, result.sources, activeSource));
@@ -66,13 +70,21 @@ export function readActiveSource(dir) {
66
70
  ? source.trim()
67
71
  : null;
68
72
  }
73
+ /** Why a product is not enabled, by the lever that would enable it — the words `catalog` uses. */
74
+ const NOT_ENABLED_BECAUSE = {
75
+ flag: 'its Flag is off',
76
+ plan: 'no active plan',
77
+ entitlement: 'not granted',
78
+ };
69
79
  function humanSummary(ui, host, sources, activeSource) {
70
80
  if (sources.length === 0) {
71
81
  return ui.result({
72
- title: 'No sources',
82
+ // Read by any signed-in account, a team member's too: no word here
83
+ // may imply the host serves more than one customer.
84
+ title: 'No partner seats',
73
85
  tone: 'warn',
74
86
  rows: [['Host', shortHost(host)]],
75
- notes: ['This account holds no developer seats on this host.'],
87
+ notes: ['This account has no partner seats on this host.'],
76
88
  });
77
89
  }
78
90
  const orphaned = activeSource && !sources.some((s) => s.slug === activeSource);
@@ -98,9 +110,10 @@ function humanSummary(ui, host, sources, activeSource) {
98
110
  * kind (Experience or Integration), and whether it is enabled for the Source.
99
111
  * `enable|disable <product>` switch one through the levers `/admin` uses
100
112
  * (`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.
113
+ * the Experience lever for an Experience). A Source admin switches the
114
+ * integrations their Source built (`owned`); anything else is a super-admin
115
+ * grant, which an `ekanos login` session never carries, so from the terminal
116
+ * that write answers with where to do it.
104
117
  */
105
118
  async function runProducts(ctx, args, rest) {
106
119
  const [verb, rawProduct, ...extra] = rest;
@@ -117,7 +130,10 @@ async function runProducts(ctx, args, rest) {
117
130
  const env = resolveAuthEnvironment(ctx, args.host, args.env, {
118
131
  projectDir: args.dir,
119
132
  });
120
- const resolved = await resolveSourceTarget(env, requireSession(env.store, env.host), { source: args.source, dir: args.dir });
133
+ const resolved = await resolveSourceTarget(env, requireSession(env), {
134
+ source: args.source,
135
+ dir: args.dir,
136
+ });
121
137
  const client = new ProductsClient(env, resolved.session);
122
138
  if (!verb || !product) {
123
139
  const list = await client.call((token) => listSourceProducts(env.host, token, resolved.source));
@@ -125,7 +141,7 @@ async function runProducts(ctx, args, rest) {
125
141
  .filter((entry) => entry.kind === kind)
126
142
  .map((entry) => [
127
143
  entry.slug,
128
- `${entry.enabled ? '✓ enabled' : '✗ off'} · ${entry.name}${entry.registered ? '' : ' · no package on this host'}`,
144
+ `${entry.enabled ? '✓ enabled' : `✗ not enabled (${NOT_ENABLED_BECAUSE[entry.lever]})`} · ${entry.name}${entry.owned ? ' · built by this Source' : ''}${entry.registered ? '' : ' · no package on this host'}`,
129
145
  ]);
130
146
  return ctx.succeed(Object.assign({ host: env.host }, list), [
131
147
  ctx.ui.result({
@@ -138,7 +154,9 @@ async function runProducts(ctx, args, rest) {
138
154
  notes: [
139
155
  list.canEnable
140
156
  ? '"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.',
157
+ : list.canEnableOwned
158
+ ? '"ekanos sources products enable|disable <product>" switches one built by this Source; any other is a super-admin grant, made in the browser at /admin/sources → the Source → Products.'
159
+ : 'Enabling one is a super-admin grant, made in the browser at /admin/sources → the Source → Products.',
142
160
  '"ekanos teams connect <team> <product>" connects an enabled integration for a team.',
143
161
  ],
144
162
  }),
@@ -172,6 +190,102 @@ async function runProducts(ctx, args, rest) {
172
190
  : [],
173
191
  }));
174
192
  }
193
+ /**
194
+ * `sources scopes` — the Source's product scopes, for its Source admin: each
195
+ * scope's products and how many teams hold it. Once a Source has a scope,
196
+ * each team sees in the app only its scopes' products. `add|remove <scope>
197
+ * <product>` changes one scope (by name or id) through what
198
+ * `/admin/sources/[id]/product-scopes` uses; a product can only be added if
199
+ * the Source has it. Taking one out hides it from every team on the scope
200
+ * that no other of its scopes shows it to, so that needs `--yes`.
201
+ */
202
+ async function runScopes(ctx, args, rest) {
203
+ const [verb, rawScope, rawProduct, ...extra] = rest;
204
+ const usage = 'Run "ekanos sources scopes", "ekanos sources scopes add <scope> <product>" or "ekanos sources scopes remove <scope> <product> --yes".';
205
+ if (verb !== undefined && verb !== 'add' && verb !== 'remove') {
206
+ throw usageError(`Unknown sources scopes subcommand "${verb}".`, usage);
207
+ }
208
+ if (extra.length > 0) {
209
+ throw usageError(`Unexpected argument "${extra[0]}".`, usage);
210
+ }
211
+ const scope = rawScope === null || rawScope === void 0 ? void 0 : rawScope.trim();
212
+ if (verb && !scope) {
213
+ throw usageError(`sources scopes ${verb} needs a scope and a product.`, usage);
214
+ }
215
+ const product = verb ? scopeProductSlug(rawProduct, verb) : null;
216
+ if (verb === 'remove' && !args.yes) {
217
+ throw invalidStateError(`Taking ${product} out of ${scope} hides it, in the app, from every team on ${scope} that no other of its scopes shows it to.`, `Re-run with --yes: ekanos sources scopes remove ${quoteArg(scope)} ${product} --yes`);
218
+ }
219
+ const env = resolveAuthEnvironment(ctx, args.host, args.env, {
220
+ projectDir: args.dir,
221
+ });
222
+ const resolved = await resolveSourceTarget(env, requireSession(env), {
223
+ source: args.source,
224
+ dir: args.dir,
225
+ });
226
+ const client = new ProductsClient(env, resolved.session);
227
+ if (!verb || !product || !scope) {
228
+ const list = await client.call((token) => listProductScopes(env.host, token, resolved.source));
229
+ if (list.scopes.length === 0) {
230
+ return ctx.succeed(Object.assign({ host: env.host }, list), ctx.ui.result({
231
+ title: `No product scopes on ${list.source.slug}`,
232
+ rows: [['Teams see', 'every product the Source has']],
233
+ notes: [
234
+ 'Scopes are created at /admin/sources → the Source → Product scopes.',
235
+ ],
236
+ }));
237
+ }
238
+ return ctx.succeed(Object.assign({ host: env.host }, list), ctx.ui.result({
239
+ title: `Product scopes on ${list.source.slug}`,
240
+ rows: list.scopes.map((entry) => [
241
+ entry.name,
242
+ [
243
+ `${pluralize(entry.teamCount, 'team')}${entry.isDefault ? ' · given to every new team' : ''}`,
244
+ entry.products.length > 0
245
+ ? entry.products.map((item) => item.slug).join(', ')
246
+ : 'no products',
247
+ ],
248
+ ]),
249
+ notes: [
250
+ 'A team sees in the app only the products of the scopes it holds.',
251
+ '"ekanos sources scopes add <scope> <product>" shows a product to every team on a scope; "ekanos teams scope show|set <team>" reads or changes which scopes a team holds.',
252
+ ],
253
+ }));
254
+ }
255
+ const included = verb === 'add';
256
+ const result = await client.call((token) => setScopeProduct(env.host, token, { source: resolved.source, scope, product }, included));
257
+ return ctx.succeed(Object.assign({ host: env.host }, result), ctx.ui.result({
258
+ title: result.changed
259
+ ? `${included ? 'Added' : 'Took'} ${result.product.name} ${included ? 'to' : 'out of'} ${result.scope.name}`
260
+ : `${result.product.name} was already ${included ? 'in' : 'not in'} ${result.scope.name}`,
261
+ tone: !included && result.changed ? 'warn' : 'ok',
262
+ rows: [
263
+ ['Teams on it', String(result.scope.teamCount)],
264
+ [
265
+ 'Products',
266
+ result.scope.products.length > 0
267
+ ? result.scope.products.map((item) => item.slug).join(', ')
268
+ : 'none',
269
+ ],
270
+ ],
271
+ notes: [
272
+ included
273
+ ? `Every team on ${result.scope.name} sees ${result.product.slug} in the app now.`
274
+ : `Teams on ${result.scope.name} see ${result.product.slug} only if another of their scopes has it.`,
275
+ ],
276
+ }));
277
+ }
278
+ function scopeProductSlug(value, verb) {
279
+ const slug = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
280
+ if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug))
281
+ return slug;
282
+ throw usageError(value
283
+ ? `"${value}" is not a product slug.`
284
+ : `sources scopes ${verb} needs a product.`, '"ekanos sources products" lists them, e.g. "ekanos sources scopes add Bronze linear".');
285
+ }
286
+ function quoteArg(value) {
287
+ return /^[A-Za-z0-9._-]+$/.test(value) ? value : `"${value}"`;
288
+ }
175
289
  function productSlug(value, verb) {
176
290
  const slug = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
177
291
  if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug))
@@ -193,7 +307,7 @@ class ProductsClient {
193
307
  }
194
308
  if (result.status === 'ok')
195
309
  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.`);
310
+ throw authRequiredError(`The session for ${this.env.host} could not authorize the sources call.`, loginHint(this.env));
197
311
  }
198
312
  }
199
313
  //# 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 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"]}
1
+ {"version":3,"file":"sources.js","sourceRoot":"","sources":["../../src/commands/sources.ts"],"names":[],"mappings":"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","sourcesContent":["import * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport type { StoredSession } from '../auth/credential-store';\nimport { loginHint } from '../auth/host-trust';\nimport {\n type AuthEnvironment,\n refreshStoredSession,\n requireSession,\n resolveAuthEnvironment,\n} from '../auth/session';\nimport type { CliContext } from '../context';\nimport { authRequiredError, invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { EKANOS_CONFIG_FILENAME } from '../project';\nimport { fetchSeatsWithOneRefresh } from '../seats';\nimport {\n type SourceProduct,\n type SourceProductsApiResult,\n listSourceProducts,\n setSourceProduct,\n} from '../source-products-api';\nimport { resolveSourceTarget } from '../source-target';\nimport { type SourceSeat, stillUnauthorizedSourceSeats } from '../sources-api';\nimport { listProductScopes, setScopeProduct } from '../teams-api';\nimport { type Ui, pluralize, shortHost } from '../ui';\n\nexport interface SourcesArgs {\n host?: string;\n /** `products [enable|disable <product>]`, `scopes [add|remove <scope> <product>]`; none lists the sources. */\n positionals?: readonly string[];\n source?: string;\n yes?: boolean;\n /** Where a project's ekanos.json may sit — its `source` field, if any, is the marker. */\n dir: string;\n env: Record<string, string | undefined>;\n}\n\n/**\n * `sources` — list every source the caller holds a developer or admin seat\n * on, the read half of the publish-target-verification story.\n *\n * The list itself is the mechanism that makes `publish` safe: a partner (or\n * an agent acting for one) can always answer \"which sources can I possibly\n * publish to?\" before running `ekanos use` or passing `--source`.\n */\nexport async function runSources(\n ctx: CliContext,\n args: SourcesArgs,\n): Promise<ExitCode> {\n const [subcommand, ...rest] = args.positionals ?? [];\n if (subcommand !== undefined) {\n if (subcommand === 'scopes') return runScopes(ctx, args, rest);\n if (subcommand !== 'products') {\n throw usageError(\n `Unknown sources subcommand \"${subcommand}\".`,\n 'Run \"ekanos sources\" to list your sources, \"ekanos sources products [enable|disable <product>]\" or \"ekanos sources scopes [add|remove <scope> <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);\n\n const result = await fetchSeatsWithOneRefresh(env, session);\n\n if (result.status === 'unauthorized') {\n stillUnauthorizedSourceSeats(env);\n }\n\n const activeSource = readActiveSource(args.dir);\n\n return ctx.succeed(\n { host: env.host, sources: result.sources, activeSource },\n humanSummary(ctx.ui, env.host, result.sources, activeSource),\n );\n}\n\n/**\n * Best-effort, lenient read of ekanos.json's `source` field — mirrors\n * `readProjectHost` in `auth/session.ts`. A missing, unparseable, or\n * sourceless ekanos.json (or no project at all) simply means \"no active\n * source to mark\", never an error: `sources` must answer outside a project\n * too.\n */\nexport function readActiveSource(dir: string): string | null {\n const configPath = path.join(dir, EKANOS_CONFIG_FILENAME);\n\n let raw: string;\n try {\n raw = fs.readFileSync(configPath, 'utf8');\n } catch {\n return null;\n }\n\n let parsed: unknown;\n try {\n parsed = JSON.parse(raw);\n } catch {\n return null;\n }\n\n const source =\n typeof parsed === 'object' && parsed !== null\n ? (parsed as { source?: unknown }).source\n : undefined;\n\n return typeof source === 'string' && source.trim().length > 0\n ? source.trim()\n : null;\n}\n\n/** Why a product is not enabled, by the lever that would enable it — the words `catalog` uses. */\nconst NOT_ENABLED_BECAUSE: Record<SourceProduct['lever'], string> = {\n flag: 'its Flag is off',\n plan: 'no active plan',\n entitlement: 'not granted',\n};\n\nfunction humanSummary(\n ui: Ui,\n host: string,\n sources: SourceSeat[],\n activeSource: string | null,\n): string {\n if (sources.length === 0) {\n return ui.result({\n // Read by any signed-in account, a team member's too: no word here\n // may imply the host serves more than one customer.\n title: 'No partner seats',\n tone: 'warn',\n rows: [['Host', shortHost(host)]],\n notes: ['This account has no partner seats on this host.'],\n });\n }\n\n const orphaned =\n activeSource && !sources.some((s) => s.slug === activeSource);\n\n return ui.result({\n title: `${pluralize(sources.length, 'source')} on ${shortHost(host)}`,\n rows: sources.map((source): [string, string] => [\n source.slug,\n [\n source.name ?? '(unnamed)',\n source.roles.join(', '),\n ...(source.slug === activeSource ? [ui.accent('this project')] : []),\n ].join(' · '),\n ]),\n notes: orphaned\n ? [\n `This project's ekanos.json points at \"${activeSource}\", which is not in the list above.`,\n ]\n : [],\n });\n}\n\n/**\n * `sources products` — the catalog as one Source has it: every product, its\n * kind (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). A Source admin switches the\n * integrations their Source built (`owned`); anything else is a super-admin\n * grant, which an `ekanos login` session never carries, so from the terminal\n * that write answers with where to do it.\n */\nasync function runProducts(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawProduct, ...extra] = rest;\n if (extra.length > 0) {\n throw usageError(\n `Unexpected argument \"${extra[0]}\".`,\n 'Run \"ekanos sources products [enable|disable <product>] [--source <slug>]\".',\n );\n }\n if (verb !== undefined && verb !== 'enable' && verb !== 'disable') {\n throw usageError(\n `Unknown sources products subcommand \"${verb}\".`,\n 'Run \"ekanos sources products\", \"ekanos sources products enable <product>\" or \"ekanos sources products disable <product> --yes\".',\n );\n }\n const product = verb ? productSlug(rawProduct, verb) : null;\n if (verb === 'disable' && !args.yes) {\n throw invalidStateError(\n `Disabling ${product} removes it from the Source: its plans, widget settings, Source credentials and workspaces go with it.`,\n `Re-run with --yes: ekanos sources products disable ${product} --yes`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), {\n source: args.source,\n dir: args.dir,\n });\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product) {\n const list = await client.call((token) =>\n listSourceProducts(env.host, token, resolved.source),\n );\n const 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' : `✗ not enabled (${NOT_ENABLED_BECAUSE[entry.lever]})`} · ${entry.name}${entry.owned ? ' · built by this Source' : ''}${entry.registered ? '' : ' · no package on this host'}`,\n ]);\n return ctx.succeed(\n { host: env.host, ...list },\n [\n ctx.ui.result({\n title: `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 : list.canEnableOwned\n ? '\"ekanos sources products enable|disable <product>\" switches one built by this Source; any other is a super-admin grant, made in the browser at /admin/sources → the Source → Products.'\n : 'Enabling one is a super-admin grant, made in the browser at /admin/sources → the Source → Products.',\n '\"ekanos teams connect <team> <product>\" connects an enabled integration for a team.',\n ],\n }),\n ].join('\\n'),\n );\n }\n\n const enabled = verb === 'enable';\n const result = await client.call((token) =>\n setSourceProduct(env.host, token, {\n source: resolved.source,\n product,\n enabled,\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${enabled ? 'Enabled' : 'Disabled'} ${result.product.name} for ${result.source.slug}`\n : `${result.product.name} was already ${enabled ? 'enabled' : 'off'} for ${result.source.slug}`,\n rows: [\n ['Kind', result.product.kind],\n [\n 'Switched by',\n result.product.lever === 'flag'\n ? 'its Flag'\n : result.product.lever === 'plan'\n ? 'its plan'\n : 'the entitlement',\n ],\n ],\n notes:\n enabled && result.product.kind === 'integration'\n ? [\n `Next: \"ekanos teams connect <team> ${result.product.slug}\" connects it for a team.`,\n ]\n : [],\n }),\n );\n}\n\n/**\n * `sources scopes` — the Source's product scopes, for its Source admin: each\n * scope's products and how many teams hold it. Once a Source has a scope,\n * each team sees in the app only its scopes' products. `add|remove <scope>\n * <product>` changes one scope (by name or id) through what\n * `/admin/sources/[id]/product-scopes` uses; a product can only be added if\n * the Source has it. Taking one out hides it from every team on the scope\n * that no other of its scopes shows it to, so that needs `--yes`.\n */\nasync function runScopes(\n ctx: CliContext,\n args: SourcesArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawScope, rawProduct, ...extra] = rest;\n const usage =\n 'Run \"ekanos sources scopes\", \"ekanos sources scopes add <scope> <product>\" or \"ekanos sources scopes remove <scope> <product> --yes\".';\n if (verb !== undefined && verb !== 'add' && verb !== 'remove') {\n throw usageError(`Unknown sources scopes subcommand \"${verb}\".`, usage);\n }\n if (extra.length > 0) {\n throw usageError(`Unexpected argument \"${extra[0]}\".`, usage);\n }\n const scope = rawScope?.trim();\n if (verb && !scope) {\n throw usageError(\n `sources scopes ${verb} needs a scope and a product.`,\n usage,\n );\n }\n const product = verb ? scopeProductSlug(rawProduct, verb) : null;\n if (verb === 'remove' && !args.yes) {\n throw invalidStateError(\n `Taking ${product} out of ${scope} hides it, in the app, from every team on ${scope} that no other of its scopes shows it to.`,\n `Re-run with --yes: ekanos sources scopes remove ${quoteArg(scope!)} ${product} --yes`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), {\n source: args.source,\n dir: args.dir,\n });\n const client = new ProductsClient(env, resolved.session);\n\n if (!verb || !product || !scope) {\n const list = await client.call((token) =>\n listProductScopes(env.host, token, resolved.source),\n );\n if (list.scopes.length === 0) {\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `No product scopes on ${list.source.slug}`,\n rows: [['Teams see', 'every product the Source has']],\n notes: [\n 'Scopes are created at /admin/sources → the Source → Product scopes.',\n ],\n }),\n );\n }\n return ctx.succeed(\n { host: env.host, ...list },\n ctx.ui.result({\n title: `Product scopes on ${list.source.slug}`,\n rows: list.scopes.map((entry): [string, string[]] => [\n entry.name,\n [\n `${pluralize(entry.teamCount, 'team')}${entry.isDefault ? ' · given to every new team' : ''}`,\n entry.products.length > 0\n ? entry.products.map((item) => item.slug).join(', ')\n : 'no products',\n ],\n ]),\n notes: [\n 'A team sees in the app only the products of the scopes it holds.',\n '\"ekanos sources scopes add <scope> <product>\" shows a product to every team on a scope; \"ekanos teams scope show|set <team>\" reads or changes which scopes a team holds.',\n ],\n }),\n );\n }\n\n const included = verb === 'add';\n const result = await client.call((token) =>\n setScopeProduct(\n env.host,\n token,\n { source: resolved.source, scope, product },\n included,\n ),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n ctx.ui.result({\n title: result.changed\n ? `${included ? 'Added' : 'Took'} ${result.product.name} ${included ? 'to' : 'out of'} ${result.scope.name}`\n : `${result.product.name} was already ${included ? 'in' : 'not in'} ${result.scope.name}`,\n tone: !included && result.changed ? 'warn' : 'ok',\n rows: [\n ['Teams on it', String(result.scope.teamCount)],\n [\n 'Products',\n result.scope.products.length > 0\n ? result.scope.products.map((item) => item.slug).join(', ')\n : 'none',\n ],\n ],\n notes: [\n included\n ? `Every team on ${result.scope.name} sees ${result.product.slug} in the app now.`\n : `Teams on ${result.scope.name} see ${result.product.slug} only if another of their scopes has it.`,\n ],\n }),\n );\n}\n\nfunction scopeProductSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources scopes ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources scopes add Bronze linear\".',\n );\n}\n\nfunction quoteArg(value: string): string {\n return /^[A-Za-z0-9._-]+$/.test(value) ? value : `\"${value}\"`;\n}\n\nfunction productSlug(value: string | undefined, verb: string): string {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value\n ? `\"${value}\" is not a product slug.`\n : `sources products ${verb} needs a product.`,\n '\"ekanos sources products\" lists them, e.g. \"ekanos sources products enable agents\".',\n );\n}\n\nclass ProductsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<SourceProductsApiResult<T>>,\n ): Promise<T> {\n let result = await send(this.session.accessToken);\n if (result.status === 'unauthorized') {\n this.session = await refreshStoredSession(this.env, this.session);\n result = await send(this.session.accessToken);\n }\n if (result.status === 'ok') return result.data;\n throw authRequiredError(\n `The session for ${this.env.host} could not authorize the sources call.`,\n loginHint(this.env),\n );\n }\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import * as fs from 'node:fs';
2
2
  import * as path from 'node:path';
3
+ import { loginHint } from '../auth/host-trust.js';
3
4
  import { refreshStoredSession, resolveAuthEnvironment, resolveIdentity, } from '../auth/session.js';
4
5
  import { CliError, authRequiredError, gateFailedError, preconditionError, } from '../errors.js';
5
6
  import { ERROR_CODES } from '../exit-codes.js';
@@ -85,7 +86,7 @@ export async function runStatus(ctx, args) {
85
86
  ? await probeSession(env, stored)
86
87
  : {
87
88
  authenticated: false,
88
- hint: `Run "ekanos login --host ${env.host}" to sign in.`,
89
+ hint: loginHint(env, 'to sign in.'),
89
90
  };
90
91
  // probeSession may have refreshed the session — persisting a NEW access
91
92
  // token and ROTATING the refresh token on disk. Re-read before using it:
@@ -97,7 +98,7 @@ export async function runStatus(ctx, args) {
97
98
  const project = readProjectReport(args.dir);
98
99
  if (args.watch) {
99
100
  if (!session.authenticated || !live) {
100
- throw authRequiredError(`"ekanos status --watch" needs a live session on ${env.host}.`, `Run "ekanos login --host ${env.host}" and retry.`);
101
+ throw authRequiredError(`"ekanos status --watch" needs a live session on ${env.host}.`, loginHint(env));
101
102
  }
102
103
  if (!project) {
103
104
  throw preconditionError(`No ekanos.json found in ${path.resolve(args.dir)}.`, 'Run "ekanos publish" at least once before watching its gate result.');
@@ -189,7 +190,7 @@ async function runWatch(ctx, env, project, args) {
189
190
  const current = env.store.read(env.host);
190
191
  if (!current) {
191
192
  throw authRequiredError(`The session for ${env.host} is gone — "ekanos status --watch" ` +
192
- 'cannot continue without it.', `Run "ekanos login --host ${env.host}" and retry.`);
193
+ 'cannot continue without it.', loginHint(env));
193
194
  }
194
195
  const integrations = await listWithOneRefresh(env, current, source, 'findings');
195
196
  const version = findVersion(integrations, project.slug, targetVersion);
@@ -296,7 +297,7 @@ async function listWithOneRefresh(env, session, source, detail) {
296
297
  // Authenticated a moment ago, unauthorized twice here: report the list as
297
298
  // unavailable rather than the session as dead — probeSession already proved
298
299
  // it. This is unreachable in practice; belt and braces for a racing revoke.
299
- throw authRequiredError(`The session for ${env.host} could not authorize the submission list.`, `Run "ekanos login --host ${env.host}" and retry.`);
300
+ throw authRequiredError(`The session for ${env.host} could not authorize the submission list.`, loginHint(env));
300
301
  }
301
302
  /**
302
303
  * `whoami`'s seat-lookup degradation, narrowed to one source's role: a