@savvy-web/cli 3.7.15 → 3.7.17

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/cli/index.js CHANGED
@@ -1,10 +1,10 @@
1
1
  import { changesetCommand } from "../commands/changeset/index.js";
2
2
  import { checkCommand } from "../commands/check.js";
3
+ import { cleanCommand } from "../commands/clean.js";
3
4
  import { commitCommand } from "../commands/commit/index.js";
4
5
  import { initCommand } from "../commands/init.js";
5
6
  import { lintCommand } from "../commands/lint/index.js";
6
7
  import { reposCommand } from "../commands/repos/index.js";
7
- import { cleanCommand } from "../commands/clean.js";
8
8
  import { CliConfig, Command, GlobalFlag } from "effect/cli";
9
9
  import { CliAudience } from "@effected/cli";
10
10
  import { BiomeSchemaSync, ChangesetConfigReader, Changesets, ConfigDiscovery, Repos, SilkPublishability } from "@savvy-web/silk-effects";
@@ -1,9 +1,9 @@
1
1
  import { Report } from "../../../internal/report.js";
2
2
  import { Command, Flag } from "effect/cli";
3
3
  import { resolve } from "node:path";
4
- import { CliExit } from "@effected/cli";
4
+ import { CliExit, CliFormat } from "@effected/cli";
5
5
  import { Changesets } from "@savvy-web/silk-effects";
6
- import { Console, Effect, Option } from "effect";
6
+ import { Effect, Option } from "effect";
7
7
 
8
8
  // src/commands/changeset/commands/deps-detect.ts
9
9
  /**
@@ -72,7 +72,7 @@ function runDepsDetect(cwd, from, to, pkg, json, markdown) {
72
72
  yield* Report.print([Report.verbatim(renderMarkdownBlocks(diffs))]);
73
73
  return;
74
74
  }
75
- yield* Console.log(JSON.stringify(diffs, null, 2));
75
+ yield* CliFormat.printJson(diffs);
76
76
  });
77
77
  }
78
78
  /* v8 ignore next 7 */
@@ -1,12 +1,12 @@
1
- import { Report } from "../../../internal/report.js";
2
1
  import { CommandError } from "../../../internal/command-error.js";
2
+ import { Report } from "../../../internal/report.js";
3
3
  import { join } from "node:path";
4
4
  import { CliDoc, CliExit, Doc, Fmt } from "@effected/cli";
5
5
  import { Changesets } from "@savvy-web/silk-effects";
6
6
  import { Data, Effect, Option, Result, Schema } from "effect";
7
- import { TerminalEnv } from "@effected/env";
8
7
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
9
- import { Git } from "@effected/git";
8
+ import { TerminalEnv } from "@effected/env";
9
+ import { Git, GitRemote } from "@effected/git";
10
10
  import { Jsonc, JsoncEdit, JsoncModifier } from "@effected/jsonc";
11
11
  import { WorkspaceRoot } from "@effected/workspaces";
12
12
 
@@ -124,11 +124,14 @@ function detectGitHubRepo(cwd) {
124
124
  return Effect.gen(function* () {
125
125
  const url = yield* (yield* Git).remoteUrl(cwd).pipe(Effect.catch(() => Effect.succeed(Option.none())));
126
126
  if (Option.isNone(url)) return null;
127
- const https = url.value.match(/github\.com\/([^/]+)\/([^/.]+)/);
128
- if (https) return `${https[1]}/${https[2]}`;
129
- const ssh = url.value.match(/github\.com:([^/]+)\/([^/.]+)/);
130
- if (ssh) return `${ssh[1]}/${ssh[2]}`;
131
- return null;
127
+ const remote = GitRemote.parse(url.value);
128
+ if (Option.isNone(remote)) return null;
129
+ const form = remote.value._tag === "GitRemoteTransport" ? remote.value.address : remote.value;
130
+ if (form._tag !== "GitRemoteUrl" && form._tag !== "GitRemoteScp") return null;
131
+ if (form._tag === "GitRemoteUrl" && form.user !== void 0 && /[/?#]/.test(form.user)) return null;
132
+ if (form.host.toLowerCase() !== "github.com") return null;
133
+ const [owner, repo] = GitRemote.repositoryPath(form).split("/");
134
+ return owner && repo ? `${owner}/${repo}` : null;
132
135
  });
133
136
  }
134
137
  /**
@@ -1,5 +1,5 @@
1
- import { Report } from "../../../internal/report.js";
2
1
  import { CommandError } from "../../../internal/command-error.js";
2
+ import { Report } from "../../../internal/report.js";
3
3
  import { Argument, Command } from "effect/cli";
4
4
  import { CliExit } from "@effected/cli";
5
5
  import { Changesets } from "@savvy-web/silk-effects";
package/commands/clean.js CHANGED
@@ -1,5 +1,5 @@
1
- import { Report } from "../internal/report.js";
2
1
  import { CommandError } from "../internal/command-error.js";
2
+ import { Report } from "../internal/report.js";
3
3
  import { Command, Flag } from "effect/cli";
4
4
  import { join, sep } from "node:path";
5
5
  import { CliInteractive, Fmt } from "@effected/cli";
@@ -1,7 +1,7 @@
1
- import { runCommitInit } from "./init.js";
2
- import { runCommitCheck } from "./check.js";
3
1
  import { hookCommand } from "./hook.js";
4
2
  import { lintCommand } from "./lint.js";
3
+ import { runCommitCheck } from "./check.js";
4
+ import { runCommitInit } from "./init.js";
5
5
  import { Command } from "effect/cli";
6
6
 
7
7
  // src/commands/commit/index.ts
@@ -1,5 +1,5 @@
1
- import { Report } from "../../internal/report.js";
2
1
  import { CommandError } from "../../internal/command-error.js";
2
+ import { Report } from "../../internal/report.js";
3
3
  import { HUSKY_HOOK_PATH, POST_CHECKOUT_HOOK_PATH, POST_COMMIT_HOOK_PATH, POST_MERGE_HOOK_PATH } from "./constants.js";
4
4
  import { dirname } from "node:path";
5
5
  import { SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, savvyBasePreamble, savvyHooksHygiene, savvyInstallBlock, savvyToolSection, savvyToolchainCheck } from "@savvy-web/silk-effects";
package/commands/init.js CHANGED
@@ -1,10 +1,10 @@
1
- import { Report } from "../internal/report.js";
2
1
  import { CommandError } from "../internal/command-error.js";
2
+ import { confirmDestructive, yesFlag } from "../internal/confirm.js";
3
3
  import { runChangesetInit } from "./changeset/commands/init.js";
4
+ import { Report } from "../internal/report.js";
4
5
  import "./changeset/index.js";
5
6
  import { HUSKY_HOOK_PATH } from "./commit/constants.js";
6
7
  import { runCommitInit } from "./commit/init.js";
7
- import { confirmDestructive, yesFlag } from "../internal/confirm.js";
8
8
  import { runLintInit } from "./lint/init.js";
9
9
  import { Command, Flag } from "effect/cli";
10
10
  import { Lint } from "@savvy-web/silk-effects";
@@ -19,6 +19,6 @@
19
19
  *
20
20
  * @internal
21
21
  */
22
- const BIOME_VERSION = "2.6.3";
22
+ const BIOME_VERSION = "2.6.4";
23
23
 
24
24
  export { BIOME_VERSION };
@@ -1,7 +1,7 @@
1
- import { runLintCheck } from "./check.js";
2
- import { runLintInit } from "./init.js";
3
1
  import { fmtCommand } from "./fmt.js";
4
2
  import { runLintText, textCommand } from "./text.js";
3
+ import { runLintCheck } from "./check.js";
4
+ import { runLintInit } from "./init.js";
5
5
  import { Command } from "effect/cli";
6
6
 
7
7
  // src/commands/lint/index.ts
@@ -1,5 +1,5 @@
1
- import { Report } from "../../internal/report.js";
2
1
  import { CommandError } from "../../internal/command-error.js";
2
+ import { Report } from "../../internal/report.js";
3
3
  import { BIOME_VERSION } from "./biome-version.js";
4
4
  import { dirname, join } from "node:path";
5
5
  import { BiomeSchemaSync, LIFECYCLE_SCRIPTS_CONFIG_KEY, Lint, SavvyBaseSection, SavvyHooksSection, SavvyToolchainSection, publishesBuiltLinkDirectory, savvyBasePreamble, savvyHooksHygiene, savvyInstallBlock, savvyOkfBlock, savvyToolchainCheck } from "@savvy-web/silk-effects";
@@ -1,5 +1,5 @@
1
- import { Report } from "../../../internal/report.js";
2
1
  import { confirmDestructive, yesFlag } from "../../../internal/confirm.js";
2
+ import { Report } from "../../../internal/report.js";
3
3
  import { ReposCli } from "../shared.js";
4
4
  import { Argument, Command, Flag } from "effect/cli";
5
5
  import { Doc } from "@effected/cli";
@@ -1,5 +1,5 @@
1
- import { Report } from "../../../internal/report.js";
2
1
  import { confirmDestructive, yesFlag } from "../../../internal/confirm.js";
2
+ import { Report } from "../../../internal/report.js";
3
3
  import { ReposCli } from "../shared.js";
4
4
  import { Argument, Command, Flag } from "effect/cli";
5
5
  import { CliExit, CliInteractive } from "@effected/cli";
@@ -1,9 +1,9 @@
1
1
  import { Report } from "../../../internal/report.js";
2
2
  import { ReposCli } from "../shared.js";
3
3
  import { Command, Flag } from "effect/cli";
4
- import { CliExit, Doc, Status } from "@effected/cli";
4
+ import { CliExit, CliFormat, Doc, Status } from "@effected/cli";
5
5
  import { Repos } from "@savvy-web/silk-effects";
6
- import { Console, Effect } from "effect";
6
+ import { Effect } from "effect";
7
7
 
8
8
  // src/commands/repos/commands/status.ts
9
9
  /** The human status report: a table of repos, and one of drifts under `--drift`. */
@@ -61,7 +61,7 @@ const runReposStatus = (cwd, json, drift = false) => Effect.gen(function* () {
61
61
  ...report,
62
62
  drift: driftReport
63
63
  };
64
- yield* Console.log(JSON.stringify(payload, null, 2));
64
+ yield* CliFormat.printJson(payload);
65
65
  return;
66
66
  }
67
67
  const blocks = [report.repos.length > 0 ? ReposStatusView.repos(report.repos) : Report.skip("the manifest lists no repos")];
@@ -69,21 +69,21 @@ const runReposStatus = (cwd, json, drift = false) => Effect.gen(function* () {
69
69
  yield* Report.print(blocks);
70
70
  }).pipe(Effect.catchTag("ReposConfigError", (error) => {
71
71
  if (error.kind === "missing") {
72
- if (json) return Console.log(JSON.stringify({
72
+ if (json) return CliFormat.printJson({
73
73
  repos: [],
74
74
  clean: true
75
- }, null, 2));
75
+ });
76
76
  return Report.print([Report.skip("no .repos/config.json — nothing vendored")]);
77
77
  }
78
- if (json) return CliExit.set(1).pipe(Effect.andThen(Console.log(JSON.stringify({
78
+ if (json) return CliExit.set(1).pipe(Effect.andThen(CliFormat.printJson({
79
79
  error: error.message,
80
80
  clean: false
81
- }, null, 2))), Effect.andThen(Effect.logError(error.message)));
81
+ })), Effect.andThen(Effect.logError(error.message)));
82
82
  return ReposCli.fail("read the repos manifest")(error);
83
- }), Effect.catchTag("GitSubmoduleError", (error) => json ? CliExit.set(1).pipe(Effect.andThen(Console.log(JSON.stringify({
83
+ }), Effect.catchTag("GitSubmoduleError", (error) => json ? CliExit.set(1).pipe(Effect.andThen(CliFormat.printJson({
84
84
  error: error.message,
85
85
  clean: false
86
- }, null, 2))), Effect.andThen(Effect.logError(error.message))) : ReposCli.fail("check the vendored repos")(error)));
86
+ })), Effect.andThen(Effect.logError(error.message))) : ReposCli.fail("check the vendored repos")(error)));
87
87
  /* v8 ignore start -- CLI registration; handler tested via runReposStatus */
88
88
  const statusCommand = Command.make("status", {
89
89
  json: jsonOption,
@@ -1,6 +1,6 @@
1
- import { Report } from "../../internal/report.js";
2
- import { FailureLine } from "../../internal/failure-line.js";
3
1
  import { CommandError } from "../../internal/command-error.js";
2
+ import { FailureLine } from "../../internal/failure-line.js";
3
+ import { Report } from "../../internal/report.js";
4
4
  import { CliError } from "effect/cli";
5
5
  import { CliInteractive } from "@effected/cli";
6
6
  import { Repos } from "@savvy-web/silk-effects";
@@ -1,6 +1,4 @@
1
1
  import { Doc, Status } from "@effected/cli";
2
- import { Effect } from "effect";
3
- import { TerminalEnv } from "@effected/env";
4
2
 
5
3
  // src/internal/report.ts
6
4
  /** A status line, with any detail lines muted and indented under it. */
@@ -89,12 +87,13 @@ var Report = class {
89
87
  * Render `doc` for the run's audience and write it to stdout.
90
88
  *
91
89
  * @remarks
92
- * A terminal wraps to its width. A pipe has no width to honour — the kit
93
- * would otherwise wrap a person's piped output at 80 columns and split a
94
- * long path or a `file:line:col` finding a caller greps — so off a terminal
95
- * nothing is wrapped.
90
+ * A terminal wraps to its width. A pipe has no width to honour, so off a
91
+ * terminal nothing is wrapped and a long path or a `file:line:col` finding
92
+ * a caller greps stays on one line — the kit's own default for a human
93
+ * whose stdout is not a terminal (an agent's and CI's width is unbounded
94
+ * too).
96
95
  */
97
- static print = (doc) => Effect.flatMap(TerminalEnv, (terminal) => Doc.print(doc, terminal.stdout.isTerminal ? {} : { width: Number.POSITIVE_INFINITY }));
96
+ static print = (doc) => Doc.print(doc);
98
97
  };
99
98
 
100
99
  export { Report };
@@ -1,18 +1,23 @@
1
- import { distributionSuffix } from "@effected/engine";
2
-
3
1
  // src/internal/version-line.ts
4
2
  /**
3
+ * The `--version` line.
4
+ *
5
+ * @packageDocumentation
6
+ */
7
+ /**
5
8
  * Renders the `savvy --version` line: the same `<name> v<version>` shape
6
- * `effect/cli`'s default formatter prints, plus the
7
- * `" via <carrier> <version>"` suffix when the bin was installed through a
8
- * carrier such as `@savvy-web/silk`.
9
+ * `effect/cli`'s default formatter prints, but plain even at a terminal (core's
10
+ * default paints it). The `" via <carrier> <version>"` suffix for a bin
11
+ * installed through a carrier such as `@savvy-web/silk` is not added here:
12
+ * `CliRuntime.main`'s `distribution` option appends it to whatever
13
+ * `formatVersion` is in effect.
9
14
  *
10
15
  * @internal
11
16
  */
12
17
  var VersionLine = class {
13
18
  constructor() {}
14
- /** `savvy v1.2.3`, or `savvy v1.2.3 via @savvy-web/silk 4.5.6`. */
15
- static format = (name, version, distribution) => `${name} v${version}${distributionSuffix(distribution)}`;
19
+ /** `savvy v1.2.3`. */
20
+ static format = (name, version) => `${name} v${version}`;
16
21
  };
17
22
 
18
23
  export { VersionLine };
package/main.js CHANGED
@@ -1,11 +1,10 @@
1
- import { FailureLine } from "./internal/failure-line.js";
2
1
  import { AppLive, CliConfigLive, CliPlatform, rootCommand } from "./cli/index.js";
2
+ import { FailureLine } from "./internal/failure-line.js";
3
3
  import { VersionLine } from "./internal/version-line.js";
4
4
  import { CLI_VERSION } from "./version.js";
5
5
  import { CliAudience, CliRuntime } from "@effected/cli";
6
- import { Effect, Layer, Option } from "effect";
6
+ import { Effect, Layer } from "effect";
7
7
  import * as NodeRuntime from "@effect/platform-node/NodeRuntime";
8
- import { CurrentDistribution } from "@effected/engine";
9
8
 
10
9
  // src/main.ts
11
10
  /**
@@ -21,7 +20,8 @@ import { CurrentDistribution } from "@effected/engine";
21
20
  * audience (overridable through `SAVVY_AUDIENCE`), the terminal, the theme,
22
21
  * editor links and the prompt gate — installs `CliLog` (diagnostics opt-in
23
22
  * through `SAVVY_LOG_LEVEL`, every log line on stderr) and the coloured help
24
- * formatter with the carrier-aware `--version` line. `main` reports failures
23
+ * formatter with a plain `--version` line, to which `distribution` appends
24
+ * the carrier suffix. `main` reports failures
25
25
  * through that logger (a typed failure as one line, a defect as a bug
26
26
  * report), applies the `CliExit` code a command set, and exits `64` on a
27
27
  * usage error with the help document on stderr, so stdout stays clean for a
@@ -37,16 +37,16 @@ import { CurrentDistribution } from "@effected/engine";
37
37
  * @public
38
38
  */
39
39
  const main = (options = {}) => {
40
- const distribution = Option.fromNullishOr(options.distribution);
41
- const program = CliAudience.run(rootCommand, { version: CLI_VERSION }).pipe(Effect.provide(Layer.merge(AppLive, CliConfigLive)), Effect.provideService(CurrentDistribution, distribution));
40
+ const program = CliAudience.run(rootCommand, { version: CLI_VERSION }).pipe(Effect.provide(Layer.merge(AppLive, CliConfigLive)));
42
41
  NodeRuntime.runMain(CliRuntime.main(program, {
43
42
  platform: CliPlatform,
44
43
  env: {
45
44
  audienceEnvVar: "SAVVY_AUDIENCE",
46
45
  stderrIsTerminal: Effect.sync(() => process.stderr.isTTY === true),
47
46
  log: { envVar: "SAVVY_LOG_LEVEL" },
48
- formatter: { formatVersion: (name, version) => VersionLine.format(name, version, distribution) }
47
+ formatter: { formatVersion: VersionLine.format }
49
48
  },
49
+ distribution: options.distribution ?? null,
50
50
  render: FailureLine.render,
51
51
  helpOnUsageError: "stderr"
52
52
  }));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/cli",
3
- "version": "3.7.15",
3
+ "version": "3.7.17",
4
4
  "private": false,
5
5
  "description": "The savvy CLI — unified commit, changeset, and lint commands for the Silk Suite",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/cli",
@@ -36,22 +36,22 @@
36
36
  "savvy": "bin/savvy.js"
37
37
  },
38
38
  "dependencies": {
39
- "@effect/platform-node": "^4.0.6",
40
- "@effected/cli": "^0.23.0",
41
- "@effected/commands": "^0.17.0",
42
- "@effected/config-file": "^0.21.0",
43
- "@effected/engine": "^0.9.0",
44
- "@effected/env": "^0.6.0",
45
- "@effected/git": "^0.26.0",
46
- "@effected/glob": "^0.15.0",
47
- "@effected/jsonc": "^0.20.1",
48
- "@effected/templates": "^0.14.1",
49
- "@effected/toml": "^0.16.0",
50
- "@effected/walker": "^0.21.0",
51
- "@effected/workspaces": "^0.39.1",
52
- "@effected/yaml": "^0.25.1",
53
- "@savvy-web/silk-effects": "^10.2.0",
54
- "effect": "^4.0.6",
39
+ "@effect/platform-node": "~4.1.1",
40
+ "@effected/cli": "^0.25.0",
41
+ "@effected/commands": "^0.19.0",
42
+ "@effected/config-file": "^0.23.0",
43
+ "@effected/engine": "^0.11.0",
44
+ "@effected/env": "^0.9.0",
45
+ "@effected/git": "^0.29.0",
46
+ "@effected/glob": "^0.17.0",
47
+ "@effected/jsonc": "^0.22.0",
48
+ "@effected/templates": "^0.16.0",
49
+ "@effected/toml": "^0.18.0",
50
+ "@effected/walker": "^0.24.0",
51
+ "@effected/workspaces": "^0.41.0",
52
+ "@effected/yaml": "^0.27.0",
53
+ "@savvy-web/silk-effects": "^11.0.0",
54
+ "effect": "~4.1.1",
55
55
  "ink": "^8.0.0",
56
56
  "react": "^19.3.1"
57
57
  }
package/version.js CHANGED
@@ -7,6 +7,6 @@
7
7
  * @packageDocumentation
8
8
  */
9
9
  /** @internal */
10
- const CLI_VERSION = "3.7.15";
10
+ const CLI_VERSION = "3.7.17";
11
11
 
12
12
  export { CLI_VERSION };