@savvy-web/silk-effects 4.2.6 → 5.0.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.
Files changed (40) hide show
  1. package/README.md +73 -192
  2. package/changesets/api/changelog.js +1 -2
  3. package/changesets/changelog/index.js +8 -10
  4. package/changesets/errors.js +0 -1
  5. package/changesets/index.js +1 -4
  6. package/changesets/services/changelog.js +1 -1
  7. package/changesets/services/github.js +1 -1
  8. package/changesets/utils/dependency-table.js +1 -1
  9. package/index.d.ts +95 -1398
  10. package/index.js +1 -20
  11. package/lint/cli/sections.js +9 -8
  12. package/package.json +5 -3
  13. package/schemas/SavvySections.js +26 -9
  14. package/schemas/VersioningSchemas.js +1 -32
  15. package/schemas/WorkspaceAnalysisSchemas.js +4 -5
  16. package/services/SilkPublishability.js +1 -1
  17. package/services/SilkWorkspaceAnalyzer.js +13 -16
  18. package/turbo/services/TurboInspector.js +11 -11
  19. package/changesets/services/markdown.js +0 -93
  20. package/errors/SectionParseError.js +0 -17
  21. package/errors/SectionValidationError.js +0 -17
  22. package/errors/SectionWriteError.js +0 -17
  23. package/errors/TagFormatError.js +0 -21
  24. package/errors/ToolNotFoundError.js +0 -12
  25. package/errors/ToolResolutionError.js +0 -12
  26. package/errors/ToolVersionMismatchError.js +0 -12
  27. package/errors/VersioningDetectionError.js +0 -21
  28. package/schemas/CommentStyle.js +0 -17
  29. package/schemas/ResolvedTool.js +0 -99
  30. package/schemas/SectionBlock.js +0 -71
  31. package/schemas/SectionDefinition.js +0 -123
  32. package/schemas/SectionResults.js +0 -21
  33. package/schemas/TagStrategySchemas.js +0 -19
  34. package/schemas/ToolDefinition.js +0 -40
  35. package/schemas/ToolResults.js +0 -28
  36. package/services/ManagedSection.js +0 -289
  37. package/services/TagStrategy.js +0 -56
  38. package/services/ToolDiscovery.js +0 -232
  39. package/services/VersioningStrategy.js +0 -69
  40. package/utils/ToolCommand.js +0 -67
package/index.js CHANGED
@@ -7,33 +7,14 @@ import { changesets_exports } from "./changesets/index.js";
7
7
  import { commitlint_exports } from "./commitlint/index.js";
8
8
  import { BiomeSyncError } from "./errors/BiomeSyncError.js";
9
9
  import { ConfigNotFoundError } from "./errors/ConfigNotFoundError.js";
10
- import { SectionParseError } from "./errors/SectionParseError.js";
11
- import { SectionValidationError } from "./errors/SectionValidationError.js";
12
- import { SectionWriteError } from "./errors/SectionWriteError.js";
13
- import { TagFormatError } from "./errors/TagFormatError.js";
14
- import { ToolNotFoundError } from "./errors/ToolNotFoundError.js";
15
- import { ToolResolutionError } from "./errors/ToolResolutionError.js";
16
- import { ToolVersionMismatchError } from "./errors/ToolVersionMismatchError.js";
17
- import { VersioningDetectionError } from "./errors/VersioningDetectionError.js";
18
10
  import { WorkspaceAnalysisError } from "./errors/WorkspaceAnalysisError.js";
19
- import { CheckResult, SectionDiff, SyncResult } from "./schemas/SectionResults.js";
20
- import { SectionBlock } from "./schemas/SectionBlock.js";
21
- import { SectionDefinition, ShellSectionDefinition } from "./schemas/SectionDefinition.js";
22
11
  import { SavvyBaseSection, SavvyHooksSection, savvyBasePreamble, savvyHooksHygiene, savvyToolSection } from "./schemas/SavvySections.js";
23
12
  import { lint_exports } from "./lint/index.js";
24
13
  import { repos_exports } from "./repos/index.js";
25
- import { ToolCommand } from "./utils/ToolCommand.js";
26
- import { ResolutionPolicy, SourceRequirement, ToolSource, VersionExtractor } from "./schemas/ToolResults.js";
27
- import { ResolvedTool } from "./schemas/ResolvedTool.js";
28
- import { ToolDefinition } from "./schemas/ToolDefinition.js";
29
14
  import { AnalyzedWorkspace, SilkPublishConfig, WorkspaceAnalysis } from "./schemas/WorkspaceAnalysisSchemas.js";
30
15
  import { BiomeSchemaSync, BiomeSchemaSyncLive, buildSchemaUrl, extractSemver } from "./services/BiomeSchemaSync.js";
31
16
  import { ConfigDiscovery, ConfigDiscoveryLive } from "./services/ConfigDiscovery.js";
32
- import { ManagedSection, ManagedSectionLive } from "./services/ManagedSection.js";
33
- import { TagStrategy, TagStrategyLive } from "./services/TagStrategy.js";
34
- import { VersioningStrategy, VersioningStrategyLive } from "./services/VersioningStrategy.js";
35
17
  import { SilkWorkspaceAnalyzer, SilkWorkspaceAnalyzerLive } from "./services/SilkWorkspaceAnalyzer.js";
36
- import { ToolDiscovery, ToolDiscoveryLive } from "./services/ToolDiscovery.js";
37
18
  import { turbo_exports } from "./turbo/index.js";
38
19
 
39
- export { AnalyzedWorkspace, BiomeSchemaSync, BiomeSchemaSyncLive, BiomeSyncError, ChangesetConfig, ChangesetConfigError, ChangesetConfigLive, ChangesetConfigReader, ChangesetConfigReaderLive, changesets_exports as Changesets, CheckResult, commitlint_exports as Commitlint, ConfigDiscovery, ConfigDiscoveryLive, ConfigNotFoundError, lint_exports as Lint, ManagedSection, ManagedSectionLive, PublishTargetBindingError, PublishabilityDetectorAdaptiveLive, repos_exports as Repos, ResolutionPolicy, ResolvedTool, SavvyBaseSection, SavvyHooksSection, SectionBlock, SectionDefinition, SectionDiff, SectionParseError, SectionValidationError, SectionWriteError, ShellSectionDefinition, SilkPublishConfig, SilkPublishability, SilkPublishabilityDetectorLive, SilkWorkspaceAnalyzer, SilkWorkspaceAnalyzerLive, SourceRequirement, SyncResult, TagFormatError, TagStrategy, TagStrategyLive, ToolCommand, ToolDefinition, ToolDiscovery, ToolDiscoveryLive, ToolNotFoundError, ToolResolutionError, ToolSource, ToolVersionMismatchError, turbo_exports as Turbo, VersionExtractor, VersioningDetectionError, VersioningStrategy, VersioningStrategyLive, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
20
+ export { AnalyzedWorkspace, BiomeSchemaSync, BiomeSchemaSyncLive, BiomeSyncError, ChangesetConfig, ChangesetConfigError, ChangesetConfigLive, ChangesetConfigReader, ChangesetConfigReaderLive, changesets_exports as Changesets, commitlint_exports as Commitlint, ConfigDiscovery, ConfigDiscoveryLive, ConfigNotFoundError, lint_exports as Lint, PublishTargetBindingError, PublishabilityDetectorAdaptiveLive, repos_exports as Repos, SavvyBaseSection, SavvyHooksSection, SilkPublishConfig, SilkPublishability, SilkPublishabilityDetectorLive, SilkWorkspaceAnalyzer, SilkWorkspaceAnalyzerLive, turbo_exports as Turbo, WorkspaceAnalysis, WorkspaceAnalysisError, buildSchemaUrl, extractSemver, readTargetsBinding, savvyBasePreamble, savvyHooksHygiene, savvyToolSection };
@@ -1,12 +1,7 @@
1
- import { SectionDefinition } from "../../schemas/SectionDefinition.js";
2
1
  import { savvyToolSection } from "../../schemas/SavvySections.js";
2
+ import { CommentStyle, SectionId } from "@effected/templates";
3
3
 
4
4
  //#region src/lint/cli/sections.ts
5
- /**
6
- * Shared managed section definitions and constants for CLI commands.
7
- *
8
- * @internal
9
- */
10
5
  /** Path for the husky pre-commit hook. */
11
6
  const HUSKY_HOOK_PATH = ".husky/pre-commit";
12
7
  /** Path for the husky post-checkout hook. */
@@ -20,7 +15,10 @@ const DEFAULT_CONFIG_PATH = "lib/configs/lint-staged.config.ts";
20
15
  /** Path for the markdownlint-cli2 config file. */
21
16
  const MARKDOWNLINT_CONFIG_PATH = "lib/configs/.markdownlint-cli2.jsonc";
22
17
  /** Identity definition for the savvy-lint tool section (read / check / remove). */
23
- const SavvyLintSectionDef = SectionDefinition.make({ toolName: "savvy-lint" });
18
+ const SavvyLintSectionDef = SectionId.make({
19
+ key: "SAVVY-LINT",
20
+ commentStyle: CommentStyle.hash
21
+ });
24
22
  /**
25
23
  * Identity definition for the legacy `SAVVY-LINT` hygiene section that previously
26
24
  * lived in `.husky/post-checkout` and `.husky/post-merge`.
@@ -32,7 +30,10 @@ const SavvyLintSectionDef = SectionDefinition.make({ toolName: "savvy-lint" });
32
30
  * `SavvyLintSectionDef`'s; the two definitions are split only by intent (live tool
33
31
  * section vs. legacy hygiene block that lives in a different hook).
34
32
  */
35
- const LegacySavvyLintHygieneDef = SectionDefinition.make({ toolName: "savvy-lint" });
33
+ const LegacySavvyLintHygieneDef = SectionId.make({
34
+ key: "SAVVY-LINT",
35
+ commentStyle: CommentStyle.hash
36
+ });
36
37
  /**
37
38
  * Build the lint-staged command run inside the savvy-lint tool section.
38
39
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@savvy-web/silk-effects",
3
- "version": "4.2.6",
3
+ "version": "5.0.0",
4
4
  "private": false,
5
5
  "description": "Shared Effect library for Silk Suite conventions",
6
6
  "homepage": "https://github.com/savvy-web/systems/tree/main/packages/silk-effects",
@@ -33,12 +33,14 @@
33
33
  "@changesets/config": "^4.0.0-next.6",
34
34
  "@changesets/get-github-info": "^1.0.0-next.3",
35
35
  "@changesets/get-release-plan": "^5.0.0-next.7",
36
+ "@effected/commands": "^0.1.0",
36
37
  "@effected/git": "^0.5.0",
37
38
  "@effected/glob": "^0.2.1",
38
39
  "@effected/jsonc": "^0.5.1",
39
- "@effected/package-json": "^0.5.2",
40
+ "@effected/package-json": "^0.6.0",
41
+ "@effected/templates": "^0.1.0",
40
42
  "@effected/walker": "^0.3.2",
41
- "@effected/workspaces": "^0.8.0",
43
+ "@effected/workspaces": "^0.9.0",
42
44
  "@effected/yaml": "^0.6.0",
43
45
  "@manypkg/get-packages": "^3.1.0",
44
46
  "mdast-util-heading-range": "^4.0.0",
@@ -1,20 +1,37 @@
1
- import { ShellSectionDefinition } from "./SectionDefinition.js";
1
+ import { CommentStyle, SectionId } from "@effected/templates";
2
2
 
3
3
  //#region src/schemas/SavvySections.ts
4
4
  /**
5
+ * Build a shell-hook section identity from a Silk tool name.
6
+ *
7
+ * @remarks
8
+ * **The key is uppercased here, and that is load-bearing.** The kit renders a
9
+ * key verbatim into its markers (`# --- BEGIN <key> MANAGED SECTION ---`),
10
+ * while the section model this replaces uppercased `toolName` on the way in. A
11
+ * lowercase key would therefore emit `# --- BEGIN savvy-base MANAGED SECTION ---`
12
+ * and no longer match the `SAVVY-BASE` markers already written into every
13
+ * consumer repo's hook files — `check` would report the section absent and
14
+ * `sync` would append a second copy beside the first. Uppercasing keeps the
15
+ * marker bytes identical across the migration.
16
+ */
17
+ const shellSection = (toolName) => SectionId.make({
18
+ key: toolName.toUpperCase(),
19
+ commentStyle: CommentStyle.hash
20
+ });
21
+ /**
5
22
  * Section identity for the shared package-manager preamble.
6
23
  *
7
24
  * `toolName` is `"savvy-base"`; pair with {@link savvyBasePreamble} to build the block:
8
25
  *
9
26
  * @example
10
27
  * ```ts
11
- * const block = SavvyBaseSection.block(savvyBasePreamble());
28
+ * const section = SavvyBaseSection.section(savvyBasePreamble());
12
29
  * ```
13
30
  *
14
31
  * @since 0.5.0
15
32
  * @public
16
33
  */
17
- const SavvyBaseSection = ShellSectionDefinition.make({ toolName: "savvy-base" });
34
+ const SavvyBaseSection = shellSection("savvy-base");
18
35
  /**
19
36
  * Section identity for the shared repo-hygiene block.
20
37
  *
@@ -23,7 +40,7 @@ const SavvyBaseSection = ShellSectionDefinition.make({ toolName: "savvy-base" })
23
40
  * @since 0.5.0
24
41
  * @public
25
42
  */
26
- const SavvyHooksSection = ShellSectionDefinition.make({ toolName: "savvy-hooks" });
43
+ const SavvyHooksSection = shellSection("savvy-hooks");
27
44
  /**
28
45
  * Package-manager detection preamble shared across Silk Suite hook files.
29
46
  *
@@ -93,25 +110,25 @@ fi`;
93
110
  *
94
111
  * **Precondition:** a {@link SavvyBaseSection} block must precede this section in the same
95
112
  * hook file so `in_ci` and `pm_exec` are defined. Consumers guarantee this by passing both
96
- * to `ManagedSection.syncMany` in order:
113
+ * to `ManagedSection.syncAll` in order:
97
114
  *
98
115
  * @example
99
116
  * ```ts
100
- * yield* ManagedSection.syncMany(".husky/commit-msg", [
101
- * SavvyBaseSection.block(savvyBasePreamble()),
117
+ * yield* sections.syncAll(".husky/commit-msg", [
118
+ * SavvyBaseSection.section(savvyBasePreamble()),
102
119
  * savvyToolSection("savvy-commit", 'commitlint --config "$ROOT/lib/configs/commitlint.config.ts" --edit "$1"'),
103
120
  * ]);
104
121
  * ```
105
122
  *
106
123
  * @param toolName - Section identity; also drives the marker names (uppercased).
107
124
  * @param command - The command passed verbatim to `pm_exec`, run only outside CI.
108
- * @returns A shell {@link SectionBlock} (`commentStyle: "#"`) for `toolName`.
125
+ * @returns A shell `Section` (`commentStyle: hash`) for `toolName`.
109
126
  *
110
127
  * @since 0.5.0
111
128
  * @public
112
129
  */
113
130
  function savvyToolSection(toolName, command) {
114
- return ShellSectionDefinition.make({ toolName }).block(`in_ci || pm_exec ${command}`);
131
+ return shellSection(toolName).section(`in_ci || pm_exec ${command}`);
115
132
  }
116
133
 
117
134
  //#endregion
@@ -82,37 +82,6 @@ const SilkChangesetConfigFile = Schema.Struct({
82
82
  ...ChangesetConfigFile.fields,
83
83
  _isSilk: Schema.Boolean.pipe(Schema.withDecodingDefaultType(Effect.succeed(true)), Schema.withConstructorDefault(Effect.succeed(true)))
84
84
  });
85
- /**
86
- * Versioning strategy classification for a workspace.
87
- *
88
- * @remarks
89
- * - `"single"` — one publishable package; a single version tag is used.
90
- * - `"fixed-group"` — all publishable packages are in the same changesets fixed group.
91
- * - `"independent"` — multiple publishable packages with independent version bumps.
92
- *
93
- * @since 0.1.0
94
- * @public
95
- */
96
- const VersioningStrategyType = Schema.Literals([
97
- "single",
98
- "fixed-group",
99
- "independent"
100
- ]);
101
- /**
102
- * Output of the versioning strategy detection, combining the strategy type with group metadata.
103
- *
104
- * @remarks
105
- * Produced by `VersioningStrategy.detect` and consumed by `TagStrategy.determine`
106
- * to decide on the appropriate git-tag format.
107
- *
108
- * @since 0.1.0
109
- * @public
110
- */
111
- const VersioningStrategyResult = Schema.Struct({
112
- type: VersioningStrategyType,
113
- fixedGroups: Schema.Array(Schema.Array(Schema.String)),
114
- publishablePackages: Schema.Array(Schema.String)
115
- });
116
85
 
117
86
  //#endregion
118
- export { ChangesetConfigFile, SilkChangesetConfigFile, VersioningStrategyResult, VersioningStrategyType };
87
+ export { ChangesetConfigFile, SilkChangesetConfigFile };
@@ -1,8 +1,7 @@
1
- import { ChangesetConfigFile, SilkChangesetConfigFile, VersioningStrategyResult } from "./VersioningSchemas.js";
1
+ import { ChangesetConfigFile, SilkChangesetConfigFile } from "./VersioningSchemas.js";
2
2
  import { trimTrailingSlashes } from "../utils/TrailingSlash.js";
3
- import { TagStrategyType } from "./TagStrategySchemas.js";
4
3
  import { Effect, Equal, Function, Hash, Option, Schema } from "effect";
5
- import { PublishConfig, PublishTarget } from "@effected/workspaces";
4
+ import { PublishConfig, PublishTarget, TagStyle, VersioningStrategy } from "@effected/workspaces";
6
5
 
7
6
  //#region src/schemas/WorkspaceAnalysisSchemas.ts
8
7
  const PublishProtocol = Schema.Literals(["npm", "jsr"]);
@@ -155,8 +154,8 @@ var WorkspaceAnalysis = class WorkspaceAnalysis extends Schema.TaggedClass()("Wo
155
154
  packageManager: PackageManagerInfo,
156
155
  workspaces: Schema.Array(AnalyzedWorkspace),
157
156
  changesetConfig: Schema.NullOr(Schema.Union([SilkChangesetConfigFile, ChangesetConfigFile])),
158
- versioning: Schema.NullOr(VersioningStrategyResult),
159
- tagStrategy: Schema.NullOr(TagStrategyType)
157
+ versioning: Schema.NullOr(VersioningStrategy),
158
+ tagStrategy: Schema.NullOr(TagStyle)
160
159
  }) {
161
160
  findWorkspace(name) {
162
161
  const found = this.workspaces.find((w) => w.name === name);
@@ -260,7 +260,7 @@ const SilkPublishabilityDetectorLive = Layer.effect(PublishabilityDetector, Effe
260
260
  const PublishabilityDetectorAdaptiveLive = Layer.effect(PublishabilityDetector, Effect.gen(function* () {
261
261
  const fs = yield* FileSystem.FileSystem;
262
262
  const config = yield* ChangesetConfig;
263
- const vanilla = yield* Effect.provide(PublishabilityDetector, PublishabilityDetector.layer);
263
+ const vanilla = PublishabilityDetector.npm;
264
264
  return { detect: (pkg) => Effect.gen(function* () {
265
265
  const root = pkg.workspaceRoot;
266
266
  if (yield* config.isIgnored(pkg.name, root)) return [];
@@ -3,10 +3,8 @@ import { ChangesetConfig } from "./ChangesetConfig.js";
3
3
  import { SilkPublishability, readTargetsBinding } from "./SilkPublishability.js";
4
4
  import { WorkspaceAnalysisError } from "../errors/WorkspaceAnalysisError.js";
5
5
  import { AnalyzedWorkspace, WorkspaceAnalysis } from "../schemas/WorkspaceAnalysisSchemas.js";
6
- import { TagStrategy } from "./TagStrategy.js";
7
- import { VersioningStrategy } from "./VersioningStrategy.js";
8
6
  import { Context, Effect, FileSystem, Layer, Option } from "effect";
9
- import { DependencyGraph, PackageManagerDetector, WorkspaceDiscovery } from "@effected/workspaces";
7
+ import { DependencyGraph, PackageManagerDetector, VersioningStrategy, WorkspaceDiscovery } from "@effected/workspaces";
10
8
 
11
9
  //#region src/services/SilkWorkspaceAnalyzer.ts
12
10
  /**
@@ -15,10 +13,10 @@ import { DependencyGraph, PackageManagerDetector, WorkspaceDiscovery } from "@ef
15
13
  * wiring up fixed/linked release groups.
16
14
  *
17
15
  * @remarks
18
- * Orchestrates `WorkspaceDiscovery`, `PackageManagerDetector`,
19
- * {@link ChangesetConfigReader}, {@link VersioningStrategy}, and
20
- * {@link TagStrategy} to produce a complete {@link WorkspaceAnalysis} for a
21
- * given workspace root.
16
+ * Orchestrates `WorkspaceDiscovery`, `PackageManagerDetector` and
17
+ * {@link ChangesetConfigReader}, then classifies the result with
18
+ * `@effected/workspaces`' pure `VersioningStrategy` value class, to produce a
19
+ * complete {@link WorkspaceAnalysis} for a given workspace root.
22
20
  *
23
21
  * @example
24
22
  * ```typescript
@@ -105,8 +103,9 @@ function computeReleaseStatus(pkgName, isPrivate, isPublishable, config) {
105
103
  * Live implementation of {@link SilkWorkspaceAnalyzer}.
106
104
  *
107
105
  * @remarks
108
- * Requires `WorkspaceDiscovery`, `PackageManagerDetector`,
109
- * {@link ChangesetConfigReader}, {@link VersioningStrategy}, and {@link TagStrategy}.
106
+ * Requires `WorkspaceDiscovery`, `PackageManagerDetector` and
107
+ * {@link ChangesetConfigReader}. Versioning and tag classification are pure
108
+ * `@effected/workspaces` value operations, so neither adds a requirement.
110
109
  *
111
110
  * @since 0.2.0
112
111
  * @public
@@ -116,8 +115,6 @@ const SilkWorkspaceAnalyzerLive = Layer.effect(SilkWorkspaceAnalyzer, Effect.gen
116
115
  const discovery = yield* WorkspaceDiscovery;
117
116
  const pmDetector = yield* PackageManagerDetector;
118
117
  const configReader = yield* ChangesetConfigReader;
119
- const versioningStrategy = yield* VersioningStrategy;
120
- const tagStrategy = yield* TagStrategy;
121
118
  const analyze = (root) => Effect.gen(function* () {
122
119
  const pm = yield* pmDetector.detect(root).pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
123
120
  root,
@@ -188,11 +185,11 @@ const SilkWorkspaceAnalyzerLive = Layer.effect(SilkWorkspaceAnalyzer, Effect.gen
188
185
  }
189
186
  }
190
187
  const publishableNames = analyzedWorkspaces.filter((w) => w.publishable).map((w) => w.name);
191
- const versioning = yield* versioningStrategy.detect(publishableNames, root).pipe(Effect.mapError((err) => new WorkspaceAnalysisError({
192
- root,
193
- reason: `Versioning strategy detection failed: ${String(err)}`
194
- })));
195
- const tagStrategyType = yield* tagStrategy.determine(versioning);
188
+ const versioning = VersioningStrategy.classify({
189
+ packages: publishableNames,
190
+ fixedGroups: changesetConfig?.fixed ?? []
191
+ });
192
+ const tagStrategyType = versioning.tagStyle;
196
193
  return new WorkspaceAnalysis({
197
194
  root,
198
195
  runtime: pm.runtime,
@@ -1,11 +1,10 @@
1
- import { ToolDefinition } from "../../schemas/ToolDefinition.js";
2
- import { ToolDiscovery } from "../../services/ToolDiscovery.js";
3
1
  import { TurboDigest } from "../digest.js";
4
2
  import { DryRunParseError, NotATurboRepoError, TurboExecError, TurboNotInstalledError } from "../errors.js";
5
3
  import { TurboDryRun } from "../schemas/DryRun.js";
6
4
  import { Context, Effect, FileSystem, Layer, Schema } from "effect";
7
5
  import { Git } from "@effected/git";
8
- import { ChildProcessSpawner } from "effect/unstable/process";
6
+ import { ChildProcess, ChildProcessSpawner } from "effect/unstable/process";
7
+ import { Run, Tool, ToolDiscovery } from "@effected/commands";
9
8
 
10
9
  //#region src/turbo/services/TurboInspector.ts
11
10
  /**
@@ -20,7 +19,7 @@ import { ChildProcessSpawner } from "effect/unstable/process";
20
19
  * @since 0.7.0
21
20
  */
22
21
  var TurboInspector = class extends Context.Service()("@savvy-web/silk-effects/TurboInspector") {};
23
- const TURBO = ToolDefinition.make({ name: "turbo" });
22
+ const TURBO = Tool.named("turbo");
24
23
  /** Default task used by {@link TurboInspector.taskGraph} and {@link TurboInspector.affected}. */
25
24
  const DEFAULT_BUILD_TASK = "build:dev";
26
25
  /** Default git ref `affected` compares against — matches Turborepo's own `--affected` default. */
@@ -29,10 +28,10 @@ const DEFAULT_AFFECTED_BASE = "main";
29
28
  * Live implementation of {@link TurboInspector}.
30
29
  *
31
30
  * @remarks
32
- * Requires {@link ToolDiscovery} to resolve the `turbo` binary, plus
33
- * `ChildProcessSpawner` and `FileSystem` from core (provide `NodeServices.layer`
34
- * at the app edge) and `Git` from `@effected/git`. Mirrors `ToolDiscoveryLive`:
35
- * the spawner is captured at layer construction and discharged onto each command
31
+ * Requires `ToolDiscovery` from `@effected/commands` to resolve the `turbo`
32
+ * binary, plus `ChildProcessSpawner` and `FileSystem` from core (provide
33
+ * `NodeServices.layer` at the app edge) and `Git` from `@effected/git`. The
34
+ * spawner is captured at layer construction and discharged onto each `Run`
36
35
  * effect with `Effect.provideService`, keeping the public method effects at
37
36
  * `R = never`.
38
37
  *
@@ -43,9 +42,10 @@ const TurboInspectorLive = Layer.effect(TurboInspector, Effect.gen(function* ()
43
42
  const spawner = yield* ChildProcessSpawner.ChildProcessSpawner;
44
43
  const fs = yield* FileSystem.FileSystem;
45
44
  const git = yield* Git;
46
- const runTurbo = (cwd, args, env) => discovery.require(TURBO).pipe(Effect.mapError((e) => new TurboNotInstalledError({ reason: e.reason })), Effect.flatMap((resolved) => {
47
- const command = resolved.exec(...args).workingDirectory(cwd);
48
- return Effect.provideService((env ? command.env(env) : command).string(), ChildProcessSpawner.ChildProcessSpawner, spawner).pipe(Effect.mapError((e) => new TurboExecError({
45
+ const runTurbo = (cwd, args, env) => discovery.resolve(TURBO).pipe(Effect.mapError((e) => new TurboNotInstalledError({ reason: e.message })), Effect.flatMap((resolved) => {
46
+ const base = ChildProcess.setCwd(resolved.command(...args), cwd);
47
+ const command = env ? Run.extendEnv(base, env) : base;
48
+ return Effect.provideService(Run.text(command), ChildProcessSpawner.ChildProcessSpawner, spawner).pipe(Effect.mapError((e) => new TurboExecError({
49
49
  args: [...args],
50
50
  reason: String(e)
51
51
  })));
@@ -1,93 +0,0 @@
1
- import { parseMarkdown, stringifyMarkdown } from "../utils/remark-pipeline.js";
2
- import { Context, Effect, Layer } from "effect";
3
-
4
- //#region src/changesets/services/markdown.ts
5
- /**
6
- * Markdown service for parsing and stringifying mdast trees.
7
- *
8
- * Defines the {@link MarkdownService} Effect service tag and the
9
- * {@link MarkdownLive | production layer} backed by the remark/unified
10
- * pipeline. This service provides a pure, side-effect-free interface to
11
- * markdown parsing and stringification used throughout the changelog
12
- * formatter and remark transform pipeline.
13
- *
14
- * @remarks
15
- * The service wraps the `remark-pipeline` utility functions (`parseMarkdown`
16
- * and `stringifyMarkdown`) behind an Effect interface. The `parse` operation
17
- * returns an mdast `Root` node; the `stringify` operation serializes an
18
- * mdast `Root` back to a markdown string. Both operations are synchronous
19
- * under the hood but are lifted into `Effect.sync` for composability.
20
- *
21
- * @see {@link MarkdownService} for the Effect service tag
22
- * @see {@link MarkdownServiceShape} for the service interface
23
- * @see {@link MarkdownLive} for the production layer
24
- */
25
- /**
26
- * Effect service tag for markdown parsing and stringification.
27
- *
28
- * Provides dependency-injected access to markdown parse/stringify operations.
29
- * Use `yield* MarkdownService` inside an `Effect.gen` block to obtain the
30
- * service instance.
31
- *
32
- * @remarks
33
- * This tag follows the standard Effect `Context.Service` pattern. The
34
- * {@link MarkdownLive} layer provides the default implementation backed by
35
- * the remark/unified pipeline. For testing, you can supply a custom layer
36
- * via `Layer.succeed(MarkdownService, { parse: ..., stringify: ... })`.
37
- *
38
- * @example
39
- * ```typescript
40
- * import { Effect } from "effect";
41
- * import { MarkdownService, MarkdownLive } from "\@savvy-web/changesets";
42
- *
43
- * const program = Effect.gen(function* () {
44
- * const md = yield* MarkdownService;
45
- * const tree = yield* md.parse("# Hello\n\nWorld");
46
- * const output = yield* md.stringify(tree);
47
- * console.log(output); // "# Hello\n\nWorld\n"
48
- * });
49
- *
50
- * Effect.runPromise(program.pipe(Effect.provide(MarkdownLive)));
51
- * ```
52
- *
53
- * @see {@link MarkdownServiceShape} for the service interface
54
- * @see {@link MarkdownLive} for the production layer
55
- *
56
- * @public
57
- */
58
- var MarkdownService = class extends Context.Service()("MarkdownService") {};
59
- /**
60
- * Production layer for {@link MarkdownService}.
61
- *
62
- * Wraps the remark-pipeline utility functions (`parseMarkdown` and
63
- * `stringifyMarkdown`) in `Effect.sync` for use in Effect programs.
64
- * Both operations are synchronous and infallible.
65
- *
66
- * @remarks
67
- * This layer is composed with {@link GitHubLive} in the
68
- * `\@savvy-web/changesets/changelog` entry point to form the `MainLayer`
69
- * that powers the Changesets API integration.
70
- *
71
- * @example
72
- * ```typescript
73
- * import { Effect, Layer } from "effect";
74
- * import { MarkdownService, MarkdownLive } from "\@savvy-web/changesets";
75
- *
76
- * const program = Effect.gen(function* () {
77
- * const md = yield* MarkdownService;
78
- * const tree = yield* md.parse("**bold** text");
79
- * return yield* md.stringify(tree);
80
- * });
81
- *
82
- * Effect.runPromise(program.pipe(Effect.provide(MarkdownLive)));
83
- * ```
84
- *
85
- * @public
86
- */
87
- const MarkdownLive = Layer.succeed(MarkdownService, {
88
- parse: (content) => Effect.sync(() => parseMarkdown(content)),
89
- stringify: (tree) => Effect.sync(() => stringifyMarkdown(tree))
90
- });
91
-
92
- //#endregion
93
- export { MarkdownLive, MarkdownService };
@@ -1,17 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/SectionParseError.ts
4
- /**
5
- * Raised when a managed section cannot be parsed from a file.
6
- *
7
- * @since 0.2.0
8
- * @public
9
- */
10
- var SectionParseError = class extends Data.TaggedError("SectionParseError") {
11
- get message() {
12
- return `Failed to parse section in ${this.path}: ${this.reason}`;
13
- }
14
- };
15
-
16
- //#endregion
17
- export { SectionParseError };
@@ -1,17 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/SectionValidationError.ts
4
- /**
5
- * Raised when a {@link SectionBlock} fails validation at creation time.
6
- *
7
- * @since 0.2.0
8
- * @public
9
- */
10
- var SectionValidationError = class extends Data.TaggedError("SectionValidationError") {
11
- get message() {
12
- return `Section validation failed for ${this.toolName}: ${this.reason}`;
13
- }
14
- };
15
-
16
- //#endregion
17
- export { SectionValidationError };
@@ -1,17 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/SectionWriteError.ts
4
- /**
5
- * Raised when a managed section cannot be written to a file.
6
- *
7
- * @since 0.2.0
8
- * @public
9
- */
10
- var SectionWriteError = class extends Data.TaggedError("SectionWriteError") {
11
- get message() {
12
- return `Failed to write section to ${this.path}: ${this.reason}`;
13
- }
14
- };
15
-
16
- //#endregion
17
- export { SectionWriteError };
@@ -1,21 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/TagFormatError.ts
4
- /**
5
- * Raised when a git tag string cannot be formatted for the given package name and version.
6
- *
7
- * @remarks
8
- * Returned by `TagStrategy.formatTag` when the `version` argument is an empty string
9
- * or another invariant prevents tag construction.
10
- *
11
- * @since 0.1.0
12
- * @public
13
- */
14
- var TagFormatError = class extends Data.TaggedError("TagFormatError") {
15
- get message() {
16
- return `Failed to format tag for ${this.name}@${this.version}: ${this.reason}`;
17
- }
18
- };
19
-
20
- //#endregion
21
- export { TagFormatError };
@@ -1,12 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/ToolNotFoundError.ts
4
- /** @public */
5
- var ToolNotFoundError = class extends Data.TaggedError("ToolNotFoundError") {
6
- get message() {
7
- return `Tool not found: ${this.name} — ${this.reason}`;
8
- }
9
- };
10
-
11
- //#endregion
12
- export { ToolNotFoundError };
@@ -1,12 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/ToolResolutionError.ts
4
- /** @public */
5
- var ToolResolutionError = class extends Data.TaggedError("ToolResolutionError") {
6
- get message() {
7
- return `Tool resolution failed: ${this.name} — ${this.reason}`;
8
- }
9
- };
10
-
11
- //#endregion
12
- export { ToolResolutionError };
@@ -1,12 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/ToolVersionMismatchError.ts
4
- /** @public */
5
- var ToolVersionMismatchError = class extends Data.TaggedError("ToolVersionMismatchError") {
6
- get message() {
7
- return `Tool version mismatch: ${this.name} — global ${this.globalVersion} vs local ${this.localVersion}`;
8
- }
9
- };
10
-
11
- //#endregion
12
- export { ToolVersionMismatchError };
@@ -1,21 +0,0 @@
1
- import { Data } from "effect";
2
-
3
- //#region src/errors/VersioningDetectionError.ts
4
- /**
5
- * Raised when the versioning strategy cannot be determined from the workspace state.
6
- *
7
- * @remarks
8
- * Returned by `VersioningStrategy.detect` when an unexpected condition
9
- * prevents strategy classification.
10
- *
11
- * @since 0.1.0
12
- * @public
13
- */
14
- var VersioningDetectionError = class extends Data.TaggedError("VersioningDetectionError") {
15
- get message() {
16
- return `Failed to detect versioning strategy: ${this.reason}`;
17
- }
18
- };
19
-
20
- //#endregion
21
- export { VersioningDetectionError };
@@ -1,17 +0,0 @@
1
- import { Schema } from "effect";
2
-
3
- //#region src/schemas/CommentStyle.ts
4
- /**
5
- * Comment syntax used to write managed section markers.
6
- *
7
- * @remarks
8
- * - `"#"` — shell/YAML style, suitable for hook scripts and `.env` files.
9
- * - `"//"` — C-style, suitable for JavaScript/TypeScript files.
10
- *
11
- * @since 0.1.0
12
- * @public
13
- */
14
- const CommentStyle = Schema.Literals(["#", "//"]);
15
-
16
- //#endregion
17
- export { CommentStyle };