@ekanos/cli 0.11.0 → 0.13.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/apps-api.d.ts +3 -2
- package/dist/apps-api.js +1 -5
- package/dist/apps-api.js.map +1 -1
- package/dist/commands/agents-edit.js +1 -1
- package/dist/commands/agents-edit.js.map +1 -1
- package/dist/commands/apps.d.ts +19 -6
- package/dist/commands/apps.js +366 -43
- package/dist/commands/apps.js.map +1 -1
- package/dist/commands/knowledge.d.ts +37 -0
- package/dist/commands/knowledge.js +364 -0
- package/dist/commands/knowledge.js.map +1 -0
- package/dist/commands/routes.d.ts +23 -0
- package/dist/commands/routes.js +277 -0
- package/dist/commands/routes.js.map +1 -0
- package/dist/commands/sources.d.ts +4 -0
- package/dist/commands/sources.js +115 -1
- package/dist/commands/sources.js.map +1 -1
- package/dist/commands/team-agents-triggers.js +2 -1
- package/dist/commands/team-agents-triggers.js.map +1 -1
- package/dist/commands/teams-connect.d.ts +25 -0
- package/dist/commands/teams-connect.js +242 -0
- package/dist/commands/teams-connect.js.map +1 -0
- package/dist/commands/teams-onboard.d.ts +5 -2
- package/dist/commands/teams-onboard.js +12 -40
- package/dist/commands/teams-onboard.js.map +1 -1
- package/dist/commands/teams.d.ts +60 -5
- package/dist/commands/teams.js +141 -46
- package/dist/commands/teams.js.map +1 -1
- package/dist/connections-api.d.ts +125 -0
- package/dist/connections-api.js +156 -0
- package/dist/connections-api.js.map +1 -0
- package/dist/index.js +90 -6
- package/dist/index.js.map +1 -1
- package/dist/knowledge-api.d.ts +129 -0
- package/dist/knowledge-api.js +138 -0
- package/dist/knowledge-api.js.map +1 -0
- package/dist/routes-api.d.ts +105 -0
- package/dist/routes-api.js +147 -0
- package/dist/routes-api.js.map +1 -0
- package/dist/source-products-api.d.ts +59 -0
- package/dist/source-products-api.js +113 -0
- package/dist/source-products-api.js.map +1 -0
- package/dist/team-connect-api.d.ts +244 -0
- package/dist/team-connect-api.js +95 -0
- package/dist/team-connect-api.js.map +1 -0
- package/dist/teams-api.d.ts +1 -0
- package/dist/teams-api.js +1 -1
- package/dist/teams-api.js.map +1 -1
- package/package.json +2 -2
- package/templates/package.json.tmpl +4 -4
- package/templates/skills/build-agent/SKILL.md +18 -3
- package/templates/skills/build-agent/references/agent-json.md +29 -8
- package/templates/skills/build-agent/references/app-setup.md +2 -1
- package/templates/skills/build-agent/references/set-up-an-integration.md +76 -10
- package/templates/skills/build-agent/references/skills.md +7 -4
- package/templates/skills/build-agent/references/triggers.md +44 -15
- package/templates/skills/ekanos-platform/SKILL.md +40 -8
|
@@ -49,6 +49,15 @@ every `hint`. Look things up in the `ekanos-sdk-docs` MCP server
|
|
|
49
49
|
`provider-app`) is not set up, so no team can connect. Offer to walk them
|
|
50
50
|
through it now — `references/app-setup.md` — or after the interview. The
|
|
51
51
|
agent can be drafted while it is pending.
|
|
52
|
+
- **Docs and know-how with no home yet** — when the user asks where the
|
|
53
|
+
agent's docs, policies or FAQs should live, offer **Knowledge** first:
|
|
54
|
+
Ekanos's own knowledge base, nothing to sign up for. One collection per
|
|
55
|
+
team plus the Source's General one; load a folder of markdown with
|
|
56
|
+
`ekanos knowledge push <dir> [--team <team>]`, check with
|
|
57
|
+
`ekanos knowledge search "<words>" --team <team>`, and grant the agent
|
|
58
|
+
`search_knowledge` + `read_knowledge_article` (`references/agent-json.md`
|
|
59
|
+
→ `tools`). Keep skills for how-to-work instructions; Knowledge for the
|
|
60
|
+
facts the agent looks up.
|
|
52
61
|
- **Missing** — no product does it. Say so plainly. Options: build the
|
|
53
62
|
integration (the `build-integration` skill), use a remote MCP server
|
|
54
63
|
instead if the service offers one (common for docs and knowledge bases:
|
|
@@ -99,15 +108,21 @@ in parentheses are the recommendation when the user has no preference.
|
|
|
99
108
|
connection lives (`references/set-up-an-integration.md` § 2): each team
|
|
100
109
|
connects its own, and it is `required` (the agent waits at "needs setup"
|
|
101
110
|
until the team connects it) or `optional` (its tools appear once
|
|
102
|
-
connected).
|
|
103
|
-
|
|
111
|
+
connected). Or, for integrations that support it, the Source connects it
|
|
112
|
+
once for every team (`owner: "source"`): each team's agent then works only
|
|
113
|
+
inside what is routed to that team (`references/set-up-an-integration.md`
|
|
114
|
+
§ 5). Then offer to set up any that are not ready.
|
|
104
115
|
6. **What teams may add** — their own MCP servers, their own skills, more of
|
|
105
116
|
their own integrations, or narrowing (removing tools, more approvals). All
|
|
106
117
|
off unless there is a reason. Give one concrete example per knob.
|
|
107
118
|
7. **What starts it** — see `references/triggers.md`. Declare the triggers in
|
|
108
119
|
the template (an event such as `zendesk.ticket_created` with its filters,
|
|
109
120
|
a schedule, a webhook) so every team gets them, or leave them to each
|
|
110
|
-
team.
|
|
121
|
+
team. Take event ids from the catalog's `agentEvents`, which lists every
|
|
122
|
+
event a product declares (Linear also has `linear.issue_labeled`,
|
|
123
|
+
`linear.issue_created` and `linear.assigned`; Zendesk also has
|
|
124
|
+
`zendesk.comment_added`) — map an old trigger onto the matching event
|
|
125
|
+
rather than onto an @mention. Say what each team needs connected first.
|
|
111
126
|
8. **Who it works with** — other agents of this Source it may ask or hand
|
|
112
127
|
work to (`links`). A link only exists in a team that runs both agents.
|
|
113
128
|
9. **What teams may change** — `teamOverrides` per area (approvals,
|
|
@@ -39,7 +39,7 @@ conflicting change unless `--overwrite`. Unknown fields are refused.
|
|
|
39
39
|
"key": "new-tickets",
|
|
40
40
|
"type": "event",
|
|
41
41
|
"event": "zendesk.ticket_created",
|
|
42
|
-
"filter": { "tags": ["vip", "urgent"], "
|
|
42
|
+
"filter": { "tags": ["vip", "urgent"], "brands": ["Acme Support"] }
|
|
43
43
|
},
|
|
44
44
|
{
|
|
45
45
|
"key": "weekday-digest",
|
|
@@ -70,6 +70,13 @@ The tool names above are illustrations. Take real ones from
|
|
|
70
70
|
- `all`: every tool, reads and changes.
|
|
71
71
|
- `custom`: whole `products` (slugs) plus single `tools` (names).
|
|
72
72
|
A tool it must never call is simply not granted — there is no deny list.
|
|
73
|
+
**Knowledge** (Ekanos's own knowledge base, `ekanos knowledge`): add
|
|
74
|
+
`search_knowledge` and `read_knowledge_article` to `tools.tools` for an
|
|
75
|
+
agent that should look things up — they read the team's collection plus
|
|
76
|
+
the Source's General collection, and the agent never picks which. A
|
|
77
|
+
feedback agent that turns reviewer corrections into articles also gets
|
|
78
|
+
`propose_knowledge_article` (a write: it waits for approval by default).
|
|
79
|
+
These are named one by one; no mode or product grants them.
|
|
73
80
|
Extra team integrations (`teamCustomization.integrations`) need `custom`.
|
|
74
81
|
- **`policy`** — for each granted tool, `auto` (runs on its own) or
|
|
75
82
|
`approve` (waits for a person in the app). `reads`/`writes` set the
|
|
@@ -80,8 +87,13 @@ The tool names above are illustrations. Take real ones from
|
|
|
80
87
|
folders in `agents/<key>/skills/<slug>/` are pushed and added here by
|
|
81
88
|
`agents apply` (see `skills.md`).
|
|
82
89
|
- **`connections`** — by product slug: `{ "owner": "team", "team": "required" | "optional" }`.
|
|
83
|
-
A product with no entry is `team`/`optional`. `owner: "source"`
|
|
84
|
-
connection for every team
|
|
90
|
+
A product with no entry is `team`/`optional`. `{ "owner": "source" }` is
|
|
91
|
+
one connection the Source admin makes for every team (`ekanos apps
|
|
92
|
+
connect`), used only by this provided agent and limited per team by the
|
|
93
|
+
Source's routing (`ekanos routes`); `apply` refuses it for an integration
|
|
94
|
+
that does not declare `sourceConnection`. Teams cannot add a Source-owned
|
|
95
|
+
product in their overlay. `mcpServers` with `owner: "source"` are still
|
|
96
|
+
refused.
|
|
85
97
|
- **`mcpServers`** — remote MCP servers (streamable HTTP, `https` only, up to
|
|
86
98
|
10): `key` (lowercase, ≤31), `name`, `url`, `auth` (`none` | `bearer` |
|
|
87
99
|
`oauth`, default `oauth`), `owner`/`team` as for connections, and
|
|
@@ -103,9 +115,14 @@ The tool names above are illustrations. Take real ones from
|
|
|
103
115
|
an optional `prompt` (what to do each time), and `enabled` (default
|
|
104
116
|
`true`; `false` sets it up turned off). Types:
|
|
105
117
|
- `event` — `event` is an integration event (`<slug>.<event>`, as
|
|
106
|
-
`ekanos catalog <product
|
|
107
|
-
event
|
|
108
|
-
`
|
|
118
|
+
`ekanos catalog <product> --json` lists under `agentEvents` — every
|
|
119
|
+
event the product declares, e.g. Zendesk `zendesk.ticket_created` and
|
|
120
|
+
`zendesk.comment_added`, Linear `linear.mentioned`, `linear.assigned`,
|
|
121
|
+
`linear.issue_labeled` and `linear.issue_created`); `filter` holds only
|
|
122
|
+
the keys in that event's `filterFields` (Zendesk: `brands`, `groups`,
|
|
123
|
+
`tags`, `organizations`, each a list; Linear: `teamKeys`, plus `labels`,
|
|
124
|
+
which `linear.issue_labeled` requires). Zendesk's `reply_as` is not a
|
|
125
|
+
filter: it is set in the Zendesk trigger's body (`triggers.md`).
|
|
109
126
|
- `schedule` — `cron` (5 fields, on a 5-minute boundary) and `timezone`
|
|
110
127
|
(IANA, default `UTC`); give it a `prompt`.
|
|
111
128
|
- `webhook` — each team gets its **own** URL and secret, created or
|
|
@@ -138,7 +155,9 @@ ekanos agents policy <key> unset zendesk_add_comment
|
|
|
138
155
|
ekanos agents policy <key> --reads auto --writes approve
|
|
139
156
|
ekanos agents triggers <key> # list
|
|
140
157
|
ekanos agents triggers <key> add event new-tickets --event zendesk.ticket_created \
|
|
141
|
-
--filter tags=vip,urgent --filter
|
|
158
|
+
--filter tags=vip,urgent --filter brands=Acme,
|
|
159
|
+
ekanos agents triggers <key> add event feedback-label --event linear.issue_labeled \
|
|
160
|
+
--filter labels=feedback,
|
|
142
161
|
ekanos agents triggers <key> add schedule weekday-digest --cron "0 9 * * 1-5" \
|
|
143
162
|
--timezone America/Los_Angeles --prompt "Summarize yesterday's escalations."
|
|
144
163
|
ekanos agents triggers <key> add webhook inbound --prompt "Triage the posted ticket."
|
|
@@ -151,7 +170,9 @@ ekanos agents overrides <key> disable policy
|
|
|
151
170
|
```
|
|
152
171
|
|
|
153
172
|
`--filter field=value` repeats; a value with commas is a list, `true` or
|
|
154
|
-
`false` a switch, anything else text.
|
|
173
|
+
`false` a switch, anything else text. A list field (`tags`, `brands`,
|
|
174
|
+
`labels`, `teamKeys` …) needs a list even for one item, so end a single
|
|
175
|
+
item with a comma: `--filter labels=feedback,`. `--disabled` adds a trigger turned off.
|
|
155
176
|
|
|
156
177
|
## What the host checks on `apply`
|
|
157
178
|
|
|
@@ -47,7 +47,8 @@ working from those rather than from Ekanos.
|
|
|
47
47
|
npx @ekanos/cli apps set <product> --source <slug>
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
It asks for the client ID, then the secret with hidden input
|
|
50
|
+
It asks for the client ID, then the secret with hidden input; Enter keeps
|
|
51
|
+
a saved value, so either can be changed on its own. For a team's
|
|
51
52
|
app, they enter the fields in the team's setup panel in the Ekanos app.
|
|
52
53
|
- Then check: `apps show <product> --source <slug> --json` should say
|
|
53
54
|
`configured: true`, and the catalog's step should be `done`. Tell them
|
|
@@ -35,12 +35,14 @@ integration: its members, its data and its connections.
|
|
|
35
35
|
|---|---|---|---|
|
|
36
36
|
| **Each team, through the Source's app** | One app, created once for the whole Source under the Source's own name. Each team then signs in through it. | The Source admin creates the app (`references/app-setup.md`, `ekanos apps set`); each team connects | Linear, Slack: products where every team is a separate workspace |
|
|
37
37
|
| **Each team, with its own app** | Each team creates its own app in the provider and enters its credentials | Each team, or the Source admin on the team's behalf with `ekanos teams` (below) | Zendesk: each bank or business has its own Zendesk |
|
|
38
|
-
| **One connection for the whole Source** | Every team's provided agent uses the Source's single connection, limited to
|
|
38
|
+
| **One connection for the whole Source** | Every team's provided agent uses the Source's single connection, limited to the records routed to that team (for Zendesk, the tickets of the organizations mapped to it) | The Source admin, once, plus a routing table | One shared Zendesk for many teams (§ 5). Only for integrations that declare it (Zendesk from 0.2.0; `agents apply` refuses the others), and only for **provided agents**: a team's own agents, widgets and assistant never use it |
|
|
39
39
|
|
|
40
40
|
The agent records the choice in `agent.json` → `connections`:
|
|
41
41
|
`{ "zendesk": { "owner": "team", "team": "required" } }` means each team
|
|
42
42
|
uses its own Zendesk and the agent waits at "needs setup" until it is
|
|
43
|
-
connected (`references/agent-json.md`).
|
|
43
|
+
connected (`references/agent-json.md`). `{ "zendesk": { "owner": "source" } }`
|
|
44
|
+
means every team's copy of the agent uses the Source's one Zendesk; teams
|
|
45
|
+
connect nothing for it.
|
|
44
46
|
|
|
45
47
|
## 3. Walk it, one step per message
|
|
46
48
|
|
|
@@ -60,11 +62,16 @@ connected (`references/agent-json.md`).
|
|
|
60
62
|
`ekanos teams app set`, with hidden input) or in the team's page in the app.
|
|
61
63
|
If they paste one into the chat anyway, tell them to rotate it in the
|
|
62
64
|
provider's console and enter the new one at the terminal.
|
|
63
|
-
- **
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
65
|
+
- **Connect with `teams connect <team> <product>`, run by the user in their
|
|
66
|
+
own terminal.** It does whatever the integration needs: asks a form's fields
|
|
67
|
+
(secrets hidden), runs the team-app prompts first when the team's own app is
|
|
68
|
+
missing, or opens a one-time sign-in link and waits until the team is
|
|
69
|
+
connected. The provider's consent is still a person's click, by a member of
|
|
70
|
+
the team (owner/admin for a team-wide connection): the user when they are
|
|
71
|
+
one, else `--as <email>` prints a link to send that member. `--link-only`
|
|
72
|
+
prints just the team's page. Tell them who should sign in: the account the
|
|
73
|
+
integration acts as. If the product is not enabled for the Source, a
|
|
74
|
+
super-admin enables it (`sources products` shows what the Source has). A dedicated seat such as "Support agent" makes its replies easy
|
|
68
75
|
to recognise.
|
|
69
76
|
- **Close each product out**: one line on what now works ("New tickets in
|
|
70
77
|
Acme's Zendesk will start the support agent"), then move on to the next
|
|
@@ -80,8 +87,13 @@ pilot), the team-side steps can be done from the CLI:
|
|
|
80
87
|
2. They create the app in the provider's console, step by step as above.
|
|
81
88
|
3. **In their own terminal:**
|
|
82
89
|
`npx @ekanos/cli teams app set <team> <product> --source <slug>`. It asks
|
|
83
|
-
for each field and hides the secret ones
|
|
84
|
-
that is deliberate.
|
|
90
|
+
for each field and hides the secret ones; Enter keeps a saved value. It
|
|
91
|
+
refuses to run inside Claude; that is deliberate. To change one value
|
|
92
|
+
later, they need not re-enter the rest:
|
|
93
|
+
`teams app set <team> <product> --field <name>` asks for just that field
|
|
94
|
+
(names are in brackets in `teams show`), `--set <name>=<value>` sets a
|
|
95
|
+
non-secret field (a subdomain, a client ID) without a prompt — you may run
|
|
96
|
+
that one yourself — and `--clear <name>` removes a value.
|
|
85
97
|
4. If the integration takes webhooks:
|
|
86
98
|
`npx @ekanos/cli teams webhook <team> <product> --source <slug>` prints the
|
|
87
99
|
team's webhook URL **once**. Have them paste it into the provider at that
|
|
@@ -90,6 +102,59 @@ pilot), the team-side steps can be done from the CLI:
|
|
|
90
102
|
5. Someone on the team opens the link from `teams show` and clicks Connect.
|
|
91
103
|
6. `teams show` again: every step ✓.
|
|
92
104
|
|
|
105
|
+
## 5. One connection for the whole Source
|
|
106
|
+
|
|
107
|
+
Use it when one account at the provider serves many teams: one Zendesk where
|
|
108
|
+
each bank is an organization. The Source admin connects once; events are
|
|
109
|
+
routed to teams by a value inside them (for Zendesk, the ticket's
|
|
110
|
+
**organization**); each team's provided agent then works only inside what is
|
|
111
|
+
routed to that team. Say all three parts before starting, and say plainly
|
|
112
|
+
what it does **not** do: a team's own agents, widgets and assistant never see
|
|
113
|
+
the Source's connection.
|
|
114
|
+
|
|
115
|
+
1. **Connect, once, as the Source.** For an integration where each customer
|
|
116
|
+
brings its own app (Zendesk), first create that app in the shared account,
|
|
117
|
+
exactly as in the worked example below (OAuth client, Confidential), but
|
|
118
|
+
once, for the Source. Then, **in their own terminal**:
|
|
119
|
+
`npx @ekanos/cli apps connect <product> --source <slug>`. It asks for the
|
|
120
|
+
app's fields it doesn't have yet (Zendesk: subdomain, client ID, client
|
|
121
|
+
secret, webhook signing secret; secrets hidden, never as flags, and it
|
|
122
|
+
refuses to run inside Claude), prints the redirect URL to register and the
|
|
123
|
+
consent link, then waits up to ten minutes until it is connected. Whoever
|
|
124
|
+
clicks the link is the account the integration acts as for every team, so
|
|
125
|
+
suggest a dedicated seat ("Support agent"). `apps list` shows every
|
|
126
|
+
integration the Source can connect this way. Check with
|
|
127
|
+
`npx @ekanos/cli apps show <product> --source <slug>`: connected, by whom,
|
|
128
|
+
when. In the app the same lives in the Source admin area under
|
|
129
|
+
**Shared integrations › Connections**.
|
|
130
|
+
2. **The Source's webhook.** `npx @ekanos/cli routes webhook <product> --source <slug>`
|
|
131
|
+
prints one URL, **once**, for the whole Source. Paste it into the
|
|
132
|
+
provider at that moment (for Zendesk, the webhook the triggers notify).
|
|
133
|
+
The team webhooks from § 4 are not used for this connection.
|
|
134
|
+
3. **Map values to teams.** `npx @ekanos/cli routes options <product> --source <slug>`
|
|
135
|
+
lists what can be mapped (Zendesk organizations, with names), then one
|
|
136
|
+
line per team:
|
|
137
|
+
`npx @ekanos/cli routes set <product> <value> <team> --source <slug>`.
|
|
138
|
+
`routes list` shows the table. One value goes to exactly one team.
|
|
139
|
+
4. **The agent.** In `agent.json`, `connections.<product>` is
|
|
140
|
+
`{ "owner": "source" }`; `agents apply` accepts it only when the
|
|
141
|
+
integration supports a Source connection. Teams turn the agent on as
|
|
142
|
+
usual; they connect nothing for that product.
|
|
143
|
+
5. **Try it.** A ticket from a mapped organization starts that team's agent
|
|
144
|
+
only. A ticket from an organization nobody mapped starts **nothing**: the
|
|
145
|
+
integration leaves its own fixed note (Zendesk: an internal note saying
|
|
146
|
+
no team has it yet), and it is listed by
|
|
147
|
+
`npx @ekanos/cli routes unrouted <product> --source <slug>`. Map the
|
|
148
|
+
value, then `routes replay <event-id>` to send it on once.
|
|
149
|
+
|
|
150
|
+
What is enforced, so you can say it accurately: the host routes each event
|
|
151
|
+
to exactly one team or to none (never to a default team), and gives a
|
|
152
|
+
team's agent only that team's mapped values (`ctx.routing`); the
|
|
153
|
+
integration's tools keep to them (for Zendesk, reads are limited to the
|
|
154
|
+
team's organizations, and anything that reads or changes one ticket first
|
|
155
|
+
checks its organization and refuses otherwise). The agent's policy,
|
|
156
|
+
approvals and audit apply exactly as on a team connection.
|
|
157
|
+
|
|
93
158
|
## Worked example: Zendesk for one team
|
|
94
159
|
|
|
95
160
|
The steps below are what Zendesk's own setup says, in order. Take the URLs
|
|
@@ -104,7 +169,8 @@ from `teams show zendesk`.
|
|
|
104
169
|
secret.
|
|
105
170
|
3. **Credentials into Ekanos.** `ekanos teams app set <team> zendesk` in
|
|
106
171
|
their terminal: subdomain, client ID, client secret, webhook signing
|
|
107
|
-
secret.
|
|
172
|
+
secret. Any of them can be entered or changed later on its own
|
|
173
|
+
(`--field <name>`); `teams show` says which are saved.
|
|
108
174
|
4. **Connect.** Someone on the team opens the link and connects, as the
|
|
109
175
|
Zendesk agent the integration should reply as.
|
|
110
176
|
5. **Zendesk triggers.** Objects and rules › Triggers: one for *Ticket is
|
|
@@ -70,9 +70,12 @@ whose `teamCustomization.skills` is on.
|
|
|
70
70
|
|
|
71
71
|
## Limits today
|
|
72
72
|
|
|
73
|
-
- Prompt skills only
|
|
74
|
-
|
|
75
|
-
`
|
|
76
|
-
|
|
73
|
+
- Prompt skills only. At run time the agent gets the whole folder: loading
|
|
74
|
+
the skill returns `SKILL.md`'s instructions plus the list of every other
|
|
75
|
+
file (`references/`, `assets/`, …), and it reads one on demand
|
|
76
|
+
(`read_skill_file`) when the instructions point to it — so keep `SKILL.md`
|
|
77
|
+
short and name the reference to open, e.g. `references/policy-2026.md`.
|
|
78
|
+
Text files are read in parts of about 12,000 characters; binary files are
|
|
79
|
+
listed but cannot be read as text.
|
|
77
80
|
- A `scripts/` folder is refused: executable skills need the in-app review.
|
|
78
81
|
- Up to 100 files, 1 MB per file, 3 MB per skill.
|
|
@@ -20,7 +20,14 @@ A Source admin can add them for the team from the terminal instead:
|
|
|
20
20
|
`ekanos teams triggers add acme-support support-agent event zendesk.ticket_created --filter '{"tags":["billing"]}'`,
|
|
21
21
|
`… schedule --cron "0 9 * * 1-5" --timezone America/Los_Angeles --prompt "…"`,
|
|
22
22
|
`… webhook --prompt "…"` (prints the URL and token once) or `… manual`.
|
|
23
|
-
|
|
23
|
+
Any event in a connected integration's `agentEvents` is added this way,
|
|
24
|
+
including every Linear integration event (`event linear.issue_labeled
|
|
25
|
+
--filter '{"labels":["feedback"]}'`). Only two trigger *types* are app-only:
|
|
26
|
+
a **Slack** trigger, and a **Linear (Agents app)** trigger — Ekanos's own
|
|
27
|
+
Linear app, which answers @mentions and assignments only. That app is not
|
|
28
|
+
the Linear integration, and its limits are not the integration's: an agent
|
|
29
|
+
that should start when a label is applied uses `linear.issue_labeled`, not an
|
|
30
|
+
@mention. When a provided agent's
|
|
24
31
|
template declares triggers and has not turned on team overrides for them, the
|
|
25
32
|
team's triggers follow the template and these commands refuse to change them.
|
|
26
33
|
|
|
@@ -39,23 +46,45 @@ team's triggers follow the template and these commands refuse to change them.
|
|
|
39
46
|
|
|
40
47
|
## Integrations with agent events
|
|
41
48
|
|
|
42
|
-
|
|
43
|
-
|
|
49
|
+
`ekanos catalog <product> --source <slug> --json` is the authority: its
|
|
50
|
+
`agentEvents` lists **every** event the product declares, with each one's
|
|
51
|
+
filter keys (`filterFields`). The lists below are the known shapes; never
|
|
52
|
+
conclude a product lacks an event because an example here or elsewhere
|
|
53
|
+
names only one. A refused event id is answered with the ids the product
|
|
54
|
+
does declare, and a refused filter with the keys the event takes.
|
|
44
55
|
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
agent
|
|
56
|
+
An event can be declared and still never fire for a team until the team
|
|
57
|
+
finishes that event's own setup on the provider's side. That is a setup
|
|
58
|
+
step, not a missing event — say which step, as below.
|
|
59
|
+
|
|
60
|
+
**Linear** — the agent becomes a teammate in Linear. Each team needs two
|
|
61
|
+
things in the app: each person's own Linear connection (for the tools), and
|
|
62
|
+
the team's own Linear app for the agent (client id, secret and webhook
|
|
63
|
+
signing secret, entered in Ekanos).
|
|
50
64
|
Guide: https://sdk.ekanos.dev/guides/linear-agent
|
|
51
65
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
66
|
+
| Event | Starts when | Filter keys | Needs on the team's Linear app |
|
|
67
|
+
|---|---|---|---|
|
|
68
|
+
| `linear.mentioned` | someone @mentions the agent, or writes to it again in that conversation | `teamKeys` | webhook with **Agent session events** ticked |
|
|
69
|
+
| `linear.assigned` | someone assigns (delegates) an issue to the agent | `teamKeys` | webhook with **Agent session events** ticked |
|
|
70
|
+
| `linear.issue_labeled` | someone applies one of the given labels to an issue | `labels` (**required**), `teamKeys` | webhook with **Issues** ticked |
|
|
71
|
+
| `linear.issue_created` | someone creates an issue (optionally only with given labels) | `labels`, `teamKeys` | webhook with **Issues** ticked |
|
|
72
|
+
|
|
73
|
+
**Zendesk** — each team connects its own Zendesk (subdomain plus an OAuth
|
|
74
|
+
client it creates in Zendesk) and adds a Zendesk webhook pointing at its
|
|
75
|
+
Ekanos endpoint (walk-through: `set-up-an-integration.md`, worked example).
|
|
76
|
+
The agent answers on the ticket as a public reply or an internal note —
|
|
77
|
+
recommend internal notes, or approval on public replies, until the team
|
|
78
|
+
trusts it.
|
|
79
|
+
|
|
80
|
+
| Event | Starts when | Filter keys | Needs in Zendesk |
|
|
81
|
+
|---|---|---|---|
|
|
82
|
+
| `zendesk.ticket_created` | a new ticket arrives | `brands`, `groups`, `tags`, `organizations` | a Zendesk trigger on *Ticket is Created* notifying the webhook |
|
|
83
|
+
| `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 |
|
|
84
|
+
|
|
85
|
+
Filter values are lists (`{"tags":["billing"],"brands":["Acme Support"]}`);
|
|
86
|
+
brands, groups and organizations match by name or id. Where the answer goes
|
|
87
|
+
(`reply_as`) is set in the Zendesk trigger's body, not in the filter.
|
|
59
88
|
|
|
60
89
|
## Checklist to hand each team
|
|
61
90
|
|
|
@@ -53,7 +53,9 @@ npx @ekanos/cli teams members invite bank-a raj@bank-a.com --role admin # defa
|
|
|
53
53
|
npx @ekanos/cli teams members list bank-a # members and pending invitations
|
|
54
54
|
npx @ekanos/cli teams members role bank-a raj@bank-a.com member
|
|
55
55
|
npx @ekanos/cli teams members remove bank-a raj@bank-a.com --yes
|
|
56
|
-
npx @ekanos/cli teams connect bank-a zendesk # the
|
|
56
|
+
npx @ekanos/cli teams connect bank-a zendesk # connect it for the team (asks, signs in, waits)
|
|
57
|
+
npx @ekanos/cli teams connect bank-a linear --as raj@bank-a.com # a sign-in link for raj
|
|
58
|
+
npx @ekanos/cli sources products # what the Source has enabled (super-admin enables)
|
|
57
59
|
```
|
|
58
60
|
|
|
59
61
|
- `create` without `--owner` seats the person running it as the team's
|
|
@@ -66,9 +68,18 @@ npx @ekanos/cli teams connect bank-a zendesk # the link a membe
|
|
|
66
68
|
customized ones). Pick a reviewer for agents by the role holding
|
|
67
69
|
`agents.review` in `teams roles list`. The primary owner's role cannot be
|
|
68
70
|
changed here; ownership moves in the app.
|
|
69
|
-
-
|
|
70
|
-
|
|
71
|
-
|
|
71
|
+
- `teams connect <team> <product>` does the connect: it asks a form's fields
|
|
72
|
+
at the user's terminal (hidden for secrets — so the user runs it, never you
|
|
73
|
+
with values), runs the team-app prompts first when needed (Zendesk), or
|
|
74
|
+
opens a one-time sign-in link and waits. The person who signs in is a team
|
|
75
|
+
member (owner/admin for a team-wide connection): the user when they are
|
|
76
|
+
one, else `--as <email>` prints a link to send that member. `--no-wait`,
|
|
77
|
+
`--no-open`, `--link-only` (just the team's page). `teams show <team>
|
|
78
|
+
<product>` has the full checklist.
|
|
79
|
+
- A product the Source does not have is refused; `sources products` lists
|
|
80
|
+
what it has. Enabling one is a super-admin grant (`sources products enable`)
|
|
81
|
+
that an `ekanos login` session cannot make — the super-admin does it in
|
|
82
|
+
/admin.
|
|
72
83
|
|
|
73
84
|
## Products: integrations and experiences
|
|
74
85
|
|
|
@@ -77,7 +88,11 @@ Everything in the catalog (`npx @ekanos/cli catalog --source <slug> --json`) is
|
|
|
77
88
|
|
|
78
89
|
- **Integration** — a connection to a third party (Linear, Zendesk, Slack…).
|
|
79
90
|
Brings tools an agent can call, and may declare **agent events** that start
|
|
80
|
-
agents
|
|
91
|
+
agents — Linear declares `linear.mentioned`, `linear.assigned`,
|
|
92
|
+
`linear.issue_labeled` and `linear.issue_created`; Zendesk declares
|
|
93
|
+
`zendesk.ticket_created` and `zendesk.comment_added`. The catalog's
|
|
94
|
+
`agentEvents` is the authority: read it before concluding a product lacks
|
|
95
|
+
an event, never infer the set from an example.
|
|
81
96
|
- **Experience** — an Ekanos-native capability (Agents, Workflows, Home…).
|
|
82
97
|
Never "connected"; it is simply on or off for the Source.
|
|
83
98
|
|
|
@@ -97,8 +112,12 @@ Ask them in this order; each catalog product reports where it stands
|
|
|
97
112
|
connection: two teams using Linear each connect their own. A Source admin
|
|
98
113
|
can do a team's setup for it from the terminal (`ekanos teams show`,
|
|
99
114
|
`ekanos teams app set`, `ekanos teams webhook`), but signing in is a click
|
|
100
|
-
by someone on the team.
|
|
101
|
-
|
|
115
|
+
by someone on the team. For integrations that support it, a Source admin
|
|
116
|
+
can instead connect **once for the whole Source** (`ekanos apps connect`),
|
|
117
|
+
for provided agents only: events are routed to teams by a value inside
|
|
118
|
+
them (`ekanos routes`, Zendesk by organization), and each team's agent
|
|
119
|
+
works only inside its own routed values. A team never sees that
|
|
120
|
+
connection.
|
|
102
121
|
3. **Set up by the team** where needed — some integrations have each team
|
|
103
122
|
bring its own app (a team-provided app: client id, secret, webhook signing
|
|
104
123
|
secret entered in Ekanos). Those secrets are typed into the app, never
|
|
@@ -140,6 +159,14 @@ Skills are folders (`SKILL.md` + references) an agent loads when needed.
|
|
|
140
159
|
A Source admin pushes them with `ekanos skills push <dir>`: at Source level
|
|
141
160
|
every team can use them, with `--team <slug>` only that team can.
|
|
142
161
|
|
|
162
|
+
**Knowledge** is Ekanos's own knowledge base (no outside account): markdown
|
|
163
|
+
articles, one collection per team plus the Source's **General** collection
|
|
164
|
+
every team reads. A Source admin loads folders of `.md` with
|
|
165
|
+
`ekanos knowledge push <dir> [--team <slug>]`; team members edit theirs in
|
|
166
|
+
the app (Agents → Knowledge). Agents granted `search_knowledge` /
|
|
167
|
+
`read_knowledge_article` search their own team's collection and General.
|
|
168
|
+
Skills say *how* to work; Knowledge holds the facts an agent looks up.
|
|
169
|
+
|
|
143
170
|
The `build-agent` skill walks through choosing between these and building one.
|
|
144
171
|
|
|
145
172
|
A Source admin can also do a team's agent setup from the terminal, acting on
|
|
@@ -161,7 +188,9 @@ always `ekanos teams <area> <verb> <team> …`:
|
|
|
161
188
|
follows its template unless the template turns on team overrides for it.
|
|
162
189
|
- `ekanos teams triggers list|add|remove <team> <key> …` — manual, schedule
|
|
163
190
|
(`--cron`, `--timezone`), webhook (URL and token shown once) and
|
|
164
|
-
integration events (`event zendesk.ticket_created --filter '{…}'
|
|
191
|
+
integration events (`event zendesk.ticket_created --filter '{…}'`, or any
|
|
192
|
+
other id in the product's `agentEvents`, e.g. `event linear.issue_labeled
|
|
193
|
+
--filter '{"labels":["feedback"]}'`).
|
|
165
194
|
- `ekanos teams links list|add|remove <team> <from-key> [<to-key>] --kind
|
|
166
195
|
talk|delegate [--mode await|handoff]`.
|
|
167
196
|
- `ekanos teams mcp list|add|status|token|effect <team> [<server-key> …]` — a
|
|
@@ -211,8 +240,11 @@ is refused (`USER_NOT_IN_SOURCE`): `ekanos teams list` shows the teams.
|
|
|
211
240
|
| 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` |
|
|
212
241
|
| 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` |
|
|
213
242
|
| Skills (SKILL.md folders) for every team, or one team's own | A Source admin, with `ekanos skills push` (`--team <slug>` for one team) |
|
|
243
|
+
| 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 |
|
|
214
244
|
| Who decides agent drafts that wait for a person | A Source admin, with `ekanos reviewers` |
|
|
215
245
|
| An integration's app for the whole Source (client ID and secret) | A Source admin, with `ekanos apps set` at their own terminal |
|
|
246
|
+
| 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 |
|
|
247
|
+
| Which team gets which events on that connection (Zendesk organization → team) | A Source admin, with `ekanos routes` (`webhook`, `options`, `set`, `list`, `remove`, `unrouted`, `replay`), or **Shared integrations › Routing** in the Source admin area |
|
|
216
248
|
| 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` |
|
|
217
249
|
| 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 |
|
|
218
250
|
| 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) |
|