@eigenpal/cli 0.4.2 → 0.4.3

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/CHANGELOG.md CHANGED
@@ -263,6 +263,14 @@
263
263
 
264
264
  Also scrubs internal references from CLI source ahead of open-sourcing — generic placeholder names in docstrings and test fixtures, internal-tracker IDs stripped from comments, and one user-facing error message updated to point at the public issue tracker.
265
265
 
266
+ - be693a3: `EIGENPAL_API_KEY` is now a complete profile bypass — when set, the active profile's `baseUrl` is also ignored (previously the env key was paired with the profile's URL, which is always wrong because an API key is provisioned for one server).
267
+
268
+ In CI:
269
+ - **Cloud:** set `EIGENPAL_API_KEY=eig_live_…` and you get `https://studio.eigenpal.com`.
270
+ - **On-prem:** set both `EIGENPAL_API_KEY=…` and `EIGENPAL_BASE_URL=https://eigenpal.example.com`.
271
+
272
+ Interactive profiles are unchanged: when you log in via `eigenpal auth login`, the profile stores both apiKey and baseUrl, and every subsequent command derives baseUrl from that profile. Set `EIGENPAL_PROFILE=<name>` to switch profiles per-shell without modifying state.
273
+
266
274
  - d41ee8b: CLI: fix `eigenpal status` error UX + harden `formatCliError` for real-world connection failures.
267
275
  - `eigenpal status` against an unreachable base URL no longer mis-diagnoses the failure as an auth problem. Previously, `EIGENPAL_BASE_URL=http://localhost:9999 eigenpal status` printed "Authentication check failed; try `eigenpal auth login`" — the wrong rabbit hole. The status command now rethrows non-auth errors (connection refused, DNS NXDOMAIN, timeout, HTML responses, 5xx) so `formatCliError` upstream can surface the right hint: `Could not connect to the server at <url> ... Set EIGENPAL_BASE_URL or pass --base-url <url>.` Only real 401/403 responses are treated as auth failures.
268
276
  - `formatCliError` now detects connection failures wrapped in any Error shape — bare `Error('ENOTFOUND ...')`, `Error` with `code: 'ECONNREFUSED'`, and `TypeError('fetch failed')` whose `.cause` carries the underlying error. Previously only `TypeError` whose message contained `fetch`/`URL` was recognized, so `getaddrinfo`-style errors fell through to the generic raw-message branch and lost the URL context.
@@ -282,7 +290,22 @@
282
290
  - **Path-rejection error** suggests the corrected origin: instead of just "URL must be the server origin only", it now says e.g. "Try https://studio.eigenpal.com instead of '/api/v1'".
283
291
  - **Non-TTY error copy** is consistent across CI and pipe-redirect paths — both name the missing piece (interactive terminal) and the workaround (`--base-url` / env var).
284
292
 
293
+ - be693a3: `eigenpal auth login` no longer opens your browser as the very first thing it does. The flow now mirrors mature CLIs (`gh auth login`, `vercel login`):
294
+ 1. **Pick the server** (existing select prompt).
295
+ 2. **Explain the flow** — a clear step-by-step note tells you what's about to happen and surfaces the dashboard URL prominently so you can copy it manually if you prefer.
296
+ 3. **Confirm browser launch** — "Open the dashboard in your browser?" (default Yes). Users on headless VMs, WSL without xdg-open, or who already have the dashboard open can answer No and skip the best-effort browser launch entirely.
297
+ 4. **Paste the API key** — same as before.
298
+
299
+ No surprise side effects, no "wait, why did a browser pop?" moment. The URL is also in the explanation note so a failed `openBrowser` doesn't strand you.
300
+
285
301
  - c82a215: `package.json` now carries full npm metadata: `license: Apache-2.0`, `keywords`, `repository`, `bugs`, `homepage`, and `author`. The published tarball also bundles `LICENSE` and `CHANGELOG.md` so the npm page renders the license badge instead of "License: none" and surfaces real keywords for search.
302
+ - ee32a73: Three fixes around the public CLI mirror and login UX:
303
+ 1. **Public mirror keeps history.** `sync_public_cli` no longer wipes `github.com/eigenpal/cli`'s git history on every release. It now clones the existing public repo, replaces the working tree with the new synth output, and pushes one commit per release. Each release adds `release: @eigenpal/cli@X.Y.Z` on top of the previous one. Tags accumulate too.
304
+ 2. **CHANGELOG no longer starts from `0.0.0`.** The `Pin CLI version + apply pending changesets` step in `sync_public_cli` was running `bunx changeset version` _before_ pinning the source `0.0.0-placeholder` to the real release tag, so changeset wrote CHANGELOG headings like `## 0.0.1` while the actual published version was e.g. `0.4.2`. Pin first, then run changeset version, then sed-rewrite the topmost heading to match the real release tag.
305
+ 3. **Login picker copy + URL cleanup.**
306
+ - Hint `(saved profile)` had double parens because clack auto-wraps hints in parens — was rendering as `((saved profile) from acme)`. Now `saved profile: <names>`.
307
+ - Dropped `?from=cli` from the dashboard URL — the dashboard ignores the param, and a clean URL is easier to copy/paste/visit manually.
308
+
286
309
  - c82a215: Public README cleanup:
287
310
  - Removed the duplicated `# @eigenpal/cli` heading and redundant install snippet that was being prepended to the public mirror's README. The bundled CLI README is already self-contained, so the synth header was just stacking a second title on top.
288
311
  - Reordered sections so users hit "what to install + what's available" first: Install → Commands → Use it → Primitives. Primitives is the conceptual reference; it now sits below the hands-on sections instead of above them.
@@ -386,6 +409,7 @@
386
409
  installed set.
387
410
  - Help description and CLI grouping no longer hard-code Claude Code.
388
411
 
412
+ - f13cd4d: Release commits on the public CLI mirror (`github.com/eigenpal/cli`) are now authored by the **EigenPal Release Pal** GitHub App instead of an anonymous bot identity. The App has its own logo and renders as `eigenpal-release-pal[bot]` next to each commit, with the human who triggered the release shown as co-author. No user-visible CLI behavior change — the install path and tarball contents are identical.
389
413
  - 71361fd: Review + simplification pass on the recent eval/dataset/error work:
390
414
 
391
415
  **Bug fixes** surfaced by code review:
package/README.md CHANGED
@@ -54,6 +54,19 @@ eigenpal workflow execution list <id> --json | jq # query as JSON
54
54
  | **Evaluator** | Scorers: LLM judge, exact match, custom. |
55
55
  | **Experiment** | Batch run of a workflow over a dataset, scored. |
56
56
 
57
+ ## Environment variables
58
+
59
+ Most users never need to set these — `eigenpal auth login` writes a profile to `~/.config/eigenpal/credentials.json` and every command derives its config from there. Reach for env vars when you can't run an interactive login (CI), need to switch context for one shell, or want to override a single field without editing the credentials file.
60
+
61
+ | Variable | Purpose |
62
+ | ------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
63
+ | `EIGENPAL_API_KEY` | Bypass the profile entirely. Set in CI to skip `auth login`. When set, `EIGENPAL_BASE_URL` (or the cloud default) is used — the active profile is **not** consulted, so a stale profile can't redirect a CI run to the wrong server. |
64
+ | `EIGENPAL_BASE_URL` | Override the server URL for one command or shell. Pairs with `EIGENPAL_API_KEY` to point CI at an on-prem deployment. Without `EIGENPAL_API_KEY`, this overrides whatever the active profile would have used. |
65
+ | `EIGENPAL_PROFILE` | Switch the active profile for one shell without touching `~/.config/eigenpal/credentials.json`. Useful for ad-hoc context switches: `EIGENPAL_PROFILE=staging eigenpal status`. Persistent equivalent: `eigenpal auth use <name>`. |
66
+ | `EIGENPAL_DIR` | Override the workflow project directory used by `init` / `validate`. Defaults to `./eigenpal`. |
67
+
68
+ Resolution precedence: command-line flags > env vars > active profile > defaults.
69
+
57
70
  ## Support
58
71
 
59
72
  File issues at [github.com/eigenpal/cli/issues](https://github.com/eigenpal/cli/issues).
package/dist/cli.js CHANGED
@@ -155990,7 +155990,7 @@ import { fileURLToPath as fileURLToPath6 } from "url";
155990
155990
  // package.json
155991
155991
  var package_default = {
155992
155992
  name: "@eigenpal/cli",
155993
- version: "0.4.2",
155993
+ version: "0.4.3",
155994
155994
  description: "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
155995
155995
  keywords: [
155996
155996
  "eigenpal",
@@ -156615,7 +156615,7 @@ async function pickBaseUrlInteractive() {
156615
156615
  options.push({
156616
156616
  value: url2,
156617
156617
  label: url2,
156618
- hint: `(saved profile) from ${profiles.join(", ")}`
156618
+ hint: `saved profile: ${profiles.join(", ")}`
156619
156619
  });
156620
156620
  }
156621
156621
  options.push({ value: "__custom__", label: "Custom URL…", hint: "paste your own" });
@@ -156670,16 +156670,20 @@ async function authLogin(flagBaseUrl) {
156670
156670
  }
156671
156671
  baseUrl = await pickBaseUrlInteractive();
156672
156672
  }
156673
- const settingsUrl = `${baseUrl}/developers/api-keys?from=cli`;
156674
- M2.step(`Opening browser at ${ui.dim(settingsUrl)}`);
156675
- openBrowser(settingsUrl);
156676
- Me(`If a browser didn't open, visit:
156677
- ${ui.bold(settingsUrl)}
156678
-
156679
- Create a new key (suggested name: ${ui.bold('"Eigenpal CLI"')}), copy it,
156680
- and paste it below. Input is hidden.`, "Next");
156673
+ const settingsUrl = `${baseUrl}/developers/api-keys`;
156674
+ Me(`${ui.bold("1.")} Open your dashboard:
156675
+ ` + ` ${ui.bold(settingsUrl)}
156676
+ ` + `${ui.bold("2.")} Generate a key (suggested name: ${ui.bold('"Eigenpal CLI"')}).
156677
+ ` + `${ui.bold("3.")} Copy the key and paste it back here.`, "Create an API key");
156678
+ const shouldOpen = exitOnCancel(await ye({
156679
+ message: "Open the dashboard in your browser?",
156680
+ initialValue: true
156681
+ }));
156682
+ if (shouldOpen)
156683
+ openBrowser(settingsUrl);
156684
+ M2.info(`Dashboard URL: ${ui.bold(settingsUrl)}`);
156681
156685
  const key = exitOnCancel(await ge({
156682
- message: "API key (eig_live_…)",
156686
+ message: "Paste your API key (eig_live_…)",
156683
156687
  mask: "*",
156684
156688
  validate: (value) => value.trim().length > 0 ? undefined : "Paste the key from your dashboard, or press Ctrl-C to cancel."
156685
156689
  }));
@@ -157631,7 +157635,8 @@ function runDiff(source, current) {
157631
157635
  // src/lib/config.ts
157632
157636
  var DEFAULT_BASE_URL = "https://studio.eigenpal.com";
157633
157637
  function resolveConfig(flags) {
157634
- const profile = readActiveCredentials();
157638
+ const usingEnvKey = !!env.EIGENPAL_API_KEY;
157639
+ const profile = usingEnvKey ? null : readActiveCredentials();
157635
157640
  const baseUrl = flags.baseUrl || env.EIGENPAL_BASE_URL || profile?.baseUrl || DEFAULT_BASE_URL;
157636
157641
  const apiKey = env.EIGENPAL_API_KEY || profile?.apiKey || "";
157637
157642
  const dir = flags.dir || env.EIGENPAL_DIR || "./eigenpal";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@eigenpal/cli",
3
- "version": "0.4.2",
3
+ "version": "0.4.3",
4
4
  "description": "Eigenpal CLI — author and run document workflows from your terminal. Agent-ready.",
5
5
  "keywords": [
6
6
  "eigenpal",