@ekanos/cli 0.10.0 → 0.11.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.
- package/README.md +1 -0
- package/dist/commands/agents-edit.d.ts +49 -0
- package/dist/commands/agents-edit.js +385 -0
- package/dist/commands/agents-edit.js.map +1 -0
- package/dist/commands/agents.d.ts +24 -1
- package/dist/commands/agents.js +117 -8
- package/dist/commands/agents.js.map +1 -1
- package/dist/commands/reviewers.d.ts +21 -0
- package/dist/commands/reviewers.js +162 -0
- package/dist/commands/reviewers.js.map +1 -0
- package/dist/commands/runs.d.ts +42 -0
- package/dist/commands/runs.js +362 -0
- package/dist/commands/runs.js.map +1 -0
- package/dist/commands/skills.d.ts +60 -0
- package/dist/commands/skills.js +397 -0
- package/dist/commands/skills.js.map +1 -0
- package/dist/commands/team-agents-agents.d.ts +9 -0
- package/dist/commands/team-agents-agents.js +188 -0
- package/dist/commands/team-agents-agents.js.map +1 -0
- package/dist/commands/team-agents-mcp.d.ts +4 -0
- package/dist/commands/team-agents-mcp.js +218 -0
- package/dist/commands/team-agents-mcp.js.map +1 -0
- package/dist/commands/team-agents-triggers.d.ts +12 -0
- package/dist/commands/team-agents-triggers.js +251 -0
- package/dist/commands/team-agents-triggers.js.map +1 -0
- package/dist/commands/team-agents.d.ts +31 -0
- package/dist/commands/team-agents.js +71 -0
- package/dist/commands/team-agents.js.map +1 -0
- package/dist/commands/teams-onboard.d.ts +51 -0
- package/dist/commands/teams-onboard.js +261 -0
- package/dist/commands/teams-onboard.js.map +1 -0
- package/dist/commands/teams.d.ts +16 -1
- package/dist/commands/teams.js +22 -3
- package/dist/commands/teams.js.map +1 -1
- package/dist/index.js +197 -5
- package/dist/index.js.map +1 -1
- package/dist/reviewers-api.d.ts +33 -0
- package/dist/reviewers-api.js +81 -0
- package/dist/reviewers-api.js.map +1 -0
- package/dist/runs-api.d.ts +34 -0
- package/dist/runs-api.js +112 -0
- package/dist/runs-api.js.map +1 -0
- package/dist/skills-api.d.ts +28 -0
- package/dist/skills-api.js +104 -0
- package/dist/skills-api.js.map +1 -0
- package/dist/teams-api.d.ts +45 -3
- package/dist/teams-api.js +72 -3
- package/dist/teams-api.js.map +1 -1
- package/package.json +2 -2
- package/templates/package.json.tmpl +4 -4
- package/templates/skills/build-agent/SKILL.md +90 -8
- package/templates/skills/build-agent/references/agent-json.md +78 -2
- package/templates/skills/build-agent/references/rollout.md +9 -1
- package/templates/skills/build-agent/references/set-up-an-integration.md +2 -1
- package/templates/skills/build-agent/references/skills.md +78 -0
- package/templates/skills/build-agent/references/triggers.md +25 -5
- package/templates/skills/ekanos-platform/SKILL.md +108 -3
package/dist/commands/agents.js
CHANGED
|
@@ -18,8 +18,11 @@ import { authRequiredError, notFoundError, usageError, validationError, } from '
|
|
|
18
18
|
import { classifyPath } from '../safe-fs.js';
|
|
19
19
|
import { resolveSourceTarget } from '../source-target.js';
|
|
20
20
|
import { pluralize } from '../ui.js';
|
|
21
|
+
import { areaRows, isTemplateEditSubcommand, runTemplateEdit, } from './agents-edit.js';
|
|
21
22
|
import { runAgentsInit, withDocsHint } from './agents-init.js';
|
|
22
23
|
import { promptYesNo } from './publish.js';
|
|
24
|
+
import { runAgentTest } from './runs.js';
|
|
25
|
+
import { AGENT_SKILLS_DIR, SkillsClient, findAgentSkillFolders, pushSkillFolder, pushSummary, readSkillFolder, } from './skills.js';
|
|
23
26
|
export const AGENTS_SUBCOMMANDS = [
|
|
24
27
|
'init',
|
|
25
28
|
'list',
|
|
@@ -28,6 +31,11 @@ export const AGENTS_SUBCOMMANDS = [
|
|
|
28
31
|
'apply',
|
|
29
32
|
'publish',
|
|
30
33
|
'rollback',
|
|
34
|
+
'test',
|
|
35
|
+
'policy',
|
|
36
|
+
'triggers',
|
|
37
|
+
'links',
|
|
38
|
+
'overrides',
|
|
31
39
|
];
|
|
32
40
|
/** The file `pull` writes and `apply` reads, inside an agent's directory. */
|
|
33
41
|
export const AGENT_FILE = 'agent.json';
|
|
@@ -42,27 +50,95 @@ export const AGENT_INSTRUCTIONS_FILE = 'AGENT.md';
|
|
|
42
50
|
* layout back.
|
|
43
51
|
*/
|
|
44
52
|
export async function runAgents(ctx, args) {
|
|
45
|
-
var _a
|
|
53
|
+
var _a;
|
|
54
|
+
var _b, _c, _d, _e, _f, _g, _h;
|
|
46
55
|
const subcommand = parseSubcommand(args.subcommand);
|
|
56
|
+
if (!isTemplateEditSubcommand(subcommand) && ((_b = (_a = args.rest) === null || _a === void 0 ? void 0 : _a.length) !== null && _b !== void 0 ? _b : 0) > 0) {
|
|
57
|
+
throw usageError(`"agents ${subcommand}" takes at most one argument after the subcommand.`, 'See "ekanos agents --help".');
|
|
58
|
+
}
|
|
47
59
|
// Local only: no host, no session.
|
|
48
60
|
if (subcommand === 'init') {
|
|
49
61
|
return runAgentsInit(ctx, {
|
|
50
|
-
dir: path.resolve(args.dir, (
|
|
62
|
+
dir: path.resolve(args.dir, (_c = args.target) !== null && _c !== void 0 ? _c : '.'),
|
|
51
63
|
force: args.force === true,
|
|
52
64
|
claude: args.claude,
|
|
53
65
|
canPrompt: canPrompt(ctx, args),
|
|
54
|
-
confirm: (
|
|
66
|
+
confirm: (_d = args.confirm) !== null && _d !== void 0 ? _d : promptYesNo,
|
|
67
|
+
env: args.env,
|
|
68
|
+
});
|
|
69
|
+
}
|
|
70
|
+
if (subcommand === 'test') {
|
|
71
|
+
return runAgentTest(ctx, {
|
|
72
|
+
host: args.host,
|
|
73
|
+
source: args.source,
|
|
74
|
+
positionals: [],
|
|
75
|
+
key: args.target,
|
|
76
|
+
team: args.team,
|
|
77
|
+
prompt: args.prompt,
|
|
78
|
+
input: args.input,
|
|
79
|
+
follow: args.follow === true,
|
|
80
|
+
dir: args.dir,
|
|
55
81
|
env: args.env,
|
|
56
82
|
});
|
|
57
83
|
}
|
|
58
84
|
// Read the local input before any network call, so a bad file fails fast.
|
|
59
85
|
const local = subcommand === 'apply' ? readAgentInput(args.target, args.dir) : null;
|
|
86
|
+
const localSkills = (local === null || local === void 0 ? void 0 : local.file) && args.skills !== false
|
|
87
|
+
? findAgentSkillFolders(path.dirname(local.file)).map((dir) => readSkillFolder(dir, args.dir))
|
|
88
|
+
: [];
|
|
89
|
+
if (local && localSkills.length > 0) {
|
|
90
|
+
local.body = withLocalSkills(local.body, localSkills);
|
|
91
|
+
}
|
|
60
92
|
const env = resolveAuthEnvironment(ctx, args.host, args.env, {
|
|
61
93
|
projectDir: args.dir,
|
|
62
94
|
});
|
|
63
95
|
const resolved = await resolveSourceTarget(env, requireSession(env.store, env.host), args);
|
|
64
96
|
const client = new AgentsClient(env, resolved.session);
|
|
65
97
|
const source = resolved.source;
|
|
98
|
+
if (isTemplateEditSubcommand(subcommand)) {
|
|
99
|
+
const key = requireKey(args.target, subcommand);
|
|
100
|
+
return runTemplateEdit(ctx, {
|
|
101
|
+
subcommand,
|
|
102
|
+
key,
|
|
103
|
+
rest: (_e = args.rest) !== null && _e !== void 0 ? _e : [],
|
|
104
|
+
event: args.event,
|
|
105
|
+
filter: args.filter,
|
|
106
|
+
prompt: args.prompt,
|
|
107
|
+
disabled: args.disabled === true,
|
|
108
|
+
cron: args.cron,
|
|
109
|
+
timezone: args.timezone,
|
|
110
|
+
kind: args.kind,
|
|
111
|
+
mode: args.mode,
|
|
112
|
+
reads: args.reads,
|
|
113
|
+
writes: args.writes,
|
|
114
|
+
publish: args.publish === true,
|
|
115
|
+
dir: args.dir,
|
|
116
|
+
}, {
|
|
117
|
+
host: env.host,
|
|
118
|
+
source,
|
|
119
|
+
show: async () => (await client.call((token) => showAgentTemplate(env.host, token, source, key))).template,
|
|
120
|
+
apply: (body, baseVersion) => client.call((token) => applyAgentTemplate(env.host, token, {
|
|
121
|
+
source,
|
|
122
|
+
key,
|
|
123
|
+
body,
|
|
124
|
+
baseVersion,
|
|
125
|
+
overwrite: false,
|
|
126
|
+
})),
|
|
127
|
+
publish: async (version) => {
|
|
128
|
+
await confirmPublish(ctx, args, {
|
|
129
|
+
key,
|
|
130
|
+
source,
|
|
131
|
+
what: `Publish ${key} version ${version}`,
|
|
132
|
+
});
|
|
133
|
+
return client.call((token) => publishAgentTemplate(env.host, token, 'publish', {
|
|
134
|
+
source,
|
|
135
|
+
key,
|
|
136
|
+
version,
|
|
137
|
+
}));
|
|
138
|
+
},
|
|
139
|
+
summarize: (result) => resultSummary(ctx.ui, result),
|
|
140
|
+
});
|
|
141
|
+
}
|
|
66
142
|
switch (subcommand) {
|
|
67
143
|
case 'list': {
|
|
68
144
|
const list = await client.call((token) => listAgentTemplates(env.host, token, source));
|
|
@@ -76,7 +152,7 @@ export async function runAgents(ctx, args) {
|
|
|
76
152
|
case 'pull': {
|
|
77
153
|
const key = requireKey(args.target, 'pull');
|
|
78
154
|
const shown = await client.call((token) => showAgentTemplate(env.host, token, source, key));
|
|
79
|
-
const outDir = path.resolve(args.dir, (
|
|
155
|
+
const outDir = path.resolve(args.dir, (_f = args.out) !== null && _f !== void 0 ? _f : path.join('agents', key));
|
|
80
156
|
const written = writeAgentFiles(outDir, shown.template);
|
|
81
157
|
return ctx.succeed({
|
|
82
158
|
host: env.host,
|
|
@@ -93,7 +169,14 @@ export async function runAgents(ctx, args) {
|
|
|
93
169
|
}
|
|
94
170
|
case 'apply': {
|
|
95
171
|
const input = local;
|
|
96
|
-
const baseVersion = (
|
|
172
|
+
const baseVersion = (_g = parseVersionFlag(args.baseVersion, '--base-version')) !== null && _g !== void 0 ? _g : input.baseVersion;
|
|
173
|
+
// The skills first, so the agent can name them. Source level: a
|
|
174
|
+
// template may only name the Source's skills and the platform's.
|
|
175
|
+
const skillsClient = new SkillsClient(env, resolved.session);
|
|
176
|
+
const pushedSkills = [];
|
|
177
|
+
for (const folder of localSkills) {
|
|
178
|
+
pushedSkills.push(await pushSkillFolder(skillsClient, env.host, { source, folder }));
|
|
179
|
+
}
|
|
97
180
|
const result = await client.call((token) => applyAgentTemplate(env.host, token, {
|
|
98
181
|
source,
|
|
99
182
|
key: input.key,
|
|
@@ -104,12 +187,15 @@ export async function runAgents(ctx, args) {
|
|
|
104
187
|
if (input.file && result.outcome !== 'unchanged') {
|
|
105
188
|
recordBaseVersion(input.file, result.version);
|
|
106
189
|
}
|
|
107
|
-
return ctx.succeed(Object.assign({ host: env.host }, result),
|
|
190
|
+
return ctx.succeed(Object.assign(Object.assign({ host: env.host }, result), { skills: pushedSkills }), [
|
|
191
|
+
...pushedSkills.map((pushed) => pushSummary(ctx.ui, pushed)),
|
|
192
|
+
resultSummary(ctx.ui, result),
|
|
193
|
+
].join('\n\n'));
|
|
108
194
|
}
|
|
109
195
|
case 'publish':
|
|
110
196
|
case 'rollback': {
|
|
111
197
|
const key = requireKey(args.target, subcommand);
|
|
112
|
-
let version = (
|
|
198
|
+
let version = (_h = parseVersionFlag(args.to, '--to')) !== null && _h !== void 0 ? _h : undefined;
|
|
113
199
|
if (subcommand === 'rollback' && version === undefined) {
|
|
114
200
|
throw usageError('rollback needs the version to go back to.', `Pass "--to <n>". "ekanos agents show ${key}" lists them.`);
|
|
115
201
|
}
|
|
@@ -182,6 +268,22 @@ function parseVersionFlag(value, flag) {
|
|
|
182
268
|
return version;
|
|
183
269
|
throw usageError(`${flag} must be a version number (got "${value}").`, `"ekanos agents show <key>" lists the versions.`);
|
|
184
270
|
}
|
|
271
|
+
/**
|
|
272
|
+
* The agent's skills plus the folders beside it, which it uses by being
|
|
273
|
+
* there — a repo migrated as `agents/<key>/skills/<slug>/` need not repeat
|
|
274
|
+
* them in agent.json.
|
|
275
|
+
*/
|
|
276
|
+
function withLocalSkills(body, folders) {
|
|
277
|
+
const skills = [...body.skills];
|
|
278
|
+
for (const folder of folders) {
|
|
279
|
+
if (!skills.includes(folder.slug))
|
|
280
|
+
skills.push(folder.slug);
|
|
281
|
+
}
|
|
282
|
+
if (skills.length > 50) {
|
|
283
|
+
throw validationError(`The agent would name ${skills.length} skills (with its ${AGENT_SKILLS_DIR}/ folders); the limit is 50.`, 'Drop some, or pass --no-skills and list them in agent.json.');
|
|
284
|
+
}
|
|
285
|
+
return Object.assign(Object.assign({}, body), { skills });
|
|
286
|
+
}
|
|
185
287
|
/**
|
|
186
288
|
* Read `apply`'s input: a directory holding `agent.json` (and optionally
|
|
187
289
|
* `AGENT.md`), or a `.json` file. The key is the file's `key`, else the
|
|
@@ -229,7 +331,8 @@ export function readAgentInput(target, cwd) {
|
|
|
229
331
|
`${file} is not a valid agent:`,
|
|
230
332
|
...body.error.issues.map((issue) => ` ${issue.path.join('.') || '(root)'}: ${issue.message}`),
|
|
231
333
|
].join('\n'), `Fields: name, description, instructions (or ${AGENT_INSTRUCTIONS_FILE}), ` +
|
|
232
|
-
`model, maxTurns, tools, policy, skills
|
|
334
|
+
`model, maxTurns, tools, policy, skills, connections, mcpServers, ` +
|
|
335
|
+
`teamCustomization, triggers, links, teamOverrides.`);
|
|
233
336
|
}
|
|
234
337
|
const baseVersion = typeof rawBase === 'number' && Number.isInteger(rawBase) && rawBase >= 1
|
|
235
338
|
? rawBase
|
|
@@ -340,6 +443,12 @@ function templateDetail(ui, template) {
|
|
|
340
443
|
['Skills', body.skills.length > 0 ? body.skills.join(', ') : 'none'],
|
|
341
444
|
['Connections', describeConnections(body)],
|
|
342
445
|
['Teams may add', describeCustomization(body)],
|
|
446
|
+
...areaRows('triggers', body).slice(0, 1),
|
|
447
|
+
...areaRows('links', body).slice(0, 1),
|
|
448
|
+
[
|
|
449
|
+
'Team overrides',
|
|
450
|
+
areaRows('overrides', body).map(([area, value]) => `${area}: ${value}`),
|
|
451
|
+
],
|
|
343
452
|
];
|
|
344
453
|
if (template.teams) {
|
|
345
454
|
rows.push([
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AgentTemplateBody,\n AgentTemplateBodySchema,\n type AgentTemplateDetail,\n AgentTemplateKeySchema,\n type AgentTemplateList,\n type AgentTemplateResult,\n} from '@ekanos/integration-schema';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport {\n type AgentsApiResult,\n applyAgentTemplate,\n listAgentTemplates,\n publishAgentTemplate,\n showAgentTemplate,\n} from '../agents-api';\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 { resolveSourceTarget } from '../source-target';\nimport { type ResultRow, type Ui, pluralize } from '../ui';\nimport { runAgentsInit, withDocsHint } from './agents-init';\nimport { promptYesNo } from './publish';\n\nexport const AGENTS_SUBCOMMANDS = [\n 'init',\n 'list',\n 'show',\n 'pull',\n 'apply',\n 'publish',\n 'rollback',\n] as const;\n\ntype AgentsSubcommand = (typeof AGENTS_SUBCOMMANDS)[number];\n\n/** The file `pull` writes and `apply` reads, inside an agent's directory. */\nexport const AGENT_FILE = 'agent.json';\n/** Instructions as Markdown, beside it. Used when `agent.json` has none. */\nexport const AGENT_INSTRUCTIONS_FILE = 'AGENT.md';\n\nexport interface AgentsArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n /** A template key, or for `apply` a file or directory. */\n target?: string;\n /** `publish` / `rollback`: the version to make the one teams run. */\n to?: string;\n baseVersion?: string;\n overwrite: boolean;\n out?: string;\n yes: boolean;\n /** `init`: replace the skills and CLAUDE.md even when they exist. */\n force?: boolean;\n /** `init`: `--claude` adds the docs to Claude Code without asking; `--no-claude` skips it. */\n claude?: boolean;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n confirm?: (question: string) => Promise<boolean>;\n}\n\n/**\n * `agents` — the Source's agent templates (plan 239.0 / 239.2). Ekanos holds\n * them; nothing here is deployed. `apply` stores a new version (a draft\n * until published), `publish` makes a version the one every team runs,\n * `rollback` publishes an older one. `pull` writes a template out as\n * `agent.json` + `AGENT.md` for review or Git, and `apply` reads the same\n * layout back.\n */\nexport async function runAgents(\n ctx: CliContext,\n args: AgentsArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n\n // Local only: no host, no session.\n if (subcommand === 'init') {\n return runAgentsInit(ctx, {\n dir: path.resolve(args.dir, args.target ?? '.'),\n force: args.force === true,\n claude: args.claude,\n canPrompt: canPrompt(ctx, args),\n confirm: args.confirm ?? promptYesNo,\n env: args.env,\n });\n }\n\n // Read the local input before any network call, so a bad file fails fast.\n const local =\n subcommand === 'apply' ? readAgentInput(args.target, args.dir) : 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 AgentsClient(env, resolved.session);\n const source = resolved.source;\n\n switch (subcommand) {\n case 'list': {\n const list = await client.call((token) =>\n listAgentTemplates(env.host, token, source),\n );\n return ctx.succeed(\n { host: env.host, ...list },\n withDocsHint(ctx.ui, args.dir, listSummary(ctx.ui, list)),\n );\n }\n case 'show': {\n const key = requireKey(args.target, 'show');\n const shown = await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n );\n return ctx.succeed(\n { host: env.host, ...shown },\n templateDetail(ctx.ui, shown.template),\n );\n }\n case 'pull': {\n const key = requireKey(args.target, 'pull');\n const shown = await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n );\n const outDir = path.resolve(\n args.dir,\n args.out ?? path.join('agents', key),\n );\n const written = writeAgentFiles(outDir, shown.template);\n return ctx.succeed(\n {\n host: env.host,\n key,\n version: shown.template.latestVersion,\n files: written,\n },\n ctx.ui.result({\n title: `Pulled ${key} v${shown.template.latestVersion}`,\n rows: written.map((file): ResultRow => ['Wrote', file]),\n notes: [\n `Edit, then \"ekanos agents apply ${path.relative(args.dir, outDir) || '.'}\".`,\n ],\n }),\n );\n }\n case 'apply': {\n const input = local!;\n const baseVersion =\n parseVersionFlag(args.baseVersion, '--base-version') ??\n input.baseVersion;\n const result = await client.call((token) =>\n applyAgentTemplate(env.host, token, {\n source,\n key: input.key,\n body: input.body,\n baseVersion,\n overwrite: args.overwrite,\n }),\n );\n if (input.file && result.outcome !== 'unchanged') {\n recordBaseVersion(input.file, result.version);\n }\n return ctx.succeed(\n { host: env.host, ...result },\n resultSummary(ctx.ui, result),\n );\n }\n case 'publish':\n case 'rollback': {\n const key = requireKey(args.target, subcommand);\n let version = parseVersionFlag(args.to, '--to') ?? undefined;\n if (subcommand === 'rollback' && version === undefined) {\n throw usageError(\n 'rollback needs the version to go back to.',\n `Pass \"--to <n>\". \"ekanos agents show ${key}\" lists them.`,\n );\n }\n // Refuse a script with no --yes before reading anything.\n if (!args.yes && !canPrompt(ctx, args)) {\n throw validationError(\n `${subcommand === 'rollback' ? 'Rolling back' : 'Publishing'} ${key} on ${source} needs confirmation.`,\n 'It reaches every team running this agent at once. Pass --yes to confirm.',\n );\n }\n // Publish names the version it confirmed, never \"whatever is latest\n // when the request lands\" — a draft applied in between is not shipped\n // unseen to every team.\n if (version === undefined) {\n const shown = await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n );\n version = shown.template.latestVersion;\n }\n await confirmPublish(ctx, args, {\n key,\n source,\n what:\n subcommand === 'rollback'\n ? `Roll ${key} back to version ${version}`\n : `Publish ${key} version ${version}`,\n });\n const result = await client.call((token) =>\n publishAgentTemplate(env.host, token, subcommand, {\n source,\n key,\n version,\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n resultSummary(ctx.ui, result),\n );\n }\n }\n}\n\n/** Every call refreshes the session once on a 401, then gives up. */\nclass AgentsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<AgentsApiResult<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 agents call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n}\n\nfunction parseSubcommand(value: string | undefined): AgentsSubcommand {\n const match = AGENTS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown agents subcommand \"${value}\".`\n : 'agents needs a subcommand.',\n `Run one of: ${AGENTS_SUBCOMMANDS.map((name) => `ekanos agents ${name}`).join(', ')}.`,\n );\n}\n\nfunction requireKey(value: string | undefined, verb: string): string {\n const parsed = AgentTemplateKeySchema.safeParse(value ?? '');\n if (parsed.success) return parsed.data;\n throw usageError(\n value\n ? `\"${value}\" is not an agent key.`\n : `agents ${verb} needs an agent key.`,\n `Pass the key, e.g. \"ekanos agents ${verb} support-triage\". ` +\n `\"ekanos agents list\" shows them.`,\n );\n}\n\nfunction parseVersionFlag(\n value: string | undefined,\n flag: string,\n): number | null {\n if (value === undefined) return null;\n const version = Number(value);\n if (Number.isInteger(version) && version >= 1) return version;\n throw usageError(\n `${flag} must be a version number (got \"${value}\").`,\n `\"ekanos agents show <key>\" lists the versions.`,\n );\n}\n\ninterface AgentInput {\n key: string;\n body: AgentTemplateBody;\n baseVersion: number | null;\n /** The agent.json read, when there was one, so the new version is recorded in it. */\n file: string | null;\n}\n\n/**\n * Read `apply`'s input: a directory holding `agent.json` (and optionally\n * `AGENT.md`), or a `.json` file. The key is the file's `key`, else the\n * directory's name. `baseVersion` in the file is the version it was pulled\n * or last applied at — what the host checks for a concurrent change.\n */\nexport function readAgentInput(\n target: string | undefined,\n cwd: string,\n): AgentInput {\n if (!target) {\n throw usageError(\n 'agents apply needs a file or directory.',\n `Pass an agent directory (\"ekanos agents apply agents/support\") or a ` +\n `JSON file. \"ekanos agents pull <key>\" writes the layout.`,\n );\n }\n const resolved = path.resolve(cwd, target);\n const kind = classifyPath(resolved);\n const dir = kind === 'directory' ? resolved : path.dirname(resolved);\n const file =\n kind === 'directory' ? path.join(resolved, AGENT_FILE) : resolved;\n\n if (classifyPath(file) !== 'file') {\n throw notFoundError(\n `No ${kind === 'directory' ? AGENT_FILE : 'file'} at ${file}.`,\n `\"ekanos agents pull <key>\" writes ${AGENT_FILE} and ${AGENT_INSTRUCTIONS_FILE}.`,\n );\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(file, 'utf8'));\n } catch (error) {\n throw validationError(\n `${file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n 'Fix the JSON and apply again.',\n );\n }\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw validationError(\n `${file} must hold a JSON object.`,\n 'See \"ekanos agents --help\".',\n );\n }\n\n const {\n key: rawKey,\n baseVersion: rawBase,\n $schema: _schema,\n ...rest\n } = raw as Record<string, unknown>;\n const fields: Record<string, unknown> = { ...rest };\n\n const instructionsFile = path.join(dir, AGENT_INSTRUCTIONS_FILE);\n if (\n fields.instructions === undefined &&\n classifyPath(instructionsFile) === 'file'\n ) {\n fields.instructions = fs.readFileSync(instructionsFile, 'utf8');\n }\n\n const key = AgentTemplateKeySchema.safeParse(\n typeof rawKey === 'string' ? rawKey : path.basename(dir),\n );\n if (!key.success) {\n throw validationError(\n `No usable agent key: set \"key\" in ${file}, or name the directory after it.`,\n key.error.issues[0]?.message ??\n 'Use lowercase letters, digits and hyphens.',\n );\n }\n\n const body = AgentTemplateBodySchema.safeParse(fields);\n if (!body.success) {\n throw validationError(\n [\n `${file} is not a valid agent:`,\n ...body.error.issues.map(\n (issue) => ` ${issue.path.join('.') || '(root)'}: ${issue.message}`,\n ),\n ].join('\\n'),\n `Fields: name, description, instructions (or ${AGENT_INSTRUCTIONS_FILE}), ` +\n `model, maxTurns, tools, policy, skills.`,\n );\n }\n\n const baseVersion =\n typeof rawBase === 'number' && Number.isInteger(rawBase) && rawBase >= 1\n ? rawBase\n : null;\n\n return { key: key.data, body: body.data, baseVersion, file };\n}\n\n/**\n * Write `agent.json` + `AGENT.md`. The instructions live in the Markdown so\n * they read and diff as prose; the JSON holds everything else plus the\n * version they came from.\n */\nfunction writeAgentFiles(\n outDir: string,\n template: AgentTemplateDetail,\n): string[] {\n fs.mkdirSync(outDir, { recursive: true });\n const { instructions, ...rest } = template.body;\n const json = {\n key: template.key,\n baseVersion: template.latestVersion,\n ...rest,\n };\n const jsonPath = path.join(outDir, AGENT_FILE);\n const mdPath = path.join(outDir, AGENT_INSTRUCTIONS_FILE);\n for (const target of [jsonPath, mdPath]) {\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 }\n fs.writeFileSync(jsonPath, `${JSON.stringify(json, null, 2)}\\n`);\n fs.writeFileSync(\n mdPath,\n instructions.endsWith('\\n') ? instructions : `${instructions}\\n`,\n );\n return [jsonPath, mdPath];\n}\n\n/** After a stored version, point the file at it, so the next apply is based on it. */\nfunction recordBaseVersion(file: string, version: number) {\n const raw = JSON.parse(fs.readFileSync(file, 'utf8')) as Record<\n string,\n unknown\n >;\n if (raw.baseVersion === version) return;\n const { key, baseVersion: _old, ...rest } = raw;\n const next =\n key === undefined\n ? { baseVersion: version, ...rest }\n : { key, baseVersion: version, ...rest };\n fs.writeFileSync(file, `${JSON.stringify(next, null, 2)}\\n`);\n}\n\nfunction canPrompt(ctx: CliContext, args: AgentsArgs): boolean {\n return !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n}\n\n/**\n * Publishing changes what every team running the agent does, at once. A\n * human run asks first; a scripted or JSON run needs `--yes`.\n */\nasync function confirmPublish(\n ctx: CliContext,\n args: AgentsArgs,\n target: { key: string; source: string; what: string },\n) {\n if (args.yes) return;\n if (!canPrompt(ctx, args)) {\n throw validationError(\n `${target.what} on ${target.source} needs confirmation.`,\n 'It reaches every team running this agent at once. Pass --yes to confirm.',\n );\n }\n ctx.log(\n `${target.what} on ${target.source}. Every team running it follows at once.`,\n );\n const confirmed = await (args.confirm ?? promptYesNo)('Proceed? [y/N]');\n if (!confirmed) {\n throw validationError(\n `${target.what} was not confirmed.`,\n 'Nothing was changed.',\n );\n }\n}\n\nfunction versionLabel(template: {\n latestVersion: number;\n publishedVersion: number | null;\n}): string {\n if (template.publishedVersion === null)\n return `v${template.latestVersion} draft, never published`;\n if (template.publishedVersion === template.latestVersion)\n return `v${template.latestVersion} published`;\n return `v${template.publishedVersion} published, v${template.latestVersion} latest`;\n}\n\nfunction listSummary(ui: Ui, list: AgentTemplateList): string {\n if (list.templates.length === 0) {\n return ui.result({\n title: `No agents on ${list.source.slug} yet`,\n tone: 'warn',\n notes: ['\"ekanos agents apply <dir>\" stores the first one.'],\n });\n }\n return [\n ui.result({\n title: `${pluralize(list.templates.length, 'agent')} on ${list.source.slug}`,\n rows: list.templates.map((template): ResultRow => [\n template.key,\n [\n template.name,\n versionLabel(template),\n template.status === 'archived' ? 'archived' : null,\n template.teams\n ? `${pluralize(template.teams.enabled, 'team')}`\n : null,\n ]\n .filter(Boolean)\n .join(' · '),\n ]),\n }),\n ui.hint('\"ekanos agents show <key>\" shows one, with its versions.'),\n ].join('\\n\\n');\n}\n\nfunction templateDetail(ui: Ui, template: AgentTemplateDetail): string {\n const { body } = template;\n const rows: ResultRow[] = [\n ['Versions', versionLabel(template)],\n ['Model', body.model ?? 'house default'],\n ['Tools', describeTools(body)],\n [\n 'Approval',\n `reads ${body.policy.reads}, writes ${body.policy.writes}` +\n (Object.keys(body.policy.overrides).length > 0\n ? `, ${pluralize(Object.keys(body.policy.overrides).length, 'override')}`\n : ''),\n ],\n ['Skills', body.skills.length > 0 ? body.skills.join(', ') : 'none'],\n ['Connections', describeConnections(body)],\n ['Teams may add', describeCustomization(body)],\n ];\n if (template.teams) {\n rows.push([\n 'Teams',\n `${template.teams.enabled} running` +\n (template.teams.pinned > 0\n ? `, ${template.teams.pinned} pinned to an older version`\n : ''),\n ]);\n }\n rows.push([\n 'History',\n template.versions.map(\n (version) =>\n `v${version.version} ${version.createdAt.slice(0, 10)}` +\n (version.createdBy ? ` by ${version.createdBy}` : '') +\n (version.publishedAt\n ? ` · published ${version.publishedAt.slice(0, 10)}`\n : ''),\n ),\n ]);\n return ui.result({ title: `${body.name} (${template.key})`, rows });\n}\n\nfunction describeConnections(body: AgentTemplateBody): string[] {\n const owner = (connection: AgentTemplateBody['connections'][string]) =>\n connection.owner === 'source'\n ? 'one connection for the source'\n : `each team's own (${connection.team})`;\n const lines = [\n ...Object.entries(body.connections).map(\n ([slug, connection]) => `${slug}: ${owner(connection)}`,\n ),\n ...body.mcpServers.map(\n (server) => `${server.key} (MCP, ${server.url}): ${owner(server)}`,\n ),\n ];\n return lines.length > 0 ? lines : [\"each team's own (optional)\"];\n}\n\nfunction describeCustomization(body: AgentTemplateBody): string {\n const allowed = Object.entries(body.teamCustomization)\n .filter(([, on]) => on)\n .map(([knob]) => CUSTOMIZATION_LABEL[knob] ?? knob);\n return allowed.length > 0 ? allowed.join(', ') : 'nothing (template only)';\n}\n\nconst CUSTOMIZATION_LABEL: Record<string, string> = {\n mcpServers: 'own MCP servers',\n skills: 'own skills',\n integrations: 'more integrations',\n narrow: 'narrower tools',\n};\n\nfunction describeTools(body: AgentTemplateBody): string {\n if (body.tools.mode === 'read_only')\n return 'every read the team has connected';\n if (body.tools.mode === 'all') return 'every tool the team has connected';\n return (\n [...(body.tools.products ?? []), ...(body.tools.tools ?? [])].join(', ') ||\n 'none'\n );\n}\n\nconst OUTCOME_TITLE = {\n created: 'Created',\n updated: 'Stored a new version',\n unchanged: 'Unchanged',\n published: 'Published',\n 'rolled-back': 'Rolled back',\n} as const;\n\nfunction resultSummary(ui: Ui, result: AgentTemplateResult): string {\n const { template } = result;\n const rows: ResultRow[] = [['Versions', versionLabel(template)]];\n if (result.outcome === 'published' || result.outcome === 'rolled-back') {\n rows.push(['Teams updated', String(result.teamsUpdated)]);\n }\n const notes =\n (result.outcome === 'created' || result.outcome === 'updated') &&\n template.publishedVersion !== template.latestVersion\n ? [\n `Teams still run the published version. \"ekanos agents publish ${template.key}\" moves them.`,\n ]\n : [];\n return ui.result({\n title: `${OUTCOME_TITLE[result.outcome]}: ${template.key}`,\n tone: result.outcome === 'unchanged' ? 'warn' : 'ok',\n rows,\n notes,\n });\n}\n"]}
|
|
1
|
+
{"version":3,"file":"agents.js","sourceRoot":"","sources":["../../src/commands/agents.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n type AgentTemplateBody,\n AgentTemplateBodySchema,\n type AgentTemplateDetail,\n AgentTemplateKeySchema,\n type AgentTemplateList,\n type AgentTemplateResult,\n} from '@ekanos/integration-schema';\nimport * as fs from 'node:fs';\nimport * as path from 'node:path';\n\nimport {\n type AgentsApiResult,\n applyAgentTemplate,\n listAgentTemplates,\n publishAgentTemplate,\n showAgentTemplate,\n} from '../agents-api';\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 { resolveSourceTarget } from '../source-target';\nimport { type ResultRow, type Ui, pluralize } from '../ui';\nimport {\n areaRows,\n isTemplateEditSubcommand,\n runTemplateEdit,\n} from './agents-edit';\nimport { runAgentsInit, withDocsHint } from './agents-init';\nimport { promptYesNo } from './publish';\nimport { runAgentTest } from './runs';\nimport {\n AGENT_SKILLS_DIR,\n type SkillFolder,\n SkillsClient,\n findAgentSkillFolders,\n pushSkillFolder,\n pushSummary,\n readSkillFolder,\n} from './skills';\n\nexport const AGENTS_SUBCOMMANDS = [\n 'init',\n 'list',\n 'show',\n 'pull',\n 'apply',\n 'publish',\n 'rollback',\n 'test',\n 'policy',\n 'triggers',\n 'links',\n 'overrides',\n] as const;\n\ntype AgentsSubcommand = (typeof AGENTS_SUBCOMMANDS)[number];\n\n/** The file `pull` writes and `apply` reads, inside an agent's directory. */\nexport const AGENT_FILE = 'agent.json';\n/** Instructions as Markdown, beside it. Used when `agent.json` has none. */\nexport const AGENT_INSTRUCTIONS_FILE = 'AGENT.md';\n\nexport interface AgentsArgs {\n host?: string;\n source?: string;\n subcommand?: string;\n /** A template key, or for `apply` a file or directory. */\n target?: string;\n /** `publish` / `rollback`: the version to make the one teams run. */\n to?: string;\n baseVersion?: string;\n overwrite: boolean;\n out?: string;\n yes: boolean;\n /** `init`: replace the skills and CLAUDE.md even when they exist. */\n force?: boolean;\n /**\n * `apply`: push the skill folders beside the agent (`<dir>/skills/<slug>/`)\n * first, and name them in its skills. On unless `--no-skills`.\n */\n skills?: boolean;\n /** `init`: `--claude` adds the docs to Claude Code without asking; `--no-claude` skips it. */\n claude?: boolean;\n /** `policy | triggers | links | overrides`: positionals after the key. */\n rest?: string[];\n event?: string;\n filter?: string[];\n disabled?: boolean;\n cron?: string;\n timezone?: string;\n kind?: string;\n mode?: string;\n reads?: string;\n writes?: string;\n /** `policy | triggers | links | overrides`: publish the stored version right away. */\n publish?: boolean;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n confirm?: (question: string) => Promise<boolean>;\n /** `test`: the team to run the draft on, and what to give it. Also a trigger's prompt. */\n team?: string;\n prompt?: string;\n input?: string;\n follow?: boolean;\n}\n\n/**\n * `agents` — the Source's agent templates (plan 239.0 / 239.2). Ekanos holds\n * them; nothing here is deployed. `apply` stores a new version (a draft\n * until published), `publish` makes a version the one every team runs,\n * `rollback` publishes an older one. `pull` writes a template out as\n * `agent.json` + `AGENT.md` for review or Git, and `apply` reads the same\n * layout back.\n */\nexport async function runAgents(\n ctx: CliContext,\n args: AgentsArgs,\n): Promise<ExitCode> {\n const subcommand = parseSubcommand(args.subcommand);\n if (!isTemplateEditSubcommand(subcommand) && (args.rest?.length ?? 0) > 0) {\n throw usageError(\n `\"agents ${subcommand}\" takes at most one argument after the subcommand.`,\n 'See \"ekanos agents --help\".',\n );\n }\n\n // Local only: no host, no session.\n if (subcommand === 'init') {\n return runAgentsInit(ctx, {\n dir: path.resolve(args.dir, args.target ?? '.'),\n force: args.force === true,\n claude: args.claude,\n canPrompt: canPrompt(ctx, args),\n confirm: args.confirm ?? promptYesNo,\n env: args.env,\n });\n }\n\n if (subcommand === 'test') {\n return runAgentTest(ctx, {\n host: args.host,\n source: args.source,\n positionals: [],\n key: args.target,\n team: args.team,\n prompt: args.prompt,\n input: args.input,\n follow: args.follow === true,\n dir: args.dir,\n env: args.env,\n });\n }\n\n // Read the local input before any network call, so a bad file fails fast.\n const local =\n subcommand === 'apply' ? readAgentInput(args.target, args.dir) : null;\n const localSkills =\n local?.file && args.skills !== false\n ? findAgentSkillFolders(path.dirname(local.file)).map((dir) =>\n readSkillFolder(dir, args.dir),\n )\n : [];\n if (local && localSkills.length > 0) {\n local.body = withLocalSkills(local.body, localSkills);\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 AgentsClient(env, resolved.session);\n const source = resolved.source;\n\n if (isTemplateEditSubcommand(subcommand)) {\n const key = requireKey(args.target, subcommand);\n return runTemplateEdit(\n ctx,\n {\n subcommand,\n key,\n rest: args.rest ?? [],\n event: args.event,\n filter: args.filter,\n prompt: args.prompt,\n disabled: args.disabled === true,\n cron: args.cron,\n timezone: args.timezone,\n kind: args.kind,\n mode: args.mode,\n reads: args.reads,\n writes: args.writes,\n publish: args.publish === true,\n dir: args.dir,\n },\n {\n host: env.host,\n source,\n show: async () =>\n (\n await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n )\n ).template,\n apply: (body, baseVersion) =>\n client.call((token) =>\n applyAgentTemplate(env.host, token, {\n source,\n key,\n body,\n baseVersion,\n overwrite: false,\n }),\n ),\n publish: async (version) => {\n await confirmPublish(ctx, args, {\n key,\n source,\n what: `Publish ${key} version ${version}`,\n });\n return client.call((token) =>\n publishAgentTemplate(env.host, token, 'publish', {\n source,\n key,\n version,\n }),\n );\n },\n summarize: (result) => resultSummary(ctx.ui, result),\n },\n );\n }\n\n switch (subcommand) {\n case 'list': {\n const list = await client.call((token) =>\n listAgentTemplates(env.host, token, source),\n );\n return ctx.succeed(\n { host: env.host, ...list },\n withDocsHint(ctx.ui, args.dir, listSummary(ctx.ui, list)),\n );\n }\n case 'show': {\n const key = requireKey(args.target, 'show');\n const shown = await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n );\n return ctx.succeed(\n { host: env.host, ...shown },\n templateDetail(ctx.ui, shown.template),\n );\n }\n case 'pull': {\n const key = requireKey(args.target, 'pull');\n const shown = await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n );\n const outDir = path.resolve(\n args.dir,\n args.out ?? path.join('agents', key),\n );\n const written = writeAgentFiles(outDir, shown.template);\n return ctx.succeed(\n {\n host: env.host,\n key,\n version: shown.template.latestVersion,\n files: written,\n },\n ctx.ui.result({\n title: `Pulled ${key} v${shown.template.latestVersion}`,\n rows: written.map((file): ResultRow => ['Wrote', file]),\n notes: [\n `Edit, then \"ekanos agents apply ${path.relative(args.dir, outDir) || '.'}\".`,\n ],\n }),\n );\n }\n case 'apply': {\n const input = local!;\n const baseVersion =\n parseVersionFlag(args.baseVersion, '--base-version') ??\n input.baseVersion;\n // The skills first, so the agent can name them. Source level: a\n // template may only name the Source's skills and the platform's.\n const skillsClient = new SkillsClient(env, resolved.session);\n const pushedSkills: Awaited<ReturnType<typeof pushSkillFolder>>[] = [];\n for (const folder of localSkills) {\n pushedSkills.push(\n await pushSkillFolder(skillsClient, env.host, { source, folder }),\n );\n }\n const result = await client.call((token) =>\n applyAgentTemplate(env.host, token, {\n source,\n key: input.key,\n body: input.body,\n baseVersion,\n overwrite: args.overwrite,\n }),\n );\n if (input.file && result.outcome !== 'unchanged') {\n recordBaseVersion(input.file, result.version);\n }\n return ctx.succeed(\n { host: env.host, ...result, skills: pushedSkills },\n [\n ...pushedSkills.map((pushed) => pushSummary(ctx.ui, pushed)),\n resultSummary(ctx.ui, result),\n ].join('\\n\\n'),\n );\n }\n case 'publish':\n case 'rollback': {\n const key = requireKey(args.target, subcommand);\n let version = parseVersionFlag(args.to, '--to') ?? undefined;\n if (subcommand === 'rollback' && version === undefined) {\n throw usageError(\n 'rollback needs the version to go back to.',\n `Pass \"--to <n>\". \"ekanos agents show ${key}\" lists them.`,\n );\n }\n // Refuse a script with no --yes before reading anything.\n if (!args.yes && !canPrompt(ctx, args)) {\n throw validationError(\n `${subcommand === 'rollback' ? 'Rolling back' : 'Publishing'} ${key} on ${source} needs confirmation.`,\n 'It reaches every team running this agent at once. Pass --yes to confirm.',\n );\n }\n // Publish names the version it confirmed, never \"whatever is latest\n // when the request lands\" — a draft applied in between is not shipped\n // unseen to every team.\n if (version === undefined) {\n const shown = await client.call((token) =>\n showAgentTemplate(env.host, token, source, key),\n );\n version = shown.template.latestVersion;\n }\n await confirmPublish(ctx, args, {\n key,\n source,\n what:\n subcommand === 'rollback'\n ? `Roll ${key} back to version ${version}`\n : `Publish ${key} version ${version}`,\n });\n const result = await client.call((token) =>\n publishAgentTemplate(env.host, token, subcommand, {\n source,\n key,\n version,\n }),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n resultSummary(ctx.ui, result),\n );\n }\n }\n}\n\n/** Every call refreshes the session once on a 401, then gives up. */\nclass AgentsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<AgentsApiResult<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 agents call.`,\n `Run \"ekanos login --host ${this.env.host}\" and retry.`,\n );\n }\n}\n\nfunction parseSubcommand(value: string | undefined): AgentsSubcommand {\n const match = AGENTS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown agents subcommand \"${value}\".`\n : 'agents needs a subcommand.',\n `Run one of: ${AGENTS_SUBCOMMANDS.map((name) => `ekanos agents ${name}`).join(', ')}.`,\n );\n}\n\nfunction requireKey(value: string | undefined, verb: string): string {\n const parsed = AgentTemplateKeySchema.safeParse(value ?? '');\n if (parsed.success) return parsed.data;\n throw usageError(\n value\n ? `\"${value}\" is not an agent key.`\n : `agents ${verb} needs an agent key.`,\n `Pass the key, e.g. \"ekanos agents ${verb} support-triage\". ` +\n `\"ekanos agents list\" shows them.`,\n );\n}\n\nfunction parseVersionFlag(\n value: string | undefined,\n flag: string,\n): number | null {\n if (value === undefined) return null;\n const version = Number(value);\n if (Number.isInteger(version) && version >= 1) return version;\n throw usageError(\n `${flag} must be a version number (got \"${value}\").`,\n `\"ekanos agents show <key>\" lists the versions.`,\n );\n}\n\n/**\n * The agent's skills plus the folders beside it, which it uses by being\n * there — a repo migrated as `agents/<key>/skills/<slug>/` need not repeat\n * them in agent.json.\n */\nfunction withLocalSkills(\n body: AgentTemplateBody,\n folders: SkillFolder[],\n): AgentTemplateBody {\n const skills = [...body.skills];\n for (const folder of folders) {\n if (!skills.includes(folder.slug)) skills.push(folder.slug);\n }\n if (skills.length > 50) {\n throw validationError(\n `The agent would name ${skills.length} skills (with its ${AGENT_SKILLS_DIR}/ folders); the limit is 50.`,\n 'Drop some, or pass --no-skills and list them in agent.json.',\n );\n }\n return { ...body, skills };\n}\n\ninterface AgentInput {\n key: string;\n body: AgentTemplateBody;\n baseVersion: number | null;\n /** The agent.json read, when there was one, so the new version is recorded in it. */\n file: string | null;\n}\n\n/**\n * Read `apply`'s input: a directory holding `agent.json` (and optionally\n * `AGENT.md`), or a `.json` file. The key is the file's `key`, else the\n * directory's name. `baseVersion` in the file is the version it was pulled\n * or last applied at — what the host checks for a concurrent change.\n */\nexport function readAgentInput(\n target: string | undefined,\n cwd: string,\n): AgentInput {\n if (!target) {\n throw usageError(\n 'agents apply needs a file or directory.',\n `Pass an agent directory (\"ekanos agents apply agents/support\") or a ` +\n `JSON file. \"ekanos agents pull <key>\" writes the layout.`,\n );\n }\n const resolved = path.resolve(cwd, target);\n const kind = classifyPath(resolved);\n const dir = kind === 'directory' ? resolved : path.dirname(resolved);\n const file =\n kind === 'directory' ? path.join(resolved, AGENT_FILE) : resolved;\n\n if (classifyPath(file) !== 'file') {\n throw notFoundError(\n `No ${kind === 'directory' ? AGENT_FILE : 'file'} at ${file}.`,\n `\"ekanos agents pull <key>\" writes ${AGENT_FILE} and ${AGENT_INSTRUCTIONS_FILE}.`,\n );\n }\n\n let raw: unknown;\n try {\n raw = JSON.parse(fs.readFileSync(file, 'utf8'));\n } catch (error) {\n throw validationError(\n `${file} is not valid JSON: ${error instanceof Error ? error.message : String(error)}`,\n 'Fix the JSON and apply again.',\n );\n }\n if (typeof raw !== 'object' || raw === null || Array.isArray(raw)) {\n throw validationError(\n `${file} must hold a JSON object.`,\n 'See \"ekanos agents --help\".',\n );\n }\n\n const {\n key: rawKey,\n baseVersion: rawBase,\n $schema: _schema,\n ...rest\n } = raw as Record<string, unknown>;\n const fields: Record<string, unknown> = { ...rest };\n\n const instructionsFile = path.join(dir, AGENT_INSTRUCTIONS_FILE);\n if (\n fields.instructions === undefined &&\n classifyPath(instructionsFile) === 'file'\n ) {\n fields.instructions = fs.readFileSync(instructionsFile, 'utf8');\n }\n\n const key = AgentTemplateKeySchema.safeParse(\n typeof rawKey === 'string' ? rawKey : path.basename(dir),\n );\n if (!key.success) {\n throw validationError(\n `No usable agent key: set \"key\" in ${file}, or name the directory after it.`,\n key.error.issues[0]?.message ??\n 'Use lowercase letters, digits and hyphens.',\n );\n }\n\n const body = AgentTemplateBodySchema.safeParse(fields);\n if (!body.success) {\n throw validationError(\n [\n `${file} is not a valid agent:`,\n ...body.error.issues.map(\n (issue) => ` ${issue.path.join('.') || '(root)'}: ${issue.message}`,\n ),\n ].join('\\n'),\n `Fields: name, description, instructions (or ${AGENT_INSTRUCTIONS_FILE}), ` +\n `model, maxTurns, tools, policy, skills, connections, mcpServers, ` +\n `teamCustomization, triggers, links, teamOverrides.`,\n );\n }\n\n const baseVersion =\n typeof rawBase === 'number' && Number.isInteger(rawBase) && rawBase >= 1\n ? rawBase\n : null;\n\n return { key: key.data, body: body.data, baseVersion, file };\n}\n\n/**\n * Write `agent.json` + `AGENT.md`. The instructions live in the Markdown so\n * they read and diff as prose; the JSON holds everything else plus the\n * version they came from.\n */\nfunction writeAgentFiles(\n outDir: string,\n template: AgentTemplateDetail,\n): string[] {\n fs.mkdirSync(outDir, { recursive: true });\n const { instructions, ...rest } = template.body;\n const json = {\n key: template.key,\n baseVersion: template.latestVersion,\n ...rest,\n };\n const jsonPath = path.join(outDir, AGENT_FILE);\n const mdPath = path.join(outDir, AGENT_INSTRUCTIONS_FILE);\n for (const target of [jsonPath, mdPath]) {\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 }\n fs.writeFileSync(jsonPath, `${JSON.stringify(json, null, 2)}\\n`);\n fs.writeFileSync(\n mdPath,\n instructions.endsWith('\\n') ? instructions : `${instructions}\\n`,\n );\n return [jsonPath, mdPath];\n}\n\n/** After a stored version, point the file at it, so the next apply is based on it. */\nfunction recordBaseVersion(file: string, version: number) {\n const raw = JSON.parse(fs.readFileSync(file, 'utf8')) as Record<\n string,\n unknown\n >;\n if (raw.baseVersion === version) return;\n const { key, baseVersion: _old, ...rest } = raw;\n const next =\n key === undefined\n ? { baseVersion: version, ...rest }\n : { key, baseVersion: version, ...rest };\n fs.writeFileSync(file, `${JSON.stringify(next, null, 2)}\\n`);\n}\n\nfunction canPrompt(ctx: CliContext, args: AgentsArgs): boolean {\n return !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n}\n\n/**\n * Publishing changes what every team running the agent does, at once. A\n * human run asks first; a scripted or JSON run needs `--yes`.\n */\nasync function confirmPublish(\n ctx: CliContext,\n args: AgentsArgs,\n target: { key: string; source: string; what: string },\n) {\n if (args.yes) return;\n if (!canPrompt(ctx, args)) {\n throw validationError(\n `${target.what} on ${target.source} needs confirmation.`,\n 'It reaches every team running this agent at once. Pass --yes to confirm.',\n );\n }\n ctx.log(\n `${target.what} on ${target.source}. Every team running it follows at once.`,\n );\n const confirmed = await (args.confirm ?? promptYesNo)('Proceed? [y/N]');\n if (!confirmed) {\n throw validationError(\n `${target.what} was not confirmed.`,\n 'Nothing was changed.',\n );\n }\n}\n\nfunction versionLabel(template: {\n latestVersion: number;\n publishedVersion: number | null;\n}): string {\n if (template.publishedVersion === null)\n return `v${template.latestVersion} draft, never published`;\n if (template.publishedVersion === template.latestVersion)\n return `v${template.latestVersion} published`;\n return `v${template.publishedVersion} published, v${template.latestVersion} latest`;\n}\n\nfunction listSummary(ui: Ui, list: AgentTemplateList): string {\n if (list.templates.length === 0) {\n return ui.result({\n title: `No agents on ${list.source.slug} yet`,\n tone: 'warn',\n notes: ['\"ekanos agents apply <dir>\" stores the first one.'],\n });\n }\n return [\n ui.result({\n title: `${pluralize(list.templates.length, 'agent')} on ${list.source.slug}`,\n rows: list.templates.map((template): ResultRow => [\n template.key,\n [\n template.name,\n versionLabel(template),\n template.status === 'archived' ? 'archived' : null,\n template.teams\n ? `${pluralize(template.teams.enabled, 'team')}`\n : null,\n ]\n .filter(Boolean)\n .join(' · '),\n ]),\n }),\n ui.hint('\"ekanos agents show <key>\" shows one, with its versions.'),\n ].join('\\n\\n');\n}\n\nfunction templateDetail(ui: Ui, template: AgentTemplateDetail): string {\n const { body } = template;\n const rows: ResultRow[] = [\n ['Versions', versionLabel(template)],\n ['Model', body.model ?? 'house default'],\n ['Tools', describeTools(body)],\n [\n 'Approval',\n `reads ${body.policy.reads}, writes ${body.policy.writes}` +\n (Object.keys(body.policy.overrides).length > 0\n ? `, ${pluralize(Object.keys(body.policy.overrides).length, 'override')}`\n : ''),\n ],\n ['Skills', body.skills.length > 0 ? body.skills.join(', ') : 'none'],\n ['Connections', describeConnections(body)],\n ['Teams may add', describeCustomization(body)],\n ...areaRows('triggers', body).slice(0, 1),\n ...areaRows('links', body).slice(0, 1),\n [\n 'Team overrides',\n areaRows('overrides', body).map(([area, value]) => `${area}: ${value}`),\n ],\n ];\n if (template.teams) {\n rows.push([\n 'Teams',\n `${template.teams.enabled} running` +\n (template.teams.pinned > 0\n ? `, ${template.teams.pinned} pinned to an older version`\n : ''),\n ]);\n }\n rows.push([\n 'History',\n template.versions.map(\n (version) =>\n `v${version.version} ${version.createdAt.slice(0, 10)}` +\n (version.createdBy ? ` by ${version.createdBy}` : '') +\n (version.publishedAt\n ? ` · published ${version.publishedAt.slice(0, 10)}`\n : ''),\n ),\n ]);\n return ui.result({ title: `${body.name} (${template.key})`, rows });\n}\n\nfunction describeConnections(body: AgentTemplateBody): string[] {\n const owner = (connection: AgentTemplateBody['connections'][string]) =>\n connection.owner === 'source'\n ? 'one connection for the source'\n : `each team's own (${connection.team})`;\n const lines = [\n ...Object.entries(body.connections).map(\n ([slug, connection]) => `${slug}: ${owner(connection)}`,\n ),\n ...body.mcpServers.map(\n (server) => `${server.key} (MCP, ${server.url}): ${owner(server)}`,\n ),\n ];\n return lines.length > 0 ? lines : [\"each team's own (optional)\"];\n}\n\nfunction describeCustomization(body: AgentTemplateBody): string {\n const allowed = Object.entries(body.teamCustomization)\n .filter(([, on]) => on)\n .map(([knob]) => CUSTOMIZATION_LABEL[knob] ?? knob);\n return allowed.length > 0 ? allowed.join(', ') : 'nothing (template only)';\n}\n\nconst CUSTOMIZATION_LABEL: Record<string, string> = {\n mcpServers: 'own MCP servers',\n skills: 'own skills',\n integrations: 'more integrations',\n narrow: 'narrower tools',\n};\n\nfunction describeTools(body: AgentTemplateBody): string {\n if (body.tools.mode === 'read_only')\n return 'every read the team has connected';\n if (body.tools.mode === 'all') return 'every tool the team has connected';\n return (\n [...(body.tools.products ?? []), ...(body.tools.tools ?? [])].join(', ') ||\n 'none'\n );\n}\n\nconst OUTCOME_TITLE = {\n created: 'Created',\n updated: 'Stored a new version',\n unchanged: 'Unchanged',\n published: 'Published',\n 'rolled-back': 'Rolled back',\n} as const;\n\nfunction resultSummary(ui: Ui, result: AgentTemplateResult): string {\n const { template } = result;\n const rows: ResultRow[] = [['Versions', versionLabel(template)]];\n if (result.outcome === 'published' || result.outcome === 'rolled-back') {\n rows.push(['Teams updated', String(result.teamsUpdated)]);\n }\n const notes =\n (result.outcome === 'created' || result.outcome === 'updated') &&\n template.publishedVersion !== template.latestVersion\n ? [\n `Teams still run the published version. \"ekanos agents publish ${template.key}\" moves them.`,\n ]\n : [];\n return ui.result({\n title: `${OUTCOME_TITLE[result.outcome]}: ${template.key}`,\n tone: result.outcome === 'unchanged' ? 'warn' : 'ok',\n rows,\n notes,\n });\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { CliContext } from '../context.js';
|
|
2
|
+
import type { ExitCode } from '../exit-codes.js';
|
|
3
|
+
export declare const REVIEWERS_SUBCOMMANDS: readonly ['list', 'add', 'remove'];
|
|
4
|
+
export interface ReviewersArgs {
|
|
5
|
+
host?: string;
|
|
6
|
+
source?: string;
|
|
7
|
+
/** `list`, `add <email>`, `remove <email>`. */
|
|
8
|
+
positionals: readonly string[];
|
|
9
|
+
reach?: string;
|
|
10
|
+
team?: string;
|
|
11
|
+
dir: string;
|
|
12
|
+
env: Record<string, string | undefined>;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* `reviewers` — a Source admin names who decides its agents' reply drafts
|
|
16
|
+
* held under an `approve` policy. A reviewer is one of the Source's own
|
|
17
|
+
* users, at a reach: `source` (drafts from every team's provided agents) or
|
|
18
|
+
* `team` (one named team's). `list` shows them; `add` names one; `remove`
|
|
19
|
+
* takes one off — every reach, or only the named team's with `--team`.
|
|
20
|
+
*/
|
|
21
|
+
export declare function runReviewers(ctx: CliContext, args: ReviewersArgs): Promise<ExitCode>;
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
import { refreshStoredSession, requireSession, resolveAuthEnvironment, } from '../auth/session.js';
|
|
2
|
+
import { authRequiredError, usageError } from '../errors.js';
|
|
3
|
+
import { addReviewer, listReviewers, removeReviewer, } from '../reviewers-api.js';
|
|
4
|
+
import { resolveSourceTarget } from '../source-target.js';
|
|
5
|
+
export const REVIEWERS_SUBCOMMANDS = ['list', 'add', 'remove'];
|
|
6
|
+
const REACHES = ['source', 'team'];
|
|
7
|
+
/**
|
|
8
|
+
* `reviewers` — a Source admin names who decides its agents' reply drafts
|
|
9
|
+
* held under an `approve` policy. A reviewer is one of the Source's own
|
|
10
|
+
* users, at a reach: `source` (drafts from every team's provided agents) or
|
|
11
|
+
* `team` (one named team's). `list` shows them; `add` names one; `remove`
|
|
12
|
+
* takes one off — every reach, or only the named team's with `--team`.
|
|
13
|
+
*/
|
|
14
|
+
export async function runReviewers(ctx, args) {
|
|
15
|
+
var _a;
|
|
16
|
+
var _b;
|
|
17
|
+
const [rawSubcommand, rawEmail, ...extra] = args.positionals;
|
|
18
|
+
const subcommand = parseSubcommand(rawSubcommand);
|
|
19
|
+
if (subcommand === 'list') {
|
|
20
|
+
if (rawEmail !== undefined || args.reach || args.team) {
|
|
21
|
+
throw usageError('reviewers list takes no arguments.', 'Run "ekanos reviewers list --source <slug>".');
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
else if (extra.length > 0) {
|
|
25
|
+
throw usageError(`Unexpected argument "${extra[0]}".`, 'See "ekanos reviewers --help".');
|
|
26
|
+
}
|
|
27
|
+
const email = subcommand === 'list' ? '' : requireEmail(rawEmail, subcommand);
|
|
28
|
+
const team = args.team === undefined ? undefined : requireTeam(args.team);
|
|
29
|
+
const reach = subcommand === 'add' ? requireReach(args.reach, email, team) : undefined;
|
|
30
|
+
if (subcommand === 'remove' && args.reach) {
|
|
31
|
+
throw usageError('reviewers remove takes no --reach.', `Run "ekanos reviewers remove ${email}" (every reach) or add "--team <slug>" for one team's.`);
|
|
32
|
+
}
|
|
33
|
+
const env = resolveAuthEnvironment(ctx, args.host, args.env, {
|
|
34
|
+
projectDir: args.dir,
|
|
35
|
+
});
|
|
36
|
+
const resolved = await resolveSourceTarget(env, requireSession(env.store, env.host), args);
|
|
37
|
+
const client = new ReviewersClient(env, resolved.session);
|
|
38
|
+
const source = resolved.source;
|
|
39
|
+
if (subcommand === 'list') {
|
|
40
|
+
const list = await client.call((token) => listReviewers(env.host, token, source));
|
|
41
|
+
if (list.reviewers.length === 0) {
|
|
42
|
+
return ctx.succeed(Object.assign({ host: env.host }, list), ctx.ui.result({
|
|
43
|
+
title: `No reviewers on ${list.source.slug}`,
|
|
44
|
+
tone: 'warn',
|
|
45
|
+
notes: [
|
|
46
|
+
'Reply drafts under an "approve" policy wait for a named reviewer.',
|
|
47
|
+
'Name one: "ekanos reviewers add <email> --reach source".',
|
|
48
|
+
],
|
|
49
|
+
}));
|
|
50
|
+
}
|
|
51
|
+
return ctx.succeed(Object.assign({ host: env.host }, list), [
|
|
52
|
+
ctx.ui.bold(`Reviewers on ${list.source.slug}`),
|
|
53
|
+
ctx.ui.table(['Email', 'Name', 'Reach', 'Team'], list.reviewers.map(reviewerRow)),
|
|
54
|
+
].join('\n'));
|
|
55
|
+
}
|
|
56
|
+
if (subcommand === 'add' && reach) {
|
|
57
|
+
const result = await client.call((token) => addReviewer(env.host, token, source, Object.assign({ email,
|
|
58
|
+
reach }, (team ? { team } : {}))));
|
|
59
|
+
const reviewer = result.reviewer;
|
|
60
|
+
return ctx.succeed(Object.assign({ host: env.host }, result), ctx.ui.result({
|
|
61
|
+
title: result.created
|
|
62
|
+
? `Added ${who(reviewer)} as a reviewer`
|
|
63
|
+
: `${who(reviewer)} already reviews at that reach`,
|
|
64
|
+
tone: result.created ? 'ok' : 'warn',
|
|
65
|
+
rows: [
|
|
66
|
+
['Source', source],
|
|
67
|
+
['Reach', reachLabel(reviewer)],
|
|
68
|
+
],
|
|
69
|
+
notes: [
|
|
70
|
+
reviewer.reach === 'source'
|
|
71
|
+
? "Decides drafts from every team's provided agents, in the Source's review queue."
|
|
72
|
+
: `Decides ${(_b = (_a = reviewer.team) === null || _a === void 0 ? void 0 : _a.slug) !== null && _b !== void 0 ? _b : 'the team'}'s drafts, from its Approvals inbox or the Source's review queue.`,
|
|
73
|
+
],
|
|
74
|
+
}));
|
|
75
|
+
}
|
|
76
|
+
const result = await client.call((token) => removeReviewer(env.host, token, source, Object.assign({ email }, (team ? { team } : {}))));
|
|
77
|
+
return ctx.succeed(Object.assign({ host: env.host }, result), ctx.ui.result({
|
|
78
|
+
title: `Removed ${email}${team ? ` from ${team}` : ''}`,
|
|
79
|
+
rows: [
|
|
80
|
+
['Source', source],
|
|
81
|
+
[
|
|
82
|
+
'Removed',
|
|
83
|
+
`${result.removed} reach${result.removed === 1 ? '' : 'es'}`,
|
|
84
|
+
],
|
|
85
|
+
],
|
|
86
|
+
}));
|
|
87
|
+
}
|
|
88
|
+
function reviewerRow(reviewer) {
|
|
89
|
+
var _a;
|
|
90
|
+
var _b, _c, _d;
|
|
91
|
+
return [
|
|
92
|
+
(_b = reviewer.email) !== null && _b !== void 0 ? _b : reviewer.userId,
|
|
93
|
+
(_c = reviewer.name) !== null && _c !== void 0 ? _c : '—',
|
|
94
|
+
reviewer.reach,
|
|
95
|
+
(_d = (_a = reviewer.team) === null || _a === void 0 ? void 0 : _a.slug) !== null && _d !== void 0 ? _d : '—',
|
|
96
|
+
];
|
|
97
|
+
}
|
|
98
|
+
function reachLabel(reviewer) {
|
|
99
|
+
return reviewer.reach === 'team' && reviewer.team
|
|
100
|
+
? `team ${reviewer.team.slug} (${reviewer.team.name})`
|
|
101
|
+
: 'source';
|
|
102
|
+
}
|
|
103
|
+
function who(reviewer) {
|
|
104
|
+
var _a, _b;
|
|
105
|
+
return (_b = (_a = reviewer.email) !== null && _a !== void 0 ? _a : reviewer.name) !== null && _b !== void 0 ? _b : reviewer.userId;
|
|
106
|
+
}
|
|
107
|
+
class ReviewersClient {
|
|
108
|
+
constructor(env, session) {
|
|
109
|
+
this.env = env;
|
|
110
|
+
this.session = session;
|
|
111
|
+
}
|
|
112
|
+
async call(send) {
|
|
113
|
+
let result = await send(this.session.accessToken);
|
|
114
|
+
if (result.status === 'unauthorized') {
|
|
115
|
+
this.session = await refreshStoredSession(this.env, this.session);
|
|
116
|
+
result = await send(this.session.accessToken);
|
|
117
|
+
}
|
|
118
|
+
if (result.status === 'ok')
|
|
119
|
+
return result.data;
|
|
120
|
+
throw authRequiredError(`The session for ${this.env.host} could not authorize the reviewers call.`, `Run "ekanos login --host ${this.env.host}" and retry.`);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
function parseSubcommand(value) {
|
|
124
|
+
const match = REVIEWERS_SUBCOMMANDS.find((name) => name === value);
|
|
125
|
+
if (match)
|
|
126
|
+
return match;
|
|
127
|
+
throw usageError(value
|
|
128
|
+
? `Unknown reviewers subcommand "${value}".`
|
|
129
|
+
: 'reviewers needs a subcommand.', 'Run one of: ekanos reviewers list, ekanos reviewers add <email> --reach source|team [--team <slug>], ekanos reviewers remove <email> [--team <slug>].');
|
|
130
|
+
}
|
|
131
|
+
function requireEmail(value, subcommand) {
|
|
132
|
+
const email = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
|
|
133
|
+
if (email && /^[^\s@]+@[^\s@]+$/.test(email))
|
|
134
|
+
return email;
|
|
135
|
+
throw usageError(value
|
|
136
|
+
? `"${value}" is not an email address.`
|
|
137
|
+
: 'Name the reviewer by email.', subcommand === 'add'
|
|
138
|
+
? 'e.g. "ekanos reviewers add ana@example.com --reach source".'
|
|
139
|
+
: '"ekanos reviewers list" shows who reviews.');
|
|
140
|
+
}
|
|
141
|
+
function requireTeam(value) {
|
|
142
|
+
const slug = value.trim().toLowerCase();
|
|
143
|
+
if (/^[a-z0-9][a-z0-9-]*$/.test(slug))
|
|
144
|
+
return slug;
|
|
145
|
+
throw usageError(`"${value}" is not a team slug.`, 'Run "ekanos teams list" to see the teams on this Source.');
|
|
146
|
+
}
|
|
147
|
+
function requireReach(value, email, team) {
|
|
148
|
+
const reach = REACHES.find((entry) => entry === (value === null || value === void 0 ? void 0 : value.trim().toLowerCase()));
|
|
149
|
+
if (!reach) {
|
|
150
|
+
throw usageError(value
|
|
151
|
+
? `"${value}" is not a reach: use source or team.`
|
|
152
|
+
: 'Name the reach: --reach source or --reach team.', `e.g. "ekanos reviewers add ${email} --reach source", or "--reach team --team <slug>" for one team's drafts.`);
|
|
153
|
+
}
|
|
154
|
+
if (reach === 'team' && !team) {
|
|
155
|
+
throw usageError('A team-reach reviewer needs --team <slug>.', 'Run "ekanos teams list" to see the teams on this Source.');
|
|
156
|
+
}
|
|
157
|
+
if (reach === 'source' && team) {
|
|
158
|
+
throw usageError('A source-reach reviewer decides for every team; drop --team.', `Run "ekanos reviewers add ${email} --reach source", or use "--reach team --team ${team}".`);
|
|
159
|
+
}
|
|
160
|
+
return reach;
|
|
161
|
+
}
|
|
162
|
+
//# sourceMappingURL=reviewers.js.map
|