@chanom/cli 0.4.1 → 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.
Files changed (2) hide show
  1. package/dist/index.js +47 -75
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -4,7 +4,7 @@ import { Cause, Chunk, Data, Effect, Layer, LogLevel, Logger, Option, Stream } f
4
4
  import * as clack from "@clack/prompts";
5
5
  import pc from "picocolors";
6
6
  import { NodeContext, NodeRuntime } from "@effect/platform-node";
7
- //#region ../internal/src/domain/package-manager.ts
7
+ // ../internal/src/domain/package-manager.ts
8
8
  /** How to run a locally installed binary with each package manager. */
9
9
  const PM_EXEC = {
10
10
  pnpm: ["pnpm", "exec"],
@@ -37,8 +37,7 @@ function parsePmUserAgent(agent) {
37
37
  function resolvePm(hints) {
38
38
  return parsePmField(hints.packageManagerField) ?? parsePmUserAgent(hints.userAgent) ?? hints.fallback ?? "pnpm";
39
39
  }
40
- //#endregion
41
- //#region ../internal/src/domain/vscode.ts
40
+ // ../internal/src/domain/vscode.ts
42
41
  /** Keys VS Code reads as a per-language override, e.g. `[typescript]`. */
43
42
  const LANGUAGES = [
44
43
  "markdown",
@@ -109,8 +108,7 @@ function planExtensions(current, wanted) {
109
108
  added
110
109
  };
111
110
  }
112
- //#endregion
113
- //#region ../internal/src/services/command-runner.ts
111
+ // ../internal/src/services/command-runner.ts
114
112
  const collectText = (stream) => stream.pipe(Stream.decodeText(), Stream.mkString);
115
113
  /**
116
114
  * Low-level process execution. Everything that shells out (git, package
@@ -146,8 +144,7 @@ var CommandRunner = class extends Effect.Service()("internal/CommandRunner", { e
146
144
  execInherit
147
145
  };
148
146
  }) }) {};
149
- //#endregion
150
- //#region ../internal/src/services/git.ts
147
+ // ../internal/src/services/git.ts
151
148
  /** Git operations, built on top of {@link CommandRunner}. */
152
149
  var Git = class extends Effect.Service()("internal/Git", { effect: Effect.gen(function* () {
153
150
  const runner = yield* CommandRunner;
@@ -196,8 +193,7 @@ var Git = class extends Effect.Service()("internal/Git", { effect: Effect.gen(fu
196
193
  readGitignore: (cwd) => fs.readFileString(path.join(cwd, ".gitignore"))
197
194
  };
198
195
  }) }) {};
199
- //#endregion
200
- //#region ../internal/src/services/prompter.ts
196
+ // ../internal/src/services/prompter.ts
201
197
  var Cancelled = class extends Data.TaggedError("Cancelled") {};
202
198
  const guardCancel = (make) => Effect.promise(make).pipe(Effect.filterOrFail((result) => typeof result !== "symbol", () => new Cancelled()));
203
199
  /**
@@ -283,17 +279,15 @@ function skillLink(skill) {
283
279
  target: `../../${SKILLS_ROOT}/${skill.name}`
284
280
  };
285
281
  }
286
- //#endregion
287
- //#region src/bundled-versions.ts
282
+ // src/bundled-versions.ts
288
283
  const bundledVersions = {
289
- oxlint: "1.73.0",
290
- oxlintTsgolint: "0.24.0",
291
- oxfmt: "0.58.0",
284
+ oxlint: "1.89.0",
285
+ oxlintTsgolint: "7.0.2005",
286
+ oxfmt: "0.74.0",
292
287
  knip: "6.26.0",
293
- devConfig: "0.0.3"
288
+ devConfig: "0.0.5"
294
289
  };
295
- //#endregion
296
- //#region src/domain/pkg.ts
290
+ // src/domain/pkg.ts
297
291
  var PkgNotFound = class extends Data.TaggedError("PkgNotFound") {};
298
292
  var PkgInvalid = class extends Data.TaggedError("PkgInvalid") {};
299
293
  function isEsm(pkg) {
@@ -309,8 +303,7 @@ function getMismatchedPackage(pkg, name, version) {
309
303
  const installed = pkg.dependencies?.[name] ?? pkg.devDependencies?.[name];
310
304
  return installed !== void 0 && stripRangePrefix(installed) === version ? void 0 : `${name}@${version}`;
311
305
  }
312
- //#endregion
313
- //#region src/domain/package-manager.ts
306
+ // src/domain/package-manager.ts
314
307
  /**
315
308
  * Extra `add` flags needed when installing at a workspace root: pnpm and yarn
316
309
  * classic refuse root installs without `-w` / `-W`. npm, bun, and yarn berry
@@ -324,13 +317,13 @@ function workspaceRootFlags(pm, hints) {
324
317
  case "bun": return [];
325
318
  }
326
319
  }
327
- //#endregion
328
- //#region src/services/package-installer.ts
320
+ // src/services/package-installer.ts
329
321
  var InstallFailed = class extends Data.TaggedError("InstallFailed") {};
330
322
  /**
331
323
  * Installs npm packages with the detected package manager, adding the
332
324
  * workspace-root flag (pnpm `-w`, yarn classic `-W`) when the target
333
- * directory is a workspace root.
325
+ * directory is a workspace root. Output is captured rather than inherited so
326
+ * the caller's spinner is not redrawn over the package manager's own progress.
334
327
  */
335
328
  var PackageInstaller = class extends Effect.Service()("cli/PackageInstaller", { effect: Effect.gen(function* () {
336
329
  const runner = yield* CommandRunner;
@@ -343,15 +336,17 @@ var PackageInstaller = class extends Effect.Service()("cli/PackageInstaller", {
343
336
  hasWorkspacesField: hasWorkspacesField(cwd),
344
337
  hasYarnBerryConfig: has(cwd, ".yarnrc.yml")
345
338
  }, { concurrency: 3 });
346
- return { installDev: (pm, cwd, packages) => workspaceHints(cwd).pipe(Effect.flatMap((hints) => runner.execInherit(pm, [
339
+ return { installDev: (pm, cwd, packages) => workspaceHints(cwd).pipe(Effect.flatMap((hints) => runner.capture(pm, [
347
340
  "add",
348
341
  "-D",
349
342
  ...workspaceRootFlags(pm, hints),
350
343
  ...packages
351
- ], cwd)), Effect.filterOrFail((code) => code === 0, () => new InstallFailed({ pm })), Effect.asVoid) };
344
+ ], cwd)), Effect.filterOrFail((result) => result.exitCode === 0, (result) => new InstallFailed({
345
+ pm,
346
+ output: [result.stdout, result.stderr].filter(Boolean).join("\n")
347
+ })), Effect.asVoid) };
352
348
  }) }) {};
353
- //#endregion
354
- //#region src/utils/detect-pm.ts
349
+ // src/utils/detect-pm.ts
355
350
  const detectPm = (cwd, userAgent = process.env["npm_config_user_agent"], fallback = "pnpm") => Effect.gen(function* () {
356
351
  const fs = yield* FileSystem.FileSystem;
357
352
  const pkgPath = (yield* Path.Path).join(cwd, "package.json");
@@ -361,8 +356,7 @@ const detectPm = (cwd, userAgent = process.env["npm_config_user_agent"], fallbac
361
356
  fallback
362
357
  });
363
358
  });
364
- //#endregion
365
- //#region src/utils/pkg-file.ts
359
+ // src/utils/pkg-file.ts
366
360
  const readPkg = (cwd) => Effect.gen(function* () {
367
361
  const fs = yield* FileSystem.FileSystem;
368
362
  const pkgPath = (yield* Path.Path).join(cwd, "package.json");
@@ -379,8 +373,7 @@ const readPkg = (cwd) => Effect.gen(function* () {
379
373
  const writePkg = (pkgPath, pkg) => Effect.gen(function* () {
380
374
  yield* (yield* FileSystem.FileSystem).writeFileString(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
381
375
  });
382
- //#endregion
383
- //#region src/domain/setup.ts
376
+ // src/domain/setup.ts
384
377
  const SETUP_FILE_CANDIDATES = {
385
378
  oxlint: [
386
379
  "oxlint.config.js",
@@ -450,8 +443,7 @@ function configFlag(configFile) {
450
443
  const extension = configFile.slice(configFile.lastIndexOf(".") + 1);
451
444
  return AUTO_DISCOVERED.has(extension) ? "" : ` -c ${configFile}`;
452
445
  }
453
- //#endregion
454
- //#region src/utils/detect-setup.ts
446
+ // src/utils/detect-setup.ts
455
447
  /** Finds an existing config file for the given tool, if any. */
456
448
  const detectSetupFile = (type, cwd) => Effect.gen(function* () {
457
449
  const fs = yield* FileSystem.FileSystem;
@@ -462,8 +454,7 @@ const detectSetupFile = (type, cwd) => Effect.gen(function* () {
462
454
  }
463
455
  return Option.none();
464
456
  });
465
- //#endregion
466
- //#region src/commands/add-commitlint/logic.ts
457
+ // src/commands/add-commitlint/logic.ts
467
458
  function getPackages$5(pkg) {
468
459
  const missing = [];
469
460
  if (!isPackageInstalled(pkg, "@commitlint/cli")) missing.push("@commitlint/cli");
@@ -479,8 +470,7 @@ function commitMsgHook(pm) {
479
470
  "$1"
480
471
  ].join(" ") + "\n";
481
472
  }
482
- //#endregion
483
- //#region src/commands/add-commitlint/index.ts
473
+ // src/commands/add-commitlint/index.ts
484
474
  const apply$7 = Effect.fn("add-commitlint.apply")(function* (cwd, pm) {
485
475
  const fs = yield* FileSystem.FileSystem;
486
476
  const path = yield* Path.Path;
@@ -495,13 +485,11 @@ const apply$7 = Effect.fn("add-commitlint.apply")(function* (cwd, pm) {
495
485
  else yield* fs.writeFileString(hookPath, commitMsgHook(pm));
496
486
  }
497
487
  });
498
- //#endregion
499
- //#region src/commands/add-husky/logic.ts
488
+ // src/commands/add-husky/logic.ts
500
489
  function getPackages$4(pkg) {
501
490
  return isPackageInstalled(pkg, "husky") ? [] : ["husky"];
502
491
  }
503
- //#endregion
504
- //#region src/commands/add-husky/index.ts
492
+ // src/commands/add-husky/index.ts
505
493
  var HuskyInitFailed = class extends Data.TaggedError("HuskyInitFailed") {};
506
494
  const apply$6 = Effect.fn("add-husky.apply")(function* (cwd, pm) {
507
495
  const fs = yield* FileSystem.FileSystem;
@@ -521,8 +509,7 @@ const apply$6 = Effect.fn("add-husky.apply")(function* (cwd, pm) {
521
509
  ], cwd);
522
510
  if (exitCode !== 0) return yield* new HuskyInitFailed({ exitCode });
523
511
  });
524
- //#endregion
525
- //#region src/domain/scripts.ts
512
+ // src/domain/scripts.ts
526
513
  /**
527
514
  * Merges `wanted` scripts into `current` without overwriting anything the user
528
515
  * already has. Returns the merged scripts plus which keys were added or skipped.
@@ -542,8 +529,7 @@ function planScripts(current, wanted) {
542
529
  skipped
543
530
  };
544
531
  }
545
- //#endregion
546
- //#region src/commands/add-knip/logic.ts
532
+ // src/commands/add-knip/logic.ts
547
533
  function getPackages$3(pkg, versions) {
548
534
  return isPackageInstalled(pkg, "knip") ? [] : [`knip@${versions.knip}`, `@chanom/dev-config@${versions.devConfig}`];
549
535
  }
@@ -556,8 +542,7 @@ function configFile$2(esm) {
556
542
  function getScriptPlan$2(scripts) {
557
543
  return planScripts(scripts, { knip: "knip" });
558
544
  }
559
- //#endregion
560
- //#region src/commands/add-knip/index.ts
545
+ // src/commands/add-knip/index.ts
561
546
  /** Returns a copy of `pkg` with missing scripts added; the caller owns writing package.json. */
562
547
  const apply$5 = Effect.fn("add-knip.apply")(function* (cwd, esm, pkg) {
563
548
  const fs = yield* FileSystem.FileSystem;
@@ -576,8 +561,7 @@ const apply$5 = Effect.fn("add-knip.apply")(function* (cwd, esm, pkg) {
576
561
  scripts: plan.scripts
577
562
  };
578
563
  });
579
- //#endregion
580
- //#region src/commands/add-lint-staged/logic.ts
564
+ // src/commands/add-lint-staged/logic.ts
581
565
  function getPackages$2(pkg) {
582
566
  return isPackageInstalled(pkg, "lint-staged") ? [] : ["lint-staged"];
583
567
  }
@@ -594,8 +578,7 @@ function buildConfig(linters, formatters, configFiles) {
594
578
  }
595
579
  return config;
596
580
  }
597
- //#endregion
598
- //#region src/commands/add-lint-staged/index.ts
581
+ // src/commands/add-lint-staged/index.ts
599
582
  /**
600
583
  * Config file each tool will run against: an existing one when `add-oxlint` /
601
584
  * `add-oxfmt` skipped writing, otherwise the name they scaffold. lint-staged
@@ -637,8 +620,7 @@ const apply$4 = Effect.fn("add-lint-staged.apply")(function* (cwd, esm, linters
637
620
  else yield* fs.writeFileString(hookPath, "lint-staged\n");
638
621
  }
639
622
  });
640
- //#endregion
641
- //#region src/commands/add-oxfmt/logic.ts
623
+ // src/commands/add-oxfmt/logic.ts
642
624
  function getPackages$1(pkg, versions) {
643
625
  return [getMismatchedPackage(pkg, "oxfmt", versions.oxfmt), getMismatchedPackage(pkg, "@chanom/dev-config", versions.devConfig)].filter((p) => p !== void 0);
644
626
  }
@@ -655,8 +637,7 @@ function getScriptPlan$1(scripts, configFile) {
655
637
  "format:check": `oxfmt --check${config}`
656
638
  });
657
639
  }
658
- //#endregion
659
- //#region src/commands/add-oxfmt/index.ts
640
+ // src/commands/add-oxfmt/index.ts
660
641
  /** Returns a copy of `pkg` with missing scripts added; the caller owns writing package.json. */
661
642
  const apply$3 = Effect.fn("add-oxfmt.apply")(function* (cwd, esm, pkg) {
662
643
  const fs = yield* FileSystem.FileSystem;
@@ -679,8 +660,7 @@ const apply$3 = Effect.fn("add-oxfmt.apply")(function* (cwd, esm, pkg) {
679
660
  scripts: plan.scripts
680
661
  };
681
662
  });
682
- //#endregion
683
- //#region src/commands/add-oxlint/logic.ts
663
+ // src/commands/add-oxlint/logic.ts
684
664
  function getPackages(pkg, versions) {
685
665
  return [
686
666
  getMismatchedPackage(pkg, "oxlint", versions.oxlint),
@@ -701,8 +681,7 @@ function getScriptPlan(scripts, configFile) {
701
681
  "lint:fix": `oxlint --fix${config}`
702
682
  });
703
683
  }
704
- //#endregion
705
- //#region src/commands/add-oxlint/index.ts
684
+ // src/commands/add-oxlint/index.ts
706
685
  /** Returns a copy of `pkg` with missing scripts added; the caller owns writing package.json. */
707
686
  const apply$2 = Effect.fn("add-oxlint.apply")(function* (cwd, esm, pkg) {
708
687
  const fs = yield* FileSystem.FileSystem;
@@ -725,8 +704,7 @@ const apply$2 = Effect.fn("add-oxlint.apply")(function* (cwd, esm, pkg) {
725
704
  scripts: plan.scripts
726
705
  };
727
706
  });
728
- //#endregion
729
- //#region src/commands/add-skills/logic.ts
707
+ // src/commands/add-skills/logic.ts
730
708
  /**
731
709
  * Splits the skill's files by whether they are already on disk. Existing files
732
710
  * always win: a user who has edited the standards to fit their project keeps
@@ -742,8 +720,7 @@ function planSkillFiles(files, exists) {
742
720
  skipped
743
721
  };
744
722
  }
745
- //#endregion
746
- //#region src/commands/add-skills/index.ts
723
+ // src/commands/add-skills/index.ts
747
724
  /**
748
725
  * Links `.claude/skills/<name>` at the real directory under `.agents/skills/`.
749
726
  * Anything already at the link path - a link the user already has, or a real
@@ -783,8 +760,7 @@ const apply$1 = Effect.fn("add-skills.apply")(function* (cwd) {
783
760
  }
784
761
  for (const skill of SKILLS) yield* linkSkill(cwd, skillLink(skill));
785
762
  });
786
- //#endregion
787
- //#region src/commands/add-vscode/index.ts
763
+ // src/commands/add-vscode/index.ts
788
764
  const writeJson = Effect.fn("add-vscode.writeJson")(function* (filePath, value) {
789
765
  yield* (yield* FileSystem.FileSystem).writeFileString(filePath, JSON.stringify(value, null, 2) + "\n");
790
766
  });
@@ -847,8 +823,7 @@ const apply = Effect.fn("add-vscode.apply")(function* (cwd, oxfmtConfigPath) {
847
823
  yield* applySettings(vscodeDir, oxfmtConfigPath);
848
824
  yield* applyExtensions(vscodeDir);
849
825
  });
850
- //#endregion
851
- //#region src/commands/brew/logic.ts
826
+ // src/commands/brew/logic.ts
852
827
  /** Deduplicated list of packages to install for the chosen toppings and sweetness. */
853
828
  function planPackages(pkg, toppings, sweetness, versions) {
854
829
  const packages = [];
@@ -896,8 +871,7 @@ function selectedLinters(toppings) {
896
871
  function selectedFormatters(toppings) {
897
872
  return toppings.filter((t) => t === "oxfmt");
898
873
  }
899
- //#endregion
900
- //#region src/commands/brew/index.ts
874
+ // src/commands/brew/index.ts
901
875
  var NotAtRepoRoot = class extends Data.TaggedError("NotAtRepoRoot") {};
902
876
  const ensureGitRepo = Effect.fn("brew.ensureGitRepo")(function* (cwd) {
903
877
  const git = yield* Git;
@@ -1061,13 +1035,13 @@ const brew = (cwd = process.cwd()) => Effect.gen(function* () {
1061
1035
  yield* Effect.logDebug(`planned packages: ${packages.length > 0 ? packages.join(", ") : "(none)"}`);
1062
1036
  yield* installPackages(pm, cwd, packages);
1063
1037
  const { pkg: installedPkg } = yield* readPkg(cwd);
1064
- yield* persistScripts(pkgPath, installedPkg, yield* applyToppings(cwd, isEsm(installedPkg), installedPkg, toppings));
1038
+ const updated = yield* applyToppings(cwd, isEsm(installedPkg), installedPkg, toppings);
1039
+ yield* persistScripts(pkgPath, installedPkg, updated);
1065
1040
  yield* setupCommitGate(cwd, pm, isEsm(installedPkg), toppings, sweetness);
1066
1041
  yield* commitChanges(cwd);
1067
1042
  yield* prompter.outro(pc.green(`Your Chanom with ${toppings.join(", ")} toppings and ${sweetness} sweetness is ready! Enjoy! 🧋`));
1068
1043
  });
1069
- //#endregion
1070
- //#region src/cli.ts
1044
+ // src/cli.ts
1071
1045
  var UnknownCommand = class extends Data.TaggedError("UnknownCommand") {};
1072
1046
  const commands = { brew };
1073
1047
  const dispatch = (name, cwd) => Effect.gen(function* () {
@@ -1101,13 +1075,12 @@ const run = (name, cwd = process.cwd(), options = {}) => {
1101
1075
  UnknownCommand: (e) => reportError(`Unknown command: ${e.command ?? "(none)"}\nAvailable commands: ${Object.keys(commands).join(", ")}`),
1102
1076
  PkgNotFound: (e) => reportError(`No package.json found in ${e.cwd}. Run this inside a project.`),
1103
1077
  PkgInvalid: (e) => reportError(`Could not parse ${e.pkgPath}. Is it valid JSON?`),
1104
- InstallFailed: (e) => reportError(`Package installation with ${e.pm} failed.`),
1078
+ InstallFailed: (e) => reportError([`Package installation with ${e.pm} failed.`, e.output].filter(Boolean).join("\n")),
1105
1079
  HuskyInitFailed: (e) => reportError(`\`husky init\` failed (exit code ${e.exitCode}).`),
1106
1080
  NotAtRepoRoot: (e) => reportError(`Git hooks must be set up at the repository root: ${e.root}\nRun \`chanom brew\` there, or choose light sweetness.`)
1107
1081
  }))).pipe(Logger.withMinimumLogLevel(debug ? LogLevel.Debug : LogLevel.Info));
1108
1082
  };
1109
- //#endregion
1110
- //#region src/index.ts
1083
+ // src/index.ts
1111
1084
  const args = process.argv.slice(2);
1112
1085
  const debug = args.includes("--debug");
1113
1086
  const command = args.find((arg) => !arg.startsWith("--"));
@@ -1121,5 +1094,4 @@ NodeRuntime.runMain(program, {
1121
1094
  disableErrorReporting: true,
1122
1095
  disablePrettyLogger: true
1123
1096
  });
1124
- //#endregion
1125
1097
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@chanom/cli",
3
- "version": "0.4.1",
3
+ "version": "0.4.3",
4
4
  "description": "",
5
5
  "keywords": [],
6
6
  "repository": {
@@ -29,10 +29,10 @@
29
29
  "@tsconfig/node-ts": "23.6.4",
30
30
  "@types/node": "26.0.1",
31
31
  "@vitest/coverage-v8": "3.2.6",
32
- "tsdown": "0.22.3",
33
- "typescript": "6.0.3",
32
+ "tsdown": "0.23.1",
33
+ "typescript": "7.0.2",
34
34
  "vitest": "3.2.6",
35
- "@chanom/dev-config": "0.0.3",
35
+ "@chanom/dev-config": "0.0.5",
36
36
  "@chanom/internal": "0.0.0"
37
37
  },
38
38
  "scripts": {