@ekanos/cli 0.4.2 → 0.5.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.
@@ -0,0 +1,27 @@
1
+ import { readActiveSource } from './commands/sources.js';
2
+ import { authRequiredError, validationError } from './errors.js';
3
+ import { fetchSeatsWithOneRefresh } from './seats.js';
4
+ /**
5
+ * Which Source a Source-scoped read or write (`catalog`, `agents`) is about:
6
+ * `--source`, else `source` in ekanos.json, else the caller's only seat.
7
+ * Works outside a project. With several seats and nothing named, it refuses
8
+ * rather than guessing.
9
+ */
10
+ export async function resolveSourceTarget(env, session, args) {
11
+ var _a;
12
+ const named = ((_a = args.source) === null || _a === void 0 ? void 0 : _a.trim()) || readActiveSource(args.dir);
13
+ if (named)
14
+ return { source: named, session };
15
+ const seats = await fetchSeatsWithOneRefresh(env, session);
16
+ if (seats.status !== 'ok') {
17
+ throw authRequiredError(`The session for ${env.host} could not list your sources.`, `Run "ekanos login --host ${env.host}" and retry.`);
18
+ }
19
+ if (seats.sources.length === 1) {
20
+ return { source: seats.sources[0].slug, session: seats.session };
21
+ }
22
+ throw validationError('Which Source? This account holds a seat on ' +
23
+ (seats.sources.length === 0
24
+ ? 'no source on this host.'
25
+ : `${seats.sources.map((seat) => seat.slug).join(', ')}.`), 'Pass "--source <slug>", or set "source" in ekanos.json.');
26
+ }
27
+ //# sourceMappingURL=source-target.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source-target.js","sourceRoot":"","sources":["../src/source-target.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,eAAe,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,EAAE,wBAAwB,EAAE,MAAM,SAAS,CAAC;AAEnD;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,mBAAmB,CACvC,GAAoB,EACpB,OAAsB,EACtB,IAAsC;;IAEtC,MAAM,KAAK,GAAG,CAAA,MAAA,IAAI,CAAC,MAAM,0CAAE,IAAI,EAAE,KAAI,gBAAgB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAChE,IAAI,KAAK;QAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC;IAE7C,MAAM,KAAK,GAAG,MAAM,wBAAwB,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC3D,IAAI,KAAK,CAAC,MAAM,KAAK,IAAI,EAAE,CAAC;QAC1B,MAAM,iBAAiB,CACrB,mBAAmB,GAAG,CAAC,IAAI,+BAA+B,EAC1D,4BAA4B,GAAG,CAAC,IAAI,cAAc,CACnD,CAAC;IACJ,CAAC;IACD,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,CAAC,CAAE,CAAC,IAAI,EAAE,OAAO,EAAE,KAAK,CAAC,OAAO,EAAE,CAAC;IACpE,CAAC;IAED,MAAM,eAAe,CACnB,6CAA6C;QAC3C,CAAC,KAAK,CAAC,OAAO,CAAC,MAAM,KAAK,CAAC;YACzB,CAAC,CAAC,yBAAyB;YAC3B,CAAC,CAAC,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,EAC9D,yDAAyD,CAC1D,CAAC;AACJ,CAAC","sourcesContent":["import type { StoredSession } from './auth/credential-store';\nimport type { AuthEnvironment } from './auth/session';\nimport { readActiveSource } from './commands/sources';\nimport { authRequiredError, validationError } from './errors';\nimport { fetchSeatsWithOneRefresh } from './seats';\n\n/**\n * Which Source a Source-scoped read or write (`catalog`, `agents`) is about:\n * `--source`, else `source` in ekanos.json, else the caller's only seat.\n * Works outside a project. With several seats and nothing named, it refuses\n * rather than guessing.\n */\nexport async function resolveSourceTarget(\n env: AuthEnvironment,\n session: StoredSession,\n args: { source?: string; dir: string },\n): Promise<{ source: string; session: StoredSession }> {\n const named = args.source?.trim() || readActiveSource(args.dir);\n if (named) return { source: named, session };\n\n const seats = await fetchSeatsWithOneRefresh(env, session);\n if (seats.status !== 'ok') {\n throw authRequiredError(\n `The session for ${env.host} could not list your sources.`,\n `Run \"ekanos login --host ${env.host}\" and retry.`,\n );\n }\n if (seats.sources.length === 1) {\n return { source: seats.sources[0]!.slug, session: seats.session };\n }\n\n throw validationError(\n 'Which Source? This account holds a seat on ' +\n (seats.sources.length === 0\n ? 'no source on this host.'\n : `${seats.sources.map((seat) => seat.slug).join(', ')}.`),\n 'Pass \"--source <slug>\", or set \"source\" in ekanos.json.',\n );\n}\n"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ekanos/cli",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
4
4
  "private": false,
5
5
  "description": "The Ekanos partner toolchain CLI: scaffold, validate, and test an Ekanos integration against the published @ekanos packages. Agent-native — every verb speaks JSON with a stable exit-code taxonomy.",
6
6
  "keywords": [
@@ -35,7 +35,7 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@clack/prompts": "1.7.0",
38
- "@ekanos/integration-schema": "0.8.0",
38
+ "@ekanos/integration-schema": "0.9.0",
39
39
  "esbuild": "0.28.1",
40
40
  "picocolors": "1.1.1"
41
41
  },
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: ekanos
3
- description: Build, iterate on, validate, and publish this Ekanos integration with the ekanos CLI. Use for any change to the integration definition, widgets, tools, webhooks, schedules, or tests, and for publishing to an Ekanos host.
3
+ description: Build, iterate on, validate, and publish this Ekanos integration with the ekanos CLI. Use for any change to the integration definition, widgets, tools, webhooks, schedules, or tests, and for publishing to an Ekanos host. Also use it to see what a source already has (ekanos catalog) and to create, change, publish or roll back the source's managed agents (ekanos agents) — agents live in Ekanos, not in this repo.
4
4
  ---
5
5
 
6
6
  # Working on this Ekanos integration
@@ -24,6 +24,25 @@ there (or use the `ekanos-sdk-docs` MCP server) for an API detail, an error
24
24
  code or validate finding (https://sdk.ekanos.dev/troubleshooting/common-errors),
25
25
  and after upgrading `@ekanos/*` packages. The topic → URL map is in AGENTS.md.
26
26
 
27
+ ## Before building, check what the source already has
28
+
29
+ `npx ekanos catalog --json` lists every product the source can use, its
30
+ tools and agent triggers, and the steps left to set each one up. If a product
31
+ already does what the user wants, propose setting it up (walk its
32
+ `setupSteps`, naming who does each one) instead of building it again.
33
+ `npx ekanos catalog <product> --json` shows one in full.
34
+
35
+ ## Managed agents live in Ekanos
36
+
37
+ An agent is not code in this repo: `npx ekanos agents list --json` shows the
38
+ source's agents, `pull <key>` writes one as `agent.json` + `AGENT.md`,
39
+ `apply <dir>` stores a change as a new draft version, and only a source admin
40
+ `publish`es it to every team. Name tools and products exactly as the catalog
41
+ lists them. Decide with the user, per product and MCP server, whether each
42
+ team connects its own (`required` or `optional`), and what teams may add
43
+ (`teamCustomization`, all off unless turned on). Show the user the applied draft and wait for their yes before
44
+ `publish --yes`; never `--overwrite` a version conflict you have not read.
45
+
27
46
  ## The loop
28
47
 
29
48
  1. `npx ekanos dev` — local harness (only when you need to see UI). For an
@@ -12,12 +12,12 @@
12
12
  "prepare": "node scripts/setup-hooks.mjs"
13
13
  },
14
14
  "dependencies": {
15
- "@ekanos/sdk": "^0.8.0",
16
- "@ekanos/ui": "^0.8.0"
15
+ "@ekanos/sdk": "^0.9.0",
16
+ "@ekanos/ui": "^0.9.0"
17
17
  },
18
18
  "devDependencies": {
19
- "@ekanos/cli": "^0.4.2",
20
- "@ekanos/harness": "^0.6.0",
19
+ "@ekanos/cli": "^0.5.1",
20
+ "@ekanos/harness": "^0.7.0",
21
21
  "@hookform/resolvers": "^5.2.2",
22
22
  "@tailwindcss/postcss": "^4.3.3",
23
23
  "@tanstack/react-query": "^5.101.4",