@theholocron/cli 5.0.0-alpha.125 → 5.0.0-alpha.126

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/README.md CHANGED
@@ -513,7 +513,16 @@ Axiom shipping activates when a token (`HOLOCRON_AXIOM_TOKEN` / `AXIOM_TOKEN`
513
513
  → OS keyring `axiom.<org>` → `axiom`) **and** a dataset
514
514
  (`HOLOCRON_AXIOM_DATASET` / `AXIOM_DATASET` → `log.axiom.dataset` in
515
515
  `holocron.config`) both resolve; env vars win. The token is never read from a
516
- config file. See the [logging guide](https://docs.theholocron.dev/holocron/logging/).
516
+ config file.
517
+
518
+ The dataset side of that resolution is **execution-context-aware** (ADR-0012):
519
+ a `global`-context command (`clone`, `new`, `auth set`, `upgrade node`, `plugin
520
+ create`, …) always ships to holocron's own dataset regardless of `$PWD` — it
521
+ isn't "about" any repo, so routing it through whichever repo's `.envrc`
522
+ happens to be active would be wrong. `repo-aware` / `workspace` commands
523
+ (`doctor`, `deploy`, `sync`, …) keep the env-var/config chain above, so a
524
+ per-repo `HOLOCRON_AXIOM_DATASET` — e.g. via a `.envrc` + `direnv` — separates
525
+ each consuming repo's logs. See the [logging guide](https://docs.theholocron.dev/holocron/logging/).
517
526
 
518
527
  ### Telemetry
519
528
 
package/dist/cli.mjs CHANGED
@@ -303,6 +303,63 @@ function resolveConfig(raw) {
303
303
  };
304
304
  }
305
305
  //#endregion
306
+ //#region src/commands/contexts.ts
307
+ /**
308
+ * Command → context. Keys are the command name as it lands in yargs'
309
+ * `argv._` — the full path for sub-commands (`"auth set"`, `"upgrade
310
+ * node"`), the bare verb otherwise.
311
+ *
312
+ * - **`global`** — needs nothing but the CLI binary. Works anywhere.
313
+ * - **`repo-aware`** — reads `./holocron.config` + `./package.json`
314
+ * relative to cwd, but never touches the plugin loader.
315
+ * - **`workspace`** — needs the configured providers' plugin packages to
316
+ * resolve (devDeps in a repo, or `pnpm exec`).
317
+ */
318
+ const COMMAND_CONTEXTS = {
319
+ clone: "global",
320
+ new: "global",
321
+ "upgrade node": "global",
322
+ "upgrade deps": "global",
323
+ "plugin create": "global",
324
+ "auth set": "global",
325
+ "auth unset": "global",
326
+ "auth list": "global",
327
+ "auth check": "global",
328
+ "bump-versions": "global",
329
+ publish: "global",
330
+ "skills install": "global",
331
+ "skills remove": "global",
332
+ "skills update": "global",
333
+ "lint commit-msg": "global",
334
+ run: "repo-aware",
335
+ ci: "repo-aware",
336
+ "deploy-on-release": "repo-aware",
337
+ "config show": "repo-aware",
338
+ "sync-readme": "repo-aware",
339
+ doctor: "workspace",
340
+ setup: "workspace",
341
+ "secret set": "workspace",
342
+ "secrets sync": "workspace",
343
+ deploy: "workspace",
344
+ "cleanup-preview": "workspace",
345
+ sync: "workspace",
346
+ "sync-github": "workspace"
347
+ };
348
+ /**
349
+ * The context for a command name from `argv._`. Falls back to the leading
350
+ * verb (`"auth foo"` → `"auth"`) and finally `undefined` for a name the
351
+ * map doesn't know — callers treat unknown as "don't guard".
352
+ */
353
+ function contextForCommand(name) {
354
+ const map = COMMAND_CONTEXTS;
355
+ if (map[name]) return map[name];
356
+ return map[name.split(" ")[0] ?? ""];
357
+ }
358
+ /** Command names in a given context, in registration order. */
359
+ function commandsInContext(context) {
360
+ return Object.entries(COMMAND_CONTEXTS).filter(([, c]) => c === context).map(([name]) => name);
361
+ }
362
+ //#endregion
306
363
  //#region src/ui/style.ts
307
364
  const style = {
308
365
  success: (msg) => `${chalk.green("✓")} ${msg}`,
@@ -318,6 +375,16 @@ const style = {
318
375
  //#endregion
319
376
  //#region src/logger.ts
320
377
  /**
378
+ * Dataset for `global`-context commands (`clone`, `auth set`, `upgrade
379
+ * node`, …) — ADR-0012. These commands aren't "about" any repo, so their
380
+ * logs must never depend on `$PWD` or which repo's `.envrc` happens to be
381
+ * active; they always ship to holocron's own dataset instead of whatever
382
+ * `HOLOCRON_AXIOM_DATASET` resolves to locally. Mirrors
383
+ * `telemetry/resolve.ts`'s `FALLBACK_DSN` — a holocron-owned default, not a
384
+ * per-repo override.
385
+ */
386
+ const GLOBAL_AXIOM_DATASET = "holocron-global";
387
+ /**
321
388
  * Resolve the explicit level to hand to `createLogger`, in priority order:
322
389
  *
323
390
  * 1. `--log <level>` 2. `--verbose` → `"debug"` 3. `--quiet` → `"error"`
@@ -356,20 +423,29 @@ let rootLevel;
356
423
  let rootCommand;
357
424
  let rootAxiomKey;
358
425
  /**
359
- * Resolve Axiom credentials for the CLI. Env vars win — same contract as
360
- * `@theholocron/observability`'s `resolveAxiomFromEnv`. Failing that, the CLI-only
361
- * bridge pairs the OS-keyring token (`axiom.<org>` then bare `axiom`) with a
362
- * dataset from `HOLOCRON_AXIOM_DATASET` / `AXIOM_DATASET` or
363
- * `holocron.config` `log.axiom.dataset`. Returns `undefined` unless both a
364
- * token and a dataset are found.
426
+ * Resolve Axiom credentials for the CLI.
427
+ *
428
+ * A `global`-context command (ADR-0012) always resolves to
429
+ * {@link GLOBAL_AXIOM_DATASET}, ignoring `HOLOCRON_AXIOM_DATASET` /
430
+ * `AXIOM_DATASET` / `holocron.config` `log.axiom.dataset` entirely — it
431
+ * isn't "about" any repo, so the active directory's dataset is never the
432
+ * right answer. Everything else keeps the existing chain: env vars win
433
+ * (same contract as `@theholocron/observability`'s `resolveAxiomFromEnv`),
434
+ * falling back to the CLI-only bridge that pairs the OS-keyring token
435
+ * (`axiom.<org>` then bare `axiom`) with a dataset from
436
+ * `HOLOCRON_AXIOM_DATASET` / `AXIOM_DATASET` or `log.axiom.dataset`.
437
+ * Returns `undefined` unless both a token and a dataset are found.
365
438
  */
366
439
  function resolveCliAxiom(opts) {
367
- const fromEnv = resolveAxiomFromEnv();
368
- if (fromEnv) return fromEnv;
369
- const dataset = env.get("HOLOCRON_AXIOM_DATASET") || env.get("AXIOM_DATASET") || opts.configAxiomDataset;
440
+ const isGlobal = contextForCommand(opts.command ?? rootCommand ?? "") === "global";
441
+ if (!isGlobal) {
442
+ const fromEnv = resolveAxiomFromEnv();
443
+ if (fromEnv) return fromEnv;
444
+ }
445
+ const dataset = isGlobal ? GLOBAL_AXIOM_DATASET : env.get("HOLOCRON_AXIOM_DATASET") || env.get("AXIOM_DATASET") || opts.configAxiomDataset;
370
446
  if (!dataset) return void 0;
371
447
  const org = opts.org ?? env.get("HOLOCRON_ORG");
372
- const token = (org ? getToken(`axiom.${org}`) : null) ?? getToken("axiom");
448
+ const token = env.get("HOLOCRON_AXIOM_TOKEN") || env.get("AXIOM_TOKEN") || (org ? getToken(`axiom.${org}`) : null) || getToken("axiom");
373
449
  return token ? {
374
450
  dataset,
375
451
  token
@@ -1337,53 +1413,6 @@ async function runClone(input) {
1337
1413
  };
1338
1414
  }
1339
1415
  //#endregion
1340
- //#region src/commands/contexts.ts
1341
- /**
1342
- * Command → context. Keys are the command name as it lands in yargs'
1343
- * `argv._` — the full path for sub-commands (`"auth set"`, `"upgrade
1344
- * node"`), the bare verb otherwise.
1345
- *
1346
- * - **`global`** — needs nothing but the CLI binary. Works anywhere.
1347
- * - **`repo-aware`** — reads `./holocron.config` + `./package.json`
1348
- * relative to cwd, but never touches the plugin loader.
1349
- * - **`workspace`** — needs the configured providers' plugin packages to
1350
- * resolve (devDeps in a repo, or `pnpm exec`).
1351
- */
1352
- const COMMAND_CONTEXTS = {
1353
- clone: "global",
1354
- new: "global",
1355
- "upgrade node": "global",
1356
- "upgrade deps": "global",
1357
- "plugin create": "global",
1358
- "auth set": "global",
1359
- "auth unset": "global",
1360
- "auth list": "global",
1361
- "auth check": "global",
1362
- "bump-versions": "global",
1363
- publish: "global",
1364
- "skills install": "global",
1365
- "skills remove": "global",
1366
- "skills update": "global",
1367
- "lint commit-msg": "global",
1368
- run: "repo-aware",
1369
- ci: "repo-aware",
1370
- "deploy-on-release": "repo-aware",
1371
- "config show": "repo-aware",
1372
- "sync-readme": "repo-aware",
1373
- doctor: "workspace",
1374
- setup: "workspace",
1375
- "secret set": "workspace",
1376
- "secrets sync": "workspace",
1377
- deploy: "workspace",
1378
- "cleanup-preview": "workspace",
1379
- sync: "workspace",
1380
- "sync-github": "workspace"
1381
- };
1382
- /** Command names in a given context, in registration order. */
1383
- function commandsInContext(context) {
1384
- return Object.entries(COMMAND_CONTEXTS).filter(([, c]) => c === context).map(([name]) => name);
1385
- }
1386
- //#endregion
1387
1416
  //#region src/commands/deploy.ts
1388
1417
  /**
1389
1418
  * `holocron deploy` — trigger a deployment via the configured