@ekanos/cli 0.1.4 → 0.1.5

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.
@@ -156,10 +156,20 @@ activationData is updated — **seed the cache in `onActivate`; the schedule
156
156
  keeps it fresh.** Without it, a cache-backed widget is empty until the first
157
157
  schedule tick. v1 errors are non-fatal: a throw is logged as a warning and the
158
158
  activation stays connected, so this is for cache seeding and eager
159
- validation, never a connect gate. Seed BEST-EFFORT: catch transient upstream
160
- failures (timeouts, 5xx), log, and return a throw surfaces a scary warning
161
- on a brand-new connection that the schedule will heal within one tick anyway.
162
- Reserve the throw for misconfiguration the user can actually fix.
159
+ validation, never a connect gate. Seed BEST-EFFORT swallow what you can
160
+ name, log loudly what you can't: catch the upstream error classes you can
161
+ reason about (timeouts, 5xx, provider errors) and warn; log anything
162
+ unrecognized as an error and return, so a genuine bug stays visible in logs
163
+ without telling a user their brand-new connection failed. Reserve the throw
164
+ for misconfiguration the user can actually fix. Treat onActivate as an
165
+ OPTIMIZATION, never a correctness dependency: the schedule remains the
166
+ freshness guarantee, and a config fingerprint keeps the stale window safe
167
+ whether or not the hook fires.
168
+
169
+ Troubleshooting `ekanos dev`: adding/removing/re-adding handler modules can
170
+ leave the harness's Turbopack cache resolving a deleted path ("Module not
171
+ found" for a file that exists). Clear it with `rm -rf .ekanos/harness/.next`
172
+ and restart.
163
173
 
164
174
  A cache invalidated only by age still serves the *previous* activation's data
165
175
  for a while even with `onActivate` wired up. Close that gap with a
@@ -190,8 +200,17 @@ system. Available modules (import individually, e.g. `@ekanos/ui/button`):
190
200
  `switch`, `textarea`, `tooltip`, `trans`, `utils` (the `cn()` helper),
191
201
  `ai-prompt-input`, plus the stylesheets `styles.css` / `tokens.css` /
192
202
  `theme.css` / `base.css`. Icons are Font Awesome glyph names via
193
- `@ekanos/ui/icon`; outside a host that loads Font Awesome they render as
194
- nothingexpected, not a bug.
203
+ `@ekanos/ui/icon`. This generated shell loads Font Awesome **Free**
204
+ (`@fortawesome/fontawesome-free`)a much smaller set than the Pro kit Fusion
205
+ itself runs — so a name that's Pro-only (or just mistyped) renders a
206
+ circle-question disc instead of vanishing, and dev builds `console.warn` once
207
+ per name to catch it before a screenshot review does. `fa-light` / `fa-duotone`
208
+ / `fa-thin` are rewritten to `fa-solid`, the one weight Free ships, so author
209
+ `fa-light` anyway — it degrades harmlessly today, and the intended weight
210
+ survives if this host ever loads Pro instead. Verify a glyph name against the
211
+ Free set (`pnpm --filter @ekanos/ui check:fa-free-names`, or
212
+ https://fontawesome.com/search?o=r&s=solid,regular,brands) before relying on
213
+ it looking like anything in particular.
195
214
 
196
215
  ## Testing
197
216
 
@@ -237,20 +256,40 @@ carries an imperative `hint`; treat hints as remediation instructions.
237
256
  | `ekanos test` | Run this project's test script through its package manager |
238
257
  | `ekanos login --host <url>` | Device-flow login to a Fusion deployment (stores the host for later verbs) |
239
258
  | `ekanos status` | Login state for the resolved host + this project's submissions |
240
- | `ekanos publish` | Validate, pack (whitelist: ekanos.json, package.json, README.md, src/), and submit. Refuses on any error-severity finding |
241
-
242
- Host resolution for `logout`/`whoami`/`status`/`publish`: `--host` flag
243
- `EKANOS_HOST` → the `host` field in ekanos.json → the sole stored login. The
244
- first successful `publish` saves `host` and `source` into ekanos.json.
245
- `login` is the exception it never reads ekanos.json for a host (`--host` →
246
- `EKANOS_HOST` the sole stored login only), since it is the verb that
247
- creates credentials and a committed file must not be able to redirect it.
259
+ | `ekanos sources` | List every Fusion source you hold a developer/admin seat on, marking this project's current target |
260
+ | `ekanos use <source-slug>` | Set this project's publish target — refuses (`forbidden`) a slug you hold no seat on |
261
+ | `ekanos publish` | Validate, pack (whitelist: ekanos.json, package.json, README.md, src/), verify the target, and submit. Refuses on any error-severity finding |
262
+
263
+ Host resolution for `logout`/`whoami`/`status`/`sources`/`use`/`publish`:
264
+ `--host` flag → `EKANOS_HOST` the `host` field in ekanos.json the sole
265
+ stored login. The first successful `publish` saves `host` and `source` into
266
+ ekanos.json. `login` is the exception it never reads ekanos.json for a host
267
+ (`--host` → `EKANOS_HOST` → the sole stored login only), since it is the verb
268
+ that creates credentials and a committed file must not be able to redirect it.
269
+
270
+ ### Publish targeting — do not skip this if you hold more than one seat
271
+
272
+ `publish` verifies its target BEFORE packing or submitting anything: it fetches
273
+ your seat list and refuses (`forbidden`, exit 5) a source you hold no seat on,
274
+ naming your actual seats in the hint. If the target came from ekanos.json
275
+ (not `--source` this run) and you hold more than one seat, a scripted/agent
276
+ run (JSON mode, which is what running under an agent means) is refused with
277
+ `validation` (exit 3) and the seat list **unless `--yes` is passed** — publish
278
+ never guesses and never prompts in this mode.
279
+
280
+ **As an agent: never pass `--yes` to paper over that ambiguity.** Run
281
+ `ekanos sources` first and pass `--source <slug>` explicitly, or run
282
+ `ekanos use <slug>` once to set the project's target deliberately. `--yes` is
283
+ for a human who already confirmed the target, or a pipeline pinned to one
284
+ source — not a way to silence the check when you are unsure.
248
285
 
249
286
  Exit codes (frozen contract — branch on these): `0` ok, `1` internal, `2`
250
- usage, `3` validation, `4` auth required (run `ekanos login`), `5` forbidden,
251
- `6` not found, `7` invalid state (e.g. version already submitted bump
252
- `package.json#version`), `8` network (retry, do NOT re-login), `9`
253
- precondition failed, `10` publish gate failed (fix `data.findings`).
287
+ usage, `3` validation (also: ambiguous publish target pass `--source` or
288
+ `--yes`), `4` auth required (run `ekanos login`), `5` forbidden (also: no seat
289
+ on the target source — check `ekanos sources`), `6` not found, `7` invalid
290
+ state (e.g. version already submitted bump `package.json#version`), `8`
291
+ network (retry, do NOT re-login), `9` precondition failed, `10` publish gate
292
+ failed (fix `data.findings`).
254
293
 
255
294
  The loop: `ekanos dev` → edit → `npx tsc --noEmit` → `ekanos validate` →
256
295
  `ekanos test` → `ekanos publish`.
@@ -18,8 +18,14 @@ root. Read it before writing integration code. The definition is one
18
18
  3. `npx tsc --noEmit` — types clean.
19
19
  4. `npx ekanos validate --json` — findings clean.
20
20
  5. `npm test` — green.
21
- 6. `npx ekanos publish` submits to the Fusion host (refuses while any
22
- error-severity finding remains).
21
+ 6. **Before publishing, know your target.** If you hold more than one
22
+ developer seat, run `npx ekanos sources --json` and pass the intended
23
+ `--source <slug>` explicitly to `publish`. Never pass `--yes` to get past
24
+ an ambiguous-target error you have not actually resolved — `--yes` is
25
+ consent to a target you already chose, not a way to silence the check.
26
+ 7. `npx ekanos publish --source <slug>` — submits to the Fusion host (refuses
27
+ while any error-severity finding remains, and refuses `forbidden` if you
28
+ hold no seat on that source).
23
29
 
24
30
  ## Reading CLI output
25
31
 
@@ -32,22 +38,37 @@ remediation instructions and follow them verbatim.** `ekanos validate` puts
32
38
  findings in `data.findings`; `ekanos publish` refuses with exit 10 and the
33
39
  same findings in `data.findings`.
34
40
 
35
- Exit codes to branch on: `0` ok · `2` usage · `3` validation · `4` run
36
- `ekanos login` · `7` version already submitted (bump `package.json#version`) ·
41
+ Exit codes to branch on: `0` ok · `2` usage · `3` validation (also: ambiguous
42
+ publish target pass `--source` or `--yes`, never guess) · `4` run
43
+ `ekanos login` · `5` forbidden (also: no seat on the target source — run
44
+ `ekanos sources`) · `7` version already submitted (bump `package.json#version`) ·
37
45
  `8` network (retry — do NOT re-login) · `9` precondition · `10` fix findings,
38
46
  publish again.
39
47
 
40
48
  ## Hosts and sessions
41
49
 
42
50
  `ekanos login --host <url>` stores a session; after that, `logout`/`whoami`/
43
- `status`/`publish` resolve the host from `--host` → `EKANOS_HOST` →
44
- ekanos.json's `host` field → the sole stored login. `login` itself never reads
45
- ekanos.json for a host — only `--host`, `EKANOS_HOST`, or the sole stored
46
- login — since it is the verb that creates credentials. `ekanos status` shows
47
- who you are logged in as and what this project has submitted. The first
48
- successful publish saves `host` and `source` into ekanos.json.
51
+ `status`/`sources`/`use`/`publish` resolve the host from `--host` →
52
+ `EKANOS_HOST` → ekanos.json's `host` field → the sole stored login. `login`
53
+ itself never reads ekanos.json for a host — only `--host`, `EKANOS_HOST`, or
54
+ the sole stored login — since it is the verb that creates credentials.
55
+ `ekanos status` shows who you are logged in as and what this project has
56
+ submitted. The first successful publish saves `host` and `source` into
57
+ ekanos.json.
58
+
59
+ ## Publish targets, when you hold more than one seat
60
+
61
+ `ekanos sources` lists every source you hold a seat on; `ekanos use <slug>`
62
+ sets this project's saved target (seat-checked — refuses a slug you don't
63
+ hold). `publish` verifies its resolved target against your seats before
64
+ packing anything, and — running as an agent, which is JSON/non-interactive
65
+ mode — never prompts: an ambiguous implicit target (ekanos.json, more than one
66
+ seat) is refused with the seat list unless you pass `--yes`. **Always resolve
67
+ the ambiguity yourself** (pick the right `--source`) rather than reaching for
68
+ `--yes` on a target you have not verified.
49
69
 
50
70
  ## Before claiming done
51
71
 
52
72
  Run steps 3-5 above and confirm all three are clean — a publish is only as
53
- good as the validate that precedes it.
73
+ good as the validate that precedes it. If publishing, confirm you named the
74
+ right `--source` rather than relying on `--yes`.