@savvy-web/cli 3.7.20 → 3.8.0

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
@@ -9,8 +9,8 @@ import { CliConfig, Command, GlobalFlag } from "effect/cli";
9
9
  import { CliAudience } from "@effected/cli-kit";
10
10
  import { BiomeSchemaSync, ChangesetConfigReader, Changesets, ConfigDiscovery, Repos, SilkPublishability } from "@savvy-web/silk-effects";
11
11
  import { Layer } from "effect";
12
- import { Git } from "@effected/git";
13
12
  import { PackageManagerDetector, WorkspaceDiscovery, WorkspaceRoot, Workspaces } from "@effected/workspaces";
13
+ import { Git } from "@effected/git";
14
14
  import { ManagedSection } from "@effected/templates";
15
15
  import { ToolDiscovery } from "@effected/commands";
16
16
  import * as NodeServices from "@effect/platform-node/NodeServices";
@@ -1,5 +1,6 @@
1
1
  import { DisplayPath } from "../../../internal/display-path.js";
2
2
  import { Report } from "../../../internal/report.js";
3
+ import { workspacePackageNames } from "../../../internal/workspace-package-names.js";
3
4
  import { Argument, Command } from "effect/cli";
4
5
  import { resolve } from "node:path";
5
6
  import { CliExit, Doc } from "@effected/cli-kit";
@@ -62,8 +63,9 @@ const dirArg = Argument.Directory("dir").pipe(Argument.withDefault(".changeset")
62
63
  function changesetCheckSection(dir) {
63
64
  return Effect.gen(function* () {
64
65
  const resolved = resolve(dir);
66
+ const packages = yield* workspacePackageNames(resolved);
65
67
  const messages = yield* Effect.try({
66
- try: () => ChangesetLinter.validate(resolved),
68
+ try: () => ChangesetLinter.validate(resolved, { packages }),
67
69
  catch: (e) => new Error(String(e))
68
70
  });
69
71
  const byFile = /* @__PURE__ */ new Map();
@@ -4,11 +4,11 @@ import { join } from "node:path";
4
4
  import { CliDoc, CliExit, Doc, Fmt } from "@effected/cli-kit";
5
5
  import { Changesets } from "@savvy-web/silk-effects";
6
6
  import { Data, Effect, Option, Result, Schema } from "effect";
7
+ import { WorkspaceRoot } from "@effected/workspaces";
7
8
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
8
9
  import { TerminalEnv } from "@effected/env";
9
10
  import { Git, GitRemote } from "@effected/git";
10
11
  import { Jsonc, JsoncEdit, JsoncModifier } from "@effected/jsonc";
11
- import { WorkspaceRoot } from "@effected/workspaces";
12
12
 
13
13
  // src/commands/changeset/commands/init.ts
14
14
  /**
@@ -1,3 +1,4 @@
1
+ import { workspacePackageNames } from "../../../internal/workspace-package-names.js";
1
2
  import { Argument, Command, Flag } from "effect/cli";
2
3
  import { resolve } from "node:path";
3
4
  import { CliExit } from "@effected/cli-kit";
@@ -47,7 +48,8 @@ const quietOption = Flag.Boolean("quiet").pipe(Flag.withAlias("q"), Flag.withDes
47
48
  function runLint(dir, quiet) {
48
49
  return Effect.gen(function* () {
49
50
  const resolved = resolve(dir);
50
- const messages = yield* Effect.try(() => ChangesetLinter.validate(resolved));
51
+ const packages = yield* workspacePackageNames(resolved);
52
+ const messages = yield* Effect.try(() => ChangesetLinter.validate(resolved, { packages }));
51
53
  for (const msg of messages) yield* Console.log(`${msg.file}:${msg.line}:${msg.column} ${msg.rule} ${msg.message}`);
52
54
  if (!quiet && messages.length === 0) yield* Console.log("No lint errors found.");
53
55
  if (messages.length > 0) yield* CliExit.set(1);
@@ -1,6 +1,8 @@
1
1
  import { CommandError } from "../../../internal/command-error.js";
2
2
  import { Report } from "../../../internal/report.js";
3
+ import { workspacePackageNames } from "../../../internal/workspace-package-names.js";
3
4
  import { Argument, Command } from "effect/cli";
5
+ import { dirname, resolve } from "node:path";
4
6
  import { CliExit } from "@effected/cli-kit";
5
7
  import { Changesets } from "@savvy-web/silk-effects";
6
8
  import { Effect } from "effect";
@@ -38,8 +40,9 @@ const fileArg = Argument.File("file");
38
40
  */
39
41
  function runValidateFile(filePath) {
40
42
  return Effect.gen(function* () {
43
+ const packages = yield* workspacePackageNames(dirname(resolve(filePath)));
41
44
  const result = yield* Effect.try({
42
- try: () => ChangesetLinter.validateFile(filePath),
45
+ try: () => ChangesetLinter.validateFile(filePath, { packages }),
43
46
  catch: (error) => CommandError.from(error, { message: `could not validate ${filePath}` })
44
47
  });
45
48
  if (result.length > 0) {
@@ -4,8 +4,8 @@ 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";
6
6
  import { Effect, FileSystem } from "effect";
7
- import { Jsonc, JsoncEdit, JsoncModifier } from "@effected/jsonc";
8
7
  import { WorkspaceDiscovery } from "@effected/workspaces";
8
+ import { Jsonc, JsoncEdit, JsoncModifier } from "@effected/jsonc";
9
9
  import { ManagedSection } from "@effected/templates";
10
10
  import { chmod } from "node:fs/promises";
11
11
  import { isDeepStrictEqual } from "node:util";
@@ -0,0 +1,31 @@
1
+ import { Effect, Option } from "effect";
2
+ import { WorkspaceDiscovery } from "@effected/workspaces";
3
+
4
+ // src/internal/workspace-package-names.ts
5
+ /**
6
+ * The workspace's package names, for the changeset linter's
7
+ * `changeset-known-package` (CF004) rule.
8
+ *
9
+ * @internal
10
+ */
11
+ /**
12
+ * Discover the names of the workspace packages around `from`.
13
+ *
14
+ * @remarks
15
+ * Succeeds with `undefined` when no `WorkspaceDiscovery` is provided or the
16
+ * directory is not inside a discoverable workspace. The linter then skips
17
+ * CF004 and still runs every other rule: a changeset directory outside a
18
+ * workspace stays lintable.
19
+ *
20
+ * @param from - A directory inside the workspace (the changeset directory)
21
+ * @returns The package names, or `undefined` when they cannot be discovered
22
+ *
23
+ * @internal
24
+ */
25
+ const workspacePackageNames = (from) => Effect.gen(function* () {
26
+ const discovery = yield* Effect.serviceOption(WorkspaceDiscovery);
27
+ if (Option.isNone(discovery)) return void 0;
28
+ return yield* discovery.value.listPackagesIn(from).pipe(Effect.map((packages) => packages.map((pkg) => pkg.name)), Effect.orElseSucceed(() => void 0));
29
+ });
30
+
31
+ export { workspacePackageNames };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/cli",
3
- "version": "3.7.20",
3
+ "version": "3.8.0",
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",
@@ -46,12 +46,14 @@
46
46
  "@effected/glob": "^0.21.0",
47
47
  "@effected/jsonc": "^0.25.0",
48
48
  "@effected/kit": "^0.14.0",
49
+ "@effected/markdown": "^0.29.0",
50
+ "@effected/markdown-lint": "^0.2.0",
49
51
  "@effected/templates": "^0.20.0",
50
52
  "@effected/toml": "^0.20.0",
51
53
  "@effected/walker": "^0.27.0",
52
54
  "@effected/workspaces": "^0.45.0",
53
55
  "@effected/yaml": "^0.30.0",
54
- "@savvy-web/silk-effects": "^12.0.0",
56
+ "@savvy-web/silk-effects": "^12.1.0",
55
57
  "effect": "4.1.3",
56
58
  "ink": "^8.0.0",
57
59
  "react": "^19.3.1"
package/version.js CHANGED
@@ -7,6 +7,6 @@
7
7
  * @packageDocumentation
8
8
  */
9
9
  /** @internal */
10
- const CLI_VERSION = "3.7.20";
10
+ const CLI_VERSION = "3.8.0";
11
11
 
12
12
  export { CLI_VERSION };