@savvy-web/silk 3.4.2 → 3.5.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.
@@ -2395,7 +2395,7 @@ var BunExtension = class extends effect.Schema.Class("BunExtension")({
2395
2395
  *
2396
2396
  * @public
2397
2397
  */
2398
- var CatalogResolver$1 = class CatalogResolver extends effect.Context.Service()("@effected/npm/CatalogResolver") {
2398
+ var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@effected/npm/CatalogResolver") {
2399
2399
  /**
2400
2400
  * No-op default: `rangeOf` always succeeds with `Option.none()`, never
2401
2401
  * consulting an actual catalog. A pure `Layer.succeed`, bound to a const
@@ -2419,7 +2419,7 @@ var CatalogResolver$1 = class CatalogResolver extends effect.Context.Service()("
2419
2419
  *
2420
2420
  * @public
2421
2421
  */
2422
- var DependencyResolutionError$1 = class extends effect.Schema.TaggedErrorClass()("DependencyResolutionError", {
2422
+ var DependencyResolutionError = class extends effect.Schema.TaggedErrorClass()("DependencyResolutionError", {
2423
2423
  specifier: effect.Schema.String,
2424
2424
  cause: effect.Schema.Defect()
2425
2425
  }) {
@@ -2457,7 +2457,7 @@ var DependencyResolutionError$1 = class extends effect.Schema.TaggedErrorClass()
2457
2457
  *
2458
2458
  * @public
2459
2459
  */
2460
- var WorkspaceResolver$1 = class WorkspaceResolver extends effect.Context.Service()("@effected/npm/WorkspaceResolver") {
2460
+ var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()("@effected/npm/WorkspaceResolver") {
2461
2461
  /**
2462
2462
  * No-op default: `versionOf` always succeeds with `Option.none()`, never
2463
2463
  * consulting an actual workspace. A pure `Layer.succeed`, bound to a
@@ -2509,7 +2509,15 @@ var CatalogAssemblyError = class extends effect.Schema.TaggedErrorClass()("Catal
2509
2509
  return `Failed to assemble catalogs from ${this.source} ${this.path}`;
2510
2510
  }
2511
2511
  };
2512
- effect.Schema.Literals([
2512
+ //#endregion
2513
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
2514
+ /**
2515
+ * The short dependency kind: which dependency map an entry came from, named the
2516
+ * way consumers branch on it.
2517
+ *
2518
+ * @public
2519
+ */
2520
+ const DependencyKind = effect.Schema.Literals([
2513
2521
  "prod",
2514
2522
  "dev",
2515
2523
  "peer",
@@ -2521,7 +2529,7 @@ effect.Schema.Literals([
2521
2529
  *
2522
2530
  * @public
2523
2531
  */
2524
- const DependencyField$1 = effect.Schema.Literals([
2532
+ const DependencyField = effect.Schema.Literals([
2525
2533
  "dependencies",
2526
2534
  "devDependencies",
2527
2535
  "peerDependencies",
@@ -2908,7 +2916,7 @@ const parseRangeComparators = (s) => {
2908
2916
  * Parse a range expression into comparator sets (OR of ANDs). The empty
2909
2917
  * string parses as the match-all range.
2910
2918
  */
2911
- const parseRange$2 = (raw) => {
2919
+ const parseRange$1 = (raw) => {
2912
2920
  const trimmed = raw.trim();
2913
2921
  if (trimmed.length === 0) return {
2914
2922
  ok: true,
@@ -3807,7 +3815,7 @@ sets: effect.Schema.Array(effect.Schema.Array(Comparator)) }) {
3807
3815
  */
3808
3816
  static FromString = effect.Schema.String.pipe(effect.Schema.decodeTo(Range, effect.SchemaTransformation.transformOrFail({
3809
3817
  decode: (input) => {
3810
- const result = parseRange$2(input);
3818
+ const result = parseRange$1(input);
3811
3819
  return result.ok ? effect.Effect.succeed({ sets: normalizeSets(result.value) }) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid range expression: "${result.input}" at position ${result.position}` }));
3812
3820
  },
3813
3821
  encode: (parts) => effect.Effect.succeed(formatRange(parts.sets))
@@ -3838,7 +3846,7 @@ sets: effect.Schema.Array(effect.Schema.Array(Comparator)) }) {
3838
3846
  * with {@link InvalidRangeError}.
3839
3847
  */
3840
3848
  static parseResult(input) {
3841
- const result = parseRange$2(input);
3849
+ const result = parseRange$1(input);
3842
3850
  if (!result.ok) return effect.Result.fail(new InvalidRangeError({
3843
3851
  input: result.input,
3844
3852
  position: result.position
@@ -4126,50 +4134,50 @@ const isComparatorSetSubset = (sub, sup) => {
4126
4134
  *
4127
4135
  * @public
4128
4136
  */
4129
- var InvalidDependencySpecifierError$1 = class extends effect.Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
4137
+ var InvalidDependencySpecifierError = class extends effect.Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
4130
4138
  /** The raw input string that failed validation. */
4131
4139
  input: effect.Schema.String }) {
4132
4140
  get message() {
4133
4141
  return `Invalid dependency specifier "${this.input}": not a recognized specifier`;
4134
4142
  }
4135
4143
  };
4136
- const CATALOG_PREFIX$1 = "catalog:";
4137
- const WORKSPACE_PREFIX$1 = "workspace:";
4138
- const isBarePath$1 = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4139
- const isGitHubShorthand$1 = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4140
- const isGit$1 = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand$1(value);
4141
- const isLocal$1 = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath$1(value);
4142
- const isLink$1 = (value) => value.startsWith("link:");
4143
- const isPortal$1 = (value) => value.startsWith("portal:");
4144
- const isCatalog$1 = (value) => value.startsWith(CATALOG_PREFIX$1);
4145
- const isWorkspace$1 = (value) => value.startsWith(WORKSPACE_PREFIX$1);
4146
- const isUrl$2 = (value) => value.startsWith("http://") || value.startsWith("https://");
4147
- const parseRange$1 = (value) => {
4144
+ const CATALOG_PREFIX = "catalog:";
4145
+ const WORKSPACE_PREFIX = "workspace:";
4146
+ const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4147
+ const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4148
+ const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
4149
+ const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath(value);
4150
+ const isLink = (value) => value.startsWith("link:");
4151
+ const isPortal = (value) => value.startsWith("portal:");
4152
+ const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
4153
+ const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
4154
+ const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
4155
+ const parseRange = (value) => {
4148
4156
  const exit = effect.Schema.decodeUnknownExit(Range$2.FromString)(value);
4149
4157
  return effect.Exit.isSuccess(exit) ? effect.Option.some(exit.value) : effect.Option.none();
4150
4158
  };
4151
- const isRange$1 = (value) => effect.Option.isSome(parseRange$1(value));
4152
- const protocolOf$1 = (value) => {
4153
- if (value.startsWith(CATALOG_PREFIX$1)) return "catalog";
4154
- if (value.startsWith(WORKSPACE_PREFIX$1)) return "workspace";
4159
+ const isRange = (value) => effect.Option.isSome(parseRange(value));
4160
+ const protocolOf = (value) => {
4161
+ if (value.startsWith(CATALOG_PREFIX)) return "catalog";
4162
+ if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
4155
4163
  if (value.startsWith("link:")) return "link";
4156
4164
  if (value.startsWith("portal:")) return "portal";
4157
- if (value.startsWith("file:") || isBarePath$1(value)) return "file";
4165
+ if (value.startsWith("file:") || isBarePath(value)) return "file";
4158
4166
  if (value.startsWith("npm:")) return "npm";
4159
- if (isGit$1(value)) return "git";
4160
- if (isUrl$2(value)) return "url";
4161
- if (isRange$1(value)) return "range";
4167
+ if (isGit(value)) return "git";
4168
+ if (isUrl$1(value)) return "url";
4169
+ if (isRange(value)) return "range";
4162
4170
  if (/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(value)) return "tag";
4163
4171
  return "unknown";
4164
4172
  };
4165
- const isTag$1 = (value) => protocolOf$1(value) === "tag";
4166
- const catalogNameOf$2 = (specifier) => {
4167
- if (!isCatalog$1(specifier)) return effect.Option.none();
4173
+ const isTag = (value) => protocolOf(value) === "tag";
4174
+ const catalogNameOf$1 = (specifier) => {
4175
+ if (!isCatalog(specifier)) return effect.Option.none();
4168
4176
  const rest = specifier.slice(8).trim();
4169
4177
  return rest.length === 0 ? effect.Option.none() : effect.Option.some(rest);
4170
4178
  };
4171
- const projectRangeModifier$1 = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
4172
- const splitWorkspaceRest$1 = (rest) => {
4179
+ const projectRangeModifier = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
4180
+ const splitWorkspaceRest = (rest) => {
4173
4181
  const at = rest.lastIndexOf("@");
4174
4182
  return at > 0 ? {
4175
4183
  target: rest.slice(0, at),
@@ -4179,15 +4187,15 @@ const splitWorkspaceRest$1 = (rest) => {
4179
4187
  range: rest
4180
4188
  };
4181
4189
  };
4182
- const projectWorkspaceRange$1 = (rest, version) => {
4183
- const { target, range } = splitWorkspaceRest$1(rest);
4184
- const projected = projectRangeModifier$1(range, version);
4190
+ const projectWorkspaceRange = (rest, version) => {
4191
+ const { target, range } = splitWorkspaceRest(rest);
4192
+ const projected = projectRangeModifier(range, version);
4185
4193
  return target === void 0 ? projected : `npm:${target}@${projected}`;
4186
4194
  };
4187
- const resolveWorkspace$1 = (specifier, version) => isWorkspace$1(specifier) ? projectWorkspaceRange$1(specifier.slice(10), version) : specifier;
4188
- const workspaceTargetOf$1 = (specifier) => {
4189
- if (!isWorkspace$1(specifier)) return effect.Option.none();
4190
- const { target } = splitWorkspaceRest$1(specifier.slice(10));
4195
+ const resolveWorkspace = (specifier, version) => isWorkspace(specifier) ? projectWorkspaceRange(specifier.slice(10), version) : specifier;
4196
+ const workspaceTargetOf = (specifier) => {
4197
+ if (!isWorkspace(specifier)) return effect.Option.none();
4198
+ const { target } = splitWorkspaceRest(specifier.slice(10));
4191
4199
  return target === void 0 ? effect.Option.none() : effect.Option.some(target);
4192
4200
  };
4193
4201
  /**
@@ -4197,14 +4205,14 @@ const workspaceTargetOf$1 = (specifier) => {
4197
4205
  *
4198
4206
  * @public
4199
4207
  */
4200
- const isValidDependencySpecifier$1 = (value) => value.length > 0 && protocolOf$1(value) !== "unknown";
4208
+ const isValidDependencySpecifier = (value) => value.length > 0 && protocolOf(value) !== "unknown";
4201
4209
  /**
4202
4210
  * A `catalog:` reference. `name` carries the catalog name, or `Option.none()`
4203
4211
  * for the default catalog (`catalog:`).
4204
4212
  *
4205
4213
  * @public
4206
4214
  */
4207
- var CatalogSpecifier$1 = class extends effect.Schema.TaggedClass()("catalog", {
4215
+ var CatalogSpecifier = class extends effect.Schema.TaggedClass()("catalog", {
4208
4216
  /** The original specifier string. */
4209
4217
  raw: effect.Schema.String,
4210
4218
  /** The catalog name, or `Option.none()` for the default catalog. */
@@ -4216,7 +4224,7 @@ var CatalogSpecifier$1 = class extends effect.Schema.TaggedClass()("catalog", {
4216
4224
  *
4217
4225
  * @public
4218
4226
  */
4219
- var WorkspaceSpecifier$1 = class extends effect.Schema.TaggedClass()("workspace", {
4227
+ var WorkspaceSpecifier = class extends effect.Schema.TaggedClass()("workspace", {
4220
4228
  /** The original specifier string. */
4221
4229
  raw: effect.Schema.String,
4222
4230
  /** The part after `workspace:` (e.g. `*`, `^1.2.3`, or an alias form). */
@@ -4240,7 +4248,7 @@ var WorkspaceSpecifier$1 = class extends effect.Schema.TaggedClass()("workspace"
4240
4248
  * specifier points at (the alias target's version for the alias form).
4241
4249
  */
4242
4250
  resolve(version) {
4243
- return projectWorkspaceRange$1(this.range, version);
4251
+ return projectWorkspaceRange(this.range, version);
4244
4252
  }
4245
4253
  };
4246
4254
  /**
@@ -4248,7 +4256,7 @@ var WorkspaceSpecifier$1 = class extends effect.Schema.TaggedClass()("workspace"
4248
4256
  *
4249
4257
  * @public
4250
4258
  */
4251
- var RangeSpecifier$1 = class extends effect.Schema.TaggedClass()("range", {
4259
+ var RangeSpecifier = class extends effect.Schema.TaggedClass()("range", {
4252
4260
  /** The original specifier string. */
4253
4261
  raw: effect.Schema.String }) {};
4254
4262
  /**
@@ -4256,7 +4264,7 @@ raw: effect.Schema.String }) {};
4256
4264
  *
4257
4265
  * @public
4258
4266
  */
4259
- var DistTagSpecifier$1 = class extends effect.Schema.TaggedClass()("dist-tag", {
4267
+ var DistTagSpecifier = class extends effect.Schema.TaggedClass()("dist-tag", {
4260
4268
  /** The original specifier string (also the tag name). */
4261
4269
  raw: effect.Schema.String }) {};
4262
4270
  /**
@@ -4265,35 +4273,35 @@ raw: effect.Schema.String }) {};
4265
4273
  *
4266
4274
  * @public
4267
4275
  */
4268
- var RawSpecifier$1 = class extends effect.Schema.TaggedClass()("raw", {
4276
+ var RawSpecifier = class extends effect.Schema.TaggedClass()("raw", {
4269
4277
  /** The original specifier string. */
4270
4278
  raw: effect.Schema.String }) {};
4271
- const Classified$1 = effect.Schema.Union([
4272
- CatalogSpecifier$1,
4273
- WorkspaceSpecifier$1,
4274
- RangeSpecifier$1,
4275
- DistTagSpecifier$1,
4276
- RawSpecifier$1
4279
+ const Classified = effect.Schema.Union([
4280
+ CatalogSpecifier,
4281
+ WorkspaceSpecifier,
4282
+ RangeSpecifier,
4283
+ DistTagSpecifier,
4284
+ RawSpecifier
4277
4285
  ]);
4278
- const classify$2 = (value) => {
4279
- if (isCatalog$1(value)) return CatalogSpecifier$1.make({
4286
+ const classify$1 = (value) => {
4287
+ if (isCatalog(value)) return CatalogSpecifier.make({
4280
4288
  raw: value,
4281
- name: catalogNameOf$2(value)
4289
+ name: catalogNameOf$1(value)
4282
4290
  });
4283
- if (isWorkspace$1(value)) return WorkspaceSpecifier$1.make({
4291
+ if (isWorkspace(value)) return WorkspaceSpecifier.make({
4284
4292
  raw: value,
4285
4293
  range: value.slice(10)
4286
4294
  });
4287
- if (isRange$1(value)) return RangeSpecifier$1.make({ raw: value });
4288
- if (isTag$1(value)) return DistTagSpecifier$1.make({ raw: value });
4289
- return RawSpecifier$1.make({ raw: value });
4295
+ if (isRange(value)) return RangeSpecifier.make({ raw: value });
4296
+ if (isTag(value)) return DistTagSpecifier.make({ raw: value });
4297
+ return RawSpecifier.make({ raw: value });
4290
4298
  };
4291
- const fromString$1 = effect.Schema.String.pipe(effect.Schema.decodeTo(Classified$1, effect.SchemaTransformation.transformOrFail({
4292
- decode: (input) => isValidDependencySpecifier$1(input) ? effect.Effect.succeed(classify$2(input)) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
4299
+ const fromString = effect.Schema.String.pipe(effect.Schema.decodeTo(Classified, effect.SchemaTransformation.transformOrFail({
4300
+ decode: (input) => isValidDependencySpecifier(input) ? effect.Effect.succeed(classify$1(input)) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
4293
4301
  encode: (classified) => effect.Effect.succeed(classified.raw)
4294
4302
  })));
4295
- const brandedSpecifier$1 = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidDependencySpecifier$1(value) ? void 0 : "Expected a valid dependency specifier")), effect.Schema.brand("DependencySpecifier"));
4296
- const decode$5 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier$1)(input).pipe(effect.Effect.mapError(() => new InvalidDependencySpecifierError$1({ input })));
4303
+ const brandedSpecifier = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidDependencySpecifier(value) ? void 0 : "Expected a valid dependency specifier")), effect.Schema.brand("DependencySpecifier"));
4304
+ const decode$3 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier)(input).pipe(effect.Effect.mapError(() => new InvalidDependencySpecifierError({ input })));
4297
4305
  /**
4298
4306
  * A valid dependency version specifier, carrying the protocol taxonomy statics
4299
4307
  * (`DependencySpecifier.protocolOf` and friends) that classify any specifier
@@ -4304,43 +4312,43 @@ const decode$5 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier$1
4304
4312
  *
4305
4313
  * @public
4306
4314
  */
4307
- const DependencySpecifier$1 = Object.assign(brandedSpecifier$1, {
4308
- protocolOf: protocolOf$1,
4309
- parseRange: parseRange$1,
4310
- isRange: isRange$1,
4311
- isTag: isTag$1,
4312
- isGit: isGit$1,
4313
- isUrl: isUrl$2,
4314
- isLocal: isLocal$1,
4315
- isLink: isLink$1,
4316
- isPortal: isPortal$1,
4317
- isCatalog: isCatalog$1,
4318
- isWorkspace: isWorkspace$1,
4319
- catalogNameOf: catalogNameOf$2,
4320
- resolveWorkspace: resolveWorkspace$1,
4321
- workspaceTargetOf: workspaceTargetOf$1,
4322
- isValid: isValidDependencySpecifier$1,
4323
- decode: decode$5,
4324
- FromString: fromString$1
4315
+ const DependencySpecifier = Object.assign(brandedSpecifier, {
4316
+ protocolOf,
4317
+ parseRange,
4318
+ isRange,
4319
+ isTag,
4320
+ isGit,
4321
+ isUrl: isUrl$1,
4322
+ isLocal,
4323
+ isLink,
4324
+ isPortal,
4325
+ isCatalog,
4326
+ isWorkspace,
4327
+ catalogNameOf: catalogNameOf$1,
4328
+ resolveWorkspace,
4329
+ workspaceTargetOf,
4330
+ isValid: isValidDependencySpecifier,
4331
+ decode: decode$3,
4332
+ FromString: fromString
4325
4333
  });
4326
4334
  //#endregion
4327
4335
  //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
4328
- const SRI_RE$1 = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4329
- const COREPACK_RE$1 = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4330
- const YARN_RE$1 = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
4331
- const isSri$1 = (value) => SRI_RE$1.test(value);
4332
- const isCorepack$1 = (value) => COREPACK_RE$1.test(value);
4333
- const isYarnChecksum$1 = (value) => YARN_RE$1.test(value);
4336
+ const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4337
+ const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4338
+ const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
4339
+ const isSri = (value) => SRI_RE.test(value);
4340
+ const isCorepack = (value) => COREPACK_RE.test(value);
4341
+ const isYarnChecksum = (value) => YARN_RE.test(value);
4334
4342
  /**
4335
4343
  * Whether a string is a valid integrity hash in the SRI (`<algo>-<base64>`),
4336
4344
  * corepack (`<algo>.<hex>`) or yarn (`<cachekey>/<hex>`) form.
4337
4345
  *
4338
4346
  * @public
4339
4347
  */
4340
- const isValidIntegrityHash$1 = (value) => isSri$1(value) || isCorepack$1(value) || isYarnChecksum$1(value);
4341
- const algorithmOf$1 = (value) => {
4342
- if (isSri$1(value)) return effect.Option.some(value.slice(0, value.indexOf("-")));
4343
- if (isCorepack$1(value)) return effect.Option.some(value.slice(0, value.indexOf(".")));
4348
+ const isValidIntegrityHash = (value) => isSri(value) || isCorepack(value) || isYarnChecksum(value);
4349
+ const algorithmOf = (value) => {
4350
+ if (isSri(value)) return effect.Option.some(value.slice(0, value.indexOf("-")));
4351
+ if (isCorepack(value)) return effect.Option.some(value.slice(0, value.indexOf(".")));
4344
4352
  return effect.Option.none();
4345
4353
  };
4346
4354
  /**
@@ -4351,15 +4359,15 @@ const algorithmOf$1 = (value) => {
4351
4359
  *
4352
4360
  * @public
4353
4361
  */
4354
- var InvalidIntegrityHashError$1 = class extends effect.Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
4362
+ var InvalidIntegrityHashError = class extends effect.Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
4355
4363
  /** The raw input string that failed validation. */
4356
4364
  input: effect.Schema.String }) {
4357
4365
  get message() {
4358
4366
  return `Invalid integrity hash "${this.input}": expected an SRI (<algo>-<base64>), corepack (<algo>.<hex>) or yarn (<cachekey>/<hex>) form`;
4359
4367
  }
4360
4368
  };
4361
- const brandedIntegrity$1 = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidIntegrityHash$1(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), effect.Schema.brand("IntegrityHash"));
4362
- const decode$4 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity$1)(input).pipe(effect.Effect.mapError(() => new InvalidIntegrityHashError$1({ input })));
4369
+ const brandedIntegrity = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidIntegrityHash(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), effect.Schema.brand("IntegrityHash"));
4370
+ const decode$2 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity)(input).pipe(effect.Effect.mapError(() => new InvalidIntegrityHashError({ input })));
4363
4371
  /**
4364
4372
  * A subresource-integrity hash, covering the SRI (`sha512-<base64>`), corepack
4365
4373
  * (`sha512.<hex>`) and yarn (`10c0/<hex>`) textual forms, carrying taxonomy
@@ -4368,15 +4376,66 @@ const decode$4 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity$1
4368
4376
  *
4369
4377
  * @public
4370
4378
  */
4371
- const IntegrityHash$1 = Object.assign(brandedIntegrity$1, {
4372
- isSri: isSri$1,
4373
- isCorepack: isCorepack$1,
4374
- isYarnChecksum: isYarnChecksum$1,
4375
- isValid: isValidIntegrityHash$1,
4376
- algorithmOf: algorithmOf$1,
4377
- decode: decode$4
4379
+ const IntegrityHash = Object.assign(brandedIntegrity, {
4380
+ isSri,
4381
+ isCorepack,
4382
+ isYarnChecksum,
4383
+ isValid: isValidIntegrityHash,
4384
+ algorithmOf,
4385
+ decode: decode$2
4378
4386
  });
4379
- brandedIntegrity$1.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isCorepack$1(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
4387
+ /**
4388
+ * {@link (IntegrityHash:variable)} narrowed to the corepack `<algo>.<hex>` form
4389
+ * — `sha512.deadbeef`, and corepack's own sha224 default pins
4390
+ * (`sha224.877304e3…`). An SRI (`sha512-<base64>`) or yarn (`10c0/<hex>`)
4391
+ * hash, both valid `IntegrityHash` values, fails this schema.
4392
+ *
4393
+ * @remarks
4394
+ * The corepack pin tail (`<name>@<version>+<integrity>`) is the one place the
4395
+ * kit meets this form, and two schemas name it: `PackageManagerPin.integrity`
4396
+ * here and `@effected/package-json`'s `PackageManager.integrity`. Both consume
4397
+ * **this** schema — the restriction existed privately in each module until they
4398
+ * were consolidated, and a private copy is exactly how the two drift (the
4399
+ * widening that admitted sha224 had to be made twice).
4400
+ *
4401
+ * It decodes to the same {@link IntegrityHashBrand} the unrestricted schema
4402
+ * does, so a corepack-validated value assigns anywhere an `IntegrityHash` is
4403
+ * expected; there is no second brand. Reach for
4404
+ * `IntegrityHash.isCorepack(value)` to ask the same question about a raw
4405
+ * string without decoding.
4406
+ *
4407
+ * That single brand is also why sharing this schema is not type-enforced, and
4408
+ * the consequence is sharper than it looks: a `Schema.check` is **erased from
4409
+ * the built type**, so this schema and the unrestricted one are the same
4410
+ * declared type. A consumer that quietly reverts to a private copy compiles
4411
+ * clean, and — if the copy is faithful — passes every rejection test too.
4412
+ * Neither `tsc` nor behaviour can see the re-fork.
4413
+ *
4414
+ * What does see it is **object identity**, so each consumer's suite asserts
4415
+ * that its field schema IS this export:
4416
+ * `PackageManagerPin.fields.integrity.schema === CorepackIntegrityHash` (an
4417
+ * `optionalKey` field keeps the inner schema on `.schema`), and
4418
+ * `PackageManager.fields.integrity.value === CorepackIntegrityHash` on the
4419
+ * `@effected/package-json` side (a `Schema.Option` keeps it on `.value`). Both
4420
+ * assertions carry a control against the unrestricted brand, so they discriminate
4421
+ * rather than passing on any schema at all. That identity assertion is the only
4422
+ * thing standing between the two surfaces and a silent re-fork; do not replace
4423
+ * it with a behavioural test, which cannot fail.
4424
+ *
4425
+ * @example
4426
+ * ```ts
4427
+ * import { CorepackIntegrityHash } from "@effected/npm";
4428
+ * import { Schema } from "effect";
4429
+ *
4430
+ * const decode = Schema.decodeUnknownExit(CorepackIntegrityHash);
4431
+ *
4432
+ * decode("sha512.deadbeef"); // success
4433
+ * decode("sha512-3q2+7w=="); // failure — SRI form
4434
+ * ```
4435
+ *
4436
+ * @public
4437
+ */
4438
+ const CorepackIntegrityHash = brandedIntegrity.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isCorepack(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
4380
4439
  effect.Schema.Literals([
4381
4440
  "npm",
4382
4441
  "pnpm",
@@ -5445,10 +5504,10 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
5445
5504
  */
5446
5505
  var ImporterDependency = class extends effect.Schema.Class("ImporterDependency")({
5447
5506
  name: effect.Schema.NonEmptyString,
5448
- specifier: DependencySpecifier$1.FromString,
5507
+ specifier: DependencySpecifier.FromString,
5449
5508
  version: effect.Schema.optionalKey(effect.Schema.String),
5450
5509
  peerSuffix: effect.Schema.optionalKey(effect.Schema.String),
5451
- depType: DependencyField$1
5510
+ depType: DependencyField
5452
5511
  }) {};
5453
5512
  //#endregion
5454
5513
  //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileImporter.js
@@ -5504,7 +5563,7 @@ const EMPTY_DEPENDENCIES = {};
5504
5563
  var ResolvedPackage = class extends effect.Schema.Class("ResolvedPackage")({
5505
5564
  name: effect.Schema.NonEmptyString,
5506
5565
  version: effect.Schema.String,
5507
- integrity: effect.Schema.optionalKey(IntegrityHash$1),
5566
+ integrity: effect.Schema.optionalKey(IntegrityHash),
5508
5567
  isWorkspace: effect.Schema.Boolean,
5509
5568
  relativePath: effect.Schema.optionalKey(effect.Schema.String),
5510
5569
  dependencies: effect.Schema.Record(effect.Schema.String, effect.Schema.String).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed(EMPTY_DEPENDENCIES)), effect.Schema.withConstructorDefault(effect.Effect.succeed(EMPTY_DEPENDENCIES)))
@@ -5528,7 +5587,7 @@ var ResolvedPackage = class extends effect.Schema.Class("ResolvedPackage")({
5528
5587
  var WorkspaceDependency = class extends effect.Schema.Class("WorkspaceDependency")({
5529
5588
  from: effect.Schema.NonEmptyString,
5530
5589
  to: effect.Schema.NonEmptyString,
5531
- depType: DependencyField$1,
5590
+ depType: DependencyField,
5532
5591
  constraint: effect.Schema.String
5533
5592
  }) {};
5534
5593
  //#endregion
@@ -5630,9 +5689,9 @@ const DEP_TYPES = [
5630
5689
  */
5631
5690
  const toIntegrityHash = (raw) => {
5632
5691
  if (raw === void 0) return effect.Effect.succeed(void 0);
5633
- return effect.Schema.decodeUnknownEffect(IntegrityHash$1)(raw).pipe(effect.Effect.mapError(validationFailure));
5692
+ return effect.Schema.decodeUnknownEffect(IntegrityHash)(raw).pipe(effect.Effect.mapError(validationFailure));
5634
5693
  };
5635
- const decodeSpecifier = effect.Schema.decodeUnknownExit(DependencySpecifier$1.FromString);
5694
+ const decodeSpecifier = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString);
5636
5695
  /**
5637
5696
  * Split pnpm's peer-disambiguation suffix off a recorded string: everything
5638
5697
  * from the first `(` on is suffix, since package names and versions never
@@ -15149,7 +15208,7 @@ var LockfileIntegrity = class LockfileIntegrity extends effect.Schema.Class("Loc
15149
15208
  dependency: effect.Schema.String,
15150
15209
  constraint: effect.Schema.String,
15151
15210
  resolved: effect.Schema.String,
15152
- depType: DependencyField$1
15211
+ depType: DependencyField
15153
15212
  }))
15154
15213
  }) {
15155
15214
  /**
@@ -15217,514 +15276,97 @@ var LockfileIntegrity = class LockfileIntegrity extends effect.Schema.Class("Loc
15217
15276
  }
15218
15277
  };
15219
15278
  //#endregion
15220
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/CatalogResolver.js
15279
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
15221
15280
  /**
15222
- * Contract for resolving pnpm `catalog:` dependency specifiers to concrete
15223
- * version ranges.
15224
- *
15225
- * `rangeOf` takes a package name and an optional catalog name
15226
- * (`Option.none()` selects the default catalog) and returns the configured
15227
- * range as `Option.some`, or `Option.none()` when the specifier is absent
15228
- * from the catalog. By convention the error channel is reserved for a
15229
- * failure in the resolution mechanism itself — an unmatched package or
15230
- * catalog name is an `Option.none()` success, never an error. A failure to
15231
- * *assemble* the catalogs (an unreadable or malformed catalog source)
15232
- * surfaces typed as a {@link CatalogAssemblyError}; any other mechanism
15233
- * failure is a {@link DependencyResolutionError}.
15234
- *
15235
- * This is a contract-only service: {@link CatalogResolver.noop} is the sole
15236
- * implementation this package ships, and it resolves nothing. Real consumers
15237
- * (e.g. `@effected/workspaces`) provide a working implementation at the
15238
- * application boundary.
15239
- *
15240
- * @example
15241
- * ```ts
15242
- * import { Effect, Option } from "effect";
15243
- * import { CatalogResolver } from "@effected/npm";
15244
- *
15245
- * const program = Effect.gen(function* () {
15246
- * const resolver = yield* CatalogResolver;
15247
- * return yield* resolver.rangeOf("effect", Option.none());
15248
- * });
15249
- *
15250
- * Effect.runPromise(Effect.provide(program, CatalogResolver.noop));
15251
- * // => Option.none()
15252
- * ```
15281
+ * A resolved dependency entry pairing a package name with its version
15282
+ * specifier and the `kind` of map it came from (`@effected/npm`'s
15283
+ * `DependencyKind`). The protocol predicates delegate to `DependencySpecifier`.
15253
15284
  *
15254
15285
  * @public
15255
15286
  */
15256
- var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@effected/npm/CatalogResolver") {
15257
- /**
15258
- * No-op default: `rangeOf` always succeeds with `Option.none()`, never
15259
- * consulting an actual catalog. A pure `Layer.succeed`, bound to a const
15260
- * so it memoizes by reference — the layer is built once, not once per
15261
- * reference to `CatalogResolver.noop`.
15262
- */
15263
- static noop = effect.Layer.succeed(CatalogResolver, { rangeOf: () => effect.Effect.succeed(effect.Option.none()) });
15264
- };
15265
- effect.Schema.TaggedErrorClass()("DependencyResolutionError", {
15287
+ var Dependency = class extends effect.Schema.Class("Dependency")({
15288
+ /** The package name. */
15289
+ name: effect.Schema.String,
15290
+ /** The raw version specifier. */
15266
15291
  specifier: effect.Schema.String,
15267
- cause: effect.Schema.Defect()
15268
- });
15269
- /**
15270
- * Contract for resolving pnpm `workspace:` dependency specifiers to concrete
15271
- * versions.
15272
- *
15273
- * `versionOf` takes a workspace package name and returns its concrete
15274
- * version (the range modifier stripped) as `Option.some`, or
15275
- * `Option.none()` when the name is not a known workspace member.
15276
- *
15277
- * This is a contract-only service: {@link WorkspaceResolver.noop} is the
15278
- * sole implementation this package ships, and it resolves nothing. Real
15279
- * consumers (e.g. `@effected/workspaces`) provide a working implementation
15280
- * at the application boundary.
15281
- *
15282
- * @example
15283
- * ```ts
15284
- * import { Effect } from "effect";
15285
- * import { WorkspaceResolver } from "@effected/npm";
15286
- *
15287
- * const program = Effect.gen(function* () {
15288
- * const resolver = yield* WorkspaceResolver;
15289
- * return yield* resolver.versionOf("@effected/semver");
15290
- * });
15291
- *
15292
- * Effect.runPromise(Effect.provide(program, WorkspaceResolver.noop));
15293
- * // => Option.none()
15294
- * ```
15295
- *
15296
- * @public
15297
- */
15298
- var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()("@effected/npm/WorkspaceResolver") {
15299
- /**
15300
- * No-op default: `versionOf` always succeeds with `Option.none()`, never
15301
- * consulting an actual workspace. A pure `Layer.succeed`, bound to a
15302
- * const so it memoizes by reference.
15303
- */
15304
- static noop = effect.Layer.succeed(WorkspaceResolver, { versionOf: () => effect.Effect.succeed(effect.Option.none()) });
15305
- };
15306
- //#endregion
15307
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
15308
- /**
15309
- * The short dependency kind: which dependency map an entry came from, named the
15310
- * way consumers branch on it.
15311
- *
15312
- * @public
15313
- */
15314
- const DependencyKind = effect.Schema.Literals([
15315
- "prod",
15316
- "dev",
15317
- "peer",
15318
- "optional"
15319
- ]);
15320
- effect.Schema.Literals([
15321
- "dependencies",
15322
- "devDependencies",
15323
- "peerDependencies",
15324
- "optionalDependencies"
15325
- ]);
15326
- Object.fromEntries(Object.entries({
15327
- prod: "dependencies",
15328
- dev: "devDependencies",
15329
- peer: "peerDependencies",
15330
- optional: "optionalDependencies"
15331
- }).map(([kind, field]) => [field, kind]));
15332
- //#endregion
15333
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySpecifier.js
15334
- /**
15335
- * Indicates that a string could not be parsed as a valid dependency specifier.
15336
- *
15337
- * Raised by {@link DependencySpecifier.decode}. The offending string is
15338
- * preserved on `input`.
15339
- *
15340
- * @public
15341
- */
15342
- var InvalidDependencySpecifierError = class extends effect.Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
15343
- /** The raw input string that failed validation. */
15344
- input: effect.Schema.String }) {
15345
- get message() {
15346
- return `Invalid dependency specifier "${this.input}": not a recognized specifier`;
15347
- }
15348
- };
15349
- const CATALOG_PREFIX = "catalog:";
15350
- const WORKSPACE_PREFIX = "workspace:";
15351
- const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
15352
- const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
15353
- const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
15354
- const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath(value);
15355
- const isLink = (value) => value.startsWith("link:");
15356
- const isPortal = (value) => value.startsWith("portal:");
15357
- const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
15358
- const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
15359
- const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
15360
- const parseRange = (value) => {
15361
- const exit = effect.Schema.decodeUnknownExit(Range$2.FromString)(value);
15362
- return effect.Exit.isSuccess(exit) ? effect.Option.some(exit.value) : effect.Option.none();
15363
- };
15364
- const isRange = (value) => effect.Option.isSome(parseRange(value));
15365
- const protocolOf = (value) => {
15366
- if (value.startsWith(CATALOG_PREFIX)) return "catalog";
15367
- if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
15368
- if (value.startsWith("link:")) return "link";
15369
- if (value.startsWith("portal:")) return "portal";
15370
- if (value.startsWith("file:") || isBarePath(value)) return "file";
15371
- if (value.startsWith("npm:")) return "npm";
15372
- if (isGit(value)) return "git";
15373
- if (isUrl$1(value)) return "url";
15374
- if (isRange(value)) return "range";
15375
- if (/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(value)) return "tag";
15376
- return "unknown";
15377
- };
15378
- const isTag = (value) => protocolOf(value) === "tag";
15379
- const catalogNameOf$1 = (specifier) => {
15380
- if (!isCatalog(specifier)) return effect.Option.none();
15381
- const rest = specifier.slice(8).trim();
15382
- return rest.length === 0 ? effect.Option.none() : effect.Option.some(rest);
15383
- };
15384
- const projectRangeModifier = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
15385
- const splitWorkspaceRest = (rest) => {
15386
- const at = rest.lastIndexOf("@");
15387
- return at > 0 ? {
15388
- target: rest.slice(0, at),
15389
- range: rest.slice(at + 1)
15390
- } : {
15391
- target: void 0,
15392
- range: rest
15393
- };
15394
- };
15395
- const projectWorkspaceRange = (rest, version) => {
15396
- const { target, range } = splitWorkspaceRest(rest);
15397
- const projected = projectRangeModifier(range, version);
15398
- return target === void 0 ? projected : `npm:${target}@${projected}`;
15399
- };
15400
- const resolveWorkspace = (specifier, version) => isWorkspace(specifier) ? projectWorkspaceRange(specifier.slice(10), version) : specifier;
15401
- const workspaceTargetOf = (specifier) => {
15402
- if (!isWorkspace(specifier)) return effect.Option.none();
15403
- const { target } = splitWorkspaceRest(specifier.slice(10));
15404
- return target === void 0 ? effect.Option.none() : effect.Option.some(target);
15405
- };
15406
- /**
15407
- * Whether a string is a recognized dependency specifier: a semver range, exact
15408
- * version, dist-tag, URL, git ref, GitHub shorthand, file path, or an
15409
- * `npm:` / `catalog:` / `workspace:` protocol.
15410
- *
15411
- * @public
15412
- */
15413
- const isValidDependencySpecifier = (value) => value.length > 0 && protocolOf(value) !== "unknown";
15414
- /**
15415
- * A `catalog:` reference. `name` carries the catalog name, or `Option.none()`
15416
- * for the default catalog (`catalog:`).
15417
- *
15418
- * @public
15419
- */
15420
- var CatalogSpecifier = class extends effect.Schema.TaggedClass()("catalog", {
15421
- /** The original specifier string. */
15422
- raw: effect.Schema.String,
15423
- /** The catalog name, or `Option.none()` for the default catalog. */
15424
- name: effect.Schema.Option(effect.Schema.String)
15425
- }) {};
15426
- /**
15427
- * A `workspace:` reference. `range` carries the part after `workspace:` — a
15428
- * range modifier (`*`, `^`, `~`), a concrete range, or an alias form.
15429
- *
15430
- * @public
15431
- */
15432
- var WorkspaceSpecifier = class extends effect.Schema.TaggedClass()("workspace", {
15433
- /** The original specifier string. */
15434
- raw: effect.Schema.String,
15435
- /** The part after `workspace:` (e.g. `*`, `^1.2.3`, or an alias form). */
15436
- range: effect.Schema.String
15292
+ /** Which dependency map this entry came from. */
15293
+ kind: DependencyKind,
15294
+ /** For `peer` dependencies, whether the peer is optional (from `peerDependenciesMeta`). */
15295
+ isOptional: effect.Schema.optionalKey(effect.Schema.Boolean)
15437
15296
  }) {
15438
- /**
15439
- * The pnpm publish-time projection of this specifier against a concrete
15440
- * workspace version: `*` (or an empty range) becomes `version`, `~` becomes
15441
- * `~version`, `^` becomes `^version`, and a pinned range passes through
15442
- * unchanged. The alias form (`workspace:<name>@<range>`) becomes pnpm's
15443
- * publish-time aliased dependency `npm:<name>@<projected>`, with the range
15444
- * modifier projected the same way — `version` must then be the TARGET
15445
- * package's version (see `DependencySpecifier.workspaceTargetOf`).
15446
- *
15447
- * @remarks
15448
- * The same projection as `DependencySpecifier.resolveWorkspace`, applied to
15449
- * this instance's already-extracted `range`; the two share one internal
15450
- * implementation.
15451
- *
15452
- * @param version - The concrete version of the workspace package the
15453
- * specifier points at (the alias target's version for the alias form).
15454
- */
15455
- resolve(version) {
15456
- return projectWorkspaceRange(this.range, version);
15297
+ /** The classified protocol, or `None` for an empty specifier. */
15298
+ get protocol() {
15299
+ return this.specifier.length === 0 ? effect.Option.none() : effect.Option.some(DependencySpecifier.protocolOf(this.specifier));
15300
+ }
15301
+ /** Parse the specifier as a semver `Range`, `None` when it is not a range. */
15302
+ get range() {
15303
+ return DependencySpecifier.parseRange(this.specifier);
15304
+ }
15305
+ /** Whether the specifier points to a local path. */
15306
+ get isLocal() {
15307
+ return DependencySpecifier.isLocal(this.specifier);
15308
+ }
15309
+ /** Whether the specifier uses the `link:` protocol. */
15310
+ get isLink() {
15311
+ return DependencySpecifier.isLink(this.specifier);
15312
+ }
15313
+ /** Whether the specifier uses the `portal:` protocol. */
15314
+ get isPortal() {
15315
+ return DependencySpecifier.isPortal(this.specifier);
15316
+ }
15317
+ /** Whether the specifier uses the `catalog:` protocol. */
15318
+ get isCatalog() {
15319
+ return DependencySpecifier.isCatalog(this.specifier);
15320
+ }
15321
+ /** Whether the specifier uses the `workspace:` protocol. */
15322
+ get isWorkspace() {
15323
+ return DependencySpecifier.isWorkspace(this.specifier);
15324
+ }
15325
+ /** Whether the specifier is an unresolved `catalog:` or `workspace:` protocol. */
15326
+ get isUnresolved() {
15327
+ return this.isCatalog || this.isWorkspace;
15328
+ }
15329
+ /** Whether the specifier resolves to a git source. */
15330
+ get isGit() {
15331
+ return DependencySpecifier.isGit(this.specifier);
15332
+ }
15333
+ /** Whether the specifier is a parseable semver range. */
15334
+ get isRange() {
15335
+ return DependencySpecifier.isRange(this.specifier);
15336
+ }
15337
+ /** Whether the specifier is a dist-tag. */
15338
+ get isTag() {
15339
+ return DependencySpecifier.isTag(this.specifier);
15457
15340
  }
15458
15341
  };
15342
+ //#endregion
15343
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/DevEngines.js
15459
15344
  /**
15460
- * A plain semver range or exact version (e.g. `^1.2.3`, `1.x`, `>=1 <2`).
15461
- *
15462
- * @public
15463
- */
15464
- var RangeSpecifier = class extends effect.Schema.TaggedClass()("range", {
15465
- /** The original specifier string. */
15466
- raw: effect.Schema.String }) {};
15467
- /**
15468
- * A bare dist-tag (e.g. `latest`, `next`).
15345
+ * A single `devEngines` constraint with a name and optional `version` / `onFail`.
15469
15346
  *
15470
15347
  * @public
15471
15348
  */
15472
- var DistTagSpecifier = class extends effect.Schema.TaggedClass()("dist-tag", {
15473
- /** The original specifier string (also the tag name). */
15474
- raw: effect.Schema.String }) {};
15349
+ var DevEngine = class extends effect.Schema.Class("DevEngine")({
15350
+ /** The engine name (e.g. `node`, `pnpm`). */
15351
+ name: effect.Schema.String,
15352
+ /** The optional version constraint. */
15353
+ version: effect.Schema.optionalKey(effect.Schema.String),
15354
+ /** The optional behavior when the constraint is unmet. */
15355
+ onFail: effect.Schema.optionalKey(effect.Schema.Literals([
15356
+ "warn",
15357
+ "error",
15358
+ "ignore"
15359
+ ]))
15360
+ }) {};
15475
15361
  /**
15476
- * The honest fallback for `file:` / `link:` / `portal:` / git / URL / `npm:`
15477
- * forms this concept does not further interpret.
15362
+ * A `devEngines` constraint slot: a single {@link DevEngine} or an array of them.
15478
15363
  *
15479
15364
  * @public
15480
15365
  */
15481
- var RawSpecifier = class extends effect.Schema.TaggedClass()("raw", {
15482
- /** The original specifier string. */
15483
- raw: effect.Schema.String }) {};
15484
- const Classified = effect.Schema.Union([
15485
- CatalogSpecifier,
15486
- WorkspaceSpecifier,
15487
- RangeSpecifier,
15488
- DistTagSpecifier,
15489
- RawSpecifier
15490
- ]);
15491
- const classify$1 = (value) => {
15492
- if (isCatalog(value)) return CatalogSpecifier.make({
15493
- raw: value,
15494
- name: catalogNameOf$1(value)
15495
- });
15496
- if (isWorkspace(value)) return WorkspaceSpecifier.make({
15497
- raw: value,
15498
- range: value.slice(10)
15499
- });
15500
- if (isRange(value)) return RangeSpecifier.make({ raw: value });
15501
- if (isTag(value)) return DistTagSpecifier.make({ raw: value });
15502
- return RawSpecifier.make({ raw: value });
15503
- };
15504
- const fromString = effect.Schema.String.pipe(effect.Schema.decodeTo(Classified, effect.SchemaTransformation.transformOrFail({
15505
- decode: (input) => isValidDependencySpecifier(input) ? effect.Effect.succeed(classify$1(input)) : effect.Effect.fail(new effect.SchemaIssue.InvalidValue(effect.Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
15506
- encode: (classified) => effect.Effect.succeed(classified.raw)
15507
- })));
15508
- const brandedSpecifier = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidDependencySpecifier(value) ? void 0 : "Expected a valid dependency specifier")), effect.Schema.brand("DependencySpecifier"));
15509
- const decode$3 = (input) => effect.Schema.decodeUnknownEffect(brandedSpecifier)(input).pipe(effect.Effect.mapError(() => new InvalidDependencySpecifierError({ input })));
15366
+ const DevEngineOrArray = effect.Schema.Union([DevEngine, effect.Schema.Array(DevEngine)]);
15510
15367
  /**
15511
- * A valid dependency version specifier, carrying the protocol taxonomy statics
15512
- * (`DependencySpecifier.protocolOf` and friends) that classify any specifier
15513
- * string, plus the {@link (DependencySpecifier:variable).FromString} codec that
15514
- * decodes a string into a {@link ClassifiedSpecifier} tagged union. Use it as a
15515
- * schema for a specifier field and reach for the statics to inspect a raw
15516
- * string.
15517
- *
15518
- * @public
15519
- */
15520
- const DependencySpecifier = Object.assign(brandedSpecifier, {
15521
- protocolOf,
15522
- parseRange,
15523
- isRange,
15524
- isTag,
15525
- isGit,
15526
- isUrl: isUrl$1,
15527
- isLocal,
15528
- isLink,
15529
- isPortal,
15530
- isCatalog,
15531
- isWorkspace,
15532
- catalogNameOf: catalogNameOf$1,
15533
- resolveWorkspace,
15534
- workspaceTargetOf,
15535
- isValid: isValidDependencySpecifier,
15536
- decode: decode$3,
15537
- FromString: fromString
15538
- });
15539
- //#endregion
15540
- //#region ../../node_modules/.pnpm/@effected+npm@0.8.2_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/IntegrityHash.js
15541
- const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
15542
- const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
15543
- const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
15544
- const isSri = (value) => SRI_RE.test(value);
15545
- const isCorepack = (value) => COREPACK_RE.test(value);
15546
- const isYarnChecksum = (value) => YARN_RE.test(value);
15547
- /**
15548
- * Whether a string is a valid integrity hash in the SRI (`<algo>-<base64>`),
15549
- * corepack (`<algo>.<hex>`) or yarn (`<cachekey>/<hex>`) form.
15550
- *
15551
- * @public
15552
- */
15553
- const isValidIntegrityHash = (value) => isSri(value) || isCorepack(value) || isYarnChecksum(value);
15554
- const algorithmOf = (value) => {
15555
- if (isSri(value)) return effect.Option.some(value.slice(0, value.indexOf("-")));
15556
- if (isCorepack(value)) return effect.Option.some(value.slice(0, value.indexOf(".")));
15557
- return effect.Option.none();
15558
- };
15559
- /**
15560
- * Indicates that a string could not be parsed as a valid integrity hash.
15561
- *
15562
- * Raised by {@link IntegrityHash.decode}. The offending string is preserved on
15563
- * `input`.
15564
- *
15565
- * @public
15566
- */
15567
- var InvalidIntegrityHashError = class extends effect.Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
15568
- /** The raw input string that failed validation. */
15569
- input: effect.Schema.String }) {
15570
- get message() {
15571
- return `Invalid integrity hash "${this.input}": expected an SRI (<algo>-<base64>), corepack (<algo>.<hex>) or yarn (<cachekey>/<hex>) form`;
15572
- }
15573
- };
15574
- const brandedIntegrity = effect.Schema.String.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isValidIntegrityHash(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), effect.Schema.brand("IntegrityHash"));
15575
- const decode$2 = (input) => effect.Schema.decodeUnknownEffect(brandedIntegrity)(input).pipe(effect.Effect.mapError(() => new InvalidIntegrityHashError({ input })));
15576
- Object.assign(brandedIntegrity, {
15577
- isSri,
15578
- isCorepack,
15579
- isYarnChecksum,
15580
- isValid: isValidIntegrityHash,
15581
- algorithmOf,
15582
- decode: decode$2
15583
- });
15584
- /**
15585
- * {@link (IntegrityHash:variable)} narrowed to the corepack `<algo>.<hex>` form
15586
- * — `sha512.deadbeef`, and corepack's own sha224 default pins
15587
- * (`sha224.877304e3…`). An SRI (`sha512-<base64>`) or yarn (`10c0/<hex>`)
15588
- * hash, both valid `IntegrityHash` values, fails this schema.
15589
- *
15590
- * @remarks
15591
- * The corepack pin tail (`<name>@<version>+<integrity>`) is the one place the
15592
- * kit meets this form, and two schemas name it: `PackageManagerPin.integrity`
15593
- * here and `@effected/package-json`'s `PackageManager.integrity`. Both consume
15594
- * **this** schema — the restriction existed privately in each module until they
15595
- * were consolidated, and a private copy is exactly how the two drift (the
15596
- * widening that admitted sha224 had to be made twice).
15597
- *
15598
- * It decodes to the same {@link IntegrityHashBrand} the unrestricted schema
15599
- * does, so a corepack-validated value assigns anywhere an `IntegrityHash` is
15600
- * expected; there is no second brand. Reach for
15601
- * `IntegrityHash.isCorepack(value)` to ask the same question about a raw
15602
- * string without decoding.
15603
- *
15604
- * That single brand is also why sharing this schema is not type-enforced, and
15605
- * the consequence is sharper than it looks: a `Schema.check` is **erased from
15606
- * the built type**, so this schema and the unrestricted one are the same
15607
- * declared type. A consumer that quietly reverts to a private copy compiles
15608
- * clean, and — if the copy is faithful — passes every rejection test too.
15609
- * Neither `tsc` nor behaviour can see the re-fork.
15610
- *
15611
- * What does see it is **object identity**, so each consumer's suite asserts
15612
- * that its field schema IS this export:
15613
- * `PackageManagerPin.fields.integrity.schema === CorepackIntegrityHash` (an
15614
- * `optionalKey` field keeps the inner schema on `.schema`), and
15615
- * `PackageManager.fields.integrity.value === CorepackIntegrityHash` on the
15616
- * `@effected/package-json` side (a `Schema.Option` keeps it on `.value`). Both
15617
- * assertions carry a control against the unrestricted brand, so they discriminate
15618
- * rather than passing on any schema at all. That identity assertion is the only
15619
- * thing standing between the two surfaces and a silent re-fork; do not replace
15620
- * it with a behavioural test, which cannot fail.
15621
- *
15622
- * @example
15623
- * ```ts
15624
- * import { CorepackIntegrityHash } from "@effected/npm";
15625
- * import { Schema } from "effect";
15626
- *
15627
- * const decode = Schema.decodeUnknownExit(CorepackIntegrityHash);
15628
- *
15629
- * decode("sha512.deadbeef"); // success
15630
- * decode("sha512-3q2+7w=="); // failure — SRI form
15631
- * ```
15632
- *
15633
- * @public
15634
- */
15635
- const CorepackIntegrityHash = brandedIntegrity.pipe(effect.Schema.check(effect.Schema.makeFilter((value) => isCorepack(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
15636
- //#endregion
15637
- //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
15638
- /**
15639
- * A resolved dependency entry pairing a package name with its version
15640
- * specifier and the `kind` of map it came from (`@effected/npm`'s
15641
- * `DependencyKind`). The protocol predicates delegate to `DependencySpecifier`.
15642
- *
15643
- * @public
15644
- */
15645
- var Dependency = class extends effect.Schema.Class("Dependency")({
15646
- /** The package name. */
15647
- name: effect.Schema.String,
15648
- /** The raw version specifier. */
15649
- specifier: effect.Schema.String,
15650
- /** Which dependency map this entry came from. */
15651
- kind: DependencyKind,
15652
- /** For `peer` dependencies, whether the peer is optional (from `peerDependenciesMeta`). */
15653
- isOptional: effect.Schema.optionalKey(effect.Schema.Boolean)
15654
- }) {
15655
- /** The classified protocol, or `None` for an empty specifier. */
15656
- get protocol() {
15657
- return this.specifier.length === 0 ? effect.Option.none() : effect.Option.some(DependencySpecifier.protocolOf(this.specifier));
15658
- }
15659
- /** Parse the specifier as a semver `Range`, `None` when it is not a range. */
15660
- get range() {
15661
- return DependencySpecifier.parseRange(this.specifier);
15662
- }
15663
- /** Whether the specifier points to a local path. */
15664
- get isLocal() {
15665
- return DependencySpecifier.isLocal(this.specifier);
15666
- }
15667
- /** Whether the specifier uses the `link:` protocol. */
15668
- get isLink() {
15669
- return DependencySpecifier.isLink(this.specifier);
15670
- }
15671
- /** Whether the specifier uses the `portal:` protocol. */
15672
- get isPortal() {
15673
- return DependencySpecifier.isPortal(this.specifier);
15674
- }
15675
- /** Whether the specifier uses the `catalog:` protocol. */
15676
- get isCatalog() {
15677
- return DependencySpecifier.isCatalog(this.specifier);
15678
- }
15679
- /** Whether the specifier uses the `workspace:` protocol. */
15680
- get isWorkspace() {
15681
- return DependencySpecifier.isWorkspace(this.specifier);
15682
- }
15683
- /** Whether the specifier is an unresolved `catalog:` or `workspace:` protocol. */
15684
- get isUnresolved() {
15685
- return this.isCatalog || this.isWorkspace;
15686
- }
15687
- /** Whether the specifier resolves to a git source. */
15688
- get isGit() {
15689
- return DependencySpecifier.isGit(this.specifier);
15690
- }
15691
- /** Whether the specifier is a parseable semver range. */
15692
- get isRange() {
15693
- return DependencySpecifier.isRange(this.specifier);
15694
- }
15695
- /** Whether the specifier is a dist-tag. */
15696
- get isTag() {
15697
- return DependencySpecifier.isTag(this.specifier);
15698
- }
15699
- };
15700
- //#endregion
15701
- //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/DevEngines.js
15702
- /**
15703
- * A single `devEngines` constraint with a name and optional `version` / `onFail`.
15704
- *
15705
- * @public
15706
- */
15707
- var DevEngine = class extends effect.Schema.Class("DevEngine")({
15708
- /** The engine name (e.g. `node`, `pnpm`). */
15709
- name: effect.Schema.String,
15710
- /** The optional version constraint. */
15711
- version: effect.Schema.optionalKey(effect.Schema.String),
15712
- /** The optional behavior when the constraint is unmet. */
15713
- onFail: effect.Schema.optionalKey(effect.Schema.Literals([
15714
- "warn",
15715
- "error",
15716
- "ignore"
15717
- ]))
15718
- }) {};
15719
- /**
15720
- * A `devEngines` constraint slot: a single {@link DevEngine} or an array of them.
15721
- *
15722
- * @public
15723
- */
15724
- const DevEngineOrArray = effect.Schema.Union([DevEngine, effect.Schema.Array(DevEngine)]);
15725
- /**
15726
- * The `devEngines` field schema, modeling runtime and package-manager
15727
- * constraints as optional {@link DevEngine} slots.
15368
+ * The `devEngines` field schema, modeling runtime and package-manager
15369
+ * constraints as optional {@link DevEngine} slots.
15728
15370
  *
15729
15371
  * @public
15730
15372
  */
@@ -18317,7 +17959,7 @@ var Package = class Package extends effect.Schema.Class("Package")({
18317
17959
  }
18318
17960
  };
18319
17961
  //#endregion
18320
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
17962
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/WorkspacePackage.js
18321
17963
  const EMPTY$1 = Object.freeze(Object.create(null));
18322
17964
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
18323
17965
  /**
@@ -18915,7 +18557,7 @@ var Walker$1 = class {
18915
18557
  static findRoot = findRoot$1;
18916
18558
  };
18917
18559
  //#endregion
18918
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
18560
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/WorkspaceRoot.js
18919
18561
  /**
18920
18562
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
18921
18563
  *
@@ -19102,7 +18744,7 @@ var WorkspaceRoot = class WorkspaceRoot extends effect.Context.Service()("@effec
19102
18744
  static layerTest = (root) => effect.Layer.effect(WorkspaceRoot, WorkspaceRoot.makeTest(root)).pipe(effect.Layer.provide(effect.Path.layer));
19103
18745
  };
19104
18746
  //#endregion
19105
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
18747
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/internal/limits.js
19106
18748
  /**
19107
18749
  * Hard ceiling on directories the enumerator will visit for one pattern set.
19108
18750
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -19120,7 +18762,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
19120
18762
  */
19121
18763
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
19122
18764
  //#endregion
19123
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
18765
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/internal/traverse.js
19124
18766
  /** Directory names never descended into. */
19125
18767
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
19126
18768
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -19210,7 +18852,7 @@ var Traversal = class {
19210
18852
  }
19211
18853
  };
19212
18854
  //#endregion
19213
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
18855
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/internal/enumerate.js
19214
18856
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
19215
18857
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
19216
18858
  /**
@@ -19280,7 +18922,7 @@ const enumerate = (root, globs, options) => effect.Effect.gen(function* () {
19280
18922
  return results;
19281
18923
  });
19282
18924
  //#endregion
19283
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
18925
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/internal/patterns.js
19284
18926
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
19285
18927
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
19286
18928
  const pnpmPatternsOf = (document) => {
@@ -19337,7 +18979,7 @@ const readPatterns = (root) => effect.Effect.gen(function* () {
19337
18979
  return manifestPatternsOf(manifest);
19338
18980
  });
19339
18981
  //#endregion
19340
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
18982
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/WorkspaceDiscovery.js
19341
18983
  /**
19342
18984
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
19343
18985
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -19774,7 +19416,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
19774
19416
  * // `Package.resolve` now resolves `workspace:*` for real.
19775
19417
  * ```
19776
19418
  */
19777
- static workspaceResolver = effect.Layer.effect(WorkspaceResolver$1, effect.Effect.gen(function* () {
19419
+ static workspaceResolver = effect.Layer.effect(WorkspaceResolver, effect.Effect.gen(function* () {
19778
19420
  const discovery = yield* WorkspaceDiscovery;
19779
19421
  const versionIndexes = /* @__PURE__ */ new WeakMap();
19780
19422
  const versionsByName = (all) => {
@@ -19785,7 +19427,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
19785
19427
  versionIndexes.set(all, index);
19786
19428
  return index;
19787
19429
  };
19788
- return { versionOf: (packageName) => discovery.listPackages().pipe(effect.Effect.map((all) => effect.Option.fromUndefinedOr(versionsByName(all).get(packageName))), effect.Effect.mapError((cause) => new DependencyResolutionError$1({
19430
+ return { versionOf: (packageName) => discovery.listPackages().pipe(effect.Effect.map((all) => effect.Option.fromUndefinedOr(versionsByName(all).get(packageName))), effect.Effect.mapError((cause) => new DependencyResolutionError({
19789
19431
  specifier: `workspace:${packageName}`,
19790
19432
  cause
19791
19433
  }))) };
@@ -19793,7 +19435,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
19793
19435
  };
19794
19436
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
19795
19437
  //#endregion
19796
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
19438
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/DependencyGraph.js
19797
19439
  /**
19798
19440
  * Raised when the workspace dependency graph cannot be topologically ordered
19799
19441
  * because it contains a cycle.
@@ -20026,10 +19668,32 @@ const kahn = (edges) => {
20026
19668
  };
20027
19669
  };
20028
19670
  //#endregion
20029
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
19671
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
19672
+ /** The mask every whole-value sensitive positional is replaced with. */
19673
+ const REDACTED = "<redacted>";
19674
+ const secretValue = (value) => ({
19675
+ redact: "value",
19676
+ value
19677
+ });
19678
+ const secretUrl = (value) => ({
19679
+ redact: "url",
19680
+ value
19681
+ });
20030
19682
  /**
20031
- * Builds a `git` `ChildProcess.StandardCommand` with the argv this package
20032
- * classifies against.
19683
+ * Masks the userinfo component of a URL (`scheme://user:token@host/...`
19684
+ * `scheme://<redacted>@host/...`). A value carrying no embedded userinfo — a
19685
+ * remote name, a credential-free URL, an scp-style `host:path` — passes
19686
+ * through untouched, so the common case stays fully debuggable.
19687
+ *
19688
+ * The userinfo match is greedy (`[^/]*@` — everything through the LAST `@`
19689
+ * before the first path slash): URL authorities split at the last `@`, so a
19690
+ * password containing a literal `@` (`user:p\@ss\@host/...`) must be
19691
+ * consumed whole or its tail would survive into `redactedArgs`.
19692
+ */
19693
+ const redactUrlUserinfo = (value) => value.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/]*@/i, `$1${REDACTED}@`);
19694
+ /**
19695
+ * Builds a `git` {@link GitInvocation} with the argv this package classifies
19696
+ * against.
20033
19697
  *
20034
19698
  * @remarks
20035
19699
  * `LC_ALL=C` is pinned on every invocation because git's stderr
@@ -20045,10 +19709,18 @@ const kahn = (edges) => {
20045
19709
  * the working directory per invocation via `ChildProcess.setCwd`, which
20046
19710
  * returns a new command and leaves this one unchanged.
20047
19711
  */
20048
- const git = (args) => effect_unstable_process.ChildProcess.make("git", args, {
20049
- env: { LC_ALL: "C" },
20050
- extendEnv: true
20051
- });
19712
+ const git = (args, stdin) => {
19713
+ const raw = args.map((arg) => typeof arg === "string" ? arg : arg.value);
19714
+ const redactedArgs = args.map((arg) => typeof arg === "string" ? arg : arg.redact === "value" ? REDACTED : redactUrlUserinfo(arg.value));
19715
+ return {
19716
+ command: effect_unstable_process.ChildProcess.make("git", raw, {
19717
+ env: { LC_ALL: "C" },
19718
+ extendEnv: true,
19719
+ ...stdin !== void 0 ? { stdin: effect.Stream.make(new TextEncoder().encode(stdin)) } : {}
19720
+ }),
19721
+ redactedArgs
19722
+ };
19723
+ };
20052
19724
  const show = (ref, path) => git(["show", `${ref}:${path}`]);
20053
19725
  const lsTree = (ref, pathspec = []) => git([
20054
19726
  "ls-tree",
@@ -20107,7 +19779,7 @@ const checkout = (ref, detach = false) => git([
20107
19779
  const fetch$1 = (remote, ref, depth, tag = false) => git([
20108
19780
  "fetch",
20109
19781
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
20110
- remote,
19782
+ secretUrl(remote),
20111
19783
  ...tag ? ["tag"] : [],
20112
19784
  ref
20113
19785
  ]);
@@ -20123,7 +19795,7 @@ const submoduleAdd = (url, path, depth) => git([
20123
19795
  "add",
20124
19796
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
20125
19797
  "--",
20126
- url,
19798
+ secretUrl(url),
20127
19799
  path
20128
19800
  ]);
20129
19801
  const sparseCheckoutSet = (patterns, cone) => git([
@@ -20136,13 +19808,55 @@ const configSet = (key, value, file) => git([
20136
19808
  "config",
20137
19809
  ...file !== void 0 ? ["-f", file] : [],
20138
19810
  key,
20139
- value
19811
+ secretValue(value)
20140
19812
  ]);
20141
19813
  const add = (paths) => git([
20142
19814
  "add",
20143
19815
  "--",
20144
19816
  ...paths
20145
19817
  ]);
19818
+ const reset = (mode = "mixed", ref) => git([
19819
+ "reset",
19820
+ `--${mode}`,
19821
+ ...ref !== void 0 ? [ref] : []
19822
+ ]);
19823
+ const clean = (directories = false, ignored = false, paths = []) => git([
19824
+ "clean",
19825
+ "--force",
19826
+ ...directories ? ["-d"] : [],
19827
+ ...ignored ? ["-x"] : [],
19828
+ ...paths.length > 0 ? ["--", ...paths] : []
19829
+ ]);
19830
+ const restore = (paths, source, staged = false, worktree = false) => git([
19831
+ "restore",
19832
+ ...source !== void 0 ? ["--source", source] : [],
19833
+ ...staged ? ["--staged"] : [],
19834
+ ...worktree ? ["--worktree"] : [],
19835
+ "--",
19836
+ ...paths
19837
+ ]);
19838
+ const branchCreate = (name, startPoint, checkout = false, force = false) => checkout ? git([
19839
+ "checkout",
19840
+ force ? "-B" : "-b",
19841
+ name,
19842
+ ...startPoint !== void 0 ? [startPoint] : []
19843
+ ]) : git([
19844
+ "branch",
19845
+ ...force ? ["-f"] : [],
19846
+ name,
19847
+ ...startPoint !== void 0 ? [startPoint] : []
19848
+ ]);
19849
+ const branchDelete = (name, force = false) => git([
19850
+ "branch",
19851
+ force ? "-D" : "-d",
19852
+ name
19853
+ ]);
19854
+ const isShallow = () => git(["rev-parse", "--is-shallow-repository"]);
19855
+ const fetchUnshallow = (remote = "origin") => git([
19856
+ "fetch",
19857
+ "--unshallow",
19858
+ secretUrl(remote)
19859
+ ]);
20146
19860
  const nameStatus = (base, head, relative = false) => git([
20147
19861
  "diff",
20148
19862
  "--name-status",
@@ -20183,37 +19897,273 @@ const status = () => git([
20183
19897
  "--porcelain",
20184
19898
  "-z"
20185
19899
  ]);
20186
- /**
20187
- * Pure constructors for the `git` `ChildProcess.Command` values this package
20188
- * spawns.
20189
- *
20190
- * @remarks
20191
- * Every constructor returns a cwd-less, argv-only `Command` — no spawning,
20192
- * no working directory baked in. `Git` applies the working directory per
20193
- * call with `ChildProcess.setCwd` and owns the actual spawn, timeout, and
20194
- * error classification.
20195
- *
20196
- * @public
20197
- */
20198
- var GitCommand = class {
20199
- constructor() {}
20200
- /**
20201
- * `git show <ref>:<path>` the contents of `path` as it existed at `ref`,
20202
- * without checking anything out.
20203
- */
20204
- static show = show;
20205
- /**
20206
- * `git ls-tree -r -z <ref> [-- <pathspec>...]` every path in the tree at
20207
- * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
20208
- *
20209
- * @remarks
20210
- * `-z` is load-bearing: git paths may themselves contain newlines, so the
20211
- * caller must split on `"\0"`, never on `"\n"`. When `pathspec` is provided,
20212
- * a literal `--` separator is inserted before the pathspec entries to prevent
20213
- * git from interpreting pathspec values as options.
20214
- */
20215
- static lsTree = lsTree;
20216
- /**
19900
+ const submoduleStatus = (paths = [], recursive = false) => git([
19901
+ "submodule",
19902
+ "status",
19903
+ ...recursive ? ["--recursive"] : [],
19904
+ ...paths.length > 0 ? ["--", ...paths] : []
19905
+ ]);
19906
+ const submoduleInit = (paths = []) => git([
19907
+ "submodule",
19908
+ "init",
19909
+ ...paths.length > 0 ? ["--", ...paths] : []
19910
+ ]);
19911
+ const submoduleDeinit = (paths, all = false, force = false) => git([
19912
+ "submodule",
19913
+ "deinit",
19914
+ ...force ? ["--force"] : [],
19915
+ ...all ? ["--all"] : ["--", ...paths]
19916
+ ]);
19917
+ const submoduleSync = (paths = [], recursive = false) => git([
19918
+ "submodule",
19919
+ "sync",
19920
+ ...recursive ? ["--recursive"] : [],
19921
+ ...paths.length > 0 ? ["--", ...paths] : []
19922
+ ]);
19923
+ const submoduleSetUrl = (path, url) => git([
19924
+ "submodule",
19925
+ "set-url",
19926
+ "--",
19927
+ path,
19928
+ secretUrl(url)
19929
+ ]);
19930
+ const submoduleSetBranch = (path, branch) => git([
19931
+ "submodule",
19932
+ "set-branch",
19933
+ ...branch === void 0 ? ["--default"] : ["--branch", branch],
19934
+ "--",
19935
+ path
19936
+ ]);
19937
+ const submoduleAbsorbgitdirs = (paths = []) => git([
19938
+ "submodule",
19939
+ "absorbgitdirs",
19940
+ ...paths.length > 0 ? ["--", ...paths] : []
19941
+ ]);
19942
+ const submoduleForeach = (command, recursive = false) => git([
19943
+ "submodule",
19944
+ "foreach",
19945
+ ...recursive ? ["--recursive"] : [],
19946
+ command
19947
+ ]);
19948
+ const lsRemote = (remote, heads = false, tags = false, patterns = []) => git([
19949
+ "ls-remote",
19950
+ ...heads ? ["--heads"] : [],
19951
+ ...tags ? ["--tags"] : [],
19952
+ secretUrl(remote),
19953
+ ...patterns
19954
+ ]);
19955
+ const remoteAdd = (name, url) => git([
19956
+ "remote",
19957
+ "add",
19958
+ name,
19959
+ secretUrl(url)
19960
+ ]);
19961
+ const remoteRemove = (name) => git([
19962
+ "remote",
19963
+ "remove",
19964
+ name
19965
+ ]);
19966
+ const remoteSetUrl = (name, url) => git([
19967
+ "remote",
19968
+ "set-url",
19969
+ name,
19970
+ secretUrl(url)
19971
+ ]);
19972
+ const stashRef = (index) => `stash@{${index}}`;
19973
+ const stashPush = (message, includeUntracked = false, paths = []) => git([
19974
+ "stash",
19975
+ "push",
19976
+ ...includeUntracked ? ["--include-untracked"] : [],
19977
+ ...message !== void 0 ? ["-m", message] : [],
19978
+ ...paths.length > 0 ? ["--", ...paths] : []
19979
+ ]);
19980
+ const stashPop = (index) => git([
19981
+ "stash",
19982
+ "pop",
19983
+ ...index !== void 0 ? [stashRef(index)] : []
19984
+ ]);
19985
+ const stashApply = (index) => git([
19986
+ "stash",
19987
+ "apply",
19988
+ ...index !== void 0 ? [stashRef(index)] : []
19989
+ ]);
19990
+ const stashDrop = (index) => git([
19991
+ "stash",
19992
+ "drop",
19993
+ ...index !== void 0 ? [stashRef(index)] : []
19994
+ ]);
19995
+ const stashList = () => git([
19996
+ "stash",
19997
+ "list",
19998
+ "-z",
19999
+ "--format=%gd%x1f%H%x1f%gs"
20000
+ ]);
20001
+ const branchList = (remotes = false, all = false) => git([
20002
+ "branch",
20003
+ "--list",
20004
+ ...all ? ["--all"] : remotes ? ["--remotes"] : [],
20005
+ "--format=%(HEAD)%00%(refname:short)%00%(objectname)"
20006
+ ]);
20007
+ const tagCreate = (name, ref, message, force = false) => git([
20008
+ "tag",
20009
+ ...force ? ["--force"] : [],
20010
+ ...message !== void 0 ? ["-m", message] : [],
20011
+ name,
20012
+ ...ref !== void 0 ? [ref] : []
20013
+ ]);
20014
+ const tagDelete = (name) => git([
20015
+ "tag",
20016
+ "--delete",
20017
+ name
20018
+ ]);
20019
+ const tagList = (pattern) => git([
20020
+ "tag",
20021
+ "--list",
20022
+ ...pattern !== void 0 ? [pattern] : []
20023
+ ]);
20024
+ const forEachRef = (patterns = []) => git([
20025
+ "for-each-ref",
20026
+ "--format=%(refname)%00%(objectname)%00%(objecttype)",
20027
+ ...patterns
20028
+ ]);
20029
+ const revList = (ref, limit, firstParent = false) => git([
20030
+ "rev-list",
20031
+ ...limit !== void 0 ? [`--max-count=${limit}`] : [],
20032
+ ...firstParent ? ["--first-parent"] : [],
20033
+ ref
20034
+ ]);
20035
+ const commit = (message, all = false, allowEmpty = false, amend = false, author) => git([
20036
+ "commit",
20037
+ ...all ? ["--all"] : [],
20038
+ ...allowEmpty ? ["--allow-empty"] : [],
20039
+ ...amend ? ["--amend"] : [],
20040
+ ...author !== void 0 ? [`--author=${author}`] : [],
20041
+ "-m",
20042
+ message
20043
+ ]);
20044
+ const push$1 = (remote, refspec, force = false, forceWithLease = false, tags = false, setUpstream = false) => git([
20045
+ "push",
20046
+ ...force ? ["--force"] : [],
20047
+ ...forceWithLease ? ["--force-with-lease"] : [],
20048
+ ...tags ? ["--tags"] : [],
20049
+ ...setUpstream ? ["--set-upstream"] : [],
20050
+ secretUrl(remote),
20051
+ ...refspec !== void 0 ? [refspec] : []
20052
+ ]);
20053
+ const pull = (remote, ref, rebase = false, ffOnly = false) => git([
20054
+ "pull",
20055
+ ...rebase ? ["--rebase"] : [],
20056
+ ...ffOnly ? ["--ff-only"] : [],
20057
+ secretUrl(remote),
20058
+ ...ref !== void 0 ? [ref] : []
20059
+ ]);
20060
+ const configList = (file) => git([
20061
+ "config",
20062
+ ...file !== void 0 ? ["-f", file] : [],
20063
+ "--list",
20064
+ "-z"
20065
+ ]);
20066
+ const configGetAll = (key, file) => git([
20067
+ "config",
20068
+ ...file !== void 0 ? ["-f", file] : [],
20069
+ "--get-all",
20070
+ "-z",
20071
+ key
20072
+ ]);
20073
+ const configUnset = (key, file, all = false) => git([
20074
+ "config",
20075
+ ...file !== void 0 ? ["-f", file] : [],
20076
+ all ? "--unset-all" : "--unset",
20077
+ key
20078
+ ]);
20079
+ const rm = (paths, cached = false, recursive = false, force = false) => git([
20080
+ "rm",
20081
+ ...cached ? ["--cached"] : [],
20082
+ ...recursive ? ["-r"] : [],
20083
+ ...force ? ["--force"] : [],
20084
+ "--",
20085
+ ...paths
20086
+ ]);
20087
+ const mv = (source, destination, force = false) => git([
20088
+ "mv",
20089
+ ...force ? ["--force"] : [],
20090
+ "--",
20091
+ source,
20092
+ destination
20093
+ ]);
20094
+ const checkIgnore = (paths) => git([
20095
+ "check-ignore",
20096
+ "-z",
20097
+ "--stdin"
20098
+ ], paths.map((path) => `${path}\0`).join(""));
20099
+ const worktreeAdd = (path, ref, detach = false, force = false) => git([
20100
+ "worktree",
20101
+ "add",
20102
+ ...force ? ["--force"] : [],
20103
+ ...detach ? ["--detach"] : [],
20104
+ path,
20105
+ ...ref !== void 0 ? [ref] : []
20106
+ ]);
20107
+ const worktreeList = () => git([
20108
+ "worktree",
20109
+ "list",
20110
+ "--porcelain",
20111
+ "-z"
20112
+ ]);
20113
+ const worktreeRemove = (path, force = false) => git([
20114
+ "worktree",
20115
+ "remove",
20116
+ ...force ? ["--force"] : [],
20117
+ path
20118
+ ]);
20119
+ const lsFiles = (pathspec = []) => git([
20120
+ "ls-files",
20121
+ "--stage",
20122
+ "-z",
20123
+ ...pathspec.length > 0 ? ["--", ...pathspec] : []
20124
+ ]);
20125
+ /**
20126
+ * Pure constructors for the `git` {@link GitInvocation} values this package
20127
+ * spawns.
20128
+ *
20129
+ * @remarks
20130
+ * Every constructor returns a cwd-less, argv-only {@link GitInvocation} — no
20131
+ * spawning, no working directory baked in. `Git` applies the working
20132
+ * directory per call with `ChildProcess.setCwd` on `invocation.command` and
20133
+ * owns the actual spawn, timeout, and error classification.
20134
+ *
20135
+ * **Redaction policy.** A constructor whose argv carries a sensitive
20136
+ * positional — a config value (`configSet`), or a URL that may embed
20137
+ * userinfo (the remote of `fetch`, `fetchUnshallow`, `lsRemote`, `push` and
20138
+ * `pull`, and the url of `submoduleAdd`, `submoduleSetUrl`, `remoteAdd` and
20139
+ * `remoteSetUrl`) —
20140
+ * masks it in {@link GitInvocation.redactedArgs}: a config value becomes
20141
+ * `<redacted>` wholesale, a URL keeps everything but its `userinfo@`
20142
+ * component. The `Git` service persists only the redacted argv in error
20143
+ * values, and its span annotations carry stable identifiers only (`cwd`,
20144
+ * keys, paths, remote/ref names) — never config values, never URLs.
20145
+ *
20146
+ * @public
20147
+ */
20148
+ var GitCommand = class {
20149
+ constructor() {}
20150
+ /**
20151
+ * `git show <ref>:<path>` — the contents of `path` as it existed at `ref`,
20152
+ * without checking anything out.
20153
+ */
20154
+ static show = show;
20155
+ /**
20156
+ * `git ls-tree -r -z <ref> [-- <pathspec>...]` — every path in the tree at
20157
+ * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
20158
+ *
20159
+ * @remarks
20160
+ * `-z` is load-bearing: git paths may themselves contain newlines, so the
20161
+ * caller must split on `"\0"`, never on `"\n"`. When `pathspec` is provided,
20162
+ * a literal `--` separator is inserted before the pathspec entries to prevent
20163
+ * git from interpreting pathspec values as options.
20164
+ */
20165
+ static lsTree = lsTree;
20166
+ /**
20217
20167
  * `git cat-file -e <ref>` — checks whether `ref` resolves to an existing
20218
20168
  * object, without printing it. A non-zero exit means the ref does not exist.
20219
20169
  */
@@ -20289,9 +20239,106 @@ var GitCommand = class {
20289
20239
  /**
20290
20240
  * Mutating: `git fetch [--depth <n>] <remote> [tag] <ref>` — fetches the given
20291
20241
  * ref from a remote, optionally with a depth limit and the `tag` keyword.
20242
+ *
20243
+ * @remarks
20244
+ * `remote` may be a URL as well as a remote name; an embedded
20245
+ * `userinfo@` credential is masked in {@link GitInvocation.redactedArgs}.
20292
20246
  */
20293
20247
  static fetch = fetch$1;
20294
20248
  /**
20249
+ * Mutating: `git fetch --unshallow <remote>` — converts a shallow clone
20250
+ * into a complete one by fetching the missing history.
20251
+ *
20252
+ * @remarks
20253
+ * `--unshallow` is a distinct MODE, not a depth value: git rejects it
20254
+ * outright in a repository that is not shallow, with
20255
+ * `--unshallow on a complete repository does not make sense`, so it
20256
+ * cannot be expressed as `fetch`'s `depth` option. The caller decides
20257
+ * whether to run it — probe with `Git.isShallow` first.
20258
+ *
20259
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20260
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20261
+ */
20262
+ static fetchUnshallow = fetchUnshallow;
20263
+ /**
20264
+ * `git rev-parse --is-shallow-repository` — prints `true` when the
20265
+ * repository is a shallow clone, `false` otherwise.
20266
+ *
20267
+ * @remarks
20268
+ * A dedicated probe constructor, deliberately separate from
20269
+ * {@link GitCommand.revParse}: `revParse` takes a REF and resolves it,
20270
+ * while this takes nothing and answers a repository-shape question.
20271
+ * Folding the flag into `revParse` would make that constructor
20272
+ * sometimes-takes-a-ref, sometimes-takes-a-flag.
20273
+ */
20274
+ static isShallow = isShallow;
20275
+ /**
20276
+ * Mutating: `git reset --soft|--mixed|--hard [<ref>]` — moves `HEAD` (and,
20277
+ * per mode, the index and working tree) to `ref`.
20278
+ *
20279
+ * @remarks
20280
+ * The mode flag is always explicit — `--mixed` is emitted for the default
20281
+ * rather than omitted — so the argv states what runs. `ref` may be any
20282
+ * commit-ish, including a gitlink sha.
20283
+ */
20284
+ static reset = reset;
20285
+ /**
20286
+ * Mutating: `git clean --force [-d] [-x] [-- <paths>...]` — deletes
20287
+ * untracked files from the working tree.
20288
+ *
20289
+ * @remarks
20290
+ * `--force` is unconditional: this constructor exists so a consumer can
20291
+ * restore a tree to a known state (e.g. before retrying a non-idempotent
20292
+ * operation), and without `--force` git refuses to clean at all under the
20293
+ * default `clean.requireForce` config — a clean that silently did nothing
20294
+ * would hand the retry the same dirty tree. `-d` removes untracked
20295
+ * directories too; `-x` removes ignored files as well. The literal `--`
20296
+ * separator makes the optional pathspec injection-safe by construction.
20297
+ */
20298
+ static clean = clean;
20299
+ /**
20300
+ * Mutating: `git restore [--source <ref>] [--staged] [--worktree] -- <paths...>`
20301
+ * — restores the given paths from the index (or from `source`), the
20302
+ * `checkout -- <paths>`-shaped operation.
20303
+ *
20304
+ * @remarks
20305
+ * This is a separate constructor precisely because {@link GitCommand.checkout}'s
20306
+ * service guard refuses `--` and option-like refs by design — `restore` is
20307
+ * git's own verb for pathspec restoration, and its paths always sit behind
20308
+ * a literal `--`, so they are injection-safe by construction. With neither
20309
+ * `staged` nor `worktree` set, git defaults to restoring the working tree.
20310
+ */
20311
+ static restore = restore;
20312
+ /**
20313
+ * Mutating: `git branch [-f] <name> [<start-point>]`, or
20314
+ * `git checkout (-b | -B) <name> [<start-point>]` when `checkout` is true —
20315
+ * creates a branch, optionally from an explicit start point, optionally
20316
+ * switching to it, optionally force-resetting an existing branch.
20317
+ *
20318
+ * @remarks
20319
+ * Branch creation is a branch-member concern, NOT a widening of
20320
+ * {@link GitCommand.checkout}: `checkout`'s contract stays "move to an
20321
+ * existing ref" and its option-like-ref refusal stays intact. The `-b` /
20322
+ * `-B` here is this constructor's own literal, never caller data.
20323
+ *
20324
+ * `force` with `checkout` exists because the delete-then-create longhand
20325
+ * (`branch -D` swallowed, then `checkout -b`) papers over a real edge:
20326
+ * `git branch -D` refuses to delete the currently checked-out branch,
20327
+ * while `checkout -B` resets it fine — one invocation handles both
20328
+ * states.
20329
+ */
20330
+ static branchCreate = branchCreate;
20331
+ /**
20332
+ * Mutating: `git branch -d <name>` (or `-D` when `force` is true) —
20333
+ * deletes a local branch.
20334
+ *
20335
+ * @remarks
20336
+ * The default `-d` refuses to delete a branch not fully merged — a typed
20337
+ * failure, which is usually the honest answer. `force: true` emits `-D`
20338
+ * and deletes regardless.
20339
+ */
20340
+ static branchDelete = branchDelete;
20341
+ /**
20295
20342
  * Mutating: `git submodule update [--init] [--depth <n>] [-- <paths>...]` — updates
20296
20343
  * registered submodules, optionally initializing them, with an optional depth limit,
20297
20344
  * and scoped to specific paths. The literal `--` separator makes the pathspec
@@ -20302,6 +20349,10 @@ var GitCommand = class {
20302
20349
  * Mutating: `git submodule add [--depth <n>] -- <url> <path>` — registers and
20303
20350
  * initializes a new submodule. The literal `--` separator makes the url and path
20304
20351
  * injection-safe by construction.
20352
+ *
20353
+ * @remarks
20354
+ * An embedded `userinfo@` credential in `url` is masked in
20355
+ * {@link GitInvocation.redactedArgs}.
20305
20356
  */
20306
20357
  static submoduleAdd = submoduleAdd;
20307
20358
  /**
@@ -20314,6 +20365,13 @@ var GitCommand = class {
20314
20365
  /**
20315
20366
  * Mutating: `git config [-f <file>] <key> <value>` — writes a configuration value,
20316
20367
  * optionally into an explicit configuration file (e.g., `.gitmodules`).
20368
+ *
20369
+ * @remarks
20370
+ * `value` may be a secret (a token, a credential-bearing URL), so it is
20371
+ * masked wholesale — as `<redacted>` — in
20372
+ * {@link GitInvocation.redactedArgs}. The key and file stay visible: they
20373
+ * are stable identifiers, and they are what a caller debugging a failed
20374
+ * write actually needs.
20317
20375
  */
20318
20376
  static configSet = configSet;
20319
20377
  /**
@@ -20396,9 +20454,304 @@ var GitCommand = class {
20396
20454
  * Each entry is a pair of status codes followed by a space and the path.
20397
20455
  */
20398
20456
  static status = status;
20457
+ /**
20458
+ * `git submodule status [--recursive] [-- <paths>...]` — one line per
20459
+ * registered submodule: a state prefix, the checked-out (or gitlink) sha,
20460
+ * the path, and — when the submodule is initialized — a `git describe`
20461
+ * suffix in parentheses.
20462
+ *
20463
+ * @remarks
20464
+ * `git submodule status` has no `-z` mode, so its output is line-based —
20465
+ * the one path-emitting constructor in this package that cannot follow
20466
+ * the `-z` rule. A submodule path containing a newline would corrupt the
20467
+ * parse; accepted as a git-imposed limitation.
20468
+ */
20469
+ static submoduleStatus = submoduleStatus;
20470
+ /**
20471
+ * Mutating: `git submodule init [-- <paths>...]` — registers the
20472
+ * submodules from `.gitmodules` into `.git/config` (all of them, or only
20473
+ * `paths`), without cloning or checking anything out.
20474
+ */
20475
+ static submoduleInit = submoduleInit;
20476
+ /**
20477
+ * Mutating: `git submodule deinit [--force] (--all | -- <paths>...)` —
20478
+ * unregisters submodules: clears their working trees and removes their
20479
+ * `.git/config` registration. The literal `--` separator makes the
20480
+ * pathspec injection-safe by construction.
20481
+ */
20482
+ static submoduleDeinit = submoduleDeinit;
20483
+ /**
20484
+ * Mutating: `git submodule sync [--recursive] [-- <paths>...]` —
20485
+ * re-copies each submodule's URL from `.gitmodules` into `.git/config`
20486
+ * (and into the submodule's own `remote.origin.url`), so a `.gitmodules`
20487
+ * URL change actually reaches git's live configuration.
20488
+ */
20489
+ static submoduleSync = submoduleSync;
20490
+ /**
20491
+ * Mutating: `git submodule set-url -- <path> <url>` — rewrites the
20492
+ * submodule's URL in `.gitmodules` and synchronizes it into
20493
+ * `.git/config`. The literal `--` separator makes the path and url
20494
+ * injection-safe by construction.
20495
+ *
20496
+ * @remarks
20497
+ * An embedded `userinfo@` credential in `url` is masked in
20498
+ * {@link GitInvocation.redactedArgs}.
20499
+ */
20500
+ static submoduleSetUrl = submoduleSetUrl;
20501
+ /**
20502
+ * Mutating: `git submodule set-branch (--branch <branch> | --default) -- <path>`
20503
+ * — records (or clears, when `branch` is omitted) the branch a submodule
20504
+ * tracks in `.gitmodules`. The literal `--` separator makes the path
20505
+ * injection-safe by construction.
20506
+ */
20507
+ static submoduleSetBranch = submoduleSetBranch;
20508
+ /**
20509
+ * Mutating: `git submodule absorbgitdirs [-- <paths>...]` — moves each
20510
+ * submodule's embedded `.git` directory into the superproject's
20511
+ * `.git/modules/` and leaves a gitfile pointer behind.
20512
+ */
20513
+ static submoduleAbsorbgitdirs = submoduleAbsorbgitdirs;
20514
+ /**
20515
+ * Mutating: `git submodule foreach [--recursive] <command>` — runs a shell
20516
+ * command in every checked-out submodule. `command` is a single shell
20517
+ * string, evaluated by git in each submodule's directory; it can mutate
20518
+ * anything, which is why the constructor is marked mutating regardless of
20519
+ * what the command does.
20520
+ *
20521
+ * @remarks
20522
+ * This is the ONE constructor whose argument cannot be made injection-safe
20523
+ * by construction: git evaluates `command` with `sh -c`, so every character
20524
+ * of it is shell code — a `--` separator or quoting cannot help. Callers
20525
+ * must treat `command` as a trusted literal and never interpolate untrusted
20526
+ * data into it.
20527
+ */
20528
+ static submoduleForeach = submoduleForeach;
20529
+ /**
20530
+ * `git ls-remote [--heads] [--tags] <remote> [<patterns>...]` — the refs a
20531
+ * remote advertises (sha + refname), optionally filtered to branch heads,
20532
+ * tags, and/or shell-glob patterns.
20533
+ *
20534
+ * @remarks
20535
+ * A read that talks to the NETWORK, not to the local repository — the one
20536
+ * non-mutating constructor in this package that does. An embedded
20537
+ * `userinfo@` credential in `remote` is masked in
20538
+ * {@link GitInvocation.redactedArgs}. An annotated tag advertises two
20539
+ * entries: `refs/tags/<name>` (the tag object) and `refs/tags/<name>^{}`
20540
+ * (the peeled commit).
20541
+ */
20542
+ static lsRemote = lsRemote;
20543
+ /**
20544
+ * Mutating: `git remote add <name> <url>` — registers a new remote.
20545
+ *
20546
+ * @remarks
20547
+ * An embedded `userinfo@` credential in `url` is masked in
20548
+ * {@link GitInvocation.redactedArgs}.
20549
+ */
20550
+ static remoteAdd = remoteAdd;
20551
+ /**
20552
+ * Mutating: `git remote remove <name>` — deletes a remote and its
20553
+ * remote-tracking refs and configuration.
20554
+ */
20555
+ static remoteRemove = remoteRemove;
20556
+ /**
20557
+ * Mutating: `git remote set-url <name> <url>` — rewrites a remote's fetch
20558
+ * URL.
20559
+ *
20560
+ * @remarks
20561
+ * An embedded `userinfo@` credential in `url` is masked in
20562
+ * {@link GitInvocation.redactedArgs}.
20563
+ */
20564
+ static remoteSetUrl = remoteSetUrl;
20565
+ /**
20566
+ * Mutating: `git stash push [--include-untracked] [-m <message>] [-- <paths>...]`
20567
+ * — saves the working tree (and index) state onto the stash stack. The
20568
+ * literal `--` separator makes the optional pathspec injection-safe by
20569
+ * construction; the message rides behind `-m`, which git consumes as a
20570
+ * value even when it begins with `-`.
20571
+ */
20572
+ static stashPush = stashPush;
20573
+ /**
20574
+ * Mutating: `git stash pop [stash@{n}]` — applies a stash entry and drops
20575
+ * it on success. The stash ref is rendered from an INTEGER index by this
20576
+ * package, never caller text.
20577
+ */
20578
+ static stashPop = stashPop;
20579
+ /**
20580
+ * Mutating: `git stash apply [stash@{n}]` — applies a stash entry and
20581
+ * keeps it on the stack. The stash ref is rendered from an INTEGER index
20582
+ * by this package, never caller text.
20583
+ */
20584
+ static stashApply = stashApply;
20585
+ /**
20586
+ * Mutating: `git stash drop [stash@{n}]` — deletes a stash entry without
20587
+ * applying it. The stash ref is rendered from an INTEGER index by this
20588
+ * package, never caller text.
20589
+ */
20590
+ static stashDrop = stashDrop;
20591
+ /**
20592
+ * `git stash list -z --format=%gd%x1f%H%x1f%gs` — every stash entry as a
20593
+ * NUL-terminated record of unit-separated fields: the reflog selector
20594
+ * (`stash@{0}`), the stash commit sha, and the reflog subject.
20595
+ *
20596
+ * @remarks
20597
+ * The `%x1f` (ASCII unit separator) field separator plus `-z` record
20598
+ * terminator keeps the parse split-safe: a stash message cannot contain
20599
+ * either byte (reflog subjects are single-line).
20600
+ */
20601
+ static stashList = stashList;
20602
+ /**
20603
+ * `git branch --list [--remotes | --all] --format=%(HEAD)%00%(refname:short)%00%(objectname)`
20604
+ * — every branch as a NUL-separated triple: the current-branch marker, the
20605
+ * short name, and the tip sha.
20606
+ *
20607
+ * @remarks
20608
+ * Records are newline-separated, which is split-safe here: git refnames
20609
+ * cannot contain a newline (or a space), so the only NUL bytes are the
20610
+ * format's own field separators. `all` wins over `remotes` when both are
20611
+ * set.
20612
+ */
20613
+ static branchList = branchList;
20614
+ /**
20615
+ * Mutating: `git tag [--force] [-m <message>] <name> [<ref>]` — creates a
20616
+ * lightweight tag, or an annotated one when `message` is given (`-m`
20617
+ * implies `-a`).
20618
+ */
20619
+ static tagCreate = tagCreate;
20620
+ /** Mutating: `git tag --delete <name>` — deletes a local tag. */
20621
+ static tagDelete = tagDelete;
20622
+ /**
20623
+ * `git tag --list [<pattern>]` — tag names, optionally filtered by a
20624
+ * shell-glob pattern, one per line (refnames cannot contain newlines).
20625
+ */
20626
+ static tagList = tagList;
20627
+ /**
20628
+ * `git for-each-ref --format=%(refname)%00%(objectname)%00%(objecttype) [<patterns>...]`
20629
+ * — every matching ref as a NUL-separated triple: full refname, sha, and
20630
+ * object type.
20631
+ *
20632
+ * @remarks
20633
+ * The format is this package's own fixed triple — the parse contract and
20634
+ * the argv are decided together, so the format string is a constructor
20635
+ * literal, never caller data. An annotated tag's `objecttype` is `tag`
20636
+ * (the tag object), not `commit`.
20637
+ */
20638
+ static forEachRef = forEachRef;
20639
+ /**
20640
+ * `git rev-list [--max-count=<n>] [--first-parent] <ref-or-range>` — commit
20641
+ * shas reachable from the ref (or range, e.g. `main..feat`), newest first.
20642
+ */
20643
+ static revList = revList;
20644
+ /**
20645
+ * Mutating: `git commit [--all] [--allow-empty] [--amend] [--author=<author>] -m <message>`
20646
+ * — records a commit. The message always rides argv behind `-m` (git
20647
+ * consumes it as a value even when it begins with `-`); committer identity
20648
+ * comes from the caller's environment — this constructor sets no
20649
+ * `GIT_AUTHOR_*`/`GIT_COMMITTER_*` variables, and the optional `author`
20650
+ * override is the fused `--author=` form.
20651
+ */
20652
+ static commit = commit;
20653
+ /**
20654
+ * Mutating: `git push [--force | --force-with-lease] [--tags] [--set-upstream] <remote> [<refspec>]`
20655
+ * — updates remote refs.
20656
+ *
20657
+ * @remarks
20658
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20659
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20660
+ */
20661
+ static push = push$1;
20662
+ /**
20663
+ * Mutating: `git pull [--rebase] [--ff-only] <remote> [<ref>]` — fetches
20664
+ * and integrates.
20665
+ *
20666
+ * @remarks
20667
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20668
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20669
+ */
20670
+ static pull = pull;
20671
+ /**
20672
+ * `git config [-f <file>] --list -z` — every configuration entry in scope
20673
+ * (or in the given file only), NUL-terminated, the key separated from the
20674
+ * value by a newline within each record.
20675
+ *
20676
+ * @remarks
20677
+ * `-z` is load-bearing: a config VALUE may contain newlines; only the NUL
20678
+ * record terminator plus first-newline field split parses it losslessly.
20679
+ * A valueless key (git's boolean-true shorthand) emits no newline at all.
20680
+ */
20681
+ static configList = configList;
20682
+ /**
20683
+ * `git config [-f <file>] --get-all -z <key>` — every value of a
20684
+ * (possibly multi-valued) key, NUL-terminated. An unset key exits 1 with
20685
+ * silent stderr.
20686
+ */
20687
+ static configGetAll = configGetAll;
20688
+ /**
20689
+ * Mutating: `git config [-f <file>] (--unset | --unset-all) <key>` —
20690
+ * removes a key (or, with `all`, every value of a multi-valued key).
20691
+ *
20692
+ * @remarks
20693
+ * git exits 5, silently, when the key was not set — a loud failure by
20694
+ * this package's classification, deliberately: an unset that silently did
20695
+ * nothing is indistinguishable from one that worked.
20696
+ */
20697
+ static configUnset = configUnset;
20698
+ /**
20699
+ * Mutating: `git rm [--cached] [-r] [--force] -- <paths...>` — removes
20700
+ * paths from the index (and, without `cached`, the working tree). The
20701
+ * literal `--` separator makes the pathspec injection-safe by
20702
+ * construction.
20703
+ */
20704
+ static rm = rm;
20705
+ /**
20706
+ * Mutating: `git mv [--force] -- <source> <destination>` — moves or
20707
+ * renames a tracked path. The literal `--` separator makes both positionals
20708
+ * injection-safe by construction.
20709
+ */
20710
+ static mv = mv;
20711
+ /**
20712
+ * `git check-ignore -z --stdin` — which of the given paths git would
20713
+ * ignore, paths fed NUL-separated via stdin and answers returned
20714
+ * NUL-separated.
20715
+ *
20716
+ * @remarks
20717
+ * The `--stdin -z` form is the only fully robust one: `-z` without
20718
+ * `--stdin` is rejected by git outright, and the non-`-z` output C-quotes
20719
+ * special-character paths. Feeding paths via stdin also makes them
20720
+ * injection-safe by construction — nothing caller-controlled enters the
20721
+ * argv. When NO path is ignored, git exits 1 with silent stderr.
20722
+ */
20723
+ static checkIgnore = checkIgnore;
20724
+ /**
20725
+ * Mutating: `git worktree add [--force] [--detach] <path> [<ref>]` —
20726
+ * creates a linked working tree at `path`, checked out at `ref` (or the
20727
+ * branch named after `path`'s basename).
20728
+ */
20729
+ static worktreeAdd = worktreeAdd;
20730
+ /**
20731
+ * `git worktree list --porcelain -z` — every working tree as a block of
20732
+ * NUL-terminated attributes (`worktree <path>`, `HEAD <sha>`,
20733
+ * `branch <ref>` / `detached`, `bare`, `locked [<reason>]`,
20734
+ * `prunable [<reason>]`), blocks separated by an empty attribute.
20735
+ */
20736
+ static worktreeList = worktreeList;
20737
+ /** Mutating: `git worktree remove [--force] <path>` — removes a linked working tree. */
20738
+ static worktreeRemove = worktreeRemove;
20739
+ /**
20740
+ * `git ls-files --stage -z [-- <pathspec>...]` — every INDEX entry (mode,
20741
+ * oid, stage number, path), NUL-terminated, optionally scoped to
20742
+ * `pathspec`.
20743
+ *
20744
+ * @remarks
20745
+ * The index-side sibling of {@link GitCommand.lsTree}: `lsTree` reads a
20746
+ * COMMITTED tree at a ref, while this reads the staging area — the only
20747
+ * place a staged-but-uncommitted gitlink (`160000 <oid> 0 <path>`) is
20748
+ * visible. `-z` is load-bearing twice over: paths may contain newlines,
20749
+ * and the non-`-z` output C-quotes special-character paths.
20750
+ */
20751
+ static lsFiles = lsFiles;
20399
20752
  };
20400
20753
  //#endregion
20401
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
20754
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
20402
20755
  /**
20403
20756
  * Spawns `command` and collects its stdout, stderr, and exit code as a single
20404
20757
  * triple.
@@ -20425,7 +20778,7 @@ const runCollected = (command) => effect.Effect.scoped(effect.Effect.gen(functio
20425
20778
  };
20426
20779
  }));
20427
20780
  //#endregion
20428
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
20781
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
20429
20782
  /** git's own ceiling: a run that has not answered in 30s is not going to. */
20430
20783
  const GIT_TIMEOUT = effect.Duration.seconds(30);
20431
20784
  /**
@@ -20453,7 +20806,16 @@ var GitCommandError = class extends effect.Schema.TaggedErrorClass()("GitCommand
20453
20806
  * logic routes on this instead of matching `detail` prose.
20454
20807
  */
20455
20808
  kind: effect.Schema.Literals(["refused", "failed"]),
20456
- /** The argument vector, without the leading `git`. */
20809
+ /**
20810
+ * The REDACTED argument vector, without the leading `git`.
20811
+ *
20812
+ * Sensitive positionals — config values, a URL's embedded userinfo — are
20813
+ * already masked by the constructor's redaction mask before this error is
20814
+ * constructed (`configSet`'s value reads `<redacted>`; a
20815
+ * `https://user:token@host/...` remote keeps everything but its
20816
+ * `userinfo@`). The raw argv is never persisted in an error value, and
20817
+ * `message` renders this redacted vector.
20818
+ */
20457
20819
  args: effect.Schema.Array(effect.Schema.String),
20458
20820
  /** The working directory the command ran in. */
20459
20821
  cwd: effect.Schema.String,
@@ -20499,9 +20861,74 @@ var UnknownRefError = class extends effect.Schema.TaggedErrorClass()("UnknownRef
20499
20861
  }
20500
20862
  };
20501
20863
  /**
20502
- * One entry of a `git ls-tree` listing.
20864
+ * A `git push` was rejected because the remote ref has moved: the classic
20865
+ * non-fast-forward rejection (`fetch first` / `non-fast-forward`), or a
20866
+ * `--force-with-lease` lease failure (`stale info`).
20503
20867
  *
20504
- * @public
20868
+ * @remarks
20869
+ * The typed signal a fetch-then-retry (or rebase-then-retry) fallback
20870
+ * branches on — every other push failure stays a {@link GitCommandError}.
20871
+ * Only `Git.push` can fail with this error.
20872
+ *
20873
+ * @public
20874
+ */
20875
+ var NonFastForwardError = class extends effect.Schema.TaggedErrorClass()("NonFastForwardError", {
20876
+ /** The working directory the push ran in. */
20877
+ cwd: effect.Schema.String,
20878
+ /** The refspec that was rejected, when the caller passed one. */
20879
+ refspec: effect.Schema.optionalKey(effect.Schema.String)
20880
+ }) {
20881
+ /** Renders the rejected push into a one-line message. */
20882
+ get message() {
20883
+ return this.refspec !== void 0 ? `push of '${this.refspec}' rejected as non-fast-forward in ${this.cwd}` : `push rejected as non-fast-forward in ${this.cwd}`;
20884
+ }
20885
+ };
20886
+ /**
20887
+ * A merge-shaped operation (`pull`, `stash pop`, `stash apply`) stopped with
20888
+ * conflict markers in the working tree.
20889
+ *
20890
+ * @remarks
20891
+ * The typed signal a resolve-or-abort recovery branches on. The conflicted
20892
+ * state is REAL: git has already written conflict markers, and (for `pull`)
20893
+ * `MERGE_HEAD` is set — the caller owns resolving or aborting. Detection
20894
+ * matches git's conflict report, which lands on STDOUT for a merge and on
20895
+ * stderr for a rebase-mode pull; both streams are inspected.
20896
+ *
20897
+ * @public
20898
+ */
20899
+ var MergeConflictError = class extends effect.Schema.TaggedErrorClass()("MergeConflictError", {
20900
+ /** The working directory the merge ran in. */
20901
+ cwd: effect.Schema.String }) {
20902
+ /** Renders the conflicted merge into a one-line message. */
20903
+ get message() {
20904
+ return `merge conflict in ${this.cwd}: fix conflicts (or abort) before continuing`;
20905
+ }
20906
+ };
20907
+ /**
20908
+ * A merge-shaped operation refused to start because local modifications would
20909
+ * be overwritten — git's refusal reads
20910
+ * `Your local changes ... would be overwritten by merge`.
20911
+ *
20912
+ * @remarks
20913
+ * The typed "commit or stash first" signal. Unlike {@link MergeConflictError}
20914
+ * the working tree is UNTOUCHED — git aborted before changing anything.
20915
+ * Only the merge-shaped methods (`pull`, `stashPop`, `stashApply`) can fail
20916
+ * with this error.
20917
+ *
20918
+ * @public
20919
+ */
20920
+ var DirtyWorktreeError = class extends effect.Schema.TaggedErrorClass()("DirtyWorktreeError", {
20921
+ /** The working directory whose local changes blocked the operation. */
20922
+ cwd: effect.Schema.String }) {
20923
+ /** Renders the blocked operation into a one-line message. */
20924
+ get message() {
20925
+ return `local changes would be overwritten in ${this.cwd}: commit or stash them first`;
20926
+ }
20927
+ };
20928
+ /**
20929
+ * One entry of a `git ls-tree` listing.
20930
+ *
20931
+ * @public
20505
20932
  */
20506
20933
  var LsTreeEntry = class extends effect.Schema.Class("LsTreeEntry")({
20507
20934
  /** The entry's file mode, e.g. `100644`. */
@@ -20559,11 +20986,26 @@ const UNKNOWN_REF_PATTERNS = [
20559
20986
  "couldn't find remote ref"
20560
20987
  ];
20561
20988
  const ABSENT_AT_REF_PATTERNS = ["does not exist in", "exists on disk, but not in"];
20989
+ const PUSH_REJECTED_PATTERNS = [
20990
+ "non-fast-forward",
20991
+ "fetch first",
20992
+ "stale info"
20993
+ ];
20994
+ const MERGE_CONFLICT_PATTERNS = [
20995
+ "CONFLICT (",
20996
+ "Automatic merge failed",
20997
+ "could not apply"
20998
+ ];
20999
+ const DIRTY_WORKTREE_PATTERN = "would be overwritten by";
20562
21000
  const matchesAny = (stderr, patterns) => patterns.some((pattern) => stderr.includes(pattern));
20563
21001
  /**
20564
21002
  * Classifies one completed run (or spawn-level `PlatformError`) against
20565
21003
  * git's stderr taxonomy. Written once — every `Git` method funnels through
20566
21004
  * this before deciding its own return value.
21005
+ *
21006
+ * `args` is the invocation's REDACTED argv: it is the only argv this
21007
+ * function may persist into a `GitCommandError`, per the #86 redaction
21008
+ * policy.
20567
21009
  */
20568
21010
  const classify = (cwd, args, outcome, kind) => {
20569
21011
  if (outcome instanceof effect.PlatformError.PlatformError) {
@@ -20586,6 +21028,11 @@ const classify = (cwd, args, outcome, kind) => {
20586
21028
  };
20587
21029
  if (stderr.includes(NOT_A_REPOSITORY)) return { _tag: "notARepository" };
20588
21030
  if (matchesAny(stderr, UNKNOWN_REF_PATTERNS)) return { _tag: "unknownRef" };
21031
+ if (kind === "push" && stderr.includes("[rejected]") && matchesAny(stderr, PUSH_REJECTED_PATTERNS)) return { _tag: "nonFastForward" };
21032
+ if (kind === "merge") {
21033
+ if (stderr.includes(DIRTY_WORKTREE_PATTERN)) return { _tag: "dirtyWorktree" };
21034
+ if (matchesAny(stdout, MERGE_CONFLICT_PATTERNS) || matchesAny(stderr, MERGE_CONFLICT_PATTERNS)) return { _tag: "mergeConflict" };
21035
+ }
20589
21036
  if (kind === "quiet" && exitCode === 1 && stderr === "") return { _tag: "absent" };
20590
21037
  if (kind === "noSuchRemote" && stderr.includes("No such remote")) return { _tag: "absent" };
20591
21038
  if (kind === "show" && matchesAny(stderr, ABSENT_AT_REF_PATTERNS)) return { _tag: "absent" };
@@ -20602,13 +21049,19 @@ const classify = (cwd, args, outcome, kind) => {
20602
21049
  };
20603
21050
  };
20604
21051
  /**
20605
- * Runs `command`, classifies the outcome, and never fails: a spawn-level
20606
- * `PlatformError` and a per-run timeout are both absorbed into the
20607
- * `"failure"` classification rather than escaping the effect's error
20608
- * channel.
21052
+ * Runs an invocation's command in `cwd`, classifies the outcome, and never
21053
+ * fails: a spawn-level `PlatformError` and a per-run timeout are both
21054
+ * absorbed into the `"failure"` classification rather than escaping the
21055
+ * effect's error channel.
21056
+ *
21057
+ * The argv handed to `classify` — and therefore persisted into any
21058
+ * `GitCommandError` — is the invocation's REDACTED argv, never the raw one:
21059
+ * the redaction mask the pure constructor carries is applied here, at the
21060
+ * single classification choke point (the #86 redaction policy).
20609
21061
  */
20610
- const runClassified = (command, cwd, kind) => {
20611
- const args = effect_unstable_process.ChildProcess.isStandardCommand(command) ? command.args : [];
21062
+ const runClassified = (invocation, cwd, kind) => {
21063
+ const args = invocation.redactedArgs;
21064
+ const command = effect_unstable_process.ChildProcess.setCwd(invocation.command, cwd);
20612
21065
  return runCollected(command).pipe(effect.Effect.map((collected) => classify(cwd, args, collected, kind)), effect.Effect.catch((platformError) => effect.Effect.succeed(classify(cwd, args, platformError, kind))), effect.Effect.timeoutOrElse({
20613
21066
  duration: GIT_TIMEOUT,
20614
21067
  orElse: () => effect.Effect.succeed({
@@ -20640,414 +21093,1417 @@ const parseLsTree = (output) => parseNulSeparated(output).map((entry) => {
20640
21093
  oid: header[2] ?? "",
20641
21094
  path
20642
21095
  });
20643
- });
20644
- /** git's one-letter name-status codes, score digits stripped (`R100` → `R`). */
20645
- const NAME_STATUS_CODES = {
20646
- A: "added",
20647
- B: "broken",
20648
- C: "copied",
20649
- D: "deleted",
20650
- M: "modified",
20651
- R: "renamed",
20652
- T: "typeChanged",
20653
- U: "unmerged",
20654
- X: "unknown"
20655
- };
20656
- /**
20657
- * Parses `git diff --name-status -z` output. A plain entry is two NUL tokens
20658
- * (`<code>`, `<path>`); a rename/copy entry is three (`<R|C><score>`,
20659
- * `<oldPath>`, `<newPath>`), and only the code's first character carries the
20660
- * status — the similarity score digits are dropped.
20661
- */
20662
- const parseNameStatus = (output) => {
20663
- const tokens = output.split("\0");
20664
- const entries = [];
20665
- let index = 0;
20666
- while (index < tokens.length) {
20667
- const code = tokens[index] ?? "";
20668
- if (code === "") {
20669
- index += 1;
20670
- continue;
21096
+ });
21097
+ /** git's one-letter name-status codes, score digits stripped (`R100` → `R`). */
21098
+ const NAME_STATUS_CODES = {
21099
+ A: "added",
21100
+ B: "broken",
21101
+ C: "copied",
21102
+ D: "deleted",
21103
+ M: "modified",
21104
+ R: "renamed",
21105
+ T: "typeChanged",
21106
+ U: "unmerged",
21107
+ X: "unknown"
21108
+ };
21109
+ /**
21110
+ * Parses `git diff --name-status -z` output. A plain entry is two NUL tokens
21111
+ * (`<code>`, `<path>`); a rename/copy entry is three (`<R|C><score>`,
21112
+ * `<oldPath>`, `<newPath>`), and only the code's first character carries the
21113
+ * status — the similarity score digits are dropped.
21114
+ */
21115
+ const parseNameStatus = (output) => {
21116
+ const tokens = output.split("\0");
21117
+ const entries = [];
21118
+ let index = 0;
21119
+ while (index < tokens.length) {
21120
+ const code = tokens[index] ?? "";
21121
+ if (code === "") {
21122
+ index += 1;
21123
+ continue;
21124
+ }
21125
+ const letter = code.charAt(0);
21126
+ const status = NAME_STATUS_CODES[letter] ?? "unknown";
21127
+ if (letter === "R" || letter === "C") {
21128
+ entries.push(NameStatusEntry.make({
21129
+ status,
21130
+ path: tokens[index + 2] ?? "",
21131
+ oldPath: tokens[index + 1] ?? ""
21132
+ }));
21133
+ index += 3;
21134
+ } else {
21135
+ entries.push(NameStatusEntry.make({
21136
+ status,
21137
+ path: tokens[index + 1] ?? ""
21138
+ }));
21139
+ index += 2;
21140
+ }
21141
+ }
21142
+ return entries;
21143
+ };
21144
+ /**
21145
+ * The metadata of a single commit, read via `git log -1` with NUL-separated
21146
+ * `%H` / `%G?` / `%B` placeholders.
21147
+ *
21148
+ * @public
21149
+ */
21150
+ var CommitInfo = class extends effect.Schema.Class("CommitInfo")({
21151
+ /** The commit's full object id (`%H`). */
21152
+ sha: effect.Schema.String,
21153
+ /** git's `%G?` signature verdict: Good, Bad, Unknown validity, eXpired, expired-key (Y), Revoked, cannot-check (E), None. */
21154
+ signatureStatus: effect.Schema.Literals([
21155
+ "G",
21156
+ "B",
21157
+ "U",
21158
+ "X",
21159
+ "Y",
21160
+ "R",
21161
+ "E",
21162
+ "N"
21163
+ ]),
21164
+ /** The raw commit message (`%B`), untrimmed — includes git's trailing format newline. */
21165
+ message: effect.Schema.String
21166
+ }) {};
21167
+ /** One two-letter porcelain v1 status axis code. */
21168
+ const porcelainCode = effect.Schema.Literals([
21169
+ " ",
21170
+ "M",
21171
+ "T",
21172
+ "A",
21173
+ "D",
21174
+ "R",
21175
+ "C",
21176
+ "U",
21177
+ "?",
21178
+ "!"
21179
+ ]);
21180
+ /**
21181
+ * One entry of a `git status --porcelain -z` listing.
21182
+ *
21183
+ * @public
21184
+ */
21185
+ var StatusEntry = class extends effect.Schema.Class("StatusEntry")({
21186
+ /** The index-side status code (first porcelain column). */
21187
+ x: porcelainCode,
21188
+ /** The working-tree-side status code (second porcelain column). */
21189
+ y: porcelainCode,
21190
+ /** The entry's path — for a rename or copy, the NEW path. */
21191
+ path: effect.Schema.String,
21192
+ /** The original path; present only on rename/copy entries. */
21193
+ origPath: effect.Schema.optionalKey(effect.Schema.String)
21194
+ }) {
21195
+ /**
21196
+ * Renders this entry back to one porcelain-shaped line: `XY <path>`.
21197
+ *
21198
+ * @remarks
21199
+ * **The rename convention is decided here, once, for every consumer.** By
21200
+ * default a rename/copy entry renders its NEW path only — `path` IS the
21201
+ * entry's current path, the one a line-oriented downstream can actually
21202
+ * open — which is a deliberate divergence from git's own non-`-z`
21203
+ * rendering (`orig -> new`). The arrow form is ambiguous to naive
21204
+ * line/whitespace splitters (paths may contain spaces, or a literal
21205
+ * `" -> "`), so it is opt-in via `renames: "arrow"` for consumers that
21206
+ * want git parity.
21207
+ *
21208
+ * A second recorded divergence: git's non-`-z` porcelain C-quotes paths
21209
+ * containing special characters; this renderer emits paths raw. It exists
21210
+ * for whitespace-insensitive text consumers — a machine parser should
21211
+ * consume the decoded {@link StatusEntry} values (or `-z` output)
21212
+ * directly, never re-parse this rendering.
21213
+ */
21214
+ toLine(options) {
21215
+ const rendered = options?.renames === "arrow" && this.origPath !== void 0 ? `${this.origPath} -> ${this.path}` : this.path;
21216
+ return `${this.x}${this.y} ${rendered}`;
21217
+ }
21218
+ /**
21219
+ * Renders entries back to porcelain-shaped text: one {@link StatusEntry.toLine}
21220
+ * line per entry, newline-joined, no trailing newline.
21221
+ *
21222
+ * @remarks
21223
+ * The route back from `Git.status`'s parsed entries to line-oriented text,
21224
+ * so a consumer whose downstream contract is porcelain-shaped text does
21225
+ * not hand-roll its own renderer (and re-decide the rename convention —
21226
+ * see {@link StatusEntry.toLine} for that decision). An empty array
21227
+ * renders as the empty string.
21228
+ */
21229
+ static format = (entries, options) => entries.map((entry) => entry.toLine(options)).join("\n");
21230
+ };
21231
+ /**
21232
+ * Parses `git log -1 --format=%H%x00%G?%x00%B` output: exactly two NUL
21233
+ * separators, everything after the second is the raw message, untrimmed.
21234
+ * Only ever called on the successful output of this package's own format
21235
+ * string, so the separators are guaranteed present.
21236
+ */
21237
+ const parseCommitInfo = (output) => {
21238
+ const first = output.indexOf("\0");
21239
+ const second = output.indexOf("\0", first + 1);
21240
+ return CommitInfo.make({
21241
+ sha: output.slice(0, first),
21242
+ signatureStatus: output.slice(first + 1, second),
21243
+ message: output.slice(second + 1)
21244
+ });
21245
+ };
21246
+ /**
21247
+ * Parses `git status --porcelain -z` output: each entry is `XY <path>`, and a
21248
+ * rename/copy entry appends the ORIGINAL path as one extra NUL token AFTER
21249
+ * the new path — the opposite order from `diff --name-status`.
21250
+ */
21251
+ const parseStatus = (output) => {
21252
+ const tokens = output.split("\0");
21253
+ const entries = [];
21254
+ let index = 0;
21255
+ while (index < tokens.length) {
21256
+ const token = tokens[index] ?? "";
21257
+ if (token === "") {
21258
+ index += 1;
21259
+ continue;
21260
+ }
21261
+ const x = token.charAt(0);
21262
+ const y = token.charAt(1);
21263
+ const path = token.slice(3);
21264
+ if (x === "R" || x === "C" || y === "R" || y === "C") {
21265
+ entries.push(StatusEntry.make({
21266
+ x,
21267
+ y,
21268
+ path,
21269
+ origPath: tokens[index + 1] ?? ""
21270
+ }));
21271
+ index += 2;
21272
+ } else {
21273
+ entries.push(StatusEntry.make({
21274
+ x,
21275
+ y,
21276
+ path
21277
+ }));
21278
+ index += 1;
21279
+ }
21280
+ }
21281
+ return entries;
21282
+ };
21283
+ /**
21284
+ * One line of a `git submodule status` listing.
21285
+ *
21286
+ * @remarks
21287
+ * The `state` decodes git's one-character prefix: `" "` → `"current"` (the
21288
+ * checked-out commit matches the index gitlink), `"-"` → `"uninitialized"`,
21289
+ * `"+"` → `"outOfSync"` (the checked-out commit differs from the gitlink),
21290
+ * `"U"` → `"conflict"` (merge conflicts). `describe` carries the
21291
+ * parenthesized `git describe` suffix git appends for initialized
21292
+ * submodules.
21293
+ *
21294
+ * @public
21295
+ */
21296
+ var SubmoduleStatusEntry = class extends effect.Schema.Class("SubmoduleStatusEntry")({
21297
+ /** The decoded state prefix. */
21298
+ state: effect.Schema.Literals([
21299
+ "current",
21300
+ "uninitialized",
21301
+ "outOfSync",
21302
+ "conflict"
21303
+ ]),
21304
+ /** The submodule's checked-out (or, uninitialized, gitlink) commit sha. */
21305
+ sha: effect.Schema.String,
21306
+ /** The submodule's path relative to the superproject root. */
21307
+ path: effect.Schema.String,
21308
+ /** The `git describe` suffix, present only for initialized submodules. */
21309
+ describe: effect.Schema.optionalKey(effect.Schema.String)
21310
+ }) {};
21311
+ /**
21312
+ * Parses `git submodule status` output. Line-based — the one parser in this
21313
+ * package without a `-z` mode to lean on, because git does not offer one for
21314
+ * `submodule status`; a submodule path containing a newline (or a literal
21315
+ * ` (` suffix mimicking the describe parenthesis) would corrupt the parse.
21316
+ * Accepted as a git-imposed limitation.
21317
+ */
21318
+ const parseSubmoduleStatus = (output) => {
21319
+ const entries = [];
21320
+ for (const line of output.split("\n")) {
21321
+ const trimmedEnd = line.endsWith("\r") ? line.slice(0, -1) : line;
21322
+ if (trimmedEnd === "") continue;
21323
+ const prefix = trimmedEnd.charAt(0);
21324
+ const state = prefix === "-" ? "uninitialized" : prefix === "+" ? "outOfSync" : prefix === "U" ? "conflict" : "current";
21325
+ const rest = prefix === " " || prefix === "-" || prefix === "+" || prefix === "U" ? trimmedEnd.slice(1) : trimmedEnd;
21326
+ const shaEnd = rest.indexOf(" ");
21327
+ const sha = shaEnd === -1 ? rest : rest.slice(0, shaEnd);
21328
+ const remainder = shaEnd === -1 ? "" : rest.slice(shaEnd + 1);
21329
+ const describeStart = remainder.endsWith(")") ? remainder.lastIndexOf(" (") : -1;
21330
+ if (describeStart === -1) entries.push(SubmoduleStatusEntry.make({
21331
+ state,
21332
+ sha,
21333
+ path: remainder
21334
+ }));
21335
+ else entries.push(SubmoduleStatusEntry.make({
21336
+ state,
21337
+ sha,
21338
+ path: remainder.slice(0, describeStart),
21339
+ describe: remainder.slice(describeStart + 2, -1)
21340
+ }));
21341
+ }
21342
+ return entries;
21343
+ };
21344
+ /**
21345
+ * One ref a remote advertises, from `git ls-remote`.
21346
+ *
21347
+ * @remarks
21348
+ * `ref` is the FULL refname as advertised (`refs/heads/main`,
21349
+ * `refs/tags/v1`), including the `^{}` suffix on an annotated tag's peeled
21350
+ * entry — an annotated tag appears twice, once as the tag object and once
21351
+ * peeled to its commit.
21352
+ *
21353
+ * @public
21354
+ */
21355
+ var LsRemoteEntry = class LsRemoteEntry extends effect.Schema.Class("LsRemoteEntry")({
21356
+ /** The sha the advertised ref points at. */
21357
+ sha: effect.Schema.String,
21358
+ /** The full advertised refname, `^{}` peel suffix included. */
21359
+ ref: effect.Schema.String
21360
+ }) {
21361
+ /**
21362
+ * The human-facing short name of an advertised refname: the
21363
+ * `refs/heads/` / `refs/tags/` / `refs/remotes/` prefix and any `^{}`
21364
+ * peel suffix stripped (`refs/tags/v1^{}` → `v1`).
21365
+ */
21366
+ static shortName = (ref) => {
21367
+ const base = ref.endsWith("^{}") ? ref.slice(0, -3) : ref;
21368
+ for (const prefix of [
21369
+ "refs/heads/",
21370
+ "refs/tags/",
21371
+ "refs/remotes/"
21372
+ ]) if (base.startsWith(prefix)) return base.slice(prefix.length);
21373
+ return base;
21374
+ };
21375
+ /**
21376
+ * The entries whose short name is a NEAR MISS for `ref`: not an exact
21377
+ * match, but ending in `ref` right behind a separator (`@`, `/`, `-`,
21378
+ * `_`) — the monorepo-prefixed-tag case, where a caller asks for
21379
+ * `4.0.0-beta.101` and the remote advertises `effect@4.0.0-beta.101`.
21380
+ *
21381
+ * @remarks
21382
+ * A pure, decode-side helper for validate-before-mutate flows: run
21383
+ * `lsRemote`, look for the wanted ref, and when it is absent hand the
21384
+ * listing to this to compute a suggestion. Deliberately a helper on the
21385
+ * ENTRY value rather than behavior baked into the service — the service
21386
+ * returns the full listing and the caller owns the matching policy. An
21387
+ * annotated tag's peeled `^{}` entry shares its base short name, so a
21388
+ * near miss on such a tag can surface both of its entries.
21389
+ */
21390
+ static nearMatches = (entries, ref) => {
21391
+ const separators = [
21392
+ "@",
21393
+ "/",
21394
+ "-",
21395
+ "_"
21396
+ ];
21397
+ return entries.filter((entry) => {
21398
+ const short = LsRemoteEntry.shortName(entry.ref);
21399
+ if (short === ref || !short.endsWith(ref)) return false;
21400
+ return separators.includes(short.charAt(short.length - ref.length - 1));
21401
+ });
21402
+ };
21403
+ };
21404
+ /**
21405
+ * Parses `git ls-remote` output: one `<sha>\t<refname>` line per advertised
21406
+ * ref. Line-based deliberately — refnames cannot contain a newline (or a
21407
+ * tab), so the split is safe without a `-z` mode (which `ls-remote` does not
21408
+ * offer).
21409
+ */
21410
+ const parseLsRemote = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21411
+ const tabIndex = line.indexOf(" ");
21412
+ return LsRemoteEntry.make({
21413
+ sha: line.slice(0, tabIndex),
21414
+ ref: line.slice(tabIndex + 1)
21415
+ });
21416
+ });
21417
+ /**
21418
+ * One stash entry, from `git stash list`.
21419
+ *
21420
+ * @public
21421
+ */
21422
+ var StashEntry = class extends effect.Schema.Class("StashEntry")({
21423
+ /** The reflog selector (`stash@{0}`) — the index other stash methods take. */
21424
+ ref: effect.Schema.String,
21425
+ /** The stash commit's sha. */
21426
+ sha: effect.Schema.String,
21427
+ /** The reflog subject: `WIP on <branch>: ...` or `On <branch>: <message>`. */
21428
+ message: effect.Schema.String
21429
+ }) {};
21430
+ /**
21431
+ * Parses `git stash list -z --format=%gd%x1f%H%x1f%gs` output: NUL-terminated
21432
+ * records of unit-separated (`\x1f`) fields. Reflog subjects are single-line
21433
+ * and cannot contain either separator byte.
21434
+ */
21435
+ const parseStashList = (output) => parseNulSeparated(output).map((record) => {
21436
+ const [ref = "", sha = "", ...rest] = record.split("");
21437
+ return StashEntry.make({
21438
+ ref,
21439
+ sha,
21440
+ message: rest.join("")
21441
+ });
21442
+ });
21443
+ /**
21444
+ * One local (or remote-tracking) branch, from `git branch --list`.
21445
+ *
21446
+ * @public
21447
+ */
21448
+ var BranchEntry = class extends effect.Schema.Class("BranchEntry")({
21449
+ /** The short branch name (`main`, or `origin/main` for a remote branch). */
21450
+ name: effect.Schema.String,
21451
+ /** The branch tip's sha. */
21452
+ sha: effect.Schema.String,
21453
+ /** Whether this branch is checked out in the current working tree. */
21454
+ current: effect.Schema.Boolean
21455
+ }) {};
21456
+ /**
21457
+ * Parses `git branch --list --format=%(HEAD)%00%(refname:short)%00%(objectname)`
21458
+ * output: newline-separated records (refnames cannot contain newlines) of
21459
+ * NUL-separated fields. The `%(HEAD)` marker is `*` for the checked-out
21460
+ * branch; anything else (` `, or `+` for a branch checked out in a linked
21461
+ * worktree) is not-current.
21462
+ */
21463
+ const parseBranchList = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21464
+ const [marker = "", name = "", sha = ""] = line.split("\0");
21465
+ return BranchEntry.make({
21466
+ name,
21467
+ sha,
21468
+ current: marker === "*"
21469
+ });
21470
+ });
21471
+ /**
21472
+ * One ref, from `git for-each-ref`.
21473
+ *
21474
+ * @public
21475
+ */
21476
+ var RefEntry = class extends effect.Schema.Class("RefEntry")({
21477
+ /** The full refname (`refs/tags/v1`). */
21478
+ ref: effect.Schema.String,
21479
+ /** The sha of the object the ref points at. */
21480
+ sha: effect.Schema.String,
21481
+ /**
21482
+ * The pointed-at object's type. An annotated tag is `tag` (the tag
21483
+ * object itself, not its target commit).
21484
+ */
21485
+ objectType: effect.Schema.Literals([
21486
+ "commit",
21487
+ "tag",
21488
+ "tree",
21489
+ "blob"
21490
+ ])
21491
+ }) {};
21492
+ /**
21493
+ * Parses `git for-each-ref --format=%(refname)%00%(objectname)%00%(objecttype)`
21494
+ * output: newline-separated records (refnames cannot contain newlines) of
21495
+ * NUL-separated fields.
21496
+ */
21497
+ const parseForEachRef = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21498
+ const [ref = "", sha = "", objectType = "commit"] = line.split("\0");
21499
+ return RefEntry.make({
21500
+ ref,
21501
+ sha,
21502
+ objectType
21503
+ });
21504
+ });
21505
+ /**
21506
+ * One configuration entry, from `git config --list`.
21507
+ *
21508
+ * @public
21509
+ */
21510
+ var ConfigListEntry = class extends effect.Schema.Class("ConfigListEntry")({
21511
+ /** The canonical dotted key (`section.subsection.key`). */
21512
+ key: effect.Schema.String,
21513
+ /**
21514
+ * The raw value. A valueless key (git's boolean-true shorthand,
21515
+ * `[section]` + bare `key`) surfaces as the empty string — distinguish it
21516
+ * with `configGetAll` if the difference matters.
21517
+ */
21518
+ value: effect.Schema.String
21519
+ }) {};
21520
+ /**
21521
+ * Parses `git config --list -z` output: NUL-terminated records, key separated
21522
+ * from value by the FIRST newline (a config value may itself contain
21523
+ * newlines — the reason `-z` is load-bearing). A record with no newline is a
21524
+ * valueless boolean-shorthand key.
21525
+ */
21526
+ const parseConfigList = (output) => parseNulSeparated(output).map((record) => {
21527
+ const newlineIndex = record.indexOf("\n");
21528
+ return newlineIndex === -1 ? ConfigListEntry.make({
21529
+ key: record,
21530
+ value: ""
21531
+ }) : ConfigListEntry.make({
21532
+ key: record.slice(0, newlineIndex),
21533
+ value: record.slice(newlineIndex + 1)
21534
+ });
21535
+ });
21536
+ /**
21537
+ * One working tree, from `git worktree list --porcelain`.
21538
+ *
21539
+ * @public
21540
+ */
21541
+ var WorktreeEntry = class extends effect.Schema.Class("WorktreeEntry")({
21542
+ /** The working tree's absolute path. */
21543
+ path: effect.Schema.String,
21544
+ /** The checked-out commit sha; absent for a bare repository entry. */
21545
+ head: effect.Schema.optionalKey(effect.Schema.String),
21546
+ /** The checked-out branch's full refname; absent when detached or bare. */
21547
+ branch: effect.Schema.optionalKey(effect.Schema.String),
21548
+ /** Whether the working tree is in detached-HEAD state. */
21549
+ detached: effect.Schema.Boolean,
21550
+ /** Whether the entry is the bare repository itself. */
21551
+ bare: effect.Schema.Boolean,
21552
+ /** Present when the worktree is locked; holds the lock reason (possibly empty). */
21553
+ locked: effect.Schema.optionalKey(effect.Schema.String),
21554
+ /** Present when the worktree is prunable; holds the reason (possibly empty). */
21555
+ prunable: effect.Schema.optionalKey(effect.Schema.String)
21556
+ }) {};
21557
+ /**
21558
+ * Parses `git worktree list --porcelain -z` output: NUL-terminated attribute
21559
+ * lines, one blank attribute terminating each entry. Attribute vocabulary:
21560
+ * `worktree <path>`, `HEAD <sha>`, `branch <ref>`, and the flag/annotation
21561
+ * attributes `detached`, `bare`, `locked [<reason>]`, `prunable [<reason>]`.
21562
+ */
21563
+ const parseWorktreeList = (output) => {
21564
+ const entries = [];
21565
+ let path;
21566
+ let head;
21567
+ let branch;
21568
+ let detached = false;
21569
+ let bare = false;
21570
+ let locked;
21571
+ let prunable;
21572
+ const flush = () => {
21573
+ if (path !== void 0) entries.push(WorktreeEntry.make({
21574
+ path,
21575
+ detached,
21576
+ bare,
21577
+ ...head !== void 0 ? { head } : {},
21578
+ ...branch !== void 0 ? { branch } : {},
21579
+ ...locked !== void 0 ? { locked } : {},
21580
+ ...prunable !== void 0 ? { prunable } : {}
21581
+ }));
21582
+ path = void 0;
21583
+ head = void 0;
21584
+ branch = void 0;
21585
+ detached = false;
21586
+ bare = false;
21587
+ locked = void 0;
21588
+ prunable = void 0;
21589
+ };
21590
+ for (const attribute of output.split("\0")) if (attribute === "") flush();
21591
+ else if (attribute.startsWith("worktree ")) path = attribute.slice(9);
21592
+ else if (attribute.startsWith("HEAD ")) head = attribute.slice(5);
21593
+ else if (attribute.startsWith("branch ")) branch = attribute.slice(7);
21594
+ else if (attribute === "detached") detached = true;
21595
+ else if (attribute === "bare") bare = true;
21596
+ else if (attribute === "locked" || attribute.startsWith("locked ")) locked = attribute === "locked" ? "" : attribute.slice(7);
21597
+ else if (attribute === "prunable" || attribute.startsWith("prunable ")) prunable = attribute === "prunable" ? "" : attribute.slice(9);
21598
+ flush();
21599
+ return entries;
21600
+ };
21601
+ /**
21602
+ * One index (staging area) entry, from `git ls-files --stage`.
21603
+ *
21604
+ * @remarks
21605
+ * The index-side sibling of {@link LsTreeEntry}: this is the ONLY place a
21606
+ * staged-but-uncommitted gitlink (`mode` `160000`) is visible — `lsTree`
21607
+ * reads the committed tree and misses exactly that window.
21608
+ *
21609
+ * @public
21610
+ */
21611
+ var LsFilesEntry = class extends effect.Schema.Class("LsFilesEntry")({
21612
+ /** The entry's file mode, e.g. `100644` — `160000` for a gitlink. */
21613
+ mode: effect.Schema.String,
21614
+ /** The staged object id. */
21615
+ oid: effect.Schema.String,
21616
+ /** The merge stage: `0` normally; `1`/`2`/`3` during an unresolved merge. */
21617
+ stage: effect.Schema.Number,
21618
+ /** The entry's path, relative to `cwd`. May contain spaces or newlines. */
21619
+ path: effect.Schema.String
21620
+ }) {};
21621
+ /**
21622
+ * Parses `git ls-files --stage -z` output: each NUL-terminated entry is
21623
+ * `<mode> <oid> <stage>\t<path>`. `path` is everything after the first tab,
21624
+ * so a path containing spaces or newlines is preserved intact — the same
21625
+ * split rule as `parseLsTree`.
21626
+ */
21627
+ const parseLsFiles = (output) => parseNulSeparated(output).map((entry) => {
21628
+ const tabIndex = entry.indexOf(" ");
21629
+ const header = entry.slice(0, tabIndex).split(" ");
21630
+ return LsFilesEntry.make({
21631
+ mode: header[0] ?? "",
21632
+ oid: header[1] ?? "",
21633
+ stage: Number(header[2] ?? "0"),
21634
+ path: entry.slice(tabIndex + 1)
21635
+ });
21636
+ });
21637
+ /**
21638
+ * Refuse a caller-supplied ref or range that git would parse as an option.
21639
+ *
21640
+ * Refs are caller-controlled and land in git's argv as positional entries; a
21641
+ * value beginning with `-` is read as a flag instead — `checkout("-b")` would
21642
+ * CREATE a branch. A bare `--` separator is not a safe fix for every command
21643
+ * (it switches `checkout` into pathspec mode), so option-like values are
21644
+ * refused outright, before any spawn, as a typed {@link GitCommandError}.
21645
+ * `show`'s `path` needs no guard: it is fused after the ref into one
21646
+ * `ref:path` token, which cannot begin with `-` unless the ref does.
21647
+ *
21648
+ * `sensitive` values get the same check but a REDACTED report: a refused
21649
+ * sensitive positional (a `configSet` value) must not leak into
21650
+ * `GitCommandError.args`/`detail` any more than a spawned one may — the #86
21651
+ * redaction policy applies to guard rejections too.
21652
+ */
21653
+ const rejectOptionLikeRefs = (cwd, refs, sensitive = []) => {
21654
+ const offending = refs.find((ref) => ref.startsWith("-"));
21655
+ if (offending !== void 0) return effect.Effect.fail(new GitCommandError({
21656
+ kind: "refused",
21657
+ args: [offending],
21658
+ cwd,
21659
+ stderr: "",
21660
+ detail: `refused a ref argument git would parse as an option: ${JSON.stringify(offending)}`
21661
+ }));
21662
+ return sensitive.find((value) => value.startsWith("-")) === void 0 ? effect.Effect.void : effect.Effect.fail(new GitCommandError({
21663
+ kind: "refused",
21664
+ args: ["<redacted>"],
21665
+ cwd,
21666
+ stderr: "",
21667
+ detail: "refused a sensitive argument git would parse as an option (value redacted)"
21668
+ }));
21669
+ };
21670
+ /**
21671
+ * Refuse a caller-supplied numeric index/limit that is not a non-negative
21672
+ * integer.
21673
+ *
21674
+ * Every relational comparison against `NaN` is `false`, so a bare
21675
+ * `value < 0` guard admits `NaN` (and a fractional value truncates nothing —
21676
+ * it rides straight into the argv as `stash@{1.5}` / `--max-count=NaN`).
21677
+ * Integrality and range are therefore checked together, pre-spawn, as a
21678
+ * typed refusal.
21679
+ */
21680
+ const rejectNonNaturalNumber = (cwd, label, value) => value === void 0 || Number.isInteger(value) && value >= 0 ? effect.Effect.void : effect.Effect.fail(new GitCommandError({
21681
+ kind: "refused",
21682
+ args: [String(value)],
21683
+ cwd,
21684
+ stderr: "",
21685
+ detail: `refused ${label}: expected a non-negative integer, received ${value}`
21686
+ }));
21687
+ /** Builds the `Git.Service` shape over an already-resolved `ChildProcessSpawner`. */
21688
+ const make = (spawner) => {
21689
+ const runFor = (invocation, cwd, kind) => runClassified(invocation, cwd, kind).pipe(effect.Effect.provideService(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, spawner));
21690
+ const show = effect.Effect.fn("Git.show")(function* (cwd, ref, path) {
21691
+ yield* effect.Effect.annotateCurrentSpan({
21692
+ cwd,
21693
+ ref,
21694
+ path
21695
+ });
21696
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21697
+ const classified = yield* runFor(GitCommand.show(ref, path), cwd, "show");
21698
+ switch (classified._tag) {
21699
+ case "success": return effect.Option.some(classified.output);
21700
+ case "absent": return effect.Option.none();
21701
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21702
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21703
+ ref,
21704
+ cwd
21705
+ }));
21706
+ case "failure": return yield* effect.Effect.fail(classified.error);
21707
+ default: return yield* effect.Effect.die(`Git.show: unexpected classification "${classified._tag}"`);
21708
+ }
21709
+ });
21710
+ const lsTree = effect.Effect.fn("Git.lsTree")(function* (cwd, ref, options) {
21711
+ yield* effect.Effect.annotateCurrentSpan({
21712
+ cwd,
21713
+ ref
21714
+ });
21715
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21716
+ const classified = yield* runFor(GitCommand.lsTree(ref, options?.pathspec ?? []), cwd, "generic");
21717
+ switch (classified._tag) {
21718
+ case "success": return parseLsTree(classified.output);
21719
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21720
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21721
+ ref,
21722
+ cwd
21723
+ }));
21724
+ case "failure": return yield* effect.Effect.fail(classified.error);
21725
+ default: return yield* effect.Effect.die(`Git.lsTree: unexpected classification "${classified._tag}"`);
21726
+ }
21727
+ });
21728
+ const refExists = effect.Effect.fn("Git.refExists")(function* (cwd, ref) {
21729
+ yield* effect.Effect.annotateCurrentSpan({
21730
+ cwd,
21731
+ ref
21732
+ });
21733
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21734
+ const classified = yield* runFor(GitCommand.refExists(ref), cwd, "refExists");
21735
+ switch (classified._tag) {
21736
+ case "success": return true;
21737
+ case "refMissing": return false;
21738
+ case "unknownRef": return false;
21739
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21740
+ case "failure": return yield* effect.Effect.fail(classified.error);
21741
+ default: return yield* effect.Effect.die(`Git.refExists: unexpected classification "${classified._tag}"`);
21742
+ }
21743
+ });
21744
+ const mergeBase = effect.Effect.fn("Git.mergeBase")(function* (cwd, a, b) {
21745
+ yield* effect.Effect.annotateCurrentSpan({
21746
+ cwd,
21747
+ a,
21748
+ b
21749
+ });
21750
+ yield* rejectOptionLikeRefs(cwd, [a, b]);
21751
+ const classified = yield* runFor(GitCommand.mergeBase(a, b), cwd, "generic");
21752
+ switch (classified._tag) {
21753
+ case "success": return classified.output.trim();
21754
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21755
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21756
+ ref: `${a}...${b}`,
21757
+ cwd
21758
+ }));
21759
+ case "failure": return yield* effect.Effect.fail(classified.error);
21760
+ default: return yield* effect.Effect.die(`Git.mergeBase: unexpected classification "${classified._tag}"`);
21761
+ }
21762
+ });
21763
+ const changedFiles = effect.Effect.fn("Git.changedFiles")(function* (cwd, options) {
21764
+ const relative = options.relative ?? false;
21765
+ yield* effect.Effect.annotateCurrentSpan({
21766
+ cwd,
21767
+ base: options.base,
21768
+ head: options.head,
21769
+ relative
21770
+ });
21771
+ yield* rejectOptionLikeRefs(cwd, [options.base, options.head]);
21772
+ const classified = yield* runFor(GitCommand.changedFiles(options.base, options.head, relative), cwd, "generic");
21773
+ switch (classified._tag) {
21774
+ case "success": return parseNulSeparated(classified.output);
21775
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21776
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21777
+ ref: `${options.base}...${options.head}`,
21778
+ cwd
21779
+ }));
21780
+ case "failure": return yield* effect.Effect.fail(classified.error);
21781
+ default: return yield* effect.Effect.die(`Git.changedFiles: unexpected classification "${classified._tag}"`);
21782
+ }
21783
+ });
21784
+ const collectPaths = (method, invocation, cwd) => effect.Effect.gen(function* () {
21785
+ const classified = yield* runFor(invocation, cwd, "generic");
21786
+ switch (classified._tag) {
21787
+ case "success": return parseNulSeparated(classified.output);
21788
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21789
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21790
+ ref: "working tree",
21791
+ cwd
21792
+ }));
21793
+ case "failure": return yield* effect.Effect.fail(classified.error);
21794
+ default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
21795
+ }
21796
+ });
21797
+ const unstagedChanges = effect.Effect.fn("Git.unstagedChanges")(function* (cwd, options) {
21798
+ const relative = options?.relative ?? false;
21799
+ yield* effect.Effect.annotateCurrentSpan({
21800
+ cwd,
21801
+ relative
21802
+ });
21803
+ return yield* collectPaths("Git.unstagedChanges", GitCommand.unstagedChanges(relative), cwd);
21804
+ });
21805
+ const stagedChanges = effect.Effect.fn("Git.stagedChanges")(function* (cwd, options) {
21806
+ const relative = options?.relative ?? false;
21807
+ yield* effect.Effect.annotateCurrentSpan({
21808
+ cwd,
21809
+ relative
21810
+ });
21811
+ return yield* collectPaths("Git.stagedChanges", GitCommand.stagedChanges(relative), cwd);
21812
+ });
21813
+ const untrackedFiles = effect.Effect.fn("Git.untrackedFiles")(function* (cwd, options) {
21814
+ const relative = options?.relative ?? false;
21815
+ yield* effect.Effect.annotateCurrentSpan({
21816
+ cwd,
21817
+ relative
21818
+ });
21819
+ return yield* collectPaths("Git.untrackedFiles", GitCommand.untrackedFiles(relative), cwd);
21820
+ });
21821
+ const workingChanges = effect.Effect.fn("Git.workingChanges")(function* (cwd, options) {
21822
+ yield* effect.Effect.annotateCurrentSpan({
21823
+ cwd,
21824
+ relative: options?.relative ?? false
21825
+ });
21826
+ const unstaged = yield* unstagedChanges(cwd, options);
21827
+ const staged = yield* stagedChanges(cwd, options);
21828
+ const untracked = yield* untrackedFiles(cwd, options);
21829
+ return [.../* @__PURE__ */ new Set([
21830
+ ...unstaged,
21831
+ ...staged,
21832
+ ...untracked
21833
+ ])];
21834
+ });
21835
+ const nameStatus = effect.Effect.fn("Git.nameStatus")(function* (cwd, options) {
21836
+ const relative = options.relative ?? false;
21837
+ yield* effect.Effect.annotateCurrentSpan({
21838
+ cwd,
21839
+ base: options.base,
21840
+ head: options.head ?? "(working tree)",
21841
+ relative
21842
+ });
21843
+ yield* rejectOptionLikeRefs(cwd, options.head === void 0 ? [options.base] : [options.base, options.head]);
21844
+ const classified = yield* runFor(GitCommand.nameStatus(options.base, options.head, relative), cwd, "generic");
21845
+ switch (classified._tag) {
21846
+ case "success": return parseNameStatus(classified.output);
21847
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21848
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21849
+ ref: options.head === void 0 ? options.base : `${options.base}...${options.head}`,
21850
+ cwd
21851
+ }));
21852
+ case "failure": return yield* effect.Effect.fail(classified.error);
21853
+ default: return yield* effect.Effect.die(`Git.nameStatus: unexpected classification "${classified._tag}"`);
21854
+ }
21855
+ });
21856
+ const revParse = effect.Effect.fn("Git.revParse")(function* (cwd, ref) {
21857
+ yield* effect.Effect.annotateCurrentSpan({
21858
+ cwd,
21859
+ ref
21860
+ });
21861
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21862
+ const classified = yield* runFor(GitCommand.revParse(ref), cwd, "generic");
21863
+ switch (classified._tag) {
21864
+ case "success": return classified.output.trim();
21865
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21866
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21867
+ ref,
21868
+ cwd
21869
+ }));
21870
+ case "failure": return yield* effect.Effect.fail(classified.error);
21871
+ default: return yield* effect.Effect.die(`Git.revParse: unexpected classification "${classified._tag}"`);
21872
+ }
21873
+ });
21874
+ const checkout = effect.Effect.fn("Git.checkout")(function* (cwd, ref, options) {
21875
+ const detach = options?.detach ?? false;
21876
+ yield* effect.Effect.annotateCurrentSpan({
21877
+ cwd,
21878
+ ref,
21879
+ detach
21880
+ });
21881
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21882
+ const classified = yield* runFor(GitCommand.checkout(ref, detach), cwd, "generic");
21883
+ switch (classified._tag) {
21884
+ case "success": return;
21885
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21886
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21887
+ ref,
21888
+ cwd
21889
+ }));
21890
+ case "failure": return yield* effect.Effect.fail(classified.error);
21891
+ default: return yield* effect.Effect.die(`Git.checkout: unexpected classification "${classified._tag}"`);
21892
+ }
21893
+ });
21894
+ const reset = effect.Effect.fn("Git.reset")(function* (cwd, options) {
21895
+ const mode = options?.mode ?? "mixed";
21896
+ yield* effect.Effect.annotateCurrentSpan({
21897
+ cwd,
21898
+ mode,
21899
+ ref: options?.ref ?? "HEAD"
21900
+ });
21901
+ if (options?.ref !== void 0) yield* rejectOptionLikeRefs(cwd, [options.ref]);
21902
+ const classified = yield* runFor(GitCommand.reset(mode, options?.ref), cwd, "generic");
21903
+ switch (classified._tag) {
21904
+ case "success": return;
21905
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21906
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21907
+ ref: options?.ref ?? "HEAD",
21908
+ cwd
21909
+ }));
21910
+ case "failure": return yield* effect.Effect.fail(classified.error);
21911
+ default: return yield* effect.Effect.die(`Git.reset: unexpected classification "${classified._tag}"`);
21912
+ }
21913
+ });
21914
+ const clean = effect.Effect.fn("Git.clean")(function* (cwd, options) {
21915
+ const directories = options?.directories ?? false;
21916
+ const ignored = options?.ignored ?? false;
21917
+ yield* effect.Effect.annotateCurrentSpan({
21918
+ cwd,
21919
+ directories,
21920
+ ignored
21921
+ });
21922
+ const classified = yield* runFor(GitCommand.clean(directories, ignored, options?.paths ?? []), cwd, "generic");
21923
+ switch (classified._tag) {
21924
+ case "success": return;
21925
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21926
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21927
+ ref: "working tree",
21928
+ cwd
21929
+ }));
21930
+ case "failure": return yield* effect.Effect.fail(classified.error);
21931
+ default: return yield* effect.Effect.die(`Git.clean: unexpected classification "${classified._tag}"`);
21932
+ }
21933
+ });
21934
+ const restore = effect.Effect.fn("Git.restore")(function* (cwd, paths, options) {
21935
+ yield* effect.Effect.annotateCurrentSpan({
21936
+ cwd,
21937
+ count: paths.length,
21938
+ source: options?.source ?? "(index)"
21939
+ });
21940
+ if (options?.source !== void 0) yield* rejectOptionLikeRefs(cwd, [options.source]);
21941
+ const classified = yield* runFor(GitCommand.restore(paths, options?.source, options?.staged ?? false, options?.worktree ?? false), cwd, "generic");
21942
+ switch (classified._tag) {
21943
+ case "success": return;
21944
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21945
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21946
+ ref: options?.source ?? "working tree",
21947
+ cwd
21948
+ }));
21949
+ case "failure": return yield* effect.Effect.fail(classified.error);
21950
+ default: return yield* effect.Effect.die(`Git.restore: unexpected classification "${classified._tag}"`);
21951
+ }
21952
+ });
21953
+ const branchCreate = effect.Effect.fn("Git.branchCreate")(function* (cwd, name, options) {
21954
+ const checkoutBranch = options?.checkout ?? false;
21955
+ const force = options?.force ?? false;
21956
+ yield* effect.Effect.annotateCurrentSpan({
21957
+ cwd,
21958
+ name,
21959
+ startPoint: options?.startPoint ?? "HEAD",
21960
+ checkout: checkoutBranch,
21961
+ force
21962
+ });
21963
+ yield* rejectOptionLikeRefs(cwd, [name, ...options?.startPoint !== void 0 ? [options.startPoint] : []]);
21964
+ const classified = yield* runFor(GitCommand.branchCreate(name, options?.startPoint, checkoutBranch, force), cwd, "generic");
21965
+ switch (classified._tag) {
21966
+ case "success": return;
21967
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21968
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21969
+ ref: options?.startPoint ?? name,
21970
+ cwd
21971
+ }));
21972
+ case "failure": return yield* effect.Effect.fail(classified.error);
21973
+ default: return yield* effect.Effect.die(`Git.branchCreate: unexpected classification "${classified._tag}"`);
21974
+ }
21975
+ });
21976
+ const branchDelete = effect.Effect.fn("Git.branchDelete")(function* (cwd, name, options) {
21977
+ yield* effect.Effect.annotateCurrentSpan({
21978
+ cwd,
21979
+ name,
21980
+ force: options?.force ?? false
21981
+ });
21982
+ yield* rejectOptionLikeRefs(cwd, [name]);
21983
+ const classified = yield* runFor(GitCommand.branchDelete(name, options?.force ?? false), cwd, "generic");
21984
+ switch (classified._tag) {
21985
+ case "success": return;
21986
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21987
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21988
+ ref: name,
21989
+ cwd
21990
+ }));
21991
+ case "failure": return yield* effect.Effect.fail(classified.error);
21992
+ default: return yield* effect.Effect.die(`Git.branchDelete: unexpected classification "${classified._tag}"`);
21993
+ }
21994
+ });
21995
+ const isShallow = effect.Effect.fn("Git.isShallow")(function* (cwd) {
21996
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
21997
+ const classified = yield* runFor(GitCommand.isShallow(), cwd, "generic");
21998
+ switch (classified._tag) {
21999
+ case "success": return classified.output.trim() === "true";
22000
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22001
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22002
+ ref: "HEAD",
22003
+ cwd
22004
+ }));
22005
+ case "failure": return yield* effect.Effect.fail(classified.error);
22006
+ default: return yield* effect.Effect.die(`Git.isShallow: unexpected classification "${classified._tag}"`);
22007
+ }
22008
+ });
22009
+ const fetchUnshallow = effect.Effect.fn("Git.fetchUnshallow")(function* (cwd, options) {
22010
+ const remote = options?.remote ?? "origin";
22011
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22012
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22013
+ const classified = yield* runFor(GitCommand.fetchUnshallow(remote), cwd, "generic");
22014
+ switch (classified._tag) {
22015
+ case "success": return;
22016
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22017
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22018
+ ref: "--unshallow",
22019
+ cwd
22020
+ }));
22021
+ case "failure": return yield* effect.Effect.fail(classified.error);
22022
+ default: return yield* effect.Effect.die(`Git.fetchUnshallow: unexpected classification "${classified._tag}"`);
22023
+ }
22024
+ });
22025
+ const fetch = effect.Effect.fn("Git.fetch")(function* (cwd, options) {
22026
+ const remote = options.remote ?? "origin";
22027
+ const tag = options.tag ?? false;
22028
+ yield* effect.Effect.annotateCurrentSpan({
22029
+ cwd,
22030
+ ref: options.ref,
22031
+ tag
22032
+ });
22033
+ yield* rejectOptionLikeRefs(cwd, [remote, options.ref]);
22034
+ yield* rejectNonNaturalNumber(cwd, "a fetch depth", options.depth);
22035
+ const classified = yield* runFor(GitCommand.fetch(remote, options.ref, options.depth, tag), cwd, "generic");
22036
+ switch (classified._tag) {
22037
+ case "success": return;
22038
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22039
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22040
+ ref: options.ref,
22041
+ cwd
22042
+ }));
22043
+ case "failure": return yield* effect.Effect.fail(classified.error);
22044
+ default: return yield* effect.Effect.die(`Git.fetch: unexpected classification "${classified._tag}"`);
22045
+ }
22046
+ });
22047
+ const fetchAny = effect.Effect.fn("Git.fetchAny")(function* (cwd, options) {
22048
+ yield* effect.Effect.annotateCurrentSpan({
22049
+ cwd,
22050
+ ref: options.ref
22051
+ });
22052
+ return yield* fetch(cwd, {
22053
+ ...options,
22054
+ tag: true
22055
+ }).pipe(effect.Effect.catchTag(["UnknownRefError", "GitCommandError"], (error) => error._tag === "GitCommandError" && error.kind === "refused" ? effect.Effect.fail(error) : fetch(cwd, options)));
22056
+ });
22057
+ const submoduleUpdate = effect.Effect.fn("Git.submoduleUpdate")(function* (cwd, options) {
22058
+ const init = options?.init ?? false;
22059
+ yield* effect.Effect.annotateCurrentSpan({
22060
+ cwd,
22061
+ init
22062
+ });
22063
+ yield* rejectNonNaturalNumber(cwd, "a submodule update depth", options?.depth);
22064
+ const classified = yield* runFor(GitCommand.submoduleUpdate(init, options?.depth, options?.paths ?? []), cwd, "generic");
22065
+ switch (classified._tag) {
22066
+ case "success": return;
22067
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22068
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22069
+ ref: "submodule update",
22070
+ cwd
22071
+ }));
22072
+ case "failure": return yield* effect.Effect.fail(classified.error);
22073
+ default: return yield* effect.Effect.die(`Git.submoduleUpdate: unexpected classification "${classified._tag}"`);
22074
+ }
22075
+ });
22076
+ const submoduleAdd = effect.Effect.fn("Git.submoduleAdd")(function* (cwd, options) {
22077
+ yield* effect.Effect.annotateCurrentSpan({
22078
+ cwd,
22079
+ path: options.path
22080
+ });
22081
+ yield* rejectNonNaturalNumber(cwd, "a submodule add depth", options.depth);
22082
+ const classified = yield* runFor(GitCommand.submoduleAdd(options.url, options.path, options.depth), cwd, "generic");
22083
+ switch (classified._tag) {
22084
+ case "success": return;
22085
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22086
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22087
+ ref: options.path,
22088
+ cwd
22089
+ }));
22090
+ case "failure": return yield* effect.Effect.fail(classified.error);
22091
+ default: return yield* effect.Effect.die(`Git.submoduleAdd: unexpected classification "${classified._tag}"`);
22092
+ }
22093
+ });
22094
+ const sparseCheckoutSet = effect.Effect.fn("Git.sparseCheckoutSet")(function* (cwd, patterns, options) {
22095
+ yield* effect.Effect.annotateCurrentSpan({
22096
+ cwd,
22097
+ cone: options.cone
22098
+ });
22099
+ yield* rejectOptionLikeRefs(cwd, patterns);
22100
+ const classified = yield* runFor(GitCommand.sparseCheckoutSet(patterns, options.cone), cwd, "generic");
22101
+ switch (classified._tag) {
22102
+ case "success": return;
22103
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22104
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22105
+ ref: "sparse-checkout",
22106
+ cwd
22107
+ }));
22108
+ case "failure": return yield* effect.Effect.fail(classified.error);
22109
+ default: return yield* effect.Effect.die(`Git.sparseCheckoutSet: unexpected classification "${classified._tag}"`);
22110
+ }
22111
+ });
22112
+ const configSet = effect.Effect.fn("Git.configSet")(function* (cwd, key, value, options) {
22113
+ yield* effect.Effect.annotateCurrentSpan({
22114
+ cwd,
22115
+ key,
22116
+ file: options?.file ?? "(repository config)"
22117
+ });
22118
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []], [value]);
22119
+ const classified = yield* runFor(GitCommand.configSet(key, value, options?.file), cwd, "generic");
22120
+ switch (classified._tag) {
22121
+ case "success": return;
22122
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22123
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22124
+ ref: key,
22125
+ cwd
22126
+ }));
22127
+ case "failure": return yield* effect.Effect.fail(classified.error);
22128
+ default: return yield* effect.Effect.die(`Git.configSet: unexpected classification "${classified._tag}"`);
22129
+ }
22130
+ });
22131
+ const add = effect.Effect.fn("Git.add")(function* (cwd, paths) {
22132
+ yield* effect.Effect.annotateCurrentSpan({
22133
+ cwd,
22134
+ count: paths.length
22135
+ });
22136
+ const classified = yield* runFor(GitCommand.add(paths), cwd, "generic");
22137
+ switch (classified._tag) {
22138
+ case "success": return;
22139
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22140
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22141
+ ref: "working tree",
22142
+ cwd
22143
+ }));
22144
+ case "failure": return yield* effect.Effect.fail(classified.error);
22145
+ default: return yield* effect.Effect.die(`Git.add: unexpected classification "${classified._tag}"`);
22146
+ }
22147
+ });
22148
+ const defaultBranch = effect.Effect.fn("Git.defaultBranch")(function* (cwd, options) {
22149
+ const remote = options?.remote ?? "origin";
22150
+ yield* effect.Effect.annotateCurrentSpan({
22151
+ cwd,
22152
+ remote
22153
+ });
22154
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22155
+ const classified = yield* runFor(GitCommand.defaultBranch(remote), cwd, "quiet");
22156
+ switch (classified._tag) {
22157
+ case "success": {
22158
+ const short = classified.output.trim();
22159
+ const prefix = `${remote}/`;
22160
+ return effect.Option.some(short.startsWith(prefix) ? short.slice(prefix.length) : short);
22161
+ }
22162
+ case "absent": return effect.Option.none();
22163
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22164
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22165
+ ref: `refs/remotes/${remote}/HEAD`,
22166
+ cwd
22167
+ }));
22168
+ case "failure": return yield* effect.Effect.fail(classified.error);
22169
+ default: return yield* effect.Effect.die(`Git.defaultBranch: unexpected classification "${classified._tag}"`);
22170
+ }
22171
+ });
22172
+ const currentBranch = effect.Effect.fn("Git.currentBranch")(function* (cwd) {
22173
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22174
+ const classified = yield* runFor(GitCommand.currentBranch(), cwd, "generic");
22175
+ switch (classified._tag) {
22176
+ case "success": {
22177
+ const name = classified.output.trim();
22178
+ return name === "HEAD" ? effect.Option.none() : effect.Option.some(name);
22179
+ }
22180
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22181
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22182
+ ref: "HEAD",
22183
+ cwd
22184
+ }));
22185
+ case "failure": return yield* effect.Effect.fail(classified.error);
22186
+ default: return yield* effect.Effect.die(`Git.currentBranch: unexpected classification "${classified._tag}"`);
22187
+ }
22188
+ });
22189
+ const repoRoot = effect.Effect.fn("Git.repoRoot")(function* (cwd) {
22190
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22191
+ const classified = yield* runFor(GitCommand.repoRoot(), cwd, "generic");
22192
+ switch (classified._tag) {
22193
+ case "success": return classified.output.trim();
22194
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22195
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22196
+ ref: "working tree",
22197
+ cwd
22198
+ }));
22199
+ case "failure": return yield* effect.Effect.fail(classified.error);
22200
+ default: return yield* effect.Effect.die(`Git.repoRoot: unexpected classification "${classified._tag}"`);
22201
+ }
22202
+ });
22203
+ const configGet = effect.Effect.fn("Git.configGet")(function* (cwd, key) {
22204
+ yield* effect.Effect.annotateCurrentSpan({
22205
+ cwd,
22206
+ key
22207
+ });
22208
+ yield* rejectOptionLikeRefs(cwd, [key]);
22209
+ const classified = yield* runFor(GitCommand.configGet(key), cwd, "quiet");
22210
+ switch (classified._tag) {
22211
+ case "success": return effect.Option.some(classified.output.trim());
22212
+ case "absent": return effect.Option.none();
22213
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22214
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22215
+ ref: key,
22216
+ cwd
22217
+ }));
22218
+ case "failure": return yield* effect.Effect.fail(classified.error);
22219
+ default: return yield* effect.Effect.die(`Git.configGet: unexpected classification "${classified._tag}"`);
22220
+ }
22221
+ });
22222
+ const remoteUrl = effect.Effect.fn("Git.remoteUrl")(function* (cwd, options) {
22223
+ const remote = options?.remote ?? "origin";
22224
+ yield* effect.Effect.annotateCurrentSpan({
22225
+ cwd,
22226
+ remote
22227
+ });
22228
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22229
+ const classified = yield* runFor(GitCommand.remoteUrl(remote), cwd, "noSuchRemote");
22230
+ switch (classified._tag) {
22231
+ case "success": return effect.Option.some(classified.output.trim());
22232
+ case "absent": return effect.Option.none();
22233
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22234
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22235
+ ref: remote,
22236
+ cwd
22237
+ }));
22238
+ case "failure": return yield* effect.Effect.fail(classified.error);
22239
+ default: return yield* effect.Effect.die(`Git.remoteUrl: unexpected classification "${classified._tag}"`);
20671
22240
  }
20672
- const letter = code.charAt(0);
20673
- const status = NAME_STATUS_CODES[letter] ?? "unknown";
20674
- if (letter === "R" || letter === "C") {
20675
- entries.push(NameStatusEntry.make({
20676
- status,
20677
- path: tokens[index + 2] ?? "",
20678
- oldPath: tokens[index + 1] ?? ""
22241
+ });
22242
+ const commitInfo = effect.Effect.fn("Git.commitInfo")(function* (cwd, ref) {
22243
+ const target = ref ?? "HEAD";
22244
+ yield* effect.Effect.annotateCurrentSpan({
22245
+ cwd,
22246
+ ref: target
22247
+ });
22248
+ yield* rejectOptionLikeRefs(cwd, [target]);
22249
+ const classified = yield* runFor(GitCommand.commitInfo(target), cwd, "generic");
22250
+ switch (classified._tag) {
22251
+ case "success": return parseCommitInfo(classified.output);
22252
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22253
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22254
+ ref: target,
22255
+ cwd
20679
22256
  }));
20680
- index += 3;
20681
- } else {
20682
- entries.push(NameStatusEntry.make({
20683
- status,
20684
- path: tokens[index + 1] ?? ""
22257
+ case "failure": return yield* effect.Effect.fail(classified.error);
22258
+ default: return yield* effect.Effect.die(`Git.commitInfo: unexpected classification "${classified._tag}"`);
22259
+ }
22260
+ });
22261
+ const status = effect.Effect.fn("Git.status")(function* (cwd) {
22262
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22263
+ const classified = yield* runFor(GitCommand.status(), cwd, "generic");
22264
+ switch (classified._tag) {
22265
+ case "success": return parseStatus(classified.output);
22266
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22267
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22268
+ ref: "working tree",
22269
+ cwd
20685
22270
  }));
20686
- index += 2;
22271
+ case "failure": return yield* effect.Effect.fail(classified.error);
22272
+ default: return yield* effect.Effect.die(`Git.status: unexpected classification "${classified._tag}"`);
20687
22273
  }
20688
- }
20689
- return entries;
20690
- };
20691
- /**
20692
- * The metadata of a single commit, read via `git log -1` with NUL-separated
20693
- * `%H` / `%G?` / `%B` placeholders.
20694
- *
20695
- * @public
20696
- */
20697
- var CommitInfo = class extends effect.Schema.Class("CommitInfo")({
20698
- /** The commit's full object id (`%H`). */
20699
- sha: effect.Schema.String,
20700
- /** git's `%G?` signature verdict: Good, Bad, Unknown validity, eXpired, expired-key (Y), Revoked, cannot-check (E), None. */
20701
- signatureStatus: effect.Schema.Literals([
20702
- "G",
20703
- "B",
20704
- "U",
20705
- "X",
20706
- "Y",
20707
- "R",
20708
- "E",
20709
- "N"
20710
- ]),
20711
- /** The raw commit message (`%B`), untrimmed — includes git's trailing format newline. */
20712
- message: effect.Schema.String
20713
- }) {};
20714
- /** One two-letter porcelain v1 status axis code. */
20715
- const porcelainCode = effect.Schema.Literals([
20716
- " ",
20717
- "M",
20718
- "T",
20719
- "A",
20720
- "D",
20721
- "R",
20722
- "C",
20723
- "U",
20724
- "?",
20725
- "!"
20726
- ]);
20727
- /**
20728
- * One entry of a `git status --porcelain -z` listing.
20729
- *
20730
- * @public
20731
- */
20732
- var StatusEntry = class extends effect.Schema.Class("StatusEntry")({
20733
- /** The index-side status code (first porcelain column). */
20734
- x: porcelainCode,
20735
- /** The working-tree-side status code (second porcelain column). */
20736
- y: porcelainCode,
20737
- /** The entry's path — for a rename or copy, the NEW path. */
20738
- path: effect.Schema.String,
20739
- /** The original path; present only on rename/copy entries. */
20740
- origPath: effect.Schema.optionalKey(effect.Schema.String)
20741
- }) {};
20742
- /**
20743
- * Parses `git log -1 --format=%H%x00%G?%x00%B` output: exactly two NUL
20744
- * separators, everything after the second is the raw message, untrimmed.
20745
- * Only ever called on the successful output of this package's own format
20746
- * string, so the separators are guaranteed present.
20747
- */
20748
- const parseCommitInfo = (output) => {
20749
- const first = output.indexOf("\0");
20750
- const second = output.indexOf("\0", first + 1);
20751
- return CommitInfo.make({
20752
- sha: output.slice(0, first),
20753
- signatureStatus: output.slice(first + 1, second),
20754
- message: output.slice(second + 1)
20755
22274
  });
20756
- };
20757
- /**
20758
- * Parses `git status --porcelain -z` output: each entry is `XY <path>`, and a
20759
- * rename/copy entry appends the ORIGINAL path as one extra NUL token AFTER
20760
- * the new path — the opposite order from `diff --name-status`.
20761
- */
20762
- const parseStatus = (output) => {
20763
- const tokens = output.split("\0");
20764
- const entries = [];
20765
- let index = 0;
20766
- while (index < tokens.length) {
20767
- const token = tokens[index] ?? "";
20768
- if (token === "") {
20769
- index += 1;
20770
- continue;
22275
+ const submoduleStatus = effect.Effect.fn("Git.submoduleStatus")(function* (cwd, options) {
22276
+ yield* effect.Effect.annotateCurrentSpan({
22277
+ cwd,
22278
+ recursive: options?.recursive ?? false
22279
+ });
22280
+ const classified = yield* runFor(GitCommand.submoduleStatus(options?.paths ?? [], options?.recursive ?? false), cwd, "generic");
22281
+ switch (classified._tag) {
22282
+ case "success": return parseSubmoduleStatus(classified.output);
22283
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22284
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22285
+ ref: "submodule status",
22286
+ cwd
22287
+ }));
22288
+ case "failure": return yield* effect.Effect.fail(classified.error);
22289
+ default: return yield* effect.Effect.die(`Git.submoduleStatus: unexpected classification "${classified._tag}"`);
20771
22290
  }
20772
- const x = token.charAt(0);
20773
- const y = token.charAt(1);
20774
- const path = token.slice(3);
20775
- if (x === "R" || x === "C" || y === "R" || y === "C") {
20776
- entries.push(StatusEntry.make({
20777
- x,
20778
- y,
20779
- path,
20780
- origPath: tokens[index + 1] ?? ""
22291
+ });
22292
+ const submoduleInit = effect.Effect.fn("Git.submoduleInit")(function* (cwd, options) {
22293
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22294
+ const classified = yield* runFor(GitCommand.submoduleInit(options?.paths ?? []), cwd, "generic");
22295
+ switch (classified._tag) {
22296
+ case "success": return;
22297
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22298
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22299
+ ref: "submodule init",
22300
+ cwd
20781
22301
  }));
20782
- index += 2;
20783
- } else {
20784
- entries.push(StatusEntry.make({
20785
- x,
20786
- y,
20787
- path
22302
+ case "failure": return yield* effect.Effect.fail(classified.error);
22303
+ default: return yield* effect.Effect.die(`Git.submoduleInit: unexpected classification "${classified._tag}"`);
22304
+ }
22305
+ });
22306
+ const submoduleDeinit = effect.Effect.fn("Git.submoduleDeinit")(function* (cwd, options) {
22307
+ const paths = options.paths ?? [];
22308
+ const all = options.all ?? false;
22309
+ yield* effect.Effect.annotateCurrentSpan({
22310
+ cwd,
22311
+ all,
22312
+ count: paths.length
22313
+ });
22314
+ if (!all && paths.length === 0) return yield* effect.Effect.fail(new GitCommandError({
22315
+ kind: "refused",
22316
+ args: ["submodule", "deinit"],
22317
+ cwd,
22318
+ stderr: "",
22319
+ detail: "refused: submoduleDeinit needs either paths or all: true"
22320
+ }));
22321
+ const classified = yield* runFor(GitCommand.submoduleDeinit(paths, all, options.force ?? false), cwd, "generic");
22322
+ switch (classified._tag) {
22323
+ case "success": return;
22324
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22325
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22326
+ ref: "submodule deinit",
22327
+ cwd
20788
22328
  }));
20789
- index += 1;
22329
+ case "failure": return yield* effect.Effect.fail(classified.error);
22330
+ default: return yield* effect.Effect.die(`Git.submoduleDeinit: unexpected classification "${classified._tag}"`);
20790
22331
  }
20791
- }
20792
- return entries;
20793
- };
20794
- /**
20795
- * Refuse a caller-supplied ref or range that git would parse as an option.
20796
- *
20797
- * Refs are caller-controlled and land in git's argv as positional entries; a
20798
- * value beginning with `-` is read as a flag instead — `checkout("-b")` would
20799
- * CREATE a branch. A bare `--` separator is not a safe fix for every command
20800
- * (it switches `checkout` into pathspec mode), so option-like values are
20801
- * refused outright, before any spawn, as a typed {@link GitCommandError}.
20802
- * `show`'s `path` needs no guard: it is fused after the ref into one
20803
- * `ref:path` token, which cannot begin with `-` unless the ref does.
20804
- */
20805
- const rejectOptionLikeRefs = (cwd, refs) => {
20806
- const offending = refs.find((ref) => ref.startsWith("-"));
20807
- return offending === void 0 ? effect.Effect.void : effect.Effect.fail(new GitCommandError({
20808
- kind: "refused",
20809
- args: [offending],
20810
- cwd,
20811
- stderr: "",
20812
- detail: `refused a ref argument git would parse as an option: ${JSON.stringify(offending)}`
20813
- }));
20814
- };
20815
- /** Builds the `Git.Service` shape over an already-resolved `ChildProcessSpawner`. */
20816
- const make = (spawner) => {
20817
- const runFor = (command, cwd, kind) => runClassified(command, cwd, kind).pipe(effect.Effect.provideService(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, spawner));
20818
- const show = effect.Effect.fn("Git.show")(function* (cwd, ref, path) {
22332
+ });
22333
+ const submoduleSync = effect.Effect.fn("Git.submoduleSync")(function* (cwd, options) {
20819
22334
  yield* effect.Effect.annotateCurrentSpan({
20820
22335
  cwd,
20821
- ref,
20822
- path
22336
+ recursive: options?.recursive ?? false
20823
22337
  });
20824
- yield* rejectOptionLikeRefs(cwd, [ref]);
20825
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.show(ref, path), cwd);
20826
- const classified = yield* runFor(command, cwd, "show");
22338
+ const classified = yield* runFor(GitCommand.submoduleSync(options?.paths ?? [], options?.recursive ?? false), cwd, "generic");
20827
22339
  switch (classified._tag) {
20828
- case "success": return effect.Option.some(classified.output);
20829
- case "absent": return effect.Option.none();
22340
+ case "success": return;
20830
22341
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20831
22342
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20832
- ref,
22343
+ ref: "submodule sync",
20833
22344
  cwd
20834
22345
  }));
20835
22346
  case "failure": return yield* effect.Effect.fail(classified.error);
20836
- default: return yield* effect.Effect.die(`Git.show: unexpected classification "${classified._tag}"`);
22347
+ default: return yield* effect.Effect.die(`Git.submoduleSync: unexpected classification "${classified._tag}"`);
20837
22348
  }
20838
22349
  });
20839
- const lsTree = effect.Effect.fn("Git.lsTree")(function* (cwd, ref, options) {
22350
+ const submoduleSetUrl = effect.Effect.fn("Git.submoduleSetUrl")(function* (cwd, path, url) {
20840
22351
  yield* effect.Effect.annotateCurrentSpan({
20841
22352
  cwd,
20842
- ref
22353
+ path
20843
22354
  });
20844
- yield* rejectOptionLikeRefs(cwd, [ref]);
20845
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.lsTree(ref, options?.pathspec ?? []), cwd);
20846
- const classified = yield* runFor(command, cwd, "generic");
22355
+ const classified = yield* runFor(GitCommand.submoduleSetUrl(path, url), cwd, "generic");
20847
22356
  switch (classified._tag) {
20848
- case "success": return parseLsTree(classified.output);
22357
+ case "success": return;
20849
22358
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20850
22359
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20851
- ref,
22360
+ ref: path,
20852
22361
  cwd
20853
22362
  }));
20854
22363
  case "failure": return yield* effect.Effect.fail(classified.error);
20855
- default: return yield* effect.Effect.die(`Git.lsTree: unexpected classification "${classified._tag}"`);
22364
+ default: return yield* effect.Effect.die(`Git.submoduleSetUrl: unexpected classification "${classified._tag}"`);
20856
22365
  }
20857
22366
  });
20858
- const refExists = effect.Effect.fn("Git.refExists")(function* (cwd, ref) {
22367
+ const submoduleSetBranch = effect.Effect.fn("Git.submoduleSetBranch")(function* (cwd, path, options) {
22368
+ const branch = options?.branch;
20859
22369
  yield* effect.Effect.annotateCurrentSpan({
20860
22370
  cwd,
20861
- ref
22371
+ path,
22372
+ branch: branch ?? "(default)"
20862
22373
  });
20863
- yield* rejectOptionLikeRefs(cwd, [ref]);
20864
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.refExists(ref), cwd);
20865
- const classified = yield* runFor(command, cwd, "refExists");
22374
+ if (branch !== void 0) yield* rejectOptionLikeRefs(cwd, [branch]);
22375
+ const classified = yield* runFor(GitCommand.submoduleSetBranch(path, branch), cwd, "generic");
22376
+ switch (classified._tag) {
22377
+ case "success": return;
22378
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22379
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22380
+ ref: branch ?? path,
22381
+ cwd
22382
+ }));
22383
+ case "failure": return yield* effect.Effect.fail(classified.error);
22384
+ default: return yield* effect.Effect.die(`Git.submoduleSetBranch: unexpected classification "${classified._tag}"`);
22385
+ }
22386
+ });
22387
+ const submoduleAbsorbgitdirs = effect.Effect.fn("Git.submoduleAbsorbgitdirs")(function* (cwd, options) {
22388
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22389
+ const classified = yield* runFor(GitCommand.submoduleAbsorbgitdirs(options?.paths ?? []), cwd, "generic");
20866
22390
  switch (classified._tag) {
20867
- case "success": return true;
20868
- case "refMissing": return false;
20869
- case "unknownRef": return false;
22391
+ case "success": return;
20870
22392
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22393
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22394
+ ref: "submodule absorbgitdirs",
22395
+ cwd
22396
+ }));
20871
22397
  case "failure": return yield* effect.Effect.fail(classified.error);
20872
- default: return yield* effect.Effect.die(`Git.refExists: unexpected classification "${classified._tag}"`);
22398
+ default: return yield* effect.Effect.die(`Git.submoduleAbsorbgitdirs: unexpected classification "${classified._tag}"`);
20873
22399
  }
20874
22400
  });
20875
- const mergeBase = effect.Effect.fn("Git.mergeBase")(function* (cwd, a, b) {
22401
+ const submoduleForeach = effect.Effect.fn("Git.submoduleForeach")(function* (cwd, command, options) {
20876
22402
  yield* effect.Effect.annotateCurrentSpan({
20877
22403
  cwd,
20878
- a,
20879
- b
22404
+ recursive: options?.recursive ?? false
20880
22405
  });
20881
- yield* rejectOptionLikeRefs(cwd, [a, b]);
20882
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.mergeBase(a, b), cwd);
20883
- const classified = yield* runFor(command, cwd, "generic");
22406
+ yield* rejectOptionLikeRefs(cwd, [command]);
22407
+ const classified = yield* runFor(GitCommand.submoduleForeach(command, options?.recursive ?? false), cwd, "generic");
20884
22408
  switch (classified._tag) {
20885
- case "success": return classified.output.trim();
22409
+ case "success": return classified.output;
20886
22410
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20887
22411
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20888
- ref: `${a}...${b}`,
22412
+ ref: "submodule foreach",
20889
22413
  cwd
20890
22414
  }));
20891
22415
  case "failure": return yield* effect.Effect.fail(classified.error);
20892
- default: return yield* effect.Effect.die(`Git.mergeBase: unexpected classification "${classified._tag}"`);
22416
+ default: return yield* effect.Effect.die(`Git.submoduleForeach: unexpected classification "${classified._tag}"`);
20893
22417
  }
20894
22418
  });
20895
- const changedFiles = effect.Effect.fn("Git.changedFiles")(function* (cwd, options) {
20896
- const relative = options.relative ?? false;
20897
- yield* effect.Effect.annotateCurrentSpan({
20898
- cwd,
20899
- base: options.base,
20900
- head: options.head,
20901
- relative
20902
- });
20903
- yield* rejectOptionLikeRefs(cwd, [options.base, options.head]);
20904
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.changedFiles(options.base, options.head, relative), cwd);
20905
- const classified = yield* runFor(command, cwd, "generic");
22419
+ const runVoid = (method, invocation, cwd, refLabel) => effect.Effect.gen(function* () {
22420
+ const classified = yield* runFor(invocation, cwd, "generic");
20906
22421
  switch (classified._tag) {
20907
- case "success": return parseNulSeparated(classified.output);
22422
+ case "success": return;
20908
22423
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20909
22424
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20910
- ref: `${options.base}...${options.head}`,
22425
+ ref: refLabel,
20911
22426
  cwd
20912
22427
  }));
20913
22428
  case "failure": return yield* effect.Effect.fail(classified.error);
20914
- default: return yield* effect.Effect.die(`Git.changedFiles: unexpected classification "${classified._tag}"`);
22429
+ default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
20915
22430
  }
20916
22431
  });
20917
- const collectPaths = (method, command, cwd) => effect.Effect.gen(function* () {
20918
- const classified = yield* runFor(command, cwd, "generic");
22432
+ const runParsed = (method, invocation, cwd, refLabel, kind, parse, absent) => effect.Effect.gen(function* () {
22433
+ const classified = yield* runFor(invocation, cwd, kind);
20919
22434
  switch (classified._tag) {
20920
- case "success": return parseNulSeparated(classified.output);
22435
+ case "success": return parse(classified.output);
22436
+ case "absent":
22437
+ if (absent !== void 0) return absent();
22438
+ return yield* effect.Effect.die(`${method}: unexpected classification "absent"`);
20921
22439
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20922
22440
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20923
- ref: "working tree",
22441
+ ref: refLabel,
20924
22442
  cwd
20925
22443
  }));
20926
22444
  case "failure": return yield* effect.Effect.fail(classified.error);
20927
22445
  default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
20928
22446
  }
20929
22447
  });
20930
- const unstagedChanges = effect.Effect.fn("Git.unstagedChanges")(function* (cwd, options) {
20931
- const relative = options?.relative ?? false;
20932
- yield* effect.Effect.annotateCurrentSpan({
20933
- cwd,
20934
- relative
20935
- });
20936
- return yield* collectPaths("Git.unstagedChanges", effect_unstable_process.ChildProcess.setCwd(GitCommand.unstagedChanges(relative), cwd), cwd);
20937
- });
20938
- const stagedChanges = effect.Effect.fn("Git.stagedChanges")(function* (cwd, options) {
20939
- const relative = options?.relative ?? false;
20940
- yield* effect.Effect.annotateCurrentSpan({
20941
- cwd,
20942
- relative
20943
- });
20944
- return yield* collectPaths("Git.stagedChanges", effect_unstable_process.ChildProcess.setCwd(GitCommand.stagedChanges(relative), cwd), cwd);
20945
- });
20946
- const untrackedFiles = effect.Effect.fn("Git.untrackedFiles")(function* (cwd, options) {
20947
- const relative = options?.relative ?? false;
22448
+ const lsRemote = effect.Effect.fn("Git.lsRemote")(function* (cwd, remote, options) {
20948
22449
  yield* effect.Effect.annotateCurrentSpan({
20949
22450
  cwd,
20950
- relative
22451
+ heads: options?.heads ?? false,
22452
+ tags: options?.tags ?? false,
22453
+ patterns: (options?.patterns ?? []).length
20951
22454
  });
20952
- return yield* collectPaths("Git.untrackedFiles", effect_unstable_process.ChildProcess.setCwd(GitCommand.untrackedFiles(relative), cwd), cwd);
22455
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.patterns ?? []]);
22456
+ return yield* runParsed("Git.lsRemote", GitCommand.lsRemote(remote, options?.heads ?? false, options?.tags ?? false, options?.patterns ?? []), cwd, "ls-remote", "generic", parseLsRemote);
20953
22457
  });
20954
- const workingChanges = effect.Effect.fn("Git.workingChanges")(function* (cwd, options) {
22458
+ const remoteAdd = effect.Effect.fn("Git.remoteAdd")(function* (cwd, name, url) {
20955
22459
  yield* effect.Effect.annotateCurrentSpan({
20956
22460
  cwd,
20957
- relative: options?.relative ?? false
22461
+ name
20958
22462
  });
20959
- const unstaged = yield* unstagedChanges(cwd, options);
20960
- const staged = yield* stagedChanges(cwd, options);
20961
- const untracked = yield* untrackedFiles(cwd, options);
20962
- return [.../* @__PURE__ */ new Set([
20963
- ...unstaged,
20964
- ...staged,
20965
- ...untracked
20966
- ])];
22463
+ yield* rejectOptionLikeRefs(cwd, [name, url]);
22464
+ return yield* runVoid("Git.remoteAdd", GitCommand.remoteAdd(name, url), cwd, name);
20967
22465
  });
20968
- const nameStatus = effect.Effect.fn("Git.nameStatus")(function* (cwd, options) {
20969
- const relative = options.relative ?? false;
22466
+ const remoteRemove = effect.Effect.fn("Git.remoteRemove")(function* (cwd, name) {
20970
22467
  yield* effect.Effect.annotateCurrentSpan({
20971
22468
  cwd,
20972
- base: options.base,
20973
- head: options.head ?? "(working tree)",
20974
- relative
22469
+ name
20975
22470
  });
20976
- yield* rejectOptionLikeRefs(cwd, options.head === void 0 ? [options.base] : [options.base, options.head]);
20977
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.nameStatus(options.base, options.head, relative), cwd);
20978
- const classified = yield* runFor(command, cwd, "generic");
20979
- switch (classified._tag) {
20980
- case "success": return parseNameStatus(classified.output);
20981
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20982
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20983
- ref: options.head === void 0 ? options.base : `${options.base}...${options.head}`,
20984
- cwd
20985
- }));
20986
- case "failure": return yield* effect.Effect.fail(classified.error);
20987
- default: return yield* effect.Effect.die(`Git.nameStatus: unexpected classification "${classified._tag}"`);
20988
- }
22471
+ yield* rejectOptionLikeRefs(cwd, [name]);
22472
+ return yield* runVoid("Git.remoteRemove", GitCommand.remoteRemove(name), cwd, name);
20989
22473
  });
20990
- const revParse = effect.Effect.fn("Git.revParse")(function* (cwd, ref) {
22474
+ const remoteSetUrl = effect.Effect.fn("Git.remoteSetUrl")(function* (cwd, name, url) {
20991
22475
  yield* effect.Effect.annotateCurrentSpan({
20992
22476
  cwd,
20993
- ref
22477
+ name
20994
22478
  });
20995
- yield* rejectOptionLikeRefs(cwd, [ref]);
20996
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.revParse(ref), cwd);
20997
- const classified = yield* runFor(command, cwd, "generic");
20998
- switch (classified._tag) {
20999
- case "success": return classified.output.trim();
21000
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21001
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21002
- ref,
21003
- cwd
21004
- }));
21005
- case "failure": return yield* effect.Effect.fail(classified.error);
21006
- default: return yield* effect.Effect.die(`Git.revParse: unexpected classification "${classified._tag}"`);
21007
- }
22479
+ yield* rejectOptionLikeRefs(cwd, [name, url]);
22480
+ return yield* runVoid("Git.remoteSetUrl", GitCommand.remoteSetUrl(name, url), cwd, name);
21008
22481
  });
21009
- const checkout = effect.Effect.fn("Git.checkout")(function* (cwd, ref, options) {
21010
- const detach = options?.detach ?? false;
22482
+ const stashPush = effect.Effect.fn("Git.stashPush")(function* (cwd, options) {
21011
22483
  yield* effect.Effect.annotateCurrentSpan({
21012
22484
  cwd,
21013
- ref,
21014
- detach
22485
+ includeUntracked: options?.includeUntracked ?? false
21015
22486
  });
21016
- yield* rejectOptionLikeRefs(cwd, [ref]);
21017
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.checkout(ref, detach), cwd);
21018
- const classified = yield* runFor(command, cwd, "generic");
21019
- switch (classified._tag) {
21020
- case "success": return;
21021
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21022
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21023
- ref,
21024
- cwd
21025
- }));
21026
- case "failure": return yield* effect.Effect.fail(classified.error);
21027
- default: return yield* effect.Effect.die(`Git.checkout: unexpected classification "${classified._tag}"`);
21028
- }
22487
+ return yield* runVoid("Git.stashPush", GitCommand.stashPush(options?.message, options?.includeUntracked ?? false, options?.paths ?? []), cwd, "stash");
21029
22488
  });
21030
- const fetch = effect.Effect.fn("Git.fetch")(function* (cwd, options) {
21031
- const remote = options.remote ?? "origin";
21032
- const tag = options.tag ?? false;
22489
+ const stashRestore = (method, invocation) => effect.Effect.fn(method)(function* (cwd, options) {
21033
22490
  yield* effect.Effect.annotateCurrentSpan({
21034
22491
  cwd,
21035
- remote,
21036
- ref: options.ref,
21037
- tag
22492
+ index: options?.index ?? 0
21038
22493
  });
21039
- yield* rejectOptionLikeRefs(cwd, [remote, options.ref]);
21040
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.fetch(remote, options.ref, options.depth, tag), cwd);
21041
- const classified = yield* runFor(command, cwd, "generic");
22494
+ yield* rejectNonNaturalNumber(cwd, "a stash index", options?.index);
22495
+ const classified = yield* runFor(invocation(options?.index), cwd, "merge");
21042
22496
  switch (classified._tag) {
21043
22497
  case "success": return;
22498
+ case "dirtyWorktree": return yield* effect.Effect.fail(new DirtyWorktreeError({ cwd }));
22499
+ case "mergeConflict": return yield* effect.Effect.fail(new MergeConflictError({ cwd }));
21044
22500
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21045
22501
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21046
- ref: options.ref,
22502
+ ref: "stash",
21047
22503
  cwd
21048
22504
  }));
21049
22505
  case "failure": return yield* effect.Effect.fail(classified.error);
21050
- default: return yield* effect.Effect.die(`Git.fetch: unexpected classification "${classified._tag}"`);
22506
+ default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
21051
22507
  }
21052
22508
  });
21053
22509
  return {
@@ -21060,254 +22516,235 @@ const make = (spawner) => {
21060
22516
  revParse,
21061
22517
  checkout,
21062
22518
  fetch,
21063
- fetchAny: effect.Effect.fn("Git.fetchAny")(function* (cwd, options) {
21064
- const remote = options.remote ?? "origin";
22519
+ fetchAny,
22520
+ fetchUnshallow,
22521
+ isShallow,
22522
+ reset,
22523
+ clean,
22524
+ restore,
22525
+ branchCreate,
22526
+ branchDelete,
22527
+ submoduleUpdate,
22528
+ submoduleAdd,
22529
+ submoduleStatus,
22530
+ submoduleInit,
22531
+ submoduleDeinit,
22532
+ submoduleSync,
22533
+ submoduleSetUrl,
22534
+ submoduleSetBranch,
22535
+ submoduleAbsorbgitdirs,
22536
+ submoduleForeach,
22537
+ sparseCheckoutSet,
22538
+ configSet,
22539
+ add,
22540
+ nameStatus,
22541
+ unstagedChanges,
22542
+ stagedChanges,
22543
+ untrackedFiles,
22544
+ defaultBranch,
22545
+ currentBranch,
22546
+ repoRoot,
22547
+ configGet,
22548
+ remoteUrl,
22549
+ commitInfo,
22550
+ status,
22551
+ lsRemote,
22552
+ remoteAdd,
22553
+ remoteRemove,
22554
+ remoteSetUrl,
22555
+ stashPush,
22556
+ stashPop: stashRestore("Git.stashPop", GitCommand.stashPop),
22557
+ stashApply: stashRestore("Git.stashApply", GitCommand.stashApply),
22558
+ stashDrop: effect.Effect.fn("Git.stashDrop")(function* (cwd, options) {
21065
22559
  yield* effect.Effect.annotateCurrentSpan({
21066
22560
  cwd,
21067
- remote,
21068
- ref: options.ref
22561
+ index: options?.index ?? 0
21069
22562
  });
21070
- return yield* fetch(cwd, {
21071
- ...options,
21072
- tag: true
21073
- }).pipe(effect.Effect.catchTag(["UnknownRefError", "GitCommandError"], (error) => error._tag === "GitCommandError" && error.kind === "refused" ? effect.Effect.fail(error) : fetch(cwd, options)));
22563
+ yield* rejectNonNaturalNumber(cwd, "a stash index", options?.index);
22564
+ return yield* runVoid("Git.stashDrop", GitCommand.stashDrop(options?.index), cwd, "stash");
21074
22565
  }),
21075
- submoduleUpdate: effect.Effect.fn("Git.submoduleUpdate")(function* (cwd, options) {
21076
- const init = options?.init ?? false;
22566
+ stashList: effect.Effect.fn("Git.stashList")(function* (cwd) {
22567
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22568
+ return yield* runParsed("Git.stashList", GitCommand.stashList(), cwd, "stash", "generic", parseStashList);
22569
+ }),
22570
+ branchList: effect.Effect.fn("Git.branchList")(function* (cwd, options) {
21077
22571
  yield* effect.Effect.annotateCurrentSpan({
21078
22572
  cwd,
21079
- init
22573
+ remotes: options?.remotes ?? false,
22574
+ all: options?.all ?? false
21080
22575
  });
21081
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.submoduleUpdate(init, options?.depth, options?.paths ?? []), cwd);
21082
- const classified = yield* runFor(command, cwd, "generic");
21083
- switch (classified._tag) {
21084
- case "success": return;
21085
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21086
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21087
- ref: "submodule update",
21088
- cwd
21089
- }));
21090
- case "failure": return yield* effect.Effect.fail(classified.error);
21091
- default: return yield* effect.Effect.die(`Git.submoduleUpdate: unexpected classification "${classified._tag}"`);
21092
- }
22576
+ return yield* runParsed("Git.branchList", GitCommand.branchList(options?.remotes ?? false, options?.all ?? false), cwd, "branches", "generic", parseBranchList);
21093
22577
  }),
21094
- submoduleAdd: effect.Effect.fn("Git.submoduleAdd")(function* (cwd, options) {
22578
+ tagCreate: effect.Effect.fn("Git.tagCreate")(function* (cwd, name, options) {
21095
22579
  yield* effect.Effect.annotateCurrentSpan({
21096
22580
  cwd,
21097
- url: options.url,
21098
- path: options.path
22581
+ name,
22582
+ ref: options?.ref ?? "HEAD",
22583
+ force: options?.force ?? false
21099
22584
  });
21100
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.submoduleAdd(options.url, options.path, options.depth), cwd);
21101
- const classified = yield* runFor(command, cwd, "generic");
21102
- switch (classified._tag) {
21103
- case "success": return;
21104
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21105
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21106
- ref: options.url,
21107
- cwd
21108
- }));
21109
- case "failure": return yield* effect.Effect.fail(classified.error);
21110
- default: return yield* effect.Effect.die(`Git.submoduleAdd: unexpected classification "${classified._tag}"`);
21111
- }
22585
+ yield* rejectOptionLikeRefs(cwd, [name, ...options?.ref !== void 0 ? [options.ref] : []]);
22586
+ return yield* runVoid("Git.tagCreate", GitCommand.tagCreate(name, options?.ref, options?.message, options?.force ?? false), cwd, options?.ref ?? name);
21112
22587
  }),
21113
- sparseCheckoutSet: effect.Effect.fn("Git.sparseCheckoutSet")(function* (cwd, patterns, options) {
22588
+ tagDelete: effect.Effect.fn("Git.tagDelete")(function* (cwd, name) {
21114
22589
  yield* effect.Effect.annotateCurrentSpan({
21115
22590
  cwd,
21116
- cone: options.cone
22591
+ name
21117
22592
  });
21118
- yield* rejectOptionLikeRefs(cwd, patterns);
21119
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.sparseCheckoutSet(patterns, options.cone), cwd);
21120
- const classified = yield* runFor(command, cwd, "generic");
21121
- switch (classified._tag) {
21122
- case "success": return;
21123
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21124
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21125
- ref: "sparse-checkout",
21126
- cwd
21127
- }));
21128
- case "failure": return yield* effect.Effect.fail(classified.error);
21129
- default: return yield* effect.Effect.die(`Git.sparseCheckoutSet: unexpected classification "${classified._tag}"`);
21130
- }
22593
+ yield* rejectOptionLikeRefs(cwd, [name]);
22594
+ return yield* runVoid("Git.tagDelete", GitCommand.tagDelete(name), cwd, name);
22595
+ }),
22596
+ tagList: effect.Effect.fn("Git.tagList")(function* (cwd, options) {
22597
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22598
+ yield* rejectOptionLikeRefs(cwd, options?.pattern !== void 0 ? [options.pattern] : []);
22599
+ return yield* runParsed("Git.tagList", GitCommand.tagList(options?.pattern), cwd, "tags", "generic", (output) => output.split("\n").filter((line) => line.length > 0));
21131
22600
  }),
21132
- configSet: effect.Effect.fn("Git.configSet")(function* (cwd, key, value, options) {
22601
+ forEachRef: effect.Effect.fn("Git.forEachRef")(function* (cwd, options) {
21133
22602
  yield* effect.Effect.annotateCurrentSpan({
21134
22603
  cwd,
21135
- key,
21136
- file: options?.file ?? "(repository config)"
22604
+ patterns: (options?.patterns ?? []).length
21137
22605
  });
21138
- yield* rejectOptionLikeRefs(cwd, [
21139
- key,
21140
- value,
21141
- ...options?.file !== void 0 ? [options.file] : []
21142
- ]);
21143
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.configSet(key, value, options?.file), cwd);
21144
- const classified = yield* runFor(command, cwd, "generic");
21145
- switch (classified._tag) {
21146
- case "success": return;
21147
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21148
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21149
- ref: key,
21150
- cwd
21151
- }));
21152
- case "failure": return yield* effect.Effect.fail(classified.error);
21153
- default: return yield* effect.Effect.die(`Git.configSet: unexpected classification "${classified._tag}"`);
21154
- }
22606
+ yield* rejectOptionLikeRefs(cwd, options?.patterns ?? []);
22607
+ return yield* runParsed("Git.forEachRef", GitCommand.forEachRef(options?.patterns ?? []), cwd, "for-each-ref", "generic", parseForEachRef);
21155
22608
  }),
21156
- add: effect.Effect.fn("Git.add")(function* (cwd, paths) {
22609
+ revList: effect.Effect.fn("Git.revList")(function* (cwd, ref, options) {
21157
22610
  yield* effect.Effect.annotateCurrentSpan({
21158
22611
  cwd,
21159
- count: paths.length
22612
+ ref,
22613
+ firstParent: options?.firstParent ?? false
21160
22614
  });
21161
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.add(paths), cwd);
21162
- const classified = yield* runFor(command, cwd, "generic");
22615
+ yield* rejectOptionLikeRefs(cwd, [ref]);
22616
+ yield* rejectNonNaturalNumber(cwd, "a rev-list limit", options?.limit);
22617
+ return yield* runParsed("Git.revList", GitCommand.revList(ref, options?.limit, options?.firstParent ?? false), cwd, ref, "generic", (output) => output.split("\n").filter((line) => line.length > 0));
22618
+ }),
22619
+ commit: effect.Effect.fn("Git.commit")(function* (cwd, message, options) {
22620
+ yield* effect.Effect.annotateCurrentSpan({
22621
+ cwd,
22622
+ amend: options?.amend ?? false
22623
+ });
22624
+ return yield* runVoid("Git.commit", GitCommand.commit(message, options?.all ?? false, options?.allowEmpty ?? false, options?.amend ?? false, options?.author), cwd, "HEAD");
22625
+ }),
22626
+ push: effect.Effect.fn("Git.push")(function* (cwd, options) {
22627
+ const remote = options?.remote ?? "origin";
22628
+ yield* effect.Effect.annotateCurrentSpan({
22629
+ cwd,
22630
+ refspec: options?.refspec ?? "(current branch)",
22631
+ forceWithLease: options?.forceWithLease ?? false
22632
+ });
22633
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.refspec !== void 0 ? [options.refspec] : []]);
22634
+ const classified = yield* runFor(GitCommand.push(remote, options?.refspec, options?.force ?? false, options?.forceWithLease ?? false, options?.tags ?? false, options?.setUpstream ?? false), cwd, "push");
21163
22635
  switch (classified._tag) {
21164
22636
  case "success": return;
22637
+ case "nonFastForward": return yield* effect.Effect.fail(new NonFastForwardError({
22638
+ cwd,
22639
+ ...options?.refspec !== void 0 ? { refspec: options.refspec } : {}
22640
+ }));
21165
22641
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21166
22642
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21167
- ref: "working tree",
22643
+ ref: options?.refspec ?? "HEAD",
21168
22644
  cwd
21169
22645
  }));
21170
22646
  case "failure": return yield* effect.Effect.fail(classified.error);
21171
- default: return yield* effect.Effect.die(`Git.add: unexpected classification "${classified._tag}"`);
22647
+ default: return yield* effect.Effect.die(`Git.push: unexpected classification "${classified._tag}"`);
21172
22648
  }
21173
22649
  }),
21174
- nameStatus,
21175
- unstagedChanges,
21176
- stagedChanges,
21177
- untrackedFiles,
21178
- defaultBranch: effect.Effect.fn("Git.defaultBranch")(function* (cwd, options) {
22650
+ pull: effect.Effect.fn("Git.pull")(function* (cwd, options) {
21179
22651
  const remote = options?.remote ?? "origin";
21180
22652
  yield* effect.Effect.annotateCurrentSpan({
21181
22653
  cwd,
21182
- remote
22654
+ ref: options?.ref ?? "(upstream)",
22655
+ rebase: options?.rebase ?? false
21183
22656
  });
21184
- yield* rejectOptionLikeRefs(cwd, [remote]);
21185
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.defaultBranch(remote), cwd);
21186
- const classified = yield* runFor(command, cwd, "quiet");
22657
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.ref !== void 0 ? [options.ref] : []]);
22658
+ const classified = yield* runFor(GitCommand.pull(remote, options?.ref, options?.rebase ?? false, options?.ffOnly ?? false), cwd, "merge");
21187
22659
  switch (classified._tag) {
21188
- case "success": {
21189
- const short = classified.output.trim();
21190
- const prefix = `${remote}/`;
21191
- return effect.Option.some(short.startsWith(prefix) ? short.slice(prefix.length) : short);
21192
- }
21193
- case "absent": return effect.Option.none();
22660
+ case "success": return;
22661
+ case "dirtyWorktree": return yield* effect.Effect.fail(new DirtyWorktreeError({ cwd }));
22662
+ case "mergeConflict": return yield* effect.Effect.fail(new MergeConflictError({ cwd }));
21194
22663
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21195
22664
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21196
- ref: `refs/remotes/${remote}/HEAD`,
22665
+ ref: options?.ref ?? "(upstream)",
21197
22666
  cwd
21198
22667
  }));
21199
22668
  case "failure": return yield* effect.Effect.fail(classified.error);
21200
- default: return yield* effect.Effect.die(`Git.defaultBranch: unexpected classification "${classified._tag}"`);
22669
+ default: return yield* effect.Effect.die(`Git.pull: unexpected classification "${classified._tag}"`);
21201
22670
  }
21202
22671
  }),
21203
- currentBranch: effect.Effect.fn("Git.currentBranch")(function* (cwd) {
21204
- yield* effect.Effect.annotateCurrentSpan({ cwd });
21205
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.currentBranch(), cwd);
21206
- const classified = yield* runFor(command, cwd, "generic");
21207
- switch (classified._tag) {
21208
- case "success": {
21209
- const name = classified.output.trim();
21210
- return name === "HEAD" ? effect.Option.none() : effect.Option.some(name);
21211
- }
21212
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21213
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21214
- ref: "HEAD",
21215
- cwd
21216
- }));
21217
- case "failure": return yield* effect.Effect.fail(classified.error);
21218
- default: return yield* effect.Effect.die(`Git.currentBranch: unexpected classification "${classified._tag}"`);
21219
- }
22672
+ configList: effect.Effect.fn("Git.configList")(function* (cwd, options) {
22673
+ yield* effect.Effect.annotateCurrentSpan({
22674
+ cwd,
22675
+ file: options?.file ?? "(repository config)"
22676
+ });
22677
+ yield* rejectOptionLikeRefs(cwd, options?.file !== void 0 ? [options.file] : []);
22678
+ return yield* runParsed("Git.configList", GitCommand.configList(options?.file), cwd, "config", "generic", parseConfigList);
21220
22679
  }),
21221
- repoRoot: effect.Effect.fn("Git.repoRoot")(function* (cwd) {
21222
- yield* effect.Effect.annotateCurrentSpan({ cwd });
21223
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.repoRoot(), cwd);
21224
- const classified = yield* runFor(command, cwd, "generic");
21225
- switch (classified._tag) {
21226
- case "success": return classified.output.trim();
21227
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21228
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21229
- ref: "working tree",
21230
- cwd
21231
- }));
21232
- case "failure": return yield* effect.Effect.fail(classified.error);
21233
- default: return yield* effect.Effect.die(`Git.repoRoot: unexpected classification "${classified._tag}"`);
21234
- }
22680
+ configGetAll: effect.Effect.fn("Git.configGetAll")(function* (cwd, key, options) {
22681
+ yield* effect.Effect.annotateCurrentSpan({
22682
+ cwd,
22683
+ key,
22684
+ file: options?.file ?? "(repository config)"
22685
+ });
22686
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []]);
22687
+ return yield* runParsed("Git.configGetAll", GitCommand.configGetAll(key, options?.file), cwd, key, "quiet", parseNulSeparated, () => []);
21235
22688
  }),
21236
- configGet: effect.Effect.fn("Git.configGet")(function* (cwd, key) {
22689
+ configUnset: effect.Effect.fn("Git.configUnset")(function* (cwd, key, options) {
21237
22690
  yield* effect.Effect.annotateCurrentSpan({
21238
22691
  cwd,
21239
- key
22692
+ key,
22693
+ file: options?.file ?? "(repository config)"
21240
22694
  });
21241
- yield* rejectOptionLikeRefs(cwd, [key]);
21242
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.configGet(key), cwd);
21243
- const classified = yield* runFor(command, cwd, "quiet");
21244
- switch (classified._tag) {
21245
- case "success": return effect.Option.some(classified.output.trim());
21246
- case "absent": return effect.Option.none();
21247
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21248
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21249
- ref: key,
21250
- cwd
21251
- }));
21252
- case "failure": return yield* effect.Effect.fail(classified.error);
21253
- default: return yield* effect.Effect.die(`Git.configGet: unexpected classification "${classified._tag}"`);
21254
- }
22695
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []]);
22696
+ return yield* runVoid("Git.configUnset", GitCommand.configUnset(key, options?.file, options?.all ?? false), cwd, key);
21255
22697
  }),
21256
- remoteUrl: effect.Effect.fn("Git.remoteUrl")(function* (cwd, options) {
21257
- const remote = options?.remote ?? "origin";
22698
+ rm: effect.Effect.fn("Git.rm")(function* (cwd, paths, options) {
21258
22699
  yield* effect.Effect.annotateCurrentSpan({
21259
22700
  cwd,
21260
- remote
22701
+ count: paths.length,
22702
+ cached: options?.cached ?? false
21261
22703
  });
21262
- yield* rejectOptionLikeRefs(cwd, [remote]);
21263
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.remoteUrl(remote), cwd);
21264
- const classified = yield* runFor(command, cwd, "noSuchRemote");
21265
- switch (classified._tag) {
21266
- case "success": return effect.Option.some(classified.output.trim());
21267
- case "absent": return effect.Option.none();
21268
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21269
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21270
- ref: remote,
21271
- cwd
21272
- }));
21273
- case "failure": return yield* effect.Effect.fail(classified.error);
21274
- default: return yield* effect.Effect.die(`Git.remoteUrl: unexpected classification "${classified._tag}"`);
21275
- }
22704
+ return yield* runVoid("Git.rm", GitCommand.rm(paths, options?.cached ?? false, options?.recursive ?? false, options?.force ?? false), cwd, "working tree");
21276
22705
  }),
21277
- commitInfo: effect.Effect.fn("Git.commitInfo")(function* (cwd, ref) {
21278
- const target = ref ?? "HEAD";
22706
+ mv: effect.Effect.fn("Git.mv")(function* (cwd, source, destination, options) {
21279
22707
  yield* effect.Effect.annotateCurrentSpan({
21280
22708
  cwd,
21281
- ref: target
22709
+ source,
22710
+ destination
21282
22711
  });
21283
- yield* rejectOptionLikeRefs(cwd, [target]);
21284
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.commitInfo(target), cwd);
21285
- const classified = yield* runFor(command, cwd, "generic");
21286
- switch (classified._tag) {
21287
- case "success": return parseCommitInfo(classified.output);
21288
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21289
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21290
- ref: target,
21291
- cwd
21292
- }));
21293
- case "failure": return yield* effect.Effect.fail(classified.error);
21294
- default: return yield* effect.Effect.die(`Git.commitInfo: unexpected classification "${classified._tag}"`);
21295
- }
22712
+ return yield* runVoid("Git.mv", GitCommand.mv(source, destination, options?.force ?? false), cwd, "working tree");
22713
+ }),
22714
+ checkIgnore: effect.Effect.fn("Git.checkIgnore")(function* (cwd, paths) {
22715
+ yield* effect.Effect.annotateCurrentSpan({
22716
+ cwd,
22717
+ count: paths.length
22718
+ });
22719
+ return yield* runParsed("Git.checkIgnore", GitCommand.checkIgnore(paths), cwd, "check-ignore", "quiet", parseNulSeparated, () => []);
21296
22720
  }),
21297
- status: effect.Effect.fn("Git.status")(function* (cwd) {
22721
+ worktreeAdd: effect.Effect.fn("Git.worktreeAdd")(function* (cwd, path, options) {
22722
+ yield* effect.Effect.annotateCurrentSpan({
22723
+ cwd,
22724
+ path,
22725
+ ref: options?.ref ?? "(default)"
22726
+ });
22727
+ yield* rejectOptionLikeRefs(cwd, [path, ...options?.ref !== void 0 ? [options.ref] : []]);
22728
+ return yield* runVoid("Git.worktreeAdd", GitCommand.worktreeAdd(path, options?.ref, options?.detach ?? false, options?.force ?? false), cwd, options?.ref ?? path);
22729
+ }),
22730
+ worktreeList: effect.Effect.fn("Git.worktreeList")(function* (cwd) {
21298
22731
  yield* effect.Effect.annotateCurrentSpan({ cwd });
21299
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.status(), cwd);
21300
- const classified = yield* runFor(command, cwd, "generic");
21301
- switch (classified._tag) {
21302
- case "success": return parseStatus(classified.output);
21303
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21304
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21305
- ref: "working tree",
21306
- cwd
21307
- }));
21308
- case "failure": return yield* effect.Effect.fail(classified.error);
21309
- default: return yield* effect.Effect.die(`Git.status: unexpected classification "${classified._tag}"`);
21310
- }
22732
+ return yield* runParsed("Git.worktreeList", GitCommand.worktreeList(), cwd, "worktrees", "generic", parseWorktreeList);
22733
+ }),
22734
+ worktreeRemove: effect.Effect.fn("Git.worktreeRemove")(function* (cwd, path, options) {
22735
+ yield* effect.Effect.annotateCurrentSpan({
22736
+ cwd,
22737
+ path
22738
+ });
22739
+ yield* rejectOptionLikeRefs(cwd, [path]);
22740
+ return yield* runVoid("Git.worktreeRemove", GitCommand.worktreeRemove(path, options?.force ?? false), cwd, path);
22741
+ }),
22742
+ lsFiles: effect.Effect.fn("Git.lsFiles")(function* (cwd, options) {
22743
+ yield* effect.Effect.annotateCurrentSpan({
22744
+ cwd,
22745
+ patterns: (options?.pathspec ?? []).length
22746
+ });
22747
+ return yield* runParsed("Git.lsFiles", GitCommand.lsFiles(options?.pathspec ?? []), cwd, "index", "generic", parseLsFiles);
21311
22748
  })
21312
22749
  };
21313
22750
  };
@@ -21319,17 +22756,23 @@ const make = (spawner) => {
21319
22756
  const notStubbed = (method) => () => effect.Effect.die(/* @__PURE__ */ new Error(`Git.makeTest: ${method}() was called but not stubbed — no honest default exists for a test double; pass a \`${method}\` override.`));
21320
22757
  /**
21321
22758
  * Typed git introspection over core's `ChildProcessSpawner`: read a
21322
- * repository's state at any ref without checking it out, plus the mutating
21323
- * tier (`checkout`, `fetch`, `fetchAny`, `submoduleUpdate`, `submoduleAdd`,
21324
- * `sparseCheckoutSet`, `configSet`, `add`) that changes it.
22759
+ * repository's state at any ref without checking it out (including the
22760
+ * network read `lsRemote` and the index read `lsFiles`), plus the mutating
22761
+ * tier checkout/fetch, the working-tree restore trio and stash, branches
22762
+ * and tags, remotes, worktrees, commit/push/pull, submodules,
22763
+ * sparse-checkout, config writes and staging — that changes it. Every
22764
+ * mutating method's TSDoc opens with the literal word `Mutating:`.
21325
22765
  *
21326
22766
  * @remarks
21327
22767
  * Every method takes `cwd` explicitly and classifies git's stderr/exit-code
21328
22768
  * taxonomy exactly once, in this module's private `classify` step — a
21329
22769
  * spawn-level `PlatformError` and `Cause.TimeoutError` never escape a `Git`
21330
22770
  * method; every failure surfaces as {@link GitCommandError},
21331
- * {@link NotARepositoryError}, or {@link UnknownRefError}, or degrades to
21332
- * the documented non-error (`Option.none`, `false`).
22771
+ * {@link NotARepositoryError}, {@link UnknownRefError}, or one of the three
22772
+ * consumer-branchable classifications ({@link NonFastForwardError} from
22773
+ * `push`; {@link MergeConflictError} and {@link DirtyWorktreeError} from the
22774
+ * merge-shaped `pull` / `stashPop` / `stashApply`), or degrades to the
22775
+ * documented non-error (`Option.none`, `false`, the empty array).
21333
22776
  *
21334
22777
  * Every method whose TSDoc opens "Mutating:" changes the working tree,
21335
22778
  * `HEAD`, the index, the repository config, the object database and
@@ -21338,6 +22781,12 @@ const notStubbed = (method) => () => effect.Effect.die(/* @__PURE__ */ new Error
21338
22781
  * that — a caller running two mutating calls (or a mutating call alongside a
21339
22782
  * read) against one `cwd` at once owns the race.
21340
22783
  *
22784
+ * **Redaction policy (documented, not just convention).** Error values
22785
+ * persist only the constructor's REDACTED argv (see `GitCommandError.args`),
22786
+ * and span annotations carry stable identifiers only — `cwd`, refs, keys,
22787
+ * paths, remote names — never config values and never URLs, which can embed
22788
+ * userinfo. A new method must follow both halves before it ships.
22789
+ *
21341
22790
  * @public
21342
22791
  */
21343
22792
  var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
@@ -21352,7 +22801,7 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
21352
22801
  *
21353
22802
  * @remarks
21354
22803
  * Unlike `WorkspaceDiscovery.makeTest`, **no method here has an honest
21355
- * default** — the shape is twenty-six unrelated git operations, and a
22804
+ * default** — the shape is unrelated git operations, and a
21356
22805
  * fabricated answer for any of them (an empty tree, a made-up sha, a silent
21357
22806
  * no-op `checkout`) would leak into consumer logic as fact. So every
21358
22807
  * unstubbed method fails loudly as a defect
@@ -21391,8 +22840,23 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
21391
22840
  checkout: notStubbed("checkout"),
21392
22841
  fetch: notStubbed("fetch"),
21393
22842
  fetchAny: notStubbed("fetchAny"),
22843
+ fetchUnshallow: notStubbed("fetchUnshallow"),
22844
+ isShallow: notStubbed("isShallow"),
22845
+ reset: notStubbed("reset"),
22846
+ clean: notStubbed("clean"),
22847
+ restore: notStubbed("restore"),
22848
+ branchCreate: notStubbed("branchCreate"),
22849
+ branchDelete: notStubbed("branchDelete"),
21394
22850
  submoduleUpdate: notStubbed("submoduleUpdate"),
21395
22851
  submoduleAdd: notStubbed("submoduleAdd"),
22852
+ submoduleStatus: notStubbed("submoduleStatus"),
22853
+ submoduleInit: notStubbed("submoduleInit"),
22854
+ submoduleDeinit: notStubbed("submoduleDeinit"),
22855
+ submoduleSync: notStubbed("submoduleSync"),
22856
+ submoduleSetUrl: notStubbed("submoduleSetUrl"),
22857
+ submoduleSetBranch: notStubbed("submoduleSetBranch"),
22858
+ submoduleAbsorbgitdirs: notStubbed("submoduleAbsorbgitdirs"),
22859
+ submoduleForeach: notStubbed("submoduleForeach"),
21396
22860
  sparseCheckoutSet: notStubbed("sparseCheckoutSet"),
21397
22861
  configSet: notStubbed("configSet"),
21398
22862
  add: notStubbed("add"),
@@ -21407,6 +22871,34 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
21407
22871
  remoteUrl: notStubbed("remoteUrl"),
21408
22872
  commitInfo: notStubbed("commitInfo"),
21409
22873
  status: notStubbed("status"),
22874
+ lsRemote: notStubbed("lsRemote"),
22875
+ remoteAdd: notStubbed("remoteAdd"),
22876
+ remoteRemove: notStubbed("remoteRemove"),
22877
+ remoteSetUrl: notStubbed("remoteSetUrl"),
22878
+ stashPush: notStubbed("stashPush"),
22879
+ stashPop: notStubbed("stashPop"),
22880
+ stashApply: notStubbed("stashApply"),
22881
+ stashDrop: notStubbed("stashDrop"),
22882
+ stashList: notStubbed("stashList"),
22883
+ branchList: notStubbed("branchList"),
22884
+ tagCreate: notStubbed("tagCreate"),
22885
+ tagDelete: notStubbed("tagDelete"),
22886
+ tagList: notStubbed("tagList"),
22887
+ forEachRef: notStubbed("forEachRef"),
22888
+ revList: notStubbed("revList"),
22889
+ commit: notStubbed("commit"),
22890
+ push: notStubbed("push"),
22891
+ pull: notStubbed("pull"),
22892
+ configList: notStubbed("configList"),
22893
+ configGetAll: notStubbed("configGetAll"),
22894
+ configUnset: notStubbed("configUnset"),
22895
+ rm: notStubbed("rm"),
22896
+ mv: notStubbed("mv"),
22897
+ checkIgnore: notStubbed("checkIgnore"),
22898
+ worktreeAdd: notStubbed("worktreeAdd"),
22899
+ worktreeList: notStubbed("worktreeList"),
22900
+ worktreeRemove: notStubbed("worktreeRemove"),
22901
+ lsFiles: notStubbed("lsFiles"),
21410
22902
  ...overrides
21411
22903
  });
21412
22904
  /**
@@ -21435,7 +22927,7 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
21435
22927
  static layerTest = (overrides = {}) => effect.Layer.succeed(Git, Git.makeTest(overrides));
21436
22928
  };
21437
22929
  //#endregion
21438
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
22930
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/ChangeDetector.js
21439
22931
  /**
21440
22932
  * Which git refs to compare, and whether to fold in the working tree.
21441
22933
  *
@@ -21691,7 +23183,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
21691
23183
  };
21692
23184
  }
21693
23185
  //#endregion
21694
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
23186
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/internal/catalogs.js
21695
23187
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
21696
23188
  const inlineCatalogs = (manifest) => {
21697
23189
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -21755,7 +23247,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
21755
23247
  });
21756
23248
  };
21757
23249
  //#endregion
21758
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
23250
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/ConfigDependencyHooks.js
21759
23251
  /** Whether `value` is a non-null, non-array object. */
21760
23252
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
21761
23253
  /**
@@ -21957,8 +23449,12 @@ process.stdout.write("\\n" + JSON.stringify(payload) + "\\n", () => process.exit
21957
23449
  */
21958
23450
  const REPLAY_TIMEOUT = effect.Duration.seconds(30);
21959
23451
  /**
21960
- * The subprocess protocol payload — the child's final stdout line, framed and
21961
- * parsed by `Run.jsonLine`. The envelope is strict (a payload without a usable
23452
+ * The subprocess protocol payload — a single JSON line near the end of the
23453
+ * child's stdout, framed and parsed by `Run.jsonLine`, which scans lines from
23454
+ * the end for the first that decodes (so a hook logging after the payload —
23455
+ * e.g. from `process.on("exit", ...)` — cannot displace it). The `ok`
23456
+ * discriminant is what keeps an accidental log line from satisfying the
23457
+ * envelope. The envelope is strict (a payload without a usable
21962
23458
  * `ok` discriminant is a mechanism failure, typed); the `config` slice inside a
21963
23459
  * success stays `Unknown` because a hook's returned *data* is tolerantly
21964
23460
  * threaded (`configOf`), never fatal.
@@ -22162,7 +23658,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends effect.Context.S
22162
23658
  }));
22163
23659
  };
22164
23660
  //#endregion
22165
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
23661
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/PackageManagerName.js
22166
23662
  /**
22167
23663
  * The four package managers this package understands.
22168
23664
  *
@@ -22490,7 +23986,7 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
22490
23986
  static layerTest = (overrides = {}) => effect.Layer.succeed(PackageManagerDetector, PackageManagerDetector.makeTest(overrides));
22491
23987
  };
22492
23988
  //#endregion
22493
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
23989
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/LockfileReader.js
22494
23990
  /**
22495
23991
  * Raised when the workspace's lockfile cannot be read off disk.
22496
23992
  *
@@ -22670,7 +24166,7 @@ var LockfileReader = class LockfileReader extends effect.Context.Service()("@eff
22670
24166
  static layerTest = (overrides = {}) => effect.Layer.succeed(LockfileReader, LockfileReader.makeTest(overrides));
22671
24167
  };
22672
24168
  //#endregion
22673
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
24169
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/Publishability.js
22674
24170
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
22675
24171
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
22676
24172
  /**
@@ -22829,7 +24325,7 @@ var PublishabilityDetector = class extends effect.Context.Service()("@effected/w
22829
24325
  static layerNone = effect.Layer.succeed(this, this.none);
22830
24326
  };
22831
24327
  //#endregion
22832
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/importerVersions.js
24328
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/internal/importerVersions.js
22833
24329
  /**
22834
24330
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
22835
24331
  *
@@ -22915,7 +24411,7 @@ const unanimousVersionOf = (index, dependency) => {
22915
24411
  return agreed;
22916
24412
  };
22917
24413
  //#endregion
22918
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
24414
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/WorkspaceCatalogs.js
22919
24415
  /**
22920
24416
  * An immutable, fully-normalized catalog collection — the one catalog
22921
24417
  * resolution semantic in the package.
@@ -23430,9 +24926,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
23430
24926
  * consumers to `_tag`-sniff `unknown`); only the remaining mechanism failure,
23431
24927
  * an unfindable workspace root, is wrapped as `DependencyResolutionError`.
23432
24928
  */
23433
- static catalogResolver = effect.Layer.effect(CatalogResolver$1, effect.Effect.gen(function* () {
24929
+ static catalogResolver = effect.Layer.effect(CatalogResolver, effect.Effect.gen(function* () {
23434
24930
  const catalogs = yield* WorkspaceCatalogs;
23435
- return { rangeOf: (packageName, catalog) => catalogs.set().pipe(effect.Effect.map((set) => set.rangeOf(packageName, catalog)), effect.Effect.catchTag("WorkspaceRootNotFoundError", (cause) => effect.Effect.fail(new DependencyResolutionError$1({
24931
+ return { rangeOf: (packageName, catalog) => catalogs.set().pipe(effect.Effect.map((set) => set.rangeOf(packageName, catalog)), effect.Effect.catchTag("WorkspaceRootNotFoundError", (cause) => effect.Effect.fail(new DependencyResolutionError({
23436
24932
  specifier: effect.Option.match(catalog, {
23437
24933
  onNone: () => "catalog:",
23438
24934
  onSome: (name) => `catalog:${name}`
@@ -23442,7 +24938,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
23442
24938
  }));
23443
24939
  };
23444
24940
  //#endregion
23445
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
24941
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
23446
24942
  const EMPTY = Object.freeze(Object.create(null));
23447
24943
  const DependencyMap = effect.Schema.Record(effect.Schema.String, effect.Schema.String).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed(EMPTY)), effect.Schema.withConstructorDefault(effect.Effect.succeed(EMPTY)));
23448
24944
  /**
@@ -23621,7 +25117,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
23621
25117
  * resolving to `Option.none()` so the caller falls back to the raw string.
23622
25118
  */
23623
25119
  #resolveWith(dependency, specifier, onUnresolvedCatalog) {
23624
- const exit = effect.Schema.decodeUnknownExit(DependencySpecifier$1.FromString)(specifier);
25120
+ const exit = effect.Schema.decodeUnknownExit(DependencySpecifier.FromString)(specifier);
23625
25121
  if (!effect.Exit.isSuccess(exit)) return effect.Option.none();
23626
25122
  const classified = exit.value;
23627
25123
  switch (classified._tag) {
@@ -23646,7 +25142,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
23646
25142
  * `rangeOf` never fails.
23647
25143
  */
23648
25144
  get catalogResolver() {
23649
- if (this.#catalogResolver === void 0) this.#catalogResolver = effect.Layer.succeed(CatalogResolver$1, { rangeOf: (packageName, catalog) => effect.Effect.succeed(this.catalogs.rangeOf(packageName, catalog)) });
25145
+ if (this.#catalogResolver === void 0) this.#catalogResolver = effect.Layer.succeed(CatalogResolver, { rangeOf: (packageName, catalog) => effect.Effect.succeed(this.catalogs.rangeOf(packageName, catalog)) });
23650
25146
  return this.#catalogResolver;
23651
25147
  }
23652
25148
  /**
@@ -23655,7 +25151,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
23655
25151
  * `workspace:` specifiers as of this ref. Built once per instance and cached.
23656
25152
  */
23657
25153
  get workspaceResolver() {
23658
- if (this.#workspaceResolver === void 0) this.#workspaceResolver = effect.Layer.succeed(WorkspaceResolver$1, { versionOf: (packageName) => effect.Effect.succeed(effect.Option.fromUndefinedOr(this.#versions().get(packageName))) });
25154
+ if (this.#workspaceResolver === void 0) this.#workspaceResolver = effect.Layer.succeed(WorkspaceResolver, { versionOf: (packageName) => effect.Effect.succeed(effect.Option.fromUndefinedOr(this.#versions().get(packageName))) });
23659
25155
  return this.#workspaceResolver;
23660
25156
  }
23661
25157
  /** Both snapshot-scoped resolver layers merged. Built once per instance and cached. */
@@ -23665,7 +25161,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
23665
25161
  }
23666
25162
  };
23667
25163
  //#endregion
23668
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
25164
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/WorkspaceSnapshots.js
23669
25165
  /** Whether `value` is a non-null, non-array object. */
23670
25166
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
23671
25167
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -23942,7 +25438,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
23942
25438
  static layerTest = (overrides = {}) => effect.Layer.succeed(WorkspaceSnapshots, WorkspaceSnapshots.makeTest(overrides));
23943
25439
  };
23944
25440
  //#endregion
23945
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.0_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
25441
+ //#region ../../node_modules/.pnpm/@effected+workspaces@0.10.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+semv_feff9e309e6abeafa28f7ea259b8a9bf/node_modules/@effected/workspaces/Workspaces.js
23946
25442
  const compose = (options, catalogsFactory) => {
23947
25443
  const roots = WorkspaceRoot.layer;
23948
25444
  const detector = PackageManagerDetector.layer;
@@ -24076,7 +25572,8 @@ var Workspaces = class {
24076
25572
  * never detects changes or reads at a ref should not have to be able to
24077
25573
  * spawn a subprocess. The consumer provides `ChildProcessSpawner` once at
24078
25574
  * the edge (`@effect/platform-node`'s `NodeServices.layer`); a test
24079
- * provides `Layer.succeed(Git, …)` and needs no repository on disk.
25575
+ * provides `Git.layerTest({ })` git's own shipped double, whose
25576
+ * unstubbed members die named — and needs no repository on disk.
24080
25577
  */
24081
25578
  static layerWithGit = layerWithGit;
24082
25579
  /**
@@ -24125,9 +25622,14 @@ var Workspaces = class {
24125
25622
  * import { Workspaces } from "@effected/workspaces";
24126
25623
  * import { Layer } from "effect";
24127
25624
  *
25625
+ * // Bound to consts per the warning above: each factory call mints a
25626
+ * // fresh layer reference, and layers memoize by reference.
25627
+ * const LocalExecLayer = Workspaces.localExecLayer();
25628
+ * const WorkspacesLayer = Workspaces.layer();
25629
+ *
24128
25630
  * const AppLayer = ToolDiscovery.layer.pipe(
24129
- * Layer.provide(Workspaces.localExecLayer()),
24130
- * Layer.provide(Workspaces.layer()),
25631
+ * Layer.provide(LocalExecLayer),
25632
+ * Layer.provide(WorkspacesLayer),
24131
25633
  * Layer.provide(NodeServices.layer),
24132
25634
  * );
24133
25635
  * ```