@ekanos/cli 0.16.0 → 0.17.1
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 +62 -4
- package/dist/commands/add.d.ts +2 -0
- package/dist/commands/add.js +118 -0
- package/dist/commands/add.js.map +1 -0
- package/dist/commands/audiences.d.ts +31 -0
- package/dist/commands/audiences.js +239 -0
- package/dist/commands/audiences.js.map +1 -0
- package/dist/commands/build.d.ts +2 -0
- package/dist/commands/build.js +41 -0
- package/dist/commands/build.js.map +1 -0
- package/dist/commands/check.d.ts +2 -0
- package/dist/commands/check.js +43 -0
- package/dist/commands/check.js.map +1 -0
- package/dist/commands/codegen.d.ts +2 -0
- package/dist/commands/codegen.js +49 -0
- package/dist/commands/codegen.js.map +1 -0
- package/dist/commands/contract.d.ts +52 -0
- package/dist/commands/contract.js +300 -0
- package/dist/commands/contract.js.map +1 -0
- package/dist/commands/dev.d.ts +7 -0
- package/dist/commands/dev.js +186 -12
- package/dist/commands/dev.js.map +1 -1
- package/dist/commands/index-experience.d.ts +31 -0
- package/dist/commands/index-experience.js +21 -0
- package/dist/commands/index-experience.js.map +1 -0
- package/dist/commands/init.d.ts +7 -0
- package/dist/commands/init.js +12 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/new.d.ts +2 -0
- package/dist/commands/new.js +39 -0
- package/dist/commands/new.js.map +1 -0
- package/dist/commands/publish.d.ts +59 -0
- package/dist/commands/publish.js +118 -65
- package/dist/commands/publish.js.map +1 -1
- package/dist/commands/scope-notice.d.ts +6 -0
- package/dist/commands/scope-notice.js +15 -0
- package/dist/commands/scope-notice.js.map +1 -1
- package/dist/commands/sources.js +2 -0
- package/dist/commands/sources.js.map +1 -1
- package/dist/commands/sync.d.ts +2 -0
- package/dist/commands/sync.js +150 -0
- package/dist/commands/sync.js.map +1 -0
- package/dist/commands/teams-audience.d.ts +12 -0
- package/dist/commands/teams-audience.js +144 -0
- package/dist/commands/teams-audience.js.map +1 -0
- package/dist/commands/teams-scope.js +4 -0
- package/dist/commands/teams-scope.js.map +1 -1
- package/dist/commands/teams.d.ts +1 -1
- package/dist/commands/teams.js +6 -1
- package/dist/commands/teams.js.map +1 -1
- package/dist/compatibility.d.ts +10 -1
- package/dist/compatibility.js +10 -1
- package/dist/compatibility.js.map +1 -1
- package/dist/dev-experience.d.ts +125 -0
- package/dist/dev-experience.js +128 -0
- package/dist/dev-experience.js.map +1 -0
- package/dist/experience/boundary.d.ts +12 -0
- package/dist/experience/boundary.js +260 -0
- package/dist/experience/boundary.js.map +1 -0
- package/dist/experience/build.d.ts +16 -0
- package/dist/experience/build.js +90 -0
- package/dist/experience/build.js.map +1 -0
- package/dist/experience/checks.d.ts +29 -0
- package/dist/experience/checks.js +133 -0
- package/dist/experience/checks.js.map +1 -0
- package/dist/experience/contract-sources.d.ts +36 -0
- package/dist/experience/contract-sources.js +111 -0
- package/dist/experience/contract-sources.js.map +1 -0
- package/dist/experience/definition-checks.d.ts +26 -0
- package/dist/experience/definition-checks.js +201 -0
- package/dist/experience/definition-checks.js.map +1 -0
- package/dist/experience/definition-shape.d.ts +60 -0
- package/dist/experience/definition-shape.js +2 -0
- package/dist/experience/definition-shape.js.map +1 -0
- package/dist/experience/init.d.ts +10 -0
- package/dist/experience/init.js +64 -0
- package/dist/experience/init.js.map +1 -0
- package/dist/experience/integrations-codegen.d.ts +17 -0
- package/dist/experience/integrations-codegen.js +51 -0
- package/dist/experience/integrations-codegen.js.map +1 -0
- package/dist/experience/json-schema-to-ts.d.ts +1 -0
- package/dist/experience/json-schema-to-ts.js +90 -0
- package/dist/experience/json-schema-to-ts.js.map +1 -0
- package/dist/experience/load-experience.d.ts +23 -0
- package/dist/experience/load-experience.js +115 -0
- package/dist/experience/load-experience.js.map +1 -0
- package/dist/experience/overrides.d.ts +8 -0
- package/dist/experience/overrides.js +21 -0
- package/dist/experience/overrides.js.map +1 -0
- package/dist/experience/pin-integration.d.ts +8 -0
- package/dist/experience/pin-integration.js +17 -0
- package/dist/experience/pin-integration.js.map +1 -0
- package/dist/experience/pin-ops.d.ts +12 -0
- package/dist/experience/pin-ops.js +36 -0
- package/dist/experience/pin-ops.js.map +1 -0
- package/dist/experience/pins.d.ts +35 -0
- package/dist/experience/pins.js +91 -0
- package/dist/experience/pins.js.map +1 -0
- package/dist/experience/project.d.ts +52 -0
- package/dist/experience/project.js +149 -0
- package/dist/experience/project.js.map +1 -0
- package/dist/experience/publish.d.ts +51 -0
- package/dist/experience/publish.js +144 -0
- package/dist/experience/publish.js.map +1 -0
- package/dist/experience/regenerate.d.ts +10 -0
- package/dist/experience/regenerate.js +33 -0
- package/dist/experience/regenerate.js.map +1 -0
- package/dist/experience/report.d.ts +9 -0
- package/dist/experience/report.js +23 -0
- package/dist/experience/report.js.map +1 -0
- package/dist/harness-scaffold.d.ts +52 -18
- package/dist/harness-scaffold.js +189 -9
- package/dist/harness-scaffold.js.map +1 -1
- package/dist/index.js +139 -7
- package/dist/index.js.map +1 -1
- package/dist/pack.js +5 -0
- package/dist/pack.js.map +1 -1
- package/dist/project-checks.d.ts +19 -0
- package/dist/project-checks.js +93 -0
- package/dist/project-checks.js.map +1 -1
- package/dist/project.d.ts +14 -0
- package/dist/project.js +10 -0
- package/dist/project.js.map +1 -1
- package/dist/repo/publish.d.ts +42 -0
- package/dist/repo/publish.js +225 -0
- package/dist/repo/publish.js.map +1 -0
- package/dist/repo/scaffold.d.ts +30 -0
- package/dist/repo/scaffold.js +165 -0
- package/dist/repo/scaffold.js.map +1 -0
- package/dist/teams-api.d.ts +37 -1
- package/dist/teams-api.js +62 -1
- package/dist/teams-api.js.map +1 -1
- package/dist/validate-findings.js +3 -1
- package/dist/validate-findings.js.map +1 -1
- package/package.json +2 -2
- package/templates/ekanos.json.tmpl +1 -0
- package/templates/experience/AGENTS.md.tmpl +22 -0
- package/templates/experience/ekanos.json.tmpl +7 -0
- package/templates/experience/ekanos.lock.json.tmpl +4 -0
- package/templates/experience/eslint.config.mjs.tmpl +25 -0
- package/templates/experience/gitignore.tmpl +17 -0
- package/templates/experience/package.json.tmpl +41 -0
- package/templates/experience/src/.ekanos/integrations.d.ts.tmpl +3 -0
- package/templates/experience/src/experience.ts.tmpl +30 -0
- package/templates/experience/src/widgets/hello-widget.tsx.tmpl +40 -0
- package/templates/experience/tsconfig.json.tmpl +20 -0
- package/templates/harness/app/%5F%5Fekanos/api/[...path]/route.ts.tmpl +9 -0
- package/templates/harness/app/[slug]/activation/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/tile/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/triggers/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/widgets/[widgetId]/page.tsx.tmpl +1 -1
- package/templates/harness/app/[slug]/widgets/page.tsx.tmpl +1 -1
- package/templates/harness/app/experience/layout.tsx.tmpl +17 -0
- package/templates/harness/app/experience/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/pages/[id]/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/review-queue/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/runs/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/widgets/[id]/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/widgets/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/workflows/[id]/page.tsx.tmpl +1 -0
- package/templates/harness/app/experience/workflows/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/connect/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/events/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/health/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/operations/[kind]/[name]/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/operations/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/activation/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/layout.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/tile/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/triggers/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/widgets/[widgetId]/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/preview/widgets/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/[slug]/runs/page.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/layout.tsx.tmpl +1 -0
- package/templates/harness/app/integrations/page.tsx.tmpl +1 -0
- package/templates/harness/app/page.experience.tsx.tmpl +5 -0
- package/templates/harness/repo/app/%5F%5Fekanos/api/[...path]/route.ts.tmpl +11 -0
- package/templates/harness/repo/app/(repo)/connections/page.tsx.tmpl +1 -0
- package/templates/harness/repo/app/(repo)/layout.tsx.tmpl +1 -0
- package/templates/harness/repo/app/(repo)/page.tsx.tmpl +1 -0
- package/templates/harness/repo/app/experiences/[name]/connect/page.tsx.tmpl +1 -0
- package/templates/harness/repo/app/experiences/[name]/layout.tsx.tmpl +9 -0
- package/templates/harness/repo/app/experiences/page.tsx.tmpl +5 -0
- package/templates/harness/repo/app/harness-shell.tsx.tmpl +9 -0
- package/templates/harness/repo/app/integrations/[slug]/layout.tsx.tmpl +1 -0
- package/templates/harness/repo/app/integrations/page.tsx.tmpl +5 -0
- package/templates/harness/repo/app/repo-experiences.ts.tmpl +5 -0
- package/templates/harness/styles/globals.css.tmpl +15 -1
- package/templates/package.json.tmpl +5 -4
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CliContext } from '../context.js';
|
|
2
|
+
import type { ExitCode } from '../exit-codes.js';
|
|
3
|
+
import { type TeamsArgs } from './teams.js';
|
|
4
|
+
/**
|
|
5
|
+
* `teams audience <team> [<audience>] [--member <email> [--inherit]]` — the
|
|
6
|
+
* audience a team starts its members on, and a member's own override of it
|
|
7
|
+
* (a Source admin's only; audited). Without an audience it reads. Moving
|
|
8
|
+
* people to an audience that shows fewer products hides the difference from
|
|
9
|
+
* them in the app, so that needs `--yes`. `teams scope` is the deprecated
|
|
10
|
+
* form of this.
|
|
11
|
+
*/
|
|
12
|
+
export declare function runTeamAudience(ctx: CliContext, args: TeamsArgs, rest: readonly string[]): Promise<ExitCode>;
|
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { requireSession, resolveAuthEnvironment } from '../auth/session.js';
|
|
2
|
+
import { invalidStateError, usageError } from '../errors.js';
|
|
3
|
+
import { resolveSourceTarget } from '../source-target.js';
|
|
4
|
+
import { listAudiences, setMemberAudience, setTeamAudience, showMemberAudience, showTeamAudience, } from '../teams-api.js';
|
|
5
|
+
import { TeamsClient } from './teams.js';
|
|
6
|
+
const USAGE = 'Run "ekanos teams audience <team>" to read a team’s audience, "ekanos teams audience <team> <audience> [--yes]" to set it, or add --member <email> (with <audience>, or --inherit to clear it) for one person’s own.';
|
|
7
|
+
/**
|
|
8
|
+
* `teams audience <team> [<audience>] [--member <email> [--inherit]]` — the
|
|
9
|
+
* audience a team starts its members on, and a member's own override of it
|
|
10
|
+
* (a Source admin's only; audited). Without an audience it reads. Moving
|
|
11
|
+
* people to an audience that shows fewer products hides the difference from
|
|
12
|
+
* them in the app, so that needs `--yes`. `teams scope` is the deprecated
|
|
13
|
+
* form of this.
|
|
14
|
+
*/
|
|
15
|
+
export async function runTeamAudience(ctx, args, rest) {
|
|
16
|
+
var _a, _b;
|
|
17
|
+
const [rawTeam, audience, ...extra] = rest;
|
|
18
|
+
const team = rawTeam === null || rawTeam === void 0 ? void 0 : rawTeam.trim().toLowerCase();
|
|
19
|
+
if (!team || !/^[a-z0-9][a-z0-9-]*$/.test(team)) {
|
|
20
|
+
throw usageError(rawTeam
|
|
21
|
+
? `"${rawTeam}" is not a team slug.`
|
|
22
|
+
: 'teams audience needs a team.', USAGE);
|
|
23
|
+
}
|
|
24
|
+
if (extra.length > 0) {
|
|
25
|
+
throw usageError(`Unexpected argument "${extra[0]}".`, USAGE);
|
|
26
|
+
}
|
|
27
|
+
const member = typeof ((_a = args.flags) === null || _a === void 0 ? void 0 : _a.member) === 'string'
|
|
28
|
+
? args.flags.member.trim().toLowerCase()
|
|
29
|
+
: undefined;
|
|
30
|
+
const inherit = ((_b = args.flags) === null || _b === void 0 ? void 0 : _b.inherit) === true;
|
|
31
|
+
if (inherit && !member) {
|
|
32
|
+
throw usageError('--inherit clears one member’s audience.', USAGE);
|
|
33
|
+
}
|
|
34
|
+
if (inherit && audience) {
|
|
35
|
+
throw usageError('Name an audience or pass --inherit, not both.', 'ekanos teams audience <team> --member <email> --inherit puts them back on the team’s.');
|
|
36
|
+
}
|
|
37
|
+
if (member && !/^[^@\s]+@[^@\s]+$/.test(member)) {
|
|
38
|
+
throw usageError(`"${member}" is not an email address.`, USAGE);
|
|
39
|
+
}
|
|
40
|
+
const env = resolveAuthEnvironment(ctx, args.host, args.env, {
|
|
41
|
+
projectDir: args.dir,
|
|
42
|
+
});
|
|
43
|
+
const resolved = await resolveSourceTarget(env, requireSession(env), args);
|
|
44
|
+
const client = new TeamsClient(env, resolved.session);
|
|
45
|
+
const source = resolved.source;
|
|
46
|
+
const target = { source, team };
|
|
47
|
+
if (member) {
|
|
48
|
+
const person = Object.assign(Object.assign({}, target), { email: member });
|
|
49
|
+
const current = await client.call((token) => showMemberAudience(env.host, token, person));
|
|
50
|
+
if (!audience && !inherit) {
|
|
51
|
+
return ctx.succeed(Object.assign({ host: env.host }, current), describeMember(ctx, current));
|
|
52
|
+
}
|
|
53
|
+
const next = inherit
|
|
54
|
+
? (await client.call((token) => showTeamAudience(env.host, token, target))).audience.id
|
|
55
|
+
: audience;
|
|
56
|
+
await requireYesIfNarrowing(client, env.host, {
|
|
57
|
+
source,
|
|
58
|
+
from: current.audience,
|
|
59
|
+
to: next,
|
|
60
|
+
who: `${member}`,
|
|
61
|
+
yes: args.yes,
|
|
62
|
+
retry: `ekanos teams audience ${team} ${inherit ? '' : `${quote(audience)} `}--member ${member}${inherit ? ' --inherit' : ''} --source ${source} --yes`,
|
|
63
|
+
});
|
|
64
|
+
const result = await client.call((token) => setMemberAudience(env.host, token, person, inherit ? null : audience));
|
|
65
|
+
return ctx.succeed(Object.assign({ host: env.host }, result), describeMember(ctx, result, result.before));
|
|
66
|
+
}
|
|
67
|
+
const current = await client.call((token) => showTeamAudience(env.host, token, target));
|
|
68
|
+
if (!audience) {
|
|
69
|
+
return ctx.succeed(Object.assign({ host: env.host }, current), describeTeam(ctx, current));
|
|
70
|
+
}
|
|
71
|
+
await requireYesIfNarrowing(client, env.host, {
|
|
72
|
+
source,
|
|
73
|
+
from: current.audience,
|
|
74
|
+
to: audience,
|
|
75
|
+
who: `members of ${team} on the team default`,
|
|
76
|
+
yes: args.yes,
|
|
77
|
+
retry: `ekanos teams audience ${team} ${quote(audience)} --source ${source} --yes`,
|
|
78
|
+
});
|
|
79
|
+
const result = await client.call((token) => setTeamAudience(env.host, token, target, audience));
|
|
80
|
+
return ctx.succeed(Object.assign({ host: env.host }, result), describeTeam(ctx, result, result.before));
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Refuses, before any write, a move to an audience that shows less than the
|
|
84
|
+
* one people are on, unless `--yes`. An audience that shows every entitled
|
|
85
|
+
* product can only be left for a narrower one, which is also refused.
|
|
86
|
+
*/
|
|
87
|
+
async function requireYesIfNarrowing(client, host, input) {
|
|
88
|
+
if (input.yes)
|
|
89
|
+
return;
|
|
90
|
+
const { audiences } = await client.call((token) => listAudiences(host, token, input.source));
|
|
91
|
+
const from = audiences.find((entry) => entry.id === input.from.id);
|
|
92
|
+
const to = findAudience(audiences, input.to);
|
|
93
|
+
if (!from || !to || to.includesAllEntitled)
|
|
94
|
+
return;
|
|
95
|
+
const kept = new Set(to.products.map((product) => product.slug));
|
|
96
|
+
const lost = from.includesAllEntitled
|
|
97
|
+
? null
|
|
98
|
+
: from.products.filter((product) => !kept.has(product.slug));
|
|
99
|
+
if (lost !== null && lost.length === 0)
|
|
100
|
+
return;
|
|
101
|
+
throw invalidStateError(lost === null
|
|
102
|
+
? `${to.name} does not show every product the Source has, as ${from.name} does: ${input.who} may stop seeing some in the app.`
|
|
103
|
+
: `${input.who} would stop seeing ${lost.map((product) => product.slug).join(', ')} in the app: ${from.name} shows ${lost.length === 1 ? 'it' : 'them'}, ${to.name} does not.`, `Re-run with --yes: ${input.retry}`);
|
|
104
|
+
}
|
|
105
|
+
function findAudience(audiences, ref) {
|
|
106
|
+
const wanted = ref.trim().toLowerCase();
|
|
107
|
+
return audiences.find((entry) => entry.id === wanted || entry.name.toLowerCase() === wanted);
|
|
108
|
+
}
|
|
109
|
+
function describeTeam(ctx, result, before) {
|
|
110
|
+
var _a;
|
|
111
|
+
return ctx.ui.result({
|
|
112
|
+
title: `${result.team.slug} starts its members on ${result.audience.name}`,
|
|
113
|
+
rows: [
|
|
114
|
+
['Audience', result.audience.name],
|
|
115
|
+
...(before !== undefined
|
|
116
|
+
? [['Before', (_a = before === null || before === void 0 ? void 0 : before.name) !== null && _a !== void 0 ? _a : 'none']]
|
|
117
|
+
: []),
|
|
118
|
+
],
|
|
119
|
+
notes: [
|
|
120
|
+
'A member’s own audience overrides it: "ekanos teams audience <team> <audience> --member <email>".',
|
|
121
|
+
'"ekanos audiences show <audience>" lists what it shows.',
|
|
122
|
+
],
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
function describeMember(ctx, result, before) {
|
|
126
|
+
var _a;
|
|
127
|
+
return ctx.ui.result({
|
|
128
|
+
title: `${result.member.email} is on ${result.audience.name}`,
|
|
129
|
+
rows: [
|
|
130
|
+
['Audience', result.audience.name],
|
|
131
|
+
[
|
|
132
|
+
'From',
|
|
133
|
+
result.isOverride ? 'their own' : `the ${result.team.slug} default`,
|
|
134
|
+
],
|
|
135
|
+
...(before !== undefined
|
|
136
|
+
? [['Before', (_a = before === null || before === void 0 ? void 0 : before.name) !== null && _a !== void 0 ? _a : 'none']]
|
|
137
|
+
: []),
|
|
138
|
+
],
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
function quote(name) {
|
|
142
|
+
return /^[A-Za-z0-9._-]+$/.test(name) ? name : `"${name}"`;
|
|
143
|
+
}
|
|
144
|
+
//# sourceMappingURL=teams-audience.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"teams-audience.js","sourceRoot":"","sources":["../../src/commands/teams-audience.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n Audience,\n AudienceRef,\n MemberAudience,\n TeamAudience,\n} from '@ekanos/integration-schema';\n\nimport { requireSession, resolveAuthEnvironment } from '../auth/session';\nimport type { CliContext } from '../context';\nimport { invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport {\n listAudiences,\n setMemberAudience,\n setTeamAudience,\n showMemberAudience,\n showTeamAudience,\n} from '../teams-api';\nimport { TeamsClient, type TeamsArgs } from './teams';\n\nconst USAGE =\n 'Run \"ekanos teams audience <team>\" to read a team’s audience, \"ekanos teams audience <team> <audience> [--yes]\" to set it, or add --member <email> (with <audience>, or --inherit to clear it) for one person’s own.';\n\n/**\n * `teams audience <team> [<audience>] [--member <email> [--inherit]]` — the\n * audience a team starts its members on, and a member's own override of it\n * (a Source admin's only; audited). Without an audience it reads. Moving\n * people to an audience that shows fewer products hides the difference from\n * them in the app, so that needs `--yes`. `teams scope` is the deprecated\n * form of this.\n */\nexport async function runTeamAudience(\n ctx: CliContext,\n args: TeamsArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [rawTeam, audience, ...extra] = rest;\n const team = rawTeam?.trim().toLowerCase();\n if (!team || !/^[a-z0-9][a-z0-9-]*$/.test(team)) {\n throw usageError(\n rawTeam\n ? `\"${rawTeam}\" is not a team slug.`\n : 'teams audience needs a team.',\n USAGE,\n );\n }\n if (extra.length > 0) {\n throw usageError(`Unexpected argument \"${extra[0]}\".`, USAGE);\n }\n const member =\n typeof args.flags?.member === 'string'\n ? args.flags.member.trim().toLowerCase()\n : undefined;\n const inherit = args.flags?.inherit === true;\n if (inherit && !member) {\n throw usageError('--inherit clears one member’s audience.', USAGE);\n }\n if (inherit && audience) {\n throw usageError(\n 'Name an audience or pass --inherit, not both.',\n 'ekanos teams audience <team> --member <email> --inherit puts them back on the team’s.',\n );\n }\n if (member && !/^[^@\\s]+@[^@\\s]+$/.test(member)) {\n throw usageError(`\"${member}\" is not an email address.`, USAGE);\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const client = new TeamsClient(env, resolved.session);\n const source = resolved.source;\n const target = { source, team };\n\n if (member) {\n const person = { ...target, email: member };\n const current = await client.call((token) =>\n showMemberAudience(env.host, token, person),\n );\n if (!audience && !inherit) {\n return ctx.succeed(\n { host: env.host, ...current },\n describeMember(ctx, current),\n );\n }\n\n const next = inherit\n ? (\n await client.call((token) =>\n showTeamAudience(env.host, token, target),\n )\n ).audience.id\n : audience!;\n await requireYesIfNarrowing(client, env.host, {\n source,\n from: current.audience,\n to: next,\n who: `${member}`,\n yes: args.yes,\n retry: `ekanos teams audience ${team} ${inherit ? '' : `${quote(audience!)} `}--member ${member}${inherit ? ' --inherit' : ''} --source ${source} --yes`,\n });\n const result = await client.call((token) =>\n setMemberAudience(env.host, token, person, inherit ? null : audience!),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n describeMember(ctx, result, result.before),\n );\n }\n\n const current = await client.call((token) =>\n showTeamAudience(env.host, token, target),\n );\n if (!audience) {\n return ctx.succeed(\n { host: env.host, ...current },\n describeTeam(ctx, current),\n );\n }\n await requireYesIfNarrowing(client, env.host, {\n source,\n from: current.audience,\n to: audience,\n who: `members of ${team} on the team default`,\n yes: args.yes,\n retry: `ekanos teams audience ${team} ${quote(audience)} --source ${source} --yes`,\n });\n const result = await client.call((token) =>\n setTeamAudience(env.host, token, target, audience),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n describeTeam(ctx, result, result.before),\n );\n}\n\n/**\n * Refuses, before any write, a move to an audience that shows less than the\n * one people are on, unless `--yes`. An audience that shows every entitled\n * product can only be left for a narrower one, which is also refused.\n */\nasync function requireYesIfNarrowing(\n client: TeamsClient,\n host: string,\n input: {\n source: string;\n from: AudienceRef;\n to: string;\n who: string;\n yes: boolean;\n retry: string;\n },\n): Promise<void> {\n if (input.yes) return;\n const { audiences } = await client.call((token) =>\n listAudiences(host, token, input.source),\n );\n const from = audiences.find((entry) => entry.id === input.from.id);\n const to = findAudience(audiences, input.to);\n if (!from || !to || to.includesAllEntitled) return;\n\n const kept = new Set(to.products.map((product) => product.slug));\n const lost = from.includesAllEntitled\n ? null\n : from.products.filter((product) => !kept.has(product.slug));\n if (lost !== null && lost.length === 0) return;\n\n throw invalidStateError(\n lost === null\n ? `${to.name} does not show every product the Source has, as ${from.name} does: ${input.who} may stop seeing some in the app.`\n : `${input.who} would stop seeing ${lost.map((product) => product.slug).join(', ')} in the app: ${from.name} shows ${lost.length === 1 ? 'it' : 'them'}, ${to.name} does not.`,\n `Re-run with --yes: ${input.retry}`,\n );\n}\n\nfunction findAudience(\n audiences: Audience[],\n ref: string,\n): Audience | undefined {\n const wanted = ref.trim().toLowerCase();\n return audiences.find(\n (entry) => entry.id === wanted || entry.name.toLowerCase() === wanted,\n );\n}\n\nfunction describeTeam(\n ctx: CliContext,\n result: TeamAudience,\n before?: AudienceRef | null,\n): string {\n return ctx.ui.result({\n title: `${result.team.slug} starts its members on ${result.audience.name}`,\n rows: [\n ['Audience', result.audience.name],\n ...(before !== undefined\n ? ([['Before', before?.name ?? 'none']] as Array<[string, string]>)\n : []),\n ],\n notes: [\n 'A member’s own audience overrides it: \"ekanos teams audience <team> <audience> --member <email>\".',\n '\"ekanos audiences show <audience>\" lists what it shows.',\n ],\n });\n}\n\nfunction describeMember(\n ctx: CliContext,\n result: MemberAudience,\n before?: AudienceRef | null,\n): string {\n return ctx.ui.result({\n title: `${result.member.email} is on ${result.audience.name}`,\n rows: [\n ['Audience', result.audience.name],\n [\n 'From',\n result.isOverride ? 'their own' : `the ${result.team.slug} default`,\n ],\n ...(before !== undefined\n ? ([['Before', before?.name ?? 'none']] as Array<[string, string]>)\n : []),\n ],\n });\n}\n\nfunction quote(name: string): string {\n return /^[A-Za-z0-9._-]+$/.test(name) ? name : `\"${name}\"`;\n}\n"]}
|
|
@@ -2,6 +2,7 @@ import { requireSession, resolveAuthEnvironment } from '../auth/session.js';
|
|
|
2
2
|
import { invalidStateError, usageError } from '../errors.js';
|
|
3
3
|
import { resolveSourceTarget } from '../source-target.js';
|
|
4
4
|
import { setTeamScopes, showTeamScopes } from '../teams-api.js';
|
|
5
|
+
import { scopeDeprecationNotice } from './scope-notice.js';
|
|
5
6
|
import { TeamsClient } from './teams.js';
|
|
6
7
|
const USAGE = 'Run "ekanos teams scope show <team>" or "ekanos teams scope set <team> <scope> [<scope>…] [--yes]".';
|
|
7
8
|
/**
|
|
@@ -29,6 +30,9 @@ export async function runTeamScope(ctx, args, rest) {
|
|
|
29
30
|
if (verb === 'set' && scopes.length === 0) {
|
|
30
31
|
throw usageError('Name the scope (or scopes) the team should hold.', `"ekanos sources scopes" lists them, e.g. "ekanos teams scope set ${team} Gold".`);
|
|
31
32
|
}
|
|
33
|
+
ctx.warn(scopeDeprecationNotice(verb === 'set'
|
|
34
|
+
? `teams audience ${team} <audience>`
|
|
35
|
+
: `teams audience ${team}`));
|
|
32
36
|
const env = resolveAuthEnvironment(ctx, args.host, args.env, {
|
|
33
37
|
projectDir: args.dir,
|
|
34
38
|
});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teams-scope.js","sourceRoot":"","sources":["../../src/commands/teams-scope.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TeamScopes } from '@ekanos/integration-schema';\n\nimport { requireSession, resolveAuthEnvironment } from '../auth/session';\nimport type { CliContext } from '../context';\nimport { invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport { setTeamScopes, showTeamScopes } from '../teams-api';\nimport type { Ui } from '../ui';\nimport { TeamsClient, type TeamsArgs } from './teams';\n\nconst USAGE =\n 'Run \"ekanos teams scope show <team>\" or \"ekanos teams scope set <team> <scope> [<scope>…] [--yes]\".';\n\n/**\n * `teams scope show|set <team>` — which of the Source's product scopes a team\n * holds, and so which products it sees in the app. `set` replaces them\n * (names or ids); taking one away can hide products the team uses, so that\n * needs `--yes`. The Source's scopes and their products: `sources scopes`.\n */\nexport async function runTeamScope(\n ctx: CliContext,\n args: TeamsArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawTeam, ...scopes] = rest;\n if (verb !== 'show' && verb !== 'set') {\n throw usageError(\n verb\n ? `Unknown teams scope subcommand \"${verb}\".`\n : 'teams scope needs a subcommand.',\n USAGE,\n );\n }\n const team = rawTeam?.trim().toLowerCase();\n if (!team || !/^[a-z0-9][a-z0-9-]*$/.test(team)) {\n throw usageError(\n rawTeam\n ? `\"${rawTeam}\" is not a team slug.`\n : `teams scope ${verb} needs a team.`,\n USAGE,\n );\n }\n if (verb === 'show' && scopes.length > 0) {\n throw usageError(`Unexpected argument \"${scopes[0]}\".`, USAGE);\n }\n if (verb === 'set' && scopes.length === 0) {\n throw usageError(\n 'Name the scope (or scopes) the team should hold.',\n `\"ekanos sources scopes\" lists them, e.g. \"ekanos teams scope set ${team} Gold\".`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const client = new TeamsClient(env, resolved.session);\n const target = { source: resolved.source, team };\n\n const current = await client.call((token) =>\n showTeamScopes(env.host, token, target),\n );\n if (verb === 'show') {\n return ctx.succeed(\n { host: env.host, ...current },\n describe(ctx.ui, current, resolved.source),\n );\n }\n\n const wanted = scopes.map((scope) => scope.trim().toLowerCase());\n const dropped = current.scopes.filter(\n (scope) =>\n !wanted.includes(scope.name.toLowerCase()) && !wanted.includes(scope.id),\n );\n if (dropped.length > 0 && !args.yes) {\n throw invalidStateError(\n `${team} would no longer hold ${dropped.map((scope) => scope.name).join(', ')}: any product only ${dropped.length === 1 ? 'it shows' : 'they show'} disappears from the team in the app.`,\n `Re-run with --yes: ekanos teams scope set ${team} ${scopes.map(quote).join(' ')} --source ${resolved.source} --yes`,\n );\n }\n\n const result = await client.call((token) =>\n setTeamScopes(env.host, token, target, scopes),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n [\n ctx.ui.result({\n title: `${result.team.slug} holds ${names(result.scopes)}`,\n tone: result.hidden.length > 0 ? 'warn' : 'ok',\n rows: [\n ['Before', names(result.before)],\n ...(result.hidden.length > 0\n ? ([\n [\n 'No longer sees',\n result.hidden.map((product) => product.slug),\n ],\n ] as Array<[string, string[]]>)\n : []),\n ],\n }),\n describe(ctx.ui, result, resolved.source),\n ].join('\\n\\n'),\n );\n}\n\nfunction describe(ui: Ui, scopes: TeamScopes, source: string): string {\n if (scopes.state === 'unscoped') {\n return ui.result({\n title: `${scopes.team.slug} sees every product ${scopes.source.slug} has`,\n rows: [['Scopes', `none: ${scopes.source.slug} has no product scopes`]],\n });\n }\n if (scopes.state === 'locked_out') {\n return ui.result({\n title: `${scopes.team.slug} sees no product in the app`,\n tone: 'warn',\n rows: [['Scopes', `none of ${scopes.source.slug}'s`]],\n notes: [\n `Give it one: ekanos teams scope set ${scopes.team.slug} <scope> --source ${source} (\"ekanos sources scopes\" lists them).`,\n ],\n });\n }\n return ui.result({\n title: `What ${scopes.team.slug} sees in the app`,\n rows: [\n ['Scopes', names(scopes.scopes)],\n [\n 'Products',\n (scopes.products ?? []).length > 0\n ? (scopes.products ?? []).map((product) => product.slug)\n : 'none',\n ],\n ],\n notes: [\n `\"ekanos sources scopes add <scope> <product>\" shows a product to every team on a scope.`,\n ],\n });\n}\n\nfunction names(scopes: Array<{ name: string }>): string {\n return scopes.length > 0\n ? scopes.map((scope) => scope.name).join(', ')\n : 'no scope';\n}\n\nfunction quote(name: string): string {\n return /^[A-Za-z0-9._-]+$/.test(name) ? name : `\"${name}\"`;\n}\n"]}
|
|
1
|
+
{"version":3,"file":"teams-scope.js","sourceRoot":"","sources":["../../src/commands/teams-scope.ts"],"names":[],"mappings":"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","sourcesContent":["import type { TeamScopes } from '@ekanos/integration-schema';\n\nimport { requireSession, resolveAuthEnvironment } from '../auth/session';\nimport type { CliContext } from '../context';\nimport { invalidStateError, usageError } from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { resolveSourceTarget } from '../source-target';\nimport { setTeamScopes, showTeamScopes } from '../teams-api';\nimport type { Ui } from '../ui';\nimport { scopeDeprecationNotice } from './scope-notice';\nimport { TeamsClient, type TeamsArgs } from './teams';\n\nconst USAGE =\n 'Run \"ekanos teams scope show <team>\" or \"ekanos teams scope set <team> <scope> [<scope>…] [--yes]\".';\n\n/**\n * `teams scope show|set <team>` — which of the Source's product scopes a team\n * holds, and so which products it sees in the app. `set` replaces them\n * (names or ids); taking one away can hide products the team uses, so that\n * needs `--yes`. The Source's scopes and their products: `sources scopes`.\n */\nexport async function runTeamScope(\n ctx: CliContext,\n args: TeamsArgs,\n rest: readonly string[],\n): Promise<ExitCode> {\n const [verb, rawTeam, ...scopes] = rest;\n if (verb !== 'show' && verb !== 'set') {\n throw usageError(\n verb\n ? `Unknown teams scope subcommand \"${verb}\".`\n : 'teams scope needs a subcommand.',\n USAGE,\n );\n }\n const team = rawTeam?.trim().toLowerCase();\n if (!team || !/^[a-z0-9][a-z0-9-]*$/.test(team)) {\n throw usageError(\n rawTeam\n ? `\"${rawTeam}\" is not a team slug.`\n : `teams scope ${verb} needs a team.`,\n USAGE,\n );\n }\n if (verb === 'show' && scopes.length > 0) {\n throw usageError(`Unexpected argument \"${scopes[0]}\".`, USAGE);\n }\n if (verb === 'set' && scopes.length === 0) {\n throw usageError(\n 'Name the scope (or scopes) the team should hold.',\n `\"ekanos sources scopes\" lists them, e.g. \"ekanos teams scope set ${team} Gold\".`,\n );\n }\n\n ctx.warn(\n scopeDeprecationNotice(\n verb === 'set'\n ? `teams audience ${team} <audience>`\n : `teams audience ${team}`,\n ),\n );\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const client = new TeamsClient(env, resolved.session);\n const target = { source: resolved.source, team };\n\n const current = await client.call((token) =>\n showTeamScopes(env.host, token, target),\n );\n if (verb === 'show') {\n return ctx.succeed(\n { host: env.host, ...current },\n describe(ctx.ui, current, resolved.source),\n );\n }\n\n const wanted = scopes.map((scope) => scope.trim().toLowerCase());\n const dropped = current.scopes.filter(\n (scope) =>\n !wanted.includes(scope.name.toLowerCase()) && !wanted.includes(scope.id),\n );\n if (dropped.length > 0 && !args.yes) {\n throw invalidStateError(\n `${team} would no longer hold ${dropped.map((scope) => scope.name).join(', ')}: any product only ${dropped.length === 1 ? 'it shows' : 'they show'} disappears from the team in the app.`,\n `Re-run with --yes: ekanos teams scope set ${team} ${scopes.map(quote).join(' ')} --source ${resolved.source} --yes`,\n );\n }\n\n const result = await client.call((token) =>\n setTeamScopes(env.host, token, target, scopes),\n );\n return ctx.succeed(\n { host: env.host, ...result },\n [\n ctx.ui.result({\n title: `${result.team.slug} holds ${names(result.scopes)}`,\n tone: result.hidden.length > 0 ? 'warn' : 'ok',\n rows: [\n ['Before', names(result.before)],\n ...(result.hidden.length > 0\n ? ([\n [\n 'No longer sees',\n result.hidden.map((product) => product.slug),\n ],\n ] as Array<[string, string[]]>)\n : []),\n ],\n }),\n describe(ctx.ui, result, resolved.source),\n ].join('\\n\\n'),\n );\n}\n\nfunction describe(ui: Ui, scopes: TeamScopes, source: string): string {\n if (scopes.state === 'unscoped') {\n return ui.result({\n title: `${scopes.team.slug} sees every product ${scopes.source.slug} has`,\n rows: [['Scopes', `none: ${scopes.source.slug} has no product scopes`]],\n });\n }\n if (scopes.state === 'locked_out') {\n return ui.result({\n title: `${scopes.team.slug} sees no product in the app`,\n tone: 'warn',\n rows: [['Scopes', `none of ${scopes.source.slug}'s`]],\n notes: [\n `Give it one: ekanos teams scope set ${scopes.team.slug} <scope> --source ${source} (\"ekanos sources scopes\" lists them).`,\n ],\n });\n }\n return ui.result({\n title: `What ${scopes.team.slug} sees in the app`,\n rows: [\n ['Scopes', names(scopes.scopes)],\n [\n 'Products',\n (scopes.products ?? []).length > 0\n ? (scopes.products ?? []).map((product) => product.slug)\n : 'none',\n ],\n ],\n notes: [\n `\"ekanos sources scopes add <scope> <product>\" shows a product to every team on a scope.`,\n ],\n });\n}\n\nfunction names(scopes: Array<{ name: string }>): string {\n return scopes.length > 0\n ? scopes.map((scope) => scope.name).join(', ')\n : 'no scope';\n}\n\nfunction quote(name: string): string {\n return /^[A-Za-z0-9._-]+$/.test(name) ? name : `\"${name}\"`;\n}\n"]}
|
package/dist/commands/teams.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import type { CliContext } from '../context.js';
|
|
|
5
5
|
import type { ExitCode } from '../exit-codes.js';
|
|
6
6
|
import { type SecretFlags, type SecretIO } from '../secret-input.js';
|
|
7
7
|
import { type TeamsApiResult } from '../teams-api.js';
|
|
8
|
-
export declare const TEAMS_SUBCOMMANDS: readonly ["list", "show", "app", "webhook", "events", "scope", "create", "rename", "members", "roles", "connect", "disconnect", "leave", "groups", "health", "workspace"];
|
|
8
|
+
export declare const TEAMS_SUBCOMMANDS: readonly ["list", "show", "app", "webhook", "events", "scope", "audience", "create", "rename", "members", "roles", "connect", "disconnect", "leave", "groups", "health", "workspace"];
|
|
9
9
|
export interface TeamsArgs {
|
|
10
10
|
host?: string;
|
|
11
11
|
source?: string;
|
package/dist/commands/teams.js
CHANGED
|
@@ -20,6 +20,7 @@ import { listTeams, mintTeamWebhook, setTeamApp, showTeamIntegration, } from '..
|
|
|
20
20
|
import { promptHidden, promptLine } from './apps.js';
|
|
21
21
|
import { scopeHiddenLines } from './scope-notice.js';
|
|
22
22
|
import { isTeamAgentArea, runTeamAgentCommands } from './team-agents.js';
|
|
23
|
+
import { runTeamAudience } from './teams-audience.js';
|
|
23
24
|
import { runTeamEvents } from './teams-events.js';
|
|
24
25
|
import { LIFECYCLE_SUBCOMMANDS, isLifecycleMemberVerb, isLifecycleSubcommand, parseLifecycle, runLifecycle, } from './teams-lifecycle.js';
|
|
25
26
|
import { ONBOARDING_SUBCOMMANDS, isOnboardingSubcommand, parseOnboarding, runOnboarding, } from './teams-onboard.js';
|
|
@@ -32,6 +33,7 @@ export const TEAMS_SUBCOMMANDS = [
|
|
|
32
33
|
'webhook',
|
|
33
34
|
'events',
|
|
34
35
|
'scope',
|
|
36
|
+
'audience',
|
|
35
37
|
...ONBOARDING_SUBCOMMANDS,
|
|
36
38
|
...LIFECYCLE_SUBCOMMANDS,
|
|
37
39
|
];
|
|
@@ -60,6 +62,9 @@ export async function runTeams(ctx, args) {
|
|
|
60
62
|
if (subcommand === 'scope') {
|
|
61
63
|
return runTeamScope(ctx, args, rest);
|
|
62
64
|
}
|
|
65
|
+
if (subcommand === 'audience') {
|
|
66
|
+
return runTeamAudience(ctx, args, rest);
|
|
67
|
+
}
|
|
63
68
|
if (isLifecycleSubcommand(subcommand) ||
|
|
64
69
|
(subcommand === 'members' && isLifecycleMemberVerb(rest[0]))) {
|
|
65
70
|
return runLifecycle(ctx, args, parseLifecycle(subcommand, rest, args));
|
|
@@ -543,7 +548,7 @@ function parseSubcommand(value) {
|
|
|
543
548
|
return match;
|
|
544
549
|
throw usageError(value
|
|
545
550
|
? `Unknown teams subcommand "${value}".`
|
|
546
|
-
: 'teams needs a subcommand.', 'Run one of: ekanos teams list, ekanos teams create <name>, ekanos teams rename <team> <name>, ekanos teams members list|add|invite|role|remove|resend <team> … (add <team> --self joins you), ekanos teams roles list <team>, ekanos teams leave <team> --yes, ekanos teams groups list|create|update|delete|members <team> …, ekanos teams health <team> [<product>] [--run] (<product> --mine: your own personal connection), ekanos teams workspace list|default <team> …, ekanos teams connect <team> <product>, ekanos teams disconnect <team> <product> --yes (--mine: your own personal connection), ekanos teams show <team> [<product>], ekanos teams app set <team> <product>, ekanos teams webhook <team> <product> [<webhook-id>], ekanos teams events <team> [<product>], ekanos teams scope show|set <team>
|
|
551
|
+
: 'teams needs a subcommand.', 'Run one of: ekanos teams list, ekanos teams create <name>, ekanos teams rename <team> <name>, ekanos teams members list|add|invite|role|remove|resend <team> … (add <team> --self joins you), ekanos teams roles list <team>, ekanos teams leave <team> --yes, ekanos teams groups list|create|update|delete|members <team> …, ekanos teams health <team> [<product>] [--run] (<product> --mine: your own personal connection), ekanos teams workspace list|default <team> …, ekanos teams connect <team> <product>, ekanos teams disconnect <team> <product> --yes (--mine: your own personal connection), ekanos teams show <team> [<product>], ekanos teams app set <team> <product>, ekanos teams webhook <team> <product> [<webhook-id>], ekanos teams events <team> [<product>], ekanos teams audience <team> [<audience>] [--member <email>], ekanos teams scope show|set <team> … (deprecated: audiences), ekanos teams agents|triggers|links|mcp|llm-key ….');
|
|
547
552
|
}
|
|
548
553
|
function requireSlug(value, what) {
|
|
549
554
|
const slug = value === null || value === void 0 ? void 0 : value.trim().toLowerCase();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/commands/teams.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n TeamAppState,\n TeamIntegrationStatus,\n} from '@ekanos/integration-schema';\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 usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { cli } from '../invocation';\nimport { ensureSecretsDir, writeSecretFile } from '../secret-file';\nimport {\n FIELD_SECRET_FORMS,\n type SecretFlags,\n type SecretIO,\n collectSecrets,\n parsePlainValues,\n readSecretFlags,\n secretInputGiven,\n} from '../secret-input';\nimport { resolveSourceTarget } from '../source-target';\nimport {\n type TeamsApiResult,\n listTeams,\n mintTeamWebhook,\n setTeamApp,\n showTeamIntegration,\n} from '../teams-api';\nimport { promptHidden, promptLine } from './apps';\nimport { scopeHiddenLines } from './scope-notice';\nimport { isTeamAgentArea, runTeamAgentCommands } from './team-agents';\nimport { runTeamEvents } from './teams-events';\nimport {\n LIFECYCLE_SUBCOMMANDS,\n isLifecycleMemberVerb,\n isLifecycleSubcommand,\n parseLifecycle,\n runLifecycle,\n} from './teams-lifecycle';\nimport {\n ONBOARDING_SUBCOMMANDS,\n isOnboardingSubcommand,\n parseOnboarding,\n runOnboarding,\n} from './teams-onboard';\nimport { runTeamOverview } from './teams-overview';\nimport { runTeamScope } from './teams-scope';\n\nexport const TEAMS_SUBCOMMANDS = [\n 'list',\n 'show',\n 'app',\n 'webhook',\n 'events',\n 'scope',\n ...ONBOARDING_SUBCOMMANDS,\n ...LIFECYCLE_SUBCOMMANDS,\n] as const;\ntype TeamsSubcommand = (typeof TEAMS_SUBCOMMANDS)[number];\n\nexport interface TeamsArgs {\n host?: string;\n source?: string;\n /** `list`, `show <team> [<product>]`, `app set <team> <product>`, `webhook <team> <product> [<id>]`. */\n positionals: readonly string[];\n connection?: string;\n /** `create --slug`, `create --owner <email>`, `members invite --role`. */\n slug?: string;\n owner?: string;\n role?: string;\n yes: boolean;\n /** `connect --no-wait`: print the sign-in link and return without polling. */\n noWait?: boolean;\n /** `connect --no-open`: never open a browser, only print the link. */\n noOpen?: boolean;\n /** `connect --link-only`: print the team's page, as before connect did the work. */\n linkOnly?: boolean;\n /** `connect --reconnect`: connect again though it reads as connected. */\n reconnect?: boolean;\n /** Test seams for `connect`: the wait between polls, and the browser opener. */\n pollDelayMs?: number;\n openUrl?: (url: string) => void;\n /** Every parsed flag, for `teams agents|triggers|links|mcp` (team-agents.ts). */\n flags?: Record<string, string | boolean | string[]>;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n /** Test seams for the questions `app set` asks. */\n ask?: (question: string) => Promise<string>;\n askSecret?: (question: string) => Promise<string>;\n /** Test seams for the secret-input flags (`secret-input.ts`). */\n readStdin?: () => Promise<string>;\n secretFormTimeoutMs?: number;\n}\n\nexport interface Target {\n source: string;\n team: string;\n product: string;\n}\n\n/**\n * `teams` — a Source admin's view of its teams' integration setup, the\n * team-level counterpart of `apps`. `list` names the teams; `show` reads one\n * team's setup of one product as a checklist; `app set` enters or updates\n * any of a team's own app fields (Zendesk's subdomain, client and signing\n * secret), one at a time if need be — a field left alone keeps its saved\n * value. A secret is typed at the admin's terminal with hidden input or,\n * without one, read from the environment, a private file, stdin or a form\n * in the browser (`secret-input.ts`) — never a value in argv; a non-secret\n * field may be passed as `--set name=value`; `webhook` mints the URL the\n * team's provider sends to, shown once.\n */\nexport async function runTeams(\n ctx: CliContext,\n args: TeamsArgs,\n): Promise<ExitCode> {\n const [rawSubcommand, ...rest] = args.positionals;\n if (isTeamAgentArea(rawSubcommand)) {\n return runTeamAgentCommands(ctx, args);\n }\n const subcommand = parseSubcommand(rawSubcommand);\n\n if (subcommand === 'events') {\n return runTeamEvents(ctx, args, rest);\n }\n if (subcommand === 'scope') {\n return runTeamScope(ctx, args, rest);\n }\n\n if (\n isLifecycleSubcommand(subcommand) ||\n (subcommand === 'members' && isLifecycleMemberVerb(rest[0]))\n ) {\n return runLifecycle(ctx, args, parseLifecycle(subcommand, rest, args));\n }\n\n if (isOnboardingSubcommand(subcommand)) {\n const plan = parseOnboarding(subcommand, rest, {\n ...args,\n as: typeof args.flags?.as === 'string' ? args.flags.as : undefined,\n self: args.flags?.self === true,\n mine: args.flags?.mine === true,\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 return runOnboarding(\n ctx,\n args,\n new TeamsClient(env, resolved.session),\n env.host,\n resolved.source,\n plan,\n );\n }\n\n if (subcommand === 'app' && rest[0] !== 'set') {\n throw usageError(\n rest[0]\n ? `Unknown teams app subcommand \"${rest[0]}\".`\n : 'teams app needs a subcommand.',\n 'Run \"ekanos teams app set <team> <product>\".',\n );\n }\n const operands = subcommand === 'app' ? rest.slice(1) : rest;\n\n if (subcommand === 'list' && operands.length > 0) {\n throw usageError(\n 'teams list takes no arguments.',\n 'Run \"ekanos teams list --source <slug>\".',\n );\n }\n\n const team = subcommand === 'list' ? '' : requireSlug(operands[0], 'team');\n // `teams show <team>` alone is the team's overview.\n const overview = subcommand === 'show' && operands[1] === undefined;\n const product =\n subcommand === 'list' || overview\n ? ''\n : requireSlug(operands[1], 'product');\n const extra = operands.slice(subcommand === 'webhook' ? 3 : 2);\n const appEdits = subcommand === 'app' ? parseAppEdits(args.flags) : null;\n if (subcommand !== 'list' && extra.length > 0) {\n throw usageError(\n `Unexpected argument \"${extra[0]}\".`,\n 'See \"ekanos teams --help\".',\n );\n }\n\n if (\n appEdits?.prompts &&\n !canPrompt(ctx, args) &&\n !secretInputGiven(appEdits.secret)\n ) {\n throw usageError(\n \"teams app set needs the team's secrets, and there is no terminal to ask at. Non-secret fields can be passed with --set <name>=<value>.\",\n `Without a terminal, pass ${FIELD_SECRET_FORMS}. Or run it yourself in your terminal: ${cli()} teams app set ${team} ${product}${args.connection ? ` --connection ${args.connection}` : ''}${args.source ? ` --source ${args.source}` : ''}`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const client = new TeamsClient(env, resolved.session);\n const source = resolved.source;\n\n if (subcommand === 'list') {\n const list = await client.call((token) =>\n listTeams(env.host, token, source),\n );\n return ctx.succeed(\n { host: env.host, ...list },\n list.teams.length === 0\n ? ctx.ui.result({\n title: `No teams on ${list.source.slug}`,\n tone: 'warn',\n })\n : ctx.ui.result({\n title: `Teams on ${list.source.slug}`,\n rows: list.teams.map((entry) => [entry.slug, teamLine(entry)]),\n notes: [\n '\"ekanos teams show <team>\" shows a team\\'s setup; add a product for its checklist.',\n ...(list.teams.some(\n (entry) =>\n entry.callerIsMember === false && entry.memberCount > 0,\n )\n ? [\n 'You manage every team of the Source as its admin without being a member. To connect your own account to one, join it: \"ekanos teams members add <team> --self\".',\n ]\n : []),\n ],\n }),\n );\n }\n\n if (overview) {\n return runTeamOverview(ctx, client, env.host, source, team);\n }\n\n const target: Target = { source, team, product };\n const status = await client.call((token) =>\n showTeamIntegration(env.host, token, target),\n );\n\n if (subcommand === 'show') {\n return ctx.succeed(\n { host: env.host, ...status },\n checklist(status).join('\\n'),\n );\n }\n\n if (!status.enabled) {\n throw invalidStateError(\n `\"${product}\" is not enabled on ${status.source.slug}.`,\n `\"ekanos sources products --source ${status.source.slug}\" shows what it has; only a super-admin enables a product for a Source (in /admin).`,\n );\n }\n\n if (subcommand === 'app' && appEdits) {\n return setApp(ctx, args, client, env.host, target, status, appEdits);\n }\n return mintWebhook(ctx, args, client, env.host, target, status, operands[2]);\n}\n\n/** What `teams app set` was asked to change, from its flags. */\ninterface AppEdits {\n /** `--field`: enter just these, at the terminal. */\n only: string[];\n /** `--set name=value`: non-secret values, no prompt. */\n values: Record<string, string>;\n /** `--clear name`: remove a saved value. */\n clear: string[];\n /** `--secret-*`, `--set-secret`, `--browser`: where secrets come from without a terminal. */\n secret: SecretFlags;\n /** Whether any field is collected (asked, or read from the secret-input flags). */\n prompts: boolean;\n}\n\nfunction parseAppEdits(flags: TeamsArgs['flags']): AppEdits {\n const list = (name: string): string[] => {\n const raw = flags?.[name];\n if (raw === undefined || raw === false) return [];\n if (Array.isArray(raw)) return raw;\n return typeof raw === 'string' ? [raw] : [];\n };\n const values = parsePlainValues(flags?.set);\n const only = list('field');\n const clear = list('clear');\n const secret = readSecretFlags(flags);\n return {\n only,\n values,\n clear,\n secret,\n // Bare `app set` walks every field; `--field` asks the named ones.\n prompts:\n only.length > 0 ||\n secretInputGiven(secret) ||\n (Object.keys(values).length === 0 && clear.length === 0),\n };\n}\n\nasync function setApp(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: Target,\n status: TeamIntegrationStatus,\n edits: AppEdits,\n): Promise<ExitCode> {\n const app = chooseApp(status, args.connection);\n const result = await promptAndSaveTeamApp(\n ctx,\n args,\n client,\n host,\n target,\n status,\n app,\n edits,\n );\n const missing = result.fields.filter((field) => !field.set);\n const next = [\n ...(missing.length > 0\n ? [\n `Still not set: ${missing.map((field) => field.label).join(', ')} — a team member can't connect until it is. Run \"ekanos teams app set ${target.team} ${target.product} ${missing.map((field) => `--field ${field.secretName}`).join(' ')}\".`,\n ]\n : []),\n ...nextSteps(status, app, target),\n ];\n return ctx.succeed(\n { host, ...result },\n ctx.ui.result({\n title: `Saved ${target.team}'s ${result.product.name} app`,\n rows: [\n ['Source', status.source.slug],\n ['Fields', result.fields.map(fieldLine)],\n ],\n notes: next,\n }),\n );\n}\n\n/**\n * Every field, in turn: bare `teams app set`, and `teams connect` — whose\n * `--set` and secret-input flags fill the team's app too.\n */\nfunction walkEveryField(flags: TeamsArgs['flags']): AppEdits {\n return {\n only: [],\n values: parsePlainValues(flags?.set),\n clear: [],\n secret: readSecretFlags(flags),\n prompts: true,\n };\n}\n\n/**\n * The `teams app set` walkthrough and prompts for one team app, then the\n * save — of only what was entered: a field left empty keeps its saved value.\n * Shared with `teams connect`, which runs it inline when the integration\n * needs the team's own app (Zendesk) before anyone can sign in.\n */\nexport async function promptAndSaveTeamApp(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: Target,\n status: TeamIntegrationStatus,\n app: TeamAppState,\n edits: AppEdits = walkEveryField(args.flags),\n) {\n const known = new Map(app.fields.map((field) => [field.secretName, field]));\n const names = app.fields.map((field) => field.secretName).join(', ');\n for (const name of [\n ...edits.only,\n ...Object.keys(edits.values),\n ...edits.clear,\n ]) {\n if (!known.has(name)) {\n throw usageError(\n `${status.product.name}'s team app has no field \"${name}\".`,\n `Its fields are: ${names}.`,\n );\n }\n }\n for (const name of Object.keys(edits.values)) {\n if (known.get(name)?.sensitive) {\n throw usageError(\n `\"${name}\" is a secret: it is never passed as an argument.`,\n `Pass it as --set-secret ${name}=env:<NAME>|file:<path>|stdin, use --browser, or enter it at the prompt: ekanos teams app set ${target.team} ${target.product} --field ${name}`,\n );\n }\n }\n\n const fields: Record<string, string> = { ...edits.values };\n if (edits.prompts) {\n const toAsk =\n edits.only.length > 0\n ? app.fields.filter((field) => edits.only.includes(field.secretName))\n : app.fields;\n if (edits.only.length === 0)\n ctx.log(appWalkthrough(status, app).join('\\n'));\n else {\n ctx.log(\n `${status.product.name} app for team ${target.team} on ${status.source.slug}`,\n );\n }\n const byName = new Map(toAsk.map((field) => [field.secretName, field]));\n const again = `teams app set ${target.team} ${target.product}${args.connection ? ` --connection ${args.connection}` : ''} --source ${status.source.slug}`;\n Object.assign(\n fields,\n await collectSecrets(ctx, {\n fields: toAsk\n .filter((field) => edits.values[field.secretName] === undefined)\n .map((field) => ({\n name: field.secretName,\n label: field.label,\n sensitive: field.sensitive,\n set: field.set,\n value: field.sensitive ? null : field.value,\n })),\n flags: edits.secret,\n io: teamsSecretIO(args),\n interactive: canPrompt(ctx, args),\n title: `${status.product.name} app for team ${target.team}`,\n refusal: `${status.product.name}'s team app takes secrets (${toAsk\n .filter((field) => field.sensitive)\n .map((field) => field.secretName)\n .join(', ')}), and there is no terminal to ask at.`,\n again,\n prompt: (spec) => {\n const field = byName.get(spec.name)!;\n return (\n field.sensitive\n ? (args.askSecret ?? promptHidden)\n : (args.ask ?? promptLine)\n )(fieldQuestion(field));\n },\n }),\n );\n }\n\n if (Object.keys(fields).length === 0 && edits.clear.length === 0) {\n throw validationError(\n 'Nothing was changed.',\n `Run \"ekanos teams show ${target.team} ${target.product}\" to see the current state.`,\n );\n }\n\n return client.call((token) =>\n setTeamApp(host, token, target, {\n connectionId: app.connectionId,\n fields,\n ...(edits.clear.length > 0 ? { clear: edits.clear } : {}),\n }),\n );\n}\n\n/** The prompt for one field: what is saved, and that Enter keeps it. */\nfunction fieldQuestion(field: TeamAppState['fields'][number]): string {\n const name = `${field.label} [${field.secretName}]`;\n if (field.sensitive) {\n return field.set\n ? `${name} (saved — Enter to keep, hidden): `\n : `${name} (hidden): `;\n }\n if (field.set) {\n return field.value\n ? `${name} (current: ${field.value} — Enter to keep): `\n : `${name} (saved — Enter to keep): `;\n }\n return `${name}: `;\n}\n\n/** One field's state: a secret only as saved / not set, never its value. */\nfunction fieldLine(field: TeamAppState['fields'][number]): string {\n const state = !field.set\n ? 'not set'\n : field.sensitive\n ? 'saved'\n : field.value\n ? field.value\n : 'saved';\n return `${mark(field.set)} ${field.label} (${field.secretName}): ${state}`;\n}\n\nasync function mintWebhook(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: Target,\n status: TeamIntegrationStatus,\n requested: string | undefined,\n): Promise<ExitCode> {\n const webhooks = status.teamApps.flatMap((app) => app.webhooks);\n if (webhooks.length === 0) {\n throw invalidStateError(\n `${status.product.name} has no webhook a team's app sends.`,\n `Run \"ekanos teams show ${target.team} ${target.product}\" to see its setup.`,\n );\n }\n const webhook = requested\n ? webhooks.find((entry) => entry.webhookId === requested)\n : webhooks.length === 1\n ? webhooks[0]\n : undefined;\n if (!webhook) {\n throw usageError(\n requested\n ? `${status.product.name} has no team-app webhook \"${requested}\".`\n : `${status.product.name} has several webhooks; name one.`,\n `Run one of: ${webhooks.map((entry) => `ekanos teams webhook ${target.team} ${target.product} ${entry.webhookId}`).join(', ')}.`,\n );\n }\n\n if (webhook.endpoint && !args.yes) {\n throw invalidStateError(\n `${target.team} already has a live URL for ${webhook.webhookId} (${webhook.endpoint.tokenPrefix}…). A new one revokes it, and the provider's webhook stops working until you paste the new URL there.`,\n `Re-run with --yes when you are ready to update the provider: ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId} --yes`,\n );\n }\n\n // The URL carries its token, so it goes to a 0600 file, never the output.\n const secrets = ensureSecretsDir(args.env);\n const minted = await client.call((token) =>\n mintTeamWebhook(host, token, target, webhook.webhookId),\n );\n const { url, ...rest } = minted;\n const secretFile = writeSecretFile(secrets, {\n owner: target.team,\n what: `${target.product}-${webhook.webhookId}-webhook-url`,\n purpose: `Webhook URL for team ${target.team}'s ${status.product.name} (${webhook.webhookId}). Paste it into ${status.product.name}'s webhook settings for this team; the token is part of the URL.`,\n values: [['WEBHOOK_URL', url]],\n again: `ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId} --yes`,\n });\n return ctx.succeed(\n { host, ...rest, secretFile },\n ctx.ui.result({\n title: `Webhook URL for ${target.team} · ${webhook.webhookId}`,\n tone: 'warn',\n rows: [\n ['URL', `saved to ${secretFile} (readable only by you)`],\n [\n 'Paste it into',\n `${status.product.name}'s webhook settings for this team`,\n ],\n ],\n notes: [\n 'The URL carries its token, so it is shown nowhere else and cannot be read again. Copy it from that file into the provider yourself — not into a chat or an agent session — then delete the file.',\n ...(minted.replaced\n ? ['The previous URL is revoked: the provider must use this one.']\n : []),\n ],\n }),\n );\n}\n\n/** `teams show`, read top to bottom like a setup checklist. */\nexport function checklist(status: TeamIntegrationStatus): string[] {\n const name = status.product.name;\n const lines = [\n `${name} for team ${status.team.slug} (${status.team.name}) on ${status.source.slug}`,\n ` ${mark(status.enabled)} Enabled on the Source`,\n ];\n if (!status.enabled) {\n lines.push(\n ` \"ekanos sources products --source ${status.source.slug}\" shows what it has; only a super-admin enables a product for a Source (in /admin).`,\n );\n return lines;\n }\n\n const target = { team: status.team.slug, product: status.product.slug };\n lines.push(\n ...scopeHiddenLines(status.scope, {\n ...target,\n source: status.source.slug,\n }).map((line) => ` ${line}`),\n );\n lines.push(...connectionLines(status));\n for (const app of status.teamApps) {\n lines.push(` Team app: ${app.label} (${app.connectionId})`);\n if (app.setup?.consoleUrl) lines.push(` Open: ${app.setup.consoleUrl}`);\n app.setup?.steps.forEach((step, index) =>\n lines.push(` ${index + 1}. ${step}`),\n );\n lines.push(' Callback URLs to register:');\n lines.push(...callbackUrls(app).map((url) => ` ${url}`));\n if (app.guideUrl) lines.push(` Guide: ${app.guideUrl}`);\n for (const field of app.fields) {\n lines.push(` ${fieldLine(field)}`);\n }\n const unset = app.fields.filter((field) => !field.set);\n if (unset.length > 0) {\n lines.push(\n ` → in your terminal: ${cli()} teams app set ${target.team} ${target.product} --connection ${app.connectionId} ${unset.map((field) => `--field ${field.secretName}`).join(' ')} --source ${status.source.slug}`,\n );\n }\n for (const webhook of app.webhooks) {\n lines.push(\n webhook.endpoint\n ? ` ${mark(true)} Webhook ${webhook.webhookId}: live URL ${webhook.endpoint.tokenPrefix}… since ${day(webhook.endpoint.createdAt)}${webhook.endpoint.lastUsedAt ? `, last delivery ${day(webhook.endpoint.lastUsedAt)}` : ', no delivery yet'}`\n : ` ${mark(false)} Webhook ${webhook.webhookId}: no URL yet`,\n );\n if (!webhook.endpoint) {\n lines.push(\n ` → ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId} --source ${status.source.slug}`,\n );\n }\n }\n lines.push(\n app.connection\n ? ` ${mark(true)} Connected ${day(app.connection.connectedAt)}${app.connection.connectedBy ? ` by ${who(app.connection.connectedBy)}` : ''}`\n : ` ${mark(false)} Connected: not yet\\n → in your terminal: ${connectCommand(status, app.connectionId)}`,\n );\n }\n\n lines.push(\n status.activation\n ? ` ${mark(true)} Activated for the team${status.activation.activatedAt ? ` ${day(status.activation.activatedAt)}` : ''}${status.activation.activatedBy ? ` by ${who(status.activation.activatedBy)}` : ''}`\n : ` ${mark(false)} Activated: not yet\\n → in your terminal: ${connectCommand(status)}`,\n );\n lines.push(` Team page: ${status.connectUrl}`);\n if (status.agentEvents.length > 0) {\n lines.push(' Agent events it offers:');\n lines.push(\n ...status.agentEvents.map((event) => ` ${event.id} — ${event.label}`),\n );\n }\n return lines;\n}\n\n/**\n * Each OAuth connection in one line — connected, or installed for a named\n * one, with its app's credentials and webhook URL — and which of the team's\n * agents wait on it. A named connection an agent's trigger needs and the team\n * has not installed is the gap no other line names: the trigger is stored\n * and on, and nothing ever reaches it.\n */\nfunction connectionLines(status: TeamIntegrationStatus): string[] {\n const connections = status.connections ?? [];\n if (connections.length === 0) return [];\n const lines = [' Connections:'];\n for (const entry of connections) {\n const named = entry.connectionId !== 'default';\n const app = status.teamApps.find(\n (candidate) => candidate.connectionId === entry.connectionId,\n );\n const webhooks = app?.webhooks ?? [];\n const steps = [\n ...(entry.credentialsSaved === null\n ? []\n : [\n `app credentials ${entry.credentialsSaved ? 'saved' : 'not saved'}`,\n ]),\n named\n ? entry.connected\n ? `installed ${day(entry.connectedAt ?? '')}`\n : 'not installed'\n : entry.connected\n ? `connected ${day(entry.connectedAt ?? '')}`\n : 'not connected',\n ...(webhooks.length > 0\n ? [\n webhooks.every((webhook) => webhook.endpoint)\n ? 'webhook URL made'\n : 'no webhook URL',\n ]\n : []),\n ];\n const ready =\n entry.connected &&\n entry.credentialsSaved !== false &&\n webhooks.every((webhook) => webhook.endpoint);\n lines.push(\n ` ${mark(ready)} ${entry.label} (${entry.connectionId}): ${steps.join(' · ')}${entry.connectedBy ? ` by ${who(entry.connectedBy)}` : ''}`,\n );\n if (entry.neededBy.length > 0) {\n lines.push(\n ` Needed by: ${entry.neededBy.map((need) => `${need.agent} (${need.triggers.join(', ')})`).join(', ')}`,\n );\n }\n if (!entry.connected) {\n lines.push(\n ` → in your terminal: ${connectCommand(status, entry.connectionId)}`,\n );\n }\n }\n return lines;\n}\n\n/**\n * One team in `teams list`: its members, and whether the caller is one. A\n * team nobody has joined says so with the command that joins it, rather than\n * reading as a count of zero.\n */\nexport function teamLine(entry: {\n slug: string;\n name: string;\n memberCount: number;\n callerIsMember?: boolean;\n}): string {\n const count = `${entry.memberCount} member${entry.memberCount === 1 ? '' : 's'}`;\n if (entry.callerIsMember === undefined) return `${entry.name} · ${count}`;\n if (entry.callerIsMember) return `${entry.name} · ${count}, you among them`;\n return entry.memberCount === 0\n ? `${entry.name} · 0 members · you are not a member — ekanos teams members add ${entry.slug} --self`\n : `${entry.name} · ${count} · you are not a member`;\n}\n\n/** The command that connects the team, for a hint: `--connection` only for a named one. */\nfunction connectCommand(\n status: TeamIntegrationStatus,\n connectionId = 'default',\n): string {\n return `${cli()} teams connect ${status.team.slug} ${status.product.slug}${connectionId === 'default' ? '' : ` --connection ${connectionId}`} --source ${status.source.slug}`;\n}\n\nfunction appWalkthrough(\n status: TeamIntegrationStatus,\n app: TeamAppState,\n): string[] {\n const lines = [\n `${status.product.name} app for team ${status.team.slug} on ${status.source.slug}`,\n ];\n if (app.setup?.consoleUrl) lines.push(` Open: ${app.setup.consoleUrl}`);\n const steps = app.setup?.steps.length\n ? [...app.setup.steps]\n : [\n `In ${status.product.name}, create an OAuth app for the team (or open the one it uses).`,\n ];\n steps.push(\n `Check the app lists exactly: ${callbackUrls(app).join(', ')}`,\n \"Enter its values below. Secrets are stored in Ekanos's vault and never shown again.\",\n );\n lines.push(...steps.map((step, index) => ` ${index + 1}. ${step}`));\n if (app.guideUrl) lines.push(` Guide: ${app.guideUrl}`);\n return lines;\n}\n\nfunction nextSteps(\n status: TeamIntegrationStatus,\n app: TeamAppState,\n target: Target,\n): string[] {\n return [\n ...app.webhooks\n .filter((webhook) => !webhook.endpoint)\n .map(\n (webhook) =>\n `Next: \"ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId}\" for the provider's webhook URL.`,\n ),\n ...(app.connection\n ? []\n : [`Then connect it: ${connectCommand(status, app.connectionId)}`]),\n ];\n}\n\nexport function chooseApp(\n status: TeamIntegrationStatus,\n connection: string | undefined,\n): TeamAppState {\n const apps = status.teamApps;\n if (apps.length === 0) {\n throw invalidStateError(\n `${status.product.name} takes no team app: teams connect through the Source's app, or need none.`,\n `Run \"ekanos apps show ${status.product.slug}\" for the Source's app.`,\n );\n }\n const app = connection\n ? apps.find((entry) => entry.connectionId === connection)\n : apps.length === 1\n ? apps[0]\n : apps.find((entry) => entry.connectionId === 'default');\n if (app) return app;\n throw usageError(\n connection\n ? `${status.product.name} has no team app \"${connection}\".`\n : `${status.product.name} has several team apps; name one.`,\n `Pass --connection with one of: ${apps.map((entry) => entry.connectionId).join(', ')}.`,\n );\n}\n\nexport class TeamsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<TeamsApiResult<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 teams call.`,\n loginHint(this.env),\n );\n }\n}\n\nexport function canPrompt(ctx: CliContext, args: TeamsArgs): boolean {\n return !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n}\n\n/** What the secret-input flags read from, with this run's test seams. */\nexport function teamsSecretIO(args: TeamsArgs): SecretIO {\n return {\n env: args.env,\n stdinIsTTY: args.stdinIsTTY ?? process.stdin.isTTY === true,\n readStdin: args.readStdin,\n openUrl: args.openUrl,\n formTimeoutMs: args.secretFormTimeoutMs,\n };\n}\n\nfunction parseSubcommand(value: string | undefined): TeamsSubcommand {\n const match = TEAMS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown teams subcommand \"${value}\".`\n : 'teams needs a subcommand.',\n 'Run one of: ekanos teams list, ekanos teams create <name>, ekanos teams rename <team> <name>, ekanos teams members list|add|invite|role|remove|resend <team> … (add <team> --self joins you), ekanos teams roles list <team>, ekanos teams leave <team> --yes, ekanos teams groups list|create|update|delete|members <team> …, ekanos teams health <team> [<product>] [--run] (<product> --mine: your own personal connection), ekanos teams workspace list|default <team> …, ekanos teams connect <team> <product>, ekanos teams disconnect <team> <product> --yes (--mine: your own personal connection), ekanos teams show <team> [<product>], ekanos teams app set <team> <product>, ekanos teams webhook <team> <product> [<webhook-id>], ekanos teams events <team> [<product>], ekanos teams scope show|set <team> …, ekanos teams agents|triggers|links|mcp|llm-key ….',\n );\n}\n\nfunction requireSlug(value: string | undefined, what: 'team' | 'product') {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value ? `\"${value}\" is not a ${what} slug.` : `Name the ${what}.`,\n what === 'team'\n ? '\"ekanos teams list\" lists the teams, e.g. \"ekanos teams show acme-support zendesk\".'\n : '\"ekanos catalog\" lists the products, e.g. \"ekanos teams show acme-support zendesk\".',\n );\n}\n\nfunction mark(done: boolean): string {\n return done ? '✓' : '✗';\n}\n\nfunction day(iso: string): string {\n return iso.slice(0, 10);\n}\n\nfunction who(member: {\n name: string | null;\n email: string | null;\n userId: string;\n}) {\n return member.email ?? member.name ?? member.userId;\n}\n\n/** Every redirect URI to register. */\nfunction callbackUrls(app: TeamAppState): string[] {\n return app.callbackUrls.length ? app.callbackUrls : [app.callbackUrl];\n}\n"]}
|
|
1
|
+
{"version":3,"file":"teams.js","sourceRoot":"","sources":["../../src/commands/teams.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n TeamAppState,\n TeamIntegrationStatus,\n} from '@ekanos/integration-schema';\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 usageError,\n validationError,\n} from '../errors';\nimport type { ExitCode } from '../exit-codes';\nimport { cli } from '../invocation';\nimport { ensureSecretsDir, writeSecretFile } from '../secret-file';\nimport {\n FIELD_SECRET_FORMS,\n type SecretFlags,\n type SecretIO,\n collectSecrets,\n parsePlainValues,\n readSecretFlags,\n secretInputGiven,\n} from '../secret-input';\nimport { resolveSourceTarget } from '../source-target';\nimport {\n type TeamsApiResult,\n listTeams,\n mintTeamWebhook,\n setTeamApp,\n showTeamIntegration,\n} from '../teams-api';\nimport { promptHidden, promptLine } from './apps';\nimport { scopeHiddenLines } from './scope-notice';\nimport { isTeamAgentArea, runTeamAgentCommands } from './team-agents';\nimport { runTeamAudience } from './teams-audience';\nimport { runTeamEvents } from './teams-events';\nimport {\n LIFECYCLE_SUBCOMMANDS,\n isLifecycleMemberVerb,\n isLifecycleSubcommand,\n parseLifecycle,\n runLifecycle,\n} from './teams-lifecycle';\nimport {\n ONBOARDING_SUBCOMMANDS,\n isOnboardingSubcommand,\n parseOnboarding,\n runOnboarding,\n} from './teams-onboard';\nimport { runTeamOverview } from './teams-overview';\nimport { runTeamScope } from './teams-scope';\n\nexport const TEAMS_SUBCOMMANDS = [\n 'list',\n 'show',\n 'app',\n 'webhook',\n 'events',\n 'scope',\n 'audience',\n ...ONBOARDING_SUBCOMMANDS,\n ...LIFECYCLE_SUBCOMMANDS,\n] as const;\ntype TeamsSubcommand = (typeof TEAMS_SUBCOMMANDS)[number];\n\nexport interface TeamsArgs {\n host?: string;\n source?: string;\n /** `list`, `show <team> [<product>]`, `app set <team> <product>`, `webhook <team> <product> [<id>]`. */\n positionals: readonly string[];\n connection?: string;\n /** `create --slug`, `create --owner <email>`, `members invite --role`. */\n slug?: string;\n owner?: string;\n role?: string;\n yes: boolean;\n /** `connect --no-wait`: print the sign-in link and return without polling. */\n noWait?: boolean;\n /** `connect --no-open`: never open a browser, only print the link. */\n noOpen?: boolean;\n /** `connect --link-only`: print the team's page, as before connect did the work. */\n linkOnly?: boolean;\n /** `connect --reconnect`: connect again though it reads as connected. */\n reconnect?: boolean;\n /** Test seams for `connect`: the wait between polls, and the browser opener. */\n pollDelayMs?: number;\n openUrl?: (url: string) => void;\n /** Every parsed flag, for `teams agents|triggers|links|mcp` (team-agents.ts). */\n flags?: Record<string, string | boolean | string[]>;\n dir: string;\n env: Record<string, string | undefined>;\n stdinIsTTY?: boolean;\n /** Test seams for the questions `app set` asks. */\n ask?: (question: string) => Promise<string>;\n askSecret?: (question: string) => Promise<string>;\n /** Test seams for the secret-input flags (`secret-input.ts`). */\n readStdin?: () => Promise<string>;\n secretFormTimeoutMs?: number;\n}\n\nexport interface Target {\n source: string;\n team: string;\n product: string;\n}\n\n/**\n * `teams` — a Source admin's view of its teams' integration setup, the\n * team-level counterpart of `apps`. `list` names the teams; `show` reads one\n * team's setup of one product as a checklist; `app set` enters or updates\n * any of a team's own app fields (Zendesk's subdomain, client and signing\n * secret), one at a time if need be — a field left alone keeps its saved\n * value. A secret is typed at the admin's terminal with hidden input or,\n * without one, read from the environment, a private file, stdin or a form\n * in the browser (`secret-input.ts`) — never a value in argv; a non-secret\n * field may be passed as `--set name=value`; `webhook` mints the URL the\n * team's provider sends to, shown once.\n */\nexport async function runTeams(\n ctx: CliContext,\n args: TeamsArgs,\n): Promise<ExitCode> {\n const [rawSubcommand, ...rest] = args.positionals;\n if (isTeamAgentArea(rawSubcommand)) {\n return runTeamAgentCommands(ctx, args);\n }\n const subcommand = parseSubcommand(rawSubcommand);\n\n if (subcommand === 'events') {\n return runTeamEvents(ctx, args, rest);\n }\n if (subcommand === 'scope') {\n return runTeamScope(ctx, args, rest);\n }\n if (subcommand === 'audience') {\n return runTeamAudience(ctx, args, rest);\n }\n\n if (\n isLifecycleSubcommand(subcommand) ||\n (subcommand === 'members' && isLifecycleMemberVerb(rest[0]))\n ) {\n return runLifecycle(ctx, args, parseLifecycle(subcommand, rest, args));\n }\n\n if (isOnboardingSubcommand(subcommand)) {\n const plan = parseOnboarding(subcommand, rest, {\n ...args,\n as: typeof args.flags?.as === 'string' ? args.flags.as : undefined,\n self: args.flags?.self === true,\n mine: args.flags?.mine === true,\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 return runOnboarding(\n ctx,\n args,\n new TeamsClient(env, resolved.session),\n env.host,\n resolved.source,\n plan,\n );\n }\n\n if (subcommand === 'app' && rest[0] !== 'set') {\n throw usageError(\n rest[0]\n ? `Unknown teams app subcommand \"${rest[0]}\".`\n : 'teams app needs a subcommand.',\n 'Run \"ekanos teams app set <team> <product>\".',\n );\n }\n const operands = subcommand === 'app' ? rest.slice(1) : rest;\n\n if (subcommand === 'list' && operands.length > 0) {\n throw usageError(\n 'teams list takes no arguments.',\n 'Run \"ekanos teams list --source <slug>\".',\n );\n }\n\n const team = subcommand === 'list' ? '' : requireSlug(operands[0], 'team');\n // `teams show <team>` alone is the team's overview.\n const overview = subcommand === 'show' && operands[1] === undefined;\n const product =\n subcommand === 'list' || overview\n ? ''\n : requireSlug(operands[1], 'product');\n const extra = operands.slice(subcommand === 'webhook' ? 3 : 2);\n const appEdits = subcommand === 'app' ? parseAppEdits(args.flags) : null;\n if (subcommand !== 'list' && extra.length > 0) {\n throw usageError(\n `Unexpected argument \"${extra[0]}\".`,\n 'See \"ekanos teams --help\".',\n );\n }\n\n if (\n appEdits?.prompts &&\n !canPrompt(ctx, args) &&\n !secretInputGiven(appEdits.secret)\n ) {\n throw usageError(\n \"teams app set needs the team's secrets, and there is no terminal to ask at. Non-secret fields can be passed with --set <name>=<value>.\",\n `Without a terminal, pass ${FIELD_SECRET_FORMS}. Or run it yourself in your terminal: ${cli()} teams app set ${team} ${product}${args.connection ? ` --connection ${args.connection}` : ''}${args.source ? ` --source ${args.source}` : ''}`,\n );\n }\n\n const env = resolveAuthEnvironment(ctx, args.host, args.env, {\n projectDir: args.dir,\n });\n const resolved = await resolveSourceTarget(env, requireSession(env), args);\n const client = new TeamsClient(env, resolved.session);\n const source = resolved.source;\n\n if (subcommand === 'list') {\n const list = await client.call((token) =>\n listTeams(env.host, token, source),\n );\n return ctx.succeed(\n { host: env.host, ...list },\n list.teams.length === 0\n ? ctx.ui.result({\n title: `No teams on ${list.source.slug}`,\n tone: 'warn',\n })\n : ctx.ui.result({\n title: `Teams on ${list.source.slug}`,\n rows: list.teams.map((entry) => [entry.slug, teamLine(entry)]),\n notes: [\n '\"ekanos teams show <team>\" shows a team\\'s setup; add a product for its checklist.',\n ...(list.teams.some(\n (entry) =>\n entry.callerIsMember === false && entry.memberCount > 0,\n )\n ? [\n 'You manage every team of the Source as its admin without being a member. To connect your own account to one, join it: \"ekanos teams members add <team> --self\".',\n ]\n : []),\n ],\n }),\n );\n }\n\n if (overview) {\n return runTeamOverview(ctx, client, env.host, source, team);\n }\n\n const target: Target = { source, team, product };\n const status = await client.call((token) =>\n showTeamIntegration(env.host, token, target),\n );\n\n if (subcommand === 'show') {\n return ctx.succeed(\n { host: env.host, ...status },\n checklist(status).join('\\n'),\n );\n }\n\n if (!status.enabled) {\n throw invalidStateError(\n `\"${product}\" is not enabled on ${status.source.slug}.`,\n `\"ekanos sources products --source ${status.source.slug}\" shows what it has; only a super-admin enables a product for a Source (in /admin).`,\n );\n }\n\n if (subcommand === 'app' && appEdits) {\n return setApp(ctx, args, client, env.host, target, status, appEdits);\n }\n return mintWebhook(ctx, args, client, env.host, target, status, operands[2]);\n}\n\n/** What `teams app set` was asked to change, from its flags. */\ninterface AppEdits {\n /** `--field`: enter just these, at the terminal. */\n only: string[];\n /** `--set name=value`: non-secret values, no prompt. */\n values: Record<string, string>;\n /** `--clear name`: remove a saved value. */\n clear: string[];\n /** `--secret-*`, `--set-secret`, `--browser`: where secrets come from without a terminal. */\n secret: SecretFlags;\n /** Whether any field is collected (asked, or read from the secret-input flags). */\n prompts: boolean;\n}\n\nfunction parseAppEdits(flags: TeamsArgs['flags']): AppEdits {\n const list = (name: string): string[] => {\n const raw = flags?.[name];\n if (raw === undefined || raw === false) return [];\n if (Array.isArray(raw)) return raw;\n return typeof raw === 'string' ? [raw] : [];\n };\n const values = parsePlainValues(flags?.set);\n const only = list('field');\n const clear = list('clear');\n const secret = readSecretFlags(flags);\n return {\n only,\n values,\n clear,\n secret,\n // Bare `app set` walks every field; `--field` asks the named ones.\n prompts:\n only.length > 0 ||\n secretInputGiven(secret) ||\n (Object.keys(values).length === 0 && clear.length === 0),\n };\n}\n\nasync function setApp(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: Target,\n status: TeamIntegrationStatus,\n edits: AppEdits,\n): Promise<ExitCode> {\n const app = chooseApp(status, args.connection);\n const result = await promptAndSaveTeamApp(\n ctx,\n args,\n client,\n host,\n target,\n status,\n app,\n edits,\n );\n const missing = result.fields.filter((field) => !field.set);\n const next = [\n ...(missing.length > 0\n ? [\n `Still not set: ${missing.map((field) => field.label).join(', ')} — a team member can't connect until it is. Run \"ekanos teams app set ${target.team} ${target.product} ${missing.map((field) => `--field ${field.secretName}`).join(' ')}\".`,\n ]\n : []),\n ...nextSteps(status, app, target),\n ];\n return ctx.succeed(\n { host, ...result },\n ctx.ui.result({\n title: `Saved ${target.team}'s ${result.product.name} app`,\n rows: [\n ['Source', status.source.slug],\n ['Fields', result.fields.map(fieldLine)],\n ],\n notes: next,\n }),\n );\n}\n\n/**\n * Every field, in turn: bare `teams app set`, and `teams connect` — whose\n * `--set` and secret-input flags fill the team's app too.\n */\nfunction walkEveryField(flags: TeamsArgs['flags']): AppEdits {\n return {\n only: [],\n values: parsePlainValues(flags?.set),\n clear: [],\n secret: readSecretFlags(flags),\n prompts: true,\n };\n}\n\n/**\n * The `teams app set` walkthrough and prompts for one team app, then the\n * save — of only what was entered: a field left empty keeps its saved value.\n * Shared with `teams connect`, which runs it inline when the integration\n * needs the team's own app (Zendesk) before anyone can sign in.\n */\nexport async function promptAndSaveTeamApp(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: Target,\n status: TeamIntegrationStatus,\n app: TeamAppState,\n edits: AppEdits = walkEveryField(args.flags),\n) {\n const known = new Map(app.fields.map((field) => [field.secretName, field]));\n const names = app.fields.map((field) => field.secretName).join(', ');\n for (const name of [\n ...edits.only,\n ...Object.keys(edits.values),\n ...edits.clear,\n ]) {\n if (!known.has(name)) {\n throw usageError(\n `${status.product.name}'s team app has no field \"${name}\".`,\n `Its fields are: ${names}.`,\n );\n }\n }\n for (const name of Object.keys(edits.values)) {\n if (known.get(name)?.sensitive) {\n throw usageError(\n `\"${name}\" is a secret: it is never passed as an argument.`,\n `Pass it as --set-secret ${name}=env:<NAME>|file:<path>|stdin, use --browser, or enter it at the prompt: ekanos teams app set ${target.team} ${target.product} --field ${name}`,\n );\n }\n }\n\n const fields: Record<string, string> = { ...edits.values };\n if (edits.prompts) {\n const toAsk =\n edits.only.length > 0\n ? app.fields.filter((field) => edits.only.includes(field.secretName))\n : app.fields;\n if (edits.only.length === 0)\n ctx.log(appWalkthrough(status, app).join('\\n'));\n else {\n ctx.log(\n `${status.product.name} app for team ${target.team} on ${status.source.slug}`,\n );\n }\n const byName = new Map(toAsk.map((field) => [field.secretName, field]));\n const again = `teams app set ${target.team} ${target.product}${args.connection ? ` --connection ${args.connection}` : ''} --source ${status.source.slug}`;\n Object.assign(\n fields,\n await collectSecrets(ctx, {\n fields: toAsk\n .filter((field) => edits.values[field.secretName] === undefined)\n .map((field) => ({\n name: field.secretName,\n label: field.label,\n sensitive: field.sensitive,\n set: field.set,\n value: field.sensitive ? null : field.value,\n })),\n flags: edits.secret,\n io: teamsSecretIO(args),\n interactive: canPrompt(ctx, args),\n title: `${status.product.name} app for team ${target.team}`,\n refusal: `${status.product.name}'s team app takes secrets (${toAsk\n .filter((field) => field.sensitive)\n .map((field) => field.secretName)\n .join(', ')}), and there is no terminal to ask at.`,\n again,\n prompt: (spec) => {\n const field = byName.get(spec.name)!;\n return (\n field.sensitive\n ? (args.askSecret ?? promptHidden)\n : (args.ask ?? promptLine)\n )(fieldQuestion(field));\n },\n }),\n );\n }\n\n if (Object.keys(fields).length === 0 && edits.clear.length === 0) {\n throw validationError(\n 'Nothing was changed.',\n `Run \"ekanos teams show ${target.team} ${target.product}\" to see the current state.`,\n );\n }\n\n return client.call((token) =>\n setTeamApp(host, token, target, {\n connectionId: app.connectionId,\n fields,\n ...(edits.clear.length > 0 ? { clear: edits.clear } : {}),\n }),\n );\n}\n\n/** The prompt for one field: what is saved, and that Enter keeps it. */\nfunction fieldQuestion(field: TeamAppState['fields'][number]): string {\n const name = `${field.label} [${field.secretName}]`;\n if (field.sensitive) {\n return field.set\n ? `${name} (saved — Enter to keep, hidden): `\n : `${name} (hidden): `;\n }\n if (field.set) {\n return field.value\n ? `${name} (current: ${field.value} — Enter to keep): `\n : `${name} (saved — Enter to keep): `;\n }\n return `${name}: `;\n}\n\n/** One field's state: a secret only as saved / not set, never its value. */\nfunction fieldLine(field: TeamAppState['fields'][number]): string {\n const state = !field.set\n ? 'not set'\n : field.sensitive\n ? 'saved'\n : field.value\n ? field.value\n : 'saved';\n return `${mark(field.set)} ${field.label} (${field.secretName}): ${state}`;\n}\n\nasync function mintWebhook(\n ctx: CliContext,\n args: TeamsArgs,\n client: TeamsClient,\n host: string,\n target: Target,\n status: TeamIntegrationStatus,\n requested: string | undefined,\n): Promise<ExitCode> {\n const webhooks = status.teamApps.flatMap((app) => app.webhooks);\n if (webhooks.length === 0) {\n throw invalidStateError(\n `${status.product.name} has no webhook a team's app sends.`,\n `Run \"ekanos teams show ${target.team} ${target.product}\" to see its setup.`,\n );\n }\n const webhook = requested\n ? webhooks.find((entry) => entry.webhookId === requested)\n : webhooks.length === 1\n ? webhooks[0]\n : undefined;\n if (!webhook) {\n throw usageError(\n requested\n ? `${status.product.name} has no team-app webhook \"${requested}\".`\n : `${status.product.name} has several webhooks; name one.`,\n `Run one of: ${webhooks.map((entry) => `ekanos teams webhook ${target.team} ${target.product} ${entry.webhookId}`).join(', ')}.`,\n );\n }\n\n if (webhook.endpoint && !args.yes) {\n throw invalidStateError(\n `${target.team} already has a live URL for ${webhook.webhookId} (${webhook.endpoint.tokenPrefix}…). A new one revokes it, and the provider's webhook stops working until you paste the new URL there.`,\n `Re-run with --yes when you are ready to update the provider: ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId} --yes`,\n );\n }\n\n // The URL carries its token, so it goes to a 0600 file, never the output.\n const secrets = ensureSecretsDir(args.env);\n const minted = await client.call((token) =>\n mintTeamWebhook(host, token, target, webhook.webhookId),\n );\n const { url, ...rest } = minted;\n const secretFile = writeSecretFile(secrets, {\n owner: target.team,\n what: `${target.product}-${webhook.webhookId}-webhook-url`,\n purpose: `Webhook URL for team ${target.team}'s ${status.product.name} (${webhook.webhookId}). Paste it into ${status.product.name}'s webhook settings for this team; the token is part of the URL.`,\n values: [['WEBHOOK_URL', url]],\n again: `ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId} --yes`,\n });\n return ctx.succeed(\n { host, ...rest, secretFile },\n ctx.ui.result({\n title: `Webhook URL for ${target.team} · ${webhook.webhookId}`,\n tone: 'warn',\n rows: [\n ['URL', `saved to ${secretFile} (readable only by you)`],\n [\n 'Paste it into',\n `${status.product.name}'s webhook settings for this team`,\n ],\n ],\n notes: [\n 'The URL carries its token, so it is shown nowhere else and cannot be read again. Copy it from that file into the provider yourself — not into a chat or an agent session — then delete the file.',\n ...(minted.replaced\n ? ['The previous URL is revoked: the provider must use this one.']\n : []),\n ],\n }),\n );\n}\n\n/** `teams show`, read top to bottom like a setup checklist. */\nexport function checklist(status: TeamIntegrationStatus): string[] {\n const name = status.product.name;\n const lines = [\n `${name} for team ${status.team.slug} (${status.team.name}) on ${status.source.slug}`,\n ` ${mark(status.enabled)} Enabled on the Source`,\n ];\n if (!status.enabled) {\n lines.push(\n ` \"ekanos sources products --source ${status.source.slug}\" shows what it has; only a super-admin enables a product for a Source (in /admin).`,\n );\n return lines;\n }\n\n const target = { team: status.team.slug, product: status.product.slug };\n lines.push(\n ...scopeHiddenLines(status.scope, {\n ...target,\n source: status.source.slug,\n }).map((line) => ` ${line}`),\n );\n lines.push(...connectionLines(status));\n for (const app of status.teamApps) {\n lines.push(` Team app: ${app.label} (${app.connectionId})`);\n if (app.setup?.consoleUrl) lines.push(` Open: ${app.setup.consoleUrl}`);\n app.setup?.steps.forEach((step, index) =>\n lines.push(` ${index + 1}. ${step}`),\n );\n lines.push(' Callback URLs to register:');\n lines.push(...callbackUrls(app).map((url) => ` ${url}`));\n if (app.guideUrl) lines.push(` Guide: ${app.guideUrl}`);\n for (const field of app.fields) {\n lines.push(` ${fieldLine(field)}`);\n }\n const unset = app.fields.filter((field) => !field.set);\n if (unset.length > 0) {\n lines.push(\n ` → in your terminal: ${cli()} teams app set ${target.team} ${target.product} --connection ${app.connectionId} ${unset.map((field) => `--field ${field.secretName}`).join(' ')} --source ${status.source.slug}`,\n );\n }\n for (const webhook of app.webhooks) {\n lines.push(\n webhook.endpoint\n ? ` ${mark(true)} Webhook ${webhook.webhookId}: live URL ${webhook.endpoint.tokenPrefix}… since ${day(webhook.endpoint.createdAt)}${webhook.endpoint.lastUsedAt ? `, last delivery ${day(webhook.endpoint.lastUsedAt)}` : ', no delivery yet'}`\n : ` ${mark(false)} Webhook ${webhook.webhookId}: no URL yet`,\n );\n if (!webhook.endpoint) {\n lines.push(\n ` → ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId} --source ${status.source.slug}`,\n );\n }\n }\n lines.push(\n app.connection\n ? ` ${mark(true)} Connected ${day(app.connection.connectedAt)}${app.connection.connectedBy ? ` by ${who(app.connection.connectedBy)}` : ''}`\n : ` ${mark(false)} Connected: not yet\\n → in your terminal: ${connectCommand(status, app.connectionId)}`,\n );\n }\n\n lines.push(\n status.activation\n ? ` ${mark(true)} Activated for the team${status.activation.activatedAt ? ` ${day(status.activation.activatedAt)}` : ''}${status.activation.activatedBy ? ` by ${who(status.activation.activatedBy)}` : ''}`\n : ` ${mark(false)} Activated: not yet\\n → in your terminal: ${connectCommand(status)}`,\n );\n lines.push(` Team page: ${status.connectUrl}`);\n if (status.agentEvents.length > 0) {\n lines.push(' Agent events it offers:');\n lines.push(\n ...status.agentEvents.map((event) => ` ${event.id} — ${event.label}`),\n );\n }\n return lines;\n}\n\n/**\n * Each OAuth connection in one line — connected, or installed for a named\n * one, with its app's credentials and webhook URL — and which of the team's\n * agents wait on it. A named connection an agent's trigger needs and the team\n * has not installed is the gap no other line names: the trigger is stored\n * and on, and nothing ever reaches it.\n */\nfunction connectionLines(status: TeamIntegrationStatus): string[] {\n const connections = status.connections ?? [];\n if (connections.length === 0) return [];\n const lines = [' Connections:'];\n for (const entry of connections) {\n const named = entry.connectionId !== 'default';\n const app = status.teamApps.find(\n (candidate) => candidate.connectionId === entry.connectionId,\n );\n const webhooks = app?.webhooks ?? [];\n const steps = [\n ...(entry.credentialsSaved === null\n ? []\n : [\n `app credentials ${entry.credentialsSaved ? 'saved' : 'not saved'}`,\n ]),\n named\n ? entry.connected\n ? `installed ${day(entry.connectedAt ?? '')}`\n : 'not installed'\n : entry.connected\n ? `connected ${day(entry.connectedAt ?? '')}`\n : 'not connected',\n ...(webhooks.length > 0\n ? [\n webhooks.every((webhook) => webhook.endpoint)\n ? 'webhook URL made'\n : 'no webhook URL',\n ]\n : []),\n ];\n const ready =\n entry.connected &&\n entry.credentialsSaved !== false &&\n webhooks.every((webhook) => webhook.endpoint);\n lines.push(\n ` ${mark(ready)} ${entry.label} (${entry.connectionId}): ${steps.join(' · ')}${entry.connectedBy ? ` by ${who(entry.connectedBy)}` : ''}`,\n );\n if (entry.neededBy.length > 0) {\n lines.push(\n ` Needed by: ${entry.neededBy.map((need) => `${need.agent} (${need.triggers.join(', ')})`).join(', ')}`,\n );\n }\n if (!entry.connected) {\n lines.push(\n ` → in your terminal: ${connectCommand(status, entry.connectionId)}`,\n );\n }\n }\n return lines;\n}\n\n/**\n * One team in `teams list`: its members, and whether the caller is one. A\n * team nobody has joined says so with the command that joins it, rather than\n * reading as a count of zero.\n */\nexport function teamLine(entry: {\n slug: string;\n name: string;\n memberCount: number;\n callerIsMember?: boolean;\n}): string {\n const count = `${entry.memberCount} member${entry.memberCount === 1 ? '' : 's'}`;\n if (entry.callerIsMember === undefined) return `${entry.name} · ${count}`;\n if (entry.callerIsMember) return `${entry.name} · ${count}, you among them`;\n return entry.memberCount === 0\n ? `${entry.name} · 0 members · you are not a member — ekanos teams members add ${entry.slug} --self`\n : `${entry.name} · ${count} · you are not a member`;\n}\n\n/** The command that connects the team, for a hint: `--connection` only for a named one. */\nfunction connectCommand(\n status: TeamIntegrationStatus,\n connectionId = 'default',\n): string {\n return `${cli()} teams connect ${status.team.slug} ${status.product.slug}${connectionId === 'default' ? '' : ` --connection ${connectionId}`} --source ${status.source.slug}`;\n}\n\nfunction appWalkthrough(\n status: TeamIntegrationStatus,\n app: TeamAppState,\n): string[] {\n const lines = [\n `${status.product.name} app for team ${status.team.slug} on ${status.source.slug}`,\n ];\n if (app.setup?.consoleUrl) lines.push(` Open: ${app.setup.consoleUrl}`);\n const steps = app.setup?.steps.length\n ? [...app.setup.steps]\n : [\n `In ${status.product.name}, create an OAuth app for the team (or open the one it uses).`,\n ];\n steps.push(\n `Check the app lists exactly: ${callbackUrls(app).join(', ')}`,\n \"Enter its values below. Secrets are stored in Ekanos's vault and never shown again.\",\n );\n lines.push(...steps.map((step, index) => ` ${index + 1}. ${step}`));\n if (app.guideUrl) lines.push(` Guide: ${app.guideUrl}`);\n return lines;\n}\n\nfunction nextSteps(\n status: TeamIntegrationStatus,\n app: TeamAppState,\n target: Target,\n): string[] {\n return [\n ...app.webhooks\n .filter((webhook) => !webhook.endpoint)\n .map(\n (webhook) =>\n `Next: \"ekanos teams webhook ${target.team} ${target.product} ${webhook.webhookId}\" for the provider's webhook URL.`,\n ),\n ...(app.connection\n ? []\n : [`Then connect it: ${connectCommand(status, app.connectionId)}`]),\n ];\n}\n\nexport function chooseApp(\n status: TeamIntegrationStatus,\n connection: string | undefined,\n): TeamAppState {\n const apps = status.teamApps;\n if (apps.length === 0) {\n throw invalidStateError(\n `${status.product.name} takes no team app: teams connect through the Source's app, or need none.`,\n `Run \"ekanos apps show ${status.product.slug}\" for the Source's app.`,\n );\n }\n const app = connection\n ? apps.find((entry) => entry.connectionId === connection)\n : apps.length === 1\n ? apps[0]\n : apps.find((entry) => entry.connectionId === 'default');\n if (app) return app;\n throw usageError(\n connection\n ? `${status.product.name} has no team app \"${connection}\".`\n : `${status.product.name} has several team apps; name one.`,\n `Pass --connection with one of: ${apps.map((entry) => entry.connectionId).join(', ')}.`,\n );\n}\n\nexport class TeamsClient {\n constructor(\n private readonly env: AuthEnvironment,\n private session: StoredSession,\n ) {}\n\n async call<T>(\n send: (accessToken: string) => Promise<TeamsApiResult<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 teams call.`,\n loginHint(this.env),\n );\n }\n}\n\nexport function canPrompt(ctx: CliContext, args: TeamsArgs): boolean {\n return !ctx.jsonMode && (args.stdinIsTTY ?? process.stdin.isTTY === true);\n}\n\n/** What the secret-input flags read from, with this run's test seams. */\nexport function teamsSecretIO(args: TeamsArgs): SecretIO {\n return {\n env: args.env,\n stdinIsTTY: args.stdinIsTTY ?? process.stdin.isTTY === true,\n readStdin: args.readStdin,\n openUrl: args.openUrl,\n formTimeoutMs: args.secretFormTimeoutMs,\n };\n}\n\nfunction parseSubcommand(value: string | undefined): TeamsSubcommand {\n const match = TEAMS_SUBCOMMANDS.find((name) => name === value);\n if (match) return match;\n throw usageError(\n value\n ? `Unknown teams subcommand \"${value}\".`\n : 'teams needs a subcommand.',\n 'Run one of: ekanos teams list, ekanos teams create <name>, ekanos teams rename <team> <name>, ekanos teams members list|add|invite|role|remove|resend <team> … (add <team> --self joins you), ekanos teams roles list <team>, ekanos teams leave <team> --yes, ekanos teams groups list|create|update|delete|members <team> …, ekanos teams health <team> [<product>] [--run] (<product> --mine: your own personal connection), ekanos teams workspace list|default <team> …, ekanos teams connect <team> <product>, ekanos teams disconnect <team> <product> --yes (--mine: your own personal connection), ekanos teams show <team> [<product>], ekanos teams app set <team> <product>, ekanos teams webhook <team> <product> [<webhook-id>], ekanos teams events <team> [<product>], ekanos teams audience <team> [<audience>] [--member <email>], ekanos teams scope show|set <team> … (deprecated: audiences), ekanos teams agents|triggers|links|mcp|llm-key ….',\n );\n}\n\nfunction requireSlug(value: string | undefined, what: 'team' | 'product') {\n const slug = value?.trim().toLowerCase();\n if (slug && /^[a-z0-9][a-z0-9-]*$/.test(slug)) return slug;\n throw usageError(\n value ? `\"${value}\" is not a ${what} slug.` : `Name the ${what}.`,\n what === 'team'\n ? '\"ekanos teams list\" lists the teams, e.g. \"ekanos teams show acme-support zendesk\".'\n : '\"ekanos catalog\" lists the products, e.g. \"ekanos teams show acme-support zendesk\".',\n );\n}\n\nfunction mark(done: boolean): string {\n return done ? '✓' : '✗';\n}\n\nfunction day(iso: string): string {\n return iso.slice(0, 10);\n}\n\nfunction who(member: {\n name: string | null;\n email: string | null;\n userId: string;\n}) {\n return member.email ?? member.name ?? member.userId;\n}\n\n/** Every redirect URI to register. */\nfunction callbackUrls(app: TeamAppState): string[] {\n return app.callbackUrls.length ? app.callbackUrls : [app.callbackUrl];\n}\n"]}
|