@ekanos/cli 0.12.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (175) hide show
  1. package/README.md +25 -8
  2. package/dist/agents-api.d.ts +11 -2
  3. package/dist/agents-api.js +39 -3
  4. package/dist/agents-api.js.map +1 -1
  5. package/dist/apps-api.d.ts +3 -2
  6. package/dist/apps-api.js +3 -7
  7. package/dist/apps-api.js.map +1 -1
  8. package/dist/auth/ekanos-api.d.ts +16 -2
  9. package/dist/auth/ekanos-api.js +101 -15
  10. package/dist/auth/ekanos-api.js.map +1 -1
  11. package/dist/auth/host-trust.d.ts +46 -0
  12. package/dist/auth/host-trust.js +79 -0
  13. package/dist/auth/host-trust.js.map +1 -0
  14. package/dist/auth/session.d.ts +10 -1
  15. package/dist/auth/session.js +28 -28
  16. package/dist/auth/session.js.map +1 -1
  17. package/dist/commands/agents-edit.d.ts +6 -2
  18. package/dist/commands/agents-edit.js +57 -26
  19. package/dist/commands/agents-edit.js.map +1 -1
  20. package/dist/commands/agents.d.ts +13 -2
  21. package/dist/commands/agents.js +148 -36
  22. package/dist/commands/agents.js.map +1 -1
  23. package/dist/commands/apps.d.ts +15 -4
  24. package/dist/commands/apps.js +133 -51
  25. package/dist/commands/apps.js.map +1 -1
  26. package/dist/commands/catalog.js +7 -6
  27. package/dist/commands/catalog.js.map +1 -1
  28. package/dist/commands/knowledge.d.ts +56 -0
  29. package/dist/commands/knowledge.js +456 -0
  30. package/dist/commands/knowledge.js.map +1 -0
  31. package/dist/commands/login.d.ts +4 -0
  32. package/dist/commands/login.js +30 -2
  33. package/dist/commands/login.js.map +1 -1
  34. package/dist/commands/logout.d.ts +9 -1
  35. package/dist/commands/logout.js +56 -7
  36. package/dist/commands/logout.js.map +1 -1
  37. package/dist/commands/publish.js +3 -3
  38. package/dist/commands/publish.js.map +1 -1
  39. package/dist/commands/reviewers.d.ts +2 -0
  40. package/dist/commands/reviewers.js +7 -3
  41. package/dist/commands/reviewers.js.map +1 -1
  42. package/dist/commands/routes.d.ts +2 -0
  43. package/dist/commands/routes.js +42 -9
  44. package/dist/commands/routes.js.map +1 -1
  45. package/dist/commands/runs.d.ts +13 -2
  46. package/dist/commands/runs.js +96 -15
  47. package/dist/commands/runs.js.map +1 -1
  48. package/dist/commands/scope-notice.d.ts +21 -0
  49. package/dist/commands/scope-notice.js +35 -0
  50. package/dist/commands/scope-notice.js.map +1 -0
  51. package/dist/commands/skills.d.ts +7 -1
  52. package/dist/commands/skills.js +80 -24
  53. package/dist/commands/skills.js.map +1 -1
  54. package/dist/commands/sources.d.ts +4 -0
  55. package/dist/commands/sources.js +233 -5
  56. package/dist/commands/sources.js.map +1 -1
  57. package/dist/commands/status.js +5 -4
  58. package/dist/commands/status.js.map +1 -1
  59. package/dist/commands/team-agent-readiness.d.ts +59 -0
  60. package/dist/commands/team-agent-readiness.js +341 -0
  61. package/dist/commands/team-agent-readiness.js.map +1 -0
  62. package/dist/commands/team-agents-agents.d.ts +24 -3
  63. package/dist/commands/team-agents-agents.js +336 -35
  64. package/dist/commands/team-agents-agents.js.map +1 -1
  65. package/dist/commands/team-agents-mcp.js +32 -3
  66. package/dist/commands/team-agents-mcp.js.map +1 -1
  67. package/dist/commands/team-agents-triggers.js +230 -54
  68. package/dist/commands/team-agents-triggers.js.map +1 -1
  69. package/dist/commands/team-agents.d.ts +3 -1
  70. package/dist/commands/team-agents.js +27 -7
  71. package/dist/commands/team-agents.js.map +1 -1
  72. package/dist/commands/teams-channel-install.d.ts +24 -0
  73. package/dist/commands/teams-channel-install.js +94 -0
  74. package/dist/commands/teams-channel-install.js.map +1 -0
  75. package/dist/commands/teams-connect.d.ts +66 -0
  76. package/dist/commands/teams-connect.js +397 -0
  77. package/dist/commands/teams-connect.js.map +1 -0
  78. package/dist/commands/teams-events.d.ts +12 -0
  79. package/dist/commands/teams-events.js +138 -0
  80. package/dist/commands/teams-events.js.map +1 -0
  81. package/dist/commands/teams-onboard.d.ts +16 -5
  82. package/dist/commands/teams-onboard.js +61 -36
  83. package/dist/commands/teams-onboard.js.map +1 -1
  84. package/dist/commands/teams-overview.d.ts +11 -0
  85. package/dist/commands/teams-overview.js +160 -0
  86. package/dist/commands/teams-overview.js.map +1 -0
  87. package/dist/commands/teams-scope.d.ts +10 -0
  88. package/dist/commands/teams-scope.js +109 -0
  89. package/dist/commands/teams-scope.js.map +1 -0
  90. package/dist/commands/teams.d.ts +64 -7
  91. package/dist/commands/teams.js +254 -60
  92. package/dist/commands/teams.js.map +1 -1
  93. package/dist/commands/upgrade.js +12 -2
  94. package/dist/commands/upgrade.js.map +1 -1
  95. package/dist/commands/use.js +2 -2
  96. package/dist/commands/use.js.map +1 -1
  97. package/dist/commands/whoami.js +1 -1
  98. package/dist/commands/whoami.js.map +1 -1
  99. package/dist/connections-api.js +1 -1
  100. package/dist/connections-api.js.map +1 -1
  101. package/dist/delegate.js +11 -4
  102. package/dist/delegate.js.map +1 -1
  103. package/dist/harness-scaffold.js +12 -0
  104. package/dist/harness-scaffold.js.map +1 -1
  105. package/dist/index.d.ts +6 -0
  106. package/dist/index.js +724 -152
  107. package/dist/index.js.map +1 -1
  108. package/dist/knowledge-api.d.ts +175 -0
  109. package/dist/knowledge-api.js +169 -0
  110. package/dist/knowledge-api.js.map +1 -0
  111. package/dist/open-url.d.ts +16 -0
  112. package/dist/open-url.js +73 -0
  113. package/dist/open-url.js.map +1 -0
  114. package/dist/parse-argv.d.ts +2 -0
  115. package/dist/parse-argv.js.map +1 -1
  116. package/dist/publish-api.d.ts +2 -1
  117. package/dist/publish-api.js +4 -3
  118. package/dist/publish-api.js.map +1 -1
  119. package/dist/pull-write.d.ts +27 -0
  120. package/dist/pull-write.js +60 -0
  121. package/dist/pull-write.js.map +1 -0
  122. package/dist/routes-api.d.ts +3 -0
  123. package/dist/routes-api.js +9 -4
  124. package/dist/routes-api.js.map +1 -1
  125. package/dist/runs-api.d.ts +7 -1
  126. package/dist/runs-api.js +21 -6
  127. package/dist/runs-api.js.map +1 -1
  128. package/dist/safe-fs.d.ts +2 -0
  129. package/dist/safe-fs.js +12 -6
  130. package/dist/safe-fs.js.map +1 -1
  131. package/dist/secret-file.d.ts +17 -0
  132. package/dist/secret-file.js +69 -0
  133. package/dist/secret-file.js.map +1 -0
  134. package/dist/skills-api.d.ts +10 -2
  135. package/dist/skills-api.js +37 -2
  136. package/dist/skills-api.js.map +1 -1
  137. package/dist/source-products-api.d.ts +63 -0
  138. package/dist/source-products-api.js +123 -0
  139. package/dist/source-products-api.js.map +1 -0
  140. package/dist/source-target.js +2 -1
  141. package/dist/source-target.js.map +1 -1
  142. package/dist/sources-api.d.ts +2 -1
  143. package/dist/sources-api.js +3 -2
  144. package/dist/sources-api.js.map +1 -1
  145. package/dist/team-connect-api.d.ts +286 -0
  146. package/dist/team-connect-api.js +107 -0
  147. package/dist/team-connect-api.js.map +1 -0
  148. package/dist/teams-api.d.ts +42 -1
  149. package/dist/teams-api.js +98 -20
  150. package/dist/teams-api.js.map +1 -1
  151. package/dist/toolchain-api.d.ts +9 -0
  152. package/dist/toolchain-api.js +17 -2
  153. package/dist/toolchain-api.js.map +1 -1
  154. package/dist/toolchain-resolve.d.ts +3 -0
  155. package/dist/toolchain-resolve.js +15 -1
  156. package/dist/toolchain-resolve.js.map +1 -1
  157. package/dist/toolchain.d.ts +6 -0
  158. package/dist/toolchain.js +19 -0
  159. package/dist/toolchain.js.map +1 -1
  160. package/dist/update-notice.js +2 -1
  161. package/dist/update-notice.js.map +1 -1
  162. package/package.json +2 -2
  163. package/templates/AGENTS.md.tmpl +6 -1
  164. package/templates/claude-skill.md.tmpl +5 -0
  165. package/templates/package.json.tmpl +4 -4
  166. package/templates/skills/build-agent/SKILL.md +115 -16
  167. package/templates/skills/build-agent/references/agent-json.md +26 -8
  168. package/templates/skills/build-agent/references/app-setup.md +2 -1
  169. package/templates/skills/build-agent/references/rollout.md +27 -4
  170. package/templates/skills/build-agent/references/set-up-an-integration.md +74 -15
  171. package/templates/skills/build-agent/references/skills.md +20 -1
  172. package/templates/skills/build-agent/references/triggers.md +84 -20
  173. package/templates/skills/build-integration/references/widget-design.md +3 -3
  174. package/templates/skills/ekanos-platform/SKILL.md +70 -17
  175. package/templates/skills/polish-widgets/references/patterns.md +2 -2
@@ -37,6 +37,19 @@ as "what it is — when to use it".
37
37
  | **Source** (default) | `ekanos skills push <dir>` | Every team on the Source. An agent template may name it in `skills`. |
38
38
  | **Team** | `ekanos skills push <dir> --team <team-slug>` | That one team only. For content another team must not see (one bank's own guide). |
39
39
 
40
+ A template can't name a team skill, so a provided agent reads one only once
41
+ it is **attached** on that team, and only when the template allows team
42
+ skills (`"teamCustomization": { "skills": true }` in `agent.json`, applied
43
+ and published):
44
+
45
+ ```bash
46
+ npx @ekanos/cli teams agents skills <team> <key> --source <slug> # what it reads, and whether the team may add
47
+ npx @ekanos/cli teams agents skills <team> <key> add <skill-slug> --source <slug> # attach (team, Source or platform skill)
48
+ npx @ekanos/cli teams agents skills <team> <key> remove <skill-slug> --source <slug>
49
+ ```
50
+
51
+ The template's own skills stay; `remove` refuses them.
52
+
40
53
  Pushing is a Source admin's. A push is **live at once**: there is no draft
41
54
  and no publish step, and every agent naming the skill reads the new version
42
55
  on its next run. Show the user the folder before pushing it.
@@ -48,13 +61,19 @@ npx @ekanos/cli skills list --source <slug> --json # the Source's +
48
61
  npx @ekanos/cli skills list --team <team> --source <slug> # one team's own
49
62
  npx @ekanos/cli skills show <slug> --source <slug> # files, versions
50
63
  npx @ekanos/cli skills push agents/<key>/skills/<slug> --source <slug> --json
51
- npx @ekanos/cli skills pull <slug> --source <slug> [--out <dir>]
64
+ npx @ekanos/cli skills pull <slug> --source <slug> [--out <dir>] [--force] # --force: overwrite local edits
52
65
  ```
53
66
 
54
67
  `push` prints what changed (files added, changed, removed) and the new
55
68
  version; an identical folder is `unchanged` and stores nothing — safe to run
56
69
  again.
57
70
 
71
+ `npx @ekanos/cli skills archive <slug> [--team <team>] --source <slug> --yes`
72
+ retires a skill (only on the user's explicit yes): no agent can name it and a
73
+ push to it is refused until `skills unarchive <slug>`. It is refused while an
74
+ agent names it or a team agent has it attached; the refusal lists each use
75
+ and the command that stops it. Platform skills cannot be archived.
76
+
58
77
  ## With `agents apply`
59
78
 
60
79
  `ekanos agents apply agents/<key>` pushes every `agents/<key>/skills/<slug>/`
@@ -13,14 +13,31 @@ Ask in the interview: should the Source set what starts the agent for every
13
13
  team (recommended when every team works the same way), or each team? Either
14
14
  way say what each team must connect first, so the checklist is complete.
15
15
  A webhook trigger's secret is always per team: the template declares the
16
- trigger, each team creates or rotates its own secret in the app.
16
+ trigger, each team creates or rotates its own secret in the app, or a
17
+ Source admin does with `ekanos teams triggers rotate <team> <key> <trigger-key>`
18
+ (shown once, saved to a file only the user can read and named in the
19
+ output — the user copies it to the sender; never open or print that file
20
+ yourself; replacing a live one needs `--yes`).
17
21
 
18
22
  A Source admin can add them for the team from the terminal instead:
19
23
  `ekanos teams triggers list|add|remove <team> <key> …` — for example
20
24
  `ekanos teams triggers add acme-support support-agent event zendesk.ticket_created --filter '{"tags":["billing"]}'`,
21
25
  `… schedule --cron "0 9 * * 1-5" --timezone America/Los_Angeles --prompt "…"`,
22
26
  `… webhook --prompt "…"` (prints the URL and token once) or `… manual`.
23
- Slack and Linear triggers are added in the app. When a provided agent's
27
+ Any event in a connected integration's `agentEvents` is added this way,
28
+ including every Linear integration event (`event linear.issue_labeled
29
+ --filter '{"labels":["feedback"]}'`). A **Slack** trigger and a **Linear
30
+ (Agents app)** trigger — Ekanos's own Linear app, which answers @mentions
31
+ and assignments — answer through an install the team makes first:
32
+ `ekanos teams connect <team> slack` or `ekanos teams connect <team>
33
+ linear-app` (a one-time link for a team member, opened and waited on like
34
+ any `teams connect`). Then `ekanos teams triggers add <team> <key> slack
35
+ --channel '#support' [--dms] --yes` (the bot must be in each channel; `--yes`
36
+ confirms that anyone there can ask the agent to act) or `… linear [--label
37
+ <name>]… [--no-mention]`. That app is not
38
+ the Linear integration, and its limits are not the integration's: an agent
39
+ that should start when a label is applied uses `linear.issue_labeled`, not an
40
+ @mention. When a provided agent's
24
41
  template declares triggers and has not turned on team overrides for them, the
25
42
  team's triggers follow the template and these commands refuse to change them.
26
43
 
@@ -39,30 +56,77 @@ team's triggers follow the template and these commands refuse to change them.
39
56
 
40
57
  ## Integrations with agent events
41
58
 
42
- Check `ekanos catalog <product> --source <slug> --json` for what is actually
43
- there; these are the known shapes.
59
+ `ekanos catalog <product> --source <slug> --json` is the authority: its
60
+ `agentEvents` lists **every** event the product declares, with each one's
61
+ filter keys (`filterFields`). The lists below are the known shapes; never
62
+ conclude a product lacks an event because an example here or elsewhere
63
+ names only one. A refused event id is answered with the ids the product
64
+ does declare, and a refused filter with the keys the event takes.
44
65
 
45
- **Linear** (`linear.mentioned`, `linear.assigned`, `linear.issue_labeled`) —
46
- the agent becomes a teammate in Linear: @mention it, assign it an issue, or
47
- apply a label. Each team needs two things in the app: each person's own
48
- Linear connection (for the tools), and the team's own Linear app for the
49
- agent (client id, secret and webhook signing secret, entered in Ekanos).
66
+ An event can be declared and still never fire for a team until the team
67
+ finishes that event's own setup on the provider's side. That is a setup
68
+ step, not a missing event — say which step, as below.
69
+
70
+ **Linear** — the agent becomes a teammate in Linear. Each team needs two
71
+ identities, and they are not the same thing:
72
+
73
+ - **The personal connection** (`default`): someone's own Linear sign-in, for
74
+ the agent's tools. `teams connect <team> linear`.
75
+ - **The Linear agent** (`agent`): the team's own Linear app, installed in its
76
+ workspace as a member people can @mention and assign. Linear sends every
77
+ agent event below only to an installed app, so **without it no Linear
78
+ trigger ever fires** — the trigger is saved, on, and silent.
79
+ `teams connect <team> linear --connection agent` (asks for the app's client
80
+ id, secret and webhook signing secret, opens the install, waits), plus the
81
+ webhook URL: `teams webhook <team> linear agent-events`.
82
+
83
+ Check both with `teams show <team> linear`: under **Connections**, `default`
84
+ connected, and `agent` with app credentials saved, installed and its webhook
85
+ URL made. `teams agents list <team>` lists a Linear-triggered agent whose
86
+ agent is not installed as missing ("Linear agent not installed for this
87
+ team"), and the agent's Setup tab in the app says the same.
50
88
  Guide: https://sdk.ekanos.dev/guides/linear-agent
51
89
 
52
- **Zendesk** (`zendesk.ticket_created`, `zendesk.comment_added`; filters such
53
- as brand, group, tags, organization) — when present in the catalog, each team
54
- connects its own Zendesk (subdomain plus an OAuth client it creates in
55
- Zendesk) and adds a Zendesk webhook pointing at its Ekanos endpoint
56
- (walk-through: `set-up-an-integration.md`, worked example). The agent
57
- answers on the ticket as a public reply or an internal note — recommend
58
- internal notes, or approval on public replies, until the team trusts it.
90
+ Every event needs the Linear agent installed; the last column is what the
91
+ installed app's webhook must also send.
92
+
93
+ | Event | Starts when | Filter keys | Needs on the team's Linear app |
94
+ |---|---|---|---|
95
+ | `linear.mentioned` | someone @mentions the agent, or writes to it again in that conversation | `teamKeys` | webhook with **Agent session events** ticked |
96
+ | `linear.assigned` | someone assigns (delegates) an issue to the agent | `teamKeys` | webhook with **Agent session events** ticked |
97
+ | `linear.issue_labeled` | someone applies one of the given labels to an issue | `labels` (**required**), `teamKeys` | webhook with **Issues** ticked |
98
+ | `linear.issue_created` | someone creates an issue (optionally only with given labels) | `labels`, `teamKeys` | webhook with **Issues** ticked |
99
+
100
+ **Zendesk** — each team connects its own Zendesk (subdomain plus an OAuth
101
+ client it creates in Zendesk) and adds a Zendesk webhook pointing at its
102
+ Ekanos endpoint (walk-through: `set-up-an-integration.md`, worked example).
103
+ The agent answers on the ticket as a public reply or an internal note —
104
+ recommend internal notes, or approval on public replies, until the team
105
+ trusts it.
106
+
107
+ | Event | Starts when | Filter keys | Needs in Zendesk |
108
+ |---|---|---|---|
109
+ | `zendesk.ticket_created` | a new ticket arrives | `brands`, `groups`, `tags`, `organizations` | a Zendesk trigger on *Ticket is Created* notifying the webhook |
110
+ | `zendesk.comment_added` | an end user (requester or CC) comments on a ticket; agent and admin comments never start it | `brands`, `groups`, `tags`, `organizations` | a **second** Zendesk trigger, on a customer's public reply, notifying the webhook |
111
+
112
+ Filter values are lists (`{"tags":["billing"],"brands":["Acme Support"]}`);
113
+ brands, groups and organizations match by name or id. Where the answer goes
114
+ (`reply_as`) is set in the Zendesk trigger's body, not in the filter.
59
115
 
60
116
  ## Checklist to hand each team
61
117
 
62
118
  1. Agents → "Provided for your team" → Turn on.
63
119
  2. Connect every `required` product and sign in to any MCP server that needs
64
120
  it (the agent shows what is missing).
65
- 3. Do each integration's own setup (team app, webhook) from its guide.
66
- 4. Confirm access if asked.
67
- 5. Add the triggers above — unless the template already sets them — then
68
- run one real example and review it.
121
+ 3. Install the channel each trigger listens on: for any Linear trigger the
122
+ Linear agent (`teams connect <team> linear --connection agent`, and its
123
+ webhook URL), for a Slack trigger the team's Slack. `teams agents list
124
+ <team>` shows each agent's `channels`; none may be `ready: false`.
125
+ 4. Do each integration's own setup (team app, webhook) from its guide.
126
+ 5. Confirm access: the person it runs as runs `npx @ekanos/cli teams agents
127
+ confirm <team> <key> --source <slug>` as themselves (or turned it on with
128
+ `--confirm-access`). `teams agents list <team>` shows anyone still to.
129
+ 6. Add the triggers above — unless the template already sets them.
130
+ 7. Prove it end to end: a real @mention (or the real event) → a run in
131
+ `runs list --team <team>` → the agent's reply where it was asked. A test
132
+ run started by hand does not count; it passes without the channel.
@@ -77,9 +77,9 @@ import {
77
77
  </Stat>;
78
78
  ```
79
79
 
80
- - `StatLabel` is uppercase `text-xs` — the one place `text-xs` is a primary
81
- label. `StatValue` is the heading face at `text-2xl`, `tracking-tight`,
82
- `tabular-nums`. Do not override those sizes.
80
+ - `StatLabel` is the uppercase `text-eyebrow` overline. `StatValue` is
81
+ `figure`: the heading face at the Headline tier, tabular. Do not override
82
+ those sizes.
83
83
  - `StatChange`'s `tone` is the READING, not the direction: expenses falling is
84
84
  `positive`. It pairs an arrow glyph with the color, so the tone never rides
85
85
  on hue alone.
@@ -48,12 +48,15 @@ command takes `--source <slug>` (else the Source `ekanos use` set) and
48
48
  ```sh
49
49
  npx @ekanos/cli teams create "Bank A" --slug bank-a # you are its owner
50
50
  npx @ekanos/cli teams create "Bank A" --owner ana@bank-a.com # ana is invited as owner
51
+ npx @ekanos/cli teams rename bank-a "Bank A Support" # the slug follows the name
51
52
  npx @ekanos/cli teams roles list bank-a # roles + permissions (e.g. agents.review)
52
53
  npx @ekanos/cli teams members invite bank-a raj@bank-a.com --role admin # default role: member
53
54
  npx @ekanos/cli teams members list bank-a # members and pending invitations
54
55
  npx @ekanos/cli teams members role bank-a raj@bank-a.com member
55
56
  npx @ekanos/cli teams members remove bank-a raj@bank-a.com --yes
56
- npx @ekanos/cli teams connect bank-a zendesk # the link a member opens to connect
57
+ npx @ekanos/cli teams connect bank-a zendesk # connect it for the team (asks, signs in, waits)
58
+ npx @ekanos/cli teams connect bank-a linear --as raj@bank-a.com # a sign-in link for raj
59
+ npx @ekanos/cli sources products # what the Source has enabled (super-admin enables)
57
60
  ```
58
61
 
59
62
  - `create` without `--owner` seats the person running it as the team's
@@ -66,9 +69,18 @@ npx @ekanos/cli teams connect bank-a zendesk # the link a membe
66
69
  customized ones). Pick a reviewer for agents by the role holding
67
70
  `agents.review` in `teams roles list`. The primary owner's role cannot be
68
71
  changed here; ownership moves in the app.
69
- - Connecting an integration is always a team member signing in in their
70
- browser. `teams connect` prints the link to send them and whether the team
71
- is connected yet; `teams show <team> <product>` has the full checklist.
72
+ - `teams connect <team> <product>` does the connect: it asks a form's fields
73
+ at the user's terminal (hidden for secrets — so the user runs it, never you
74
+ with values), runs the team-app prompts first when needed (Zendesk), or
75
+ opens a one-time sign-in link and waits. The person who signs in is a team
76
+ member (owner/admin for a team-wide connection): the user when they are
77
+ one, else `--as <email>` prints a link to send that member. `--no-wait`,
78
+ `--no-open`, `--link-only` (just the team's page). `teams show <team>
79
+ <product>` has the full checklist.
80
+ - A product the Source does not have is refused; `sources products` lists
81
+ what it has. Enabling one is a super-admin grant (`sources products enable`)
82
+ that an `ekanos login` session cannot make — the super-admin does it in
83
+ /admin.
72
84
 
73
85
  ## Products: integrations and experiences
74
86
 
@@ -77,7 +89,16 @@ Everything in the catalog (`npx @ekanos/cli catalog --source <slug> --json`) is
77
89
 
78
90
  - **Integration** — a connection to a third party (Linear, Zendesk, Slack…).
79
91
  Brings tools an agent can call, and may declare **agent events** that start
80
- agents (`linear.mentioned`, `zendesk.ticket_created`…).
92
+ agents — Linear declares `linear.mentioned`, `linear.assigned`,
93
+ `linear.issue_labeled` and `linear.issue_created`; Zendesk declares
94
+ `zendesk.ticket_created` and `zendesk.comment_added`. The catalog's
95
+ `agentEvents` is the authority: read it before concluding a product lacks
96
+ an event, never infer the set from an example. An event can also need a
97
+ **channel install** before it ever fires: every Linear event arrives only
98
+ through the team's Linear agent (`teams connect <team> linear --connection
99
+ agent`), a second identity beside the personal connection. `teams agents
100
+ list` names any agent whose trigger waits on one (`channels`, `ready:
101
+ false`).
81
102
  - **Experience** — an Ekanos-native capability (Agents, Workflows, Home…).
82
103
  Never "connected"; it is simply on or off for the Source.
83
104
 
@@ -144,6 +165,16 @@ Skills are folders (`SKILL.md` + references) an agent loads when needed.
144
165
  A Source admin pushes them with `ekanos skills push <dir>`: at Source level
145
166
  every team can use them, with `--team <slug>` only that team can.
146
167
 
168
+ **Knowledge** is Ekanos's own knowledge base (no outside account): markdown
169
+ articles, one collection per team plus the Source's **General** collection
170
+ that every team's agents granted `search_knowledge` also read. A Source admin loads folders of `.md` with
171
+ `ekanos knowledge push <dir> [--team <slug>]` (`--prune` also deletes the
172
+ articles an earlier push of that folder made whose files are gone, never
173
+ ones written or edited in the app); team members edit theirs in the app
174
+ (Agents → Knowledge). Agents granted `search_knowledge` /
175
+ `read_knowledge_article` search their own team's collection and General.
176
+ Skills say *how* to work; Knowledge holds the facts an agent looks up.
177
+
147
178
  The `build-agent` skill walks through choosing between these and building one.
148
179
 
149
180
  A Source admin can also do a team's agent setup from the terminal, acting on
@@ -153,19 +184,36 @@ always `ekanos teams <area> <verb> <team> …`:
153
184
  - `ekanos teams agents list <team>` — provided agents, on or off, the version
154
185
  each runs (pinned or following), triggers, links, the team's MCP servers,
155
186
  and what each still needs connected.
156
- - `ekanos teams agents enable <team> <key> [--as <member-email>]` /
157
- `disable <team> <key>` — the app's "Turn on" / "Turn off". The agent runs
158
- as a team member who manages agents (the team's owner by default); that
159
- person confirms in the app that it may use their connections.
187
+ - `ekanos teams agents enable <team> <key> [--as <member-email>]
188
+ [--confirm-access]` / `disable <team> <key>` — the app's "Turn on" /
189
+ "Turn off". The agent runs as a team member who manages agents (the
190
+ team's owner by default; with `--confirm-access`, you).
191
+ - `ekanos teams agents confirm <team> <key>` — the person the agent runs as
192
+ confirms, as themselves, that it may use their connections in runs no one
193
+ watches; the output says which products' connections that covers. It
194
+ confirms only the version it printed: a newer publish since is refused, to
195
+ be reviewed and confirmed again. Nobody confirms for anyone else.
160
196
  - `ekanos teams agents pin <team> <key> <version>` / `unpin <team> <key>`.
161
197
  - `ekanos teams agents policy <team> <key>` — every tool the agent can call,
162
198
  read or write, and whether it runs on its own or waits for approval;
163
199
  `… policy <team> <key> set <tool> auto|approve`, `unset <tool>`,
164
200
  `--reads auto|approve --writes auto|approve`. A provided agent's policy
165
201
  follows its template unless the template turns on team overrides for it.
202
+ On any agent, a change that lets more run on its own drops the confirmation
203
+ of the person it runs as, and the agent waits for them to confirm again
204
+ (`--confirm-access` when that person is you).
205
+ - `ekanos teams agents skills <team> <key> [add|remove <skill>]` — the
206
+ skills the agent reads; attach a team skill (pushed with
207
+ `skills push --team`) or a Source one. A provided agent takes them only
208
+ when its template's `teamCustomization.skills` is on; its own stay.
166
209
  - `ekanos teams triggers list|add|remove <team> <key> …` — manual, schedule
167
- (`--cron`, `--timezone`), webhook (URL and token shown once) and
168
- integration events (`event zendesk.ticket_created --filter '{…}'`).
210
+ (`--cron`, `--timezone`), webhook (the token goes to a file only the
211
+ user can read, never the output) and
212
+ integration events (`event zendesk.ticket_created --filter '{…}'`, or any
213
+ other id in the product's `agentEvents`, e.g. `event linear.issue_labeled
214
+ --filter '{"labels":["feedback"]}'`), plus `slack --channel '#name' [--dms]
215
+ --yes` and `linear [--label <name>]` once the team has installed Slack or
216
+ Ekanos's Linear app with `ekanos teams connect <team> slack|linear-app`.
169
217
  - `ekanos teams links list|add|remove <team> <from-key> [<to-key>] --kind
170
218
  talk|delegate [--mode await|handoff]`.
171
219
  - `ekanos teams mcp list|add|status|token|effect <team> [<server-key> …]` — a
@@ -197,7 +245,7 @@ reviewer's queue.
197
245
  npx @ekanos/cli reviewers list --source <slug> --json
198
246
  npx @ekanos/cli reviewers add <email> --reach source --source <slug>
199
247
  npx @ekanos/cli reviewers add <email> --reach team --team <team-slug> --source <slug>
200
- npx @ekanos/cli reviewers remove <email> [--team <team-slug>] --source <slug>
248
+ npx @ekanos/cli reviewers remove <email> [--team <team-slug>] --source <slug> --yes
201
249
  ```
202
250
 
203
251
  `remove` without `--team` takes the person off at every reach; with it, only
@@ -210,11 +258,12 @@ is refused (`USER_NOT_IN_SOURCE`): `ekanos teams list` shows the teams.
210
258
  |---|---|
211
259
  | Making a product available to a Source; granting seats | Ekanos super admin, in Ekanos's admin |
212
260
  | Building or updating an integration | A developer, with `ekanos validate` / `ekanos publish` |
213
- | Agents provided for every team | A Source admin, with `ekanos agents` |
214
- | Testing an unpublished agent version on one team | A Source admin, with `ekanos agents test <key> --team <slug>` |
261
+ | Agents provided for every team | A Source admin, with `ekanos agents` (`agents archive <key>` retires one once no team has it on) |
262
+ | Testing an unpublished agent version on one team | A Source admin: `ekanos teams agents enable\|pin <team> <key> --draft`, then `ekanos agents test <key> --team <slug>` |
215
263
  | Running a team's agent, reading its runs (transcript, tool calls) | A team's agent manager in the app, or a Source admin with `ekanos runs` |
216
- | Deciding what an agent run waits on (approve, reject, edit & send a reply) | A team's agent manager in the app, or a Source admin with `ekanos approvals` |
217
- | Skills (SKILL.md folders) for every team, or one team's own | A Source admin, with `ekanos skills push` (`--team <slug>` for one team) |
264
+ | Deciding what an agent run waits on (approve, reject, edit & send a reply) | A team's agent manager in the app, or a Source admin with `ekanos approvals` (for a team's own agent, only a Source admin who manages that team's agents) |
265
+ | Skills (SKILL.md folders) for every team, or one team's own | A Source admin, with `ekanos skills push` (`--team <slug>` for one team); `ekanos skills archive` retires one nothing uses |
266
+ | Knowledge articles for every team (General), or one team's own | A Source admin, with `ekanos knowledge push` (`--team <slug>` for one team); a team's members in the app |
218
267
  | Who decides agent drafts that wait for a person | A Source admin, with `ekanos reviewers` |
219
268
  | An integration's app for the whole Source (client ID and secret) | A Source admin, with `ekanos apps set` at their own terminal |
220
269
  | One connection for the whole Source, used by provided agents in every team | A Source admin, with `ekanos apps connect` (status: `ekanos apps show`), or **Shared integrations › Connections** in the Source admin area |
@@ -222,5 +271,9 @@ is refused (`USER_NOT_IN_SOURCE`): `ekanos teams list` shows the teams.
222
271
  | A team's own app for an integration (client ID, secrets, webhook URL) | The team in the app, or a Source admin with `ekanos teams` |
223
272
  | A provided agent's triggers, links and approvals | A Source admin, in the template (`ekanos agents triggers / links / policy / overrides`); teams change them only where `teamOverrides` allows |
224
273
  | Creating a team, inviting its members, changing their roles | A Source admin, with `ekanos teams create` / `ekanos teams members` (or the team's owner in the app) |
225
- | Connecting an integration (signing in) | Each team, in the app |
274
+ | Connecting an integration for a team (signing in) | A team member in the app, or a Source admin with `ekanos teams connect <team> <product>` (`--as <member-email>` when the connection is a person's own) |
226
275
  | Turning on a provided agent for a team, pinning its version, its triggers, links, MCP servers and approval policy | Each team in the app, or a Source admin with `ekanos teams agents\|triggers\|links\|mcp` |
276
+ | Which products a team sees in the app (product scopes) | A Source admin: `ekanos sources scopes` (and `add`/`remove <scope> <product>`), `ekanos teams scope show\|set <team>`; creating a scope is in /admin |
277
+ | Is a team's agent live, and if not, what is the next step | A Source admin, with `ekanos teams agents show <team> <key>`; the whole team on one screen with `ekanos teams show <team>` |
278
+ | Disconnecting a team's integration, removing a team's MCP server | A Source admin, with `ekanos teams disconnect <team> <product> --yes` / `ekanos teams mcp remove <team> <server-key> --yes`, or the team in the app |
279
+ | Confirming an agent may use a person's connections | Only the person it runs as, signed in as themselves: `ekanos teams agents confirm <team> <key>` (or `enable --confirm-access`, `agents publish --confirm-access`), or **Confirm access** in the app. On a team held on an earlier version (a newer one reaches further than they confirmed) it moves the team to the version waiting |
@@ -116,8 +116,8 @@ import {
116
116
  </div>
117
117
  ```
118
118
 
119
- `Stat` owns the sizes — the heading face, `text-2xl`, `tracking-tight`,
120
- `tabular-nums`, and the arrow glyph that pairs with `StatChange`'s color so
119
+ `Stat` owns the sizes — the `figure` value (heading face, Headline tier,
120
+ tabular), the `text-eyebrow` label, and the arrow glyph that pairs with `StatChange`'s color so
121
121
  the tone never rides on hue alone. Don't override them, and don't rebuild
122
122
  them by hand: a Source that swaps typefaces carries the component, not your
123
123
  spans.