@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.
@@ -2410,7 +2410,7 @@ var BunExtension = class extends Schema.Class("BunExtension")({
2410
2410
  *
2411
2411
  * @public
2412
2412
  */
2413
- var CatalogResolver$1 = class CatalogResolver extends Context.Service()("@effected/npm/CatalogResolver") {
2413
+ var CatalogResolver = class CatalogResolver extends Context.Service()("@effected/npm/CatalogResolver") {
2414
2414
  /**
2415
2415
  * No-op default: `rangeOf` always succeeds with `Option.none()`, never
2416
2416
  * consulting an actual catalog. A pure `Layer.succeed`, bound to a const
@@ -2435,7 +2435,7 @@ var CatalogResolver$1 = class CatalogResolver extends Context.Service()("@effect
2435
2435
  *
2436
2436
  * @public
2437
2437
  */
2438
- var DependencyResolutionError$1 = class extends Schema.TaggedErrorClass()("DependencyResolutionError", {
2438
+ var DependencyResolutionError = class extends Schema.TaggedErrorClass()("DependencyResolutionError", {
2439
2439
  specifier: Schema.String,
2440
2440
  cause: Schema.Defect()
2441
2441
  }) {
@@ -2473,7 +2473,7 @@ var DependencyResolutionError$1 = class extends Schema.TaggedErrorClass()("Depen
2473
2473
  *
2474
2474
  * @public
2475
2475
  */
2476
- var WorkspaceResolver$1 = class WorkspaceResolver extends Context.Service()("@effected/npm/WorkspaceResolver") {
2476
+ var WorkspaceResolver = class WorkspaceResolver extends Context.Service()("@effected/npm/WorkspaceResolver") {
2477
2477
  /**
2478
2478
  * No-op default: `versionOf` always succeeds with `Option.none()`, never
2479
2479
  * consulting an actual workspace. A pure `Layer.succeed`, bound to a
@@ -2535,7 +2535,7 @@ var CatalogAssemblyError = class extends Schema.TaggedErrorClass()("CatalogAssem
2535
2535
  *
2536
2536
  * @public
2537
2537
  */
2538
- const DependencyKind$1 = Schema.Literals([
2538
+ const DependencyKind = Schema.Literals([
2539
2539
  "prod",
2540
2540
  "dev",
2541
2541
  "peer",
@@ -2547,19 +2547,19 @@ const DependencyKind$1 = Schema.Literals([
2547
2547
  *
2548
2548
  * @public
2549
2549
  */
2550
- const DependencyField$1 = Schema.Literals([
2550
+ const DependencyField = Schema.Literals([
2551
2551
  "dependencies",
2552
2552
  "devDependencies",
2553
2553
  "peerDependencies",
2554
2554
  "optionalDependencies"
2555
2555
  ]);
2556
- const KIND_TO_FIELD$1 = {
2556
+ const KIND_TO_FIELD = {
2557
2557
  prod: "dependencies",
2558
2558
  dev: "devDependencies",
2559
2559
  peer: "peerDependencies",
2560
2560
  optional: "optionalDependencies"
2561
2561
  };
2562
- const FIELD_TO_KIND$1 = Object.fromEntries(Object.entries(KIND_TO_FIELD$1).map(([kind, field]) => [field, kind]));
2562
+ const FIELD_TO_KIND = Object.fromEntries(Object.entries(KIND_TO_FIELD).map(([kind, field]) => [field, kind]));
2563
2563
 
2564
2564
  //#endregion
2565
2565
  //#region ../../node_modules/.pnpm/@effected+semver@0.3.2_effect@4.0.0-beta.101/node_modules/@effected/semver/internal/desugar.js
@@ -2937,7 +2937,7 @@ const parseRangeComparators = (s) => {
2937
2937
  * Parse a range expression into comparator sets (OR of ANDs). The empty
2938
2938
  * string parses as the match-all range.
2939
2939
  */
2940
- const parseRange$2 = (raw) => {
2940
+ const parseRange$1 = (raw) => {
2941
2941
  const trimmed = raw.trim();
2942
2942
  if (trimmed.length === 0) return {
2943
2943
  ok: true,
@@ -3841,7 +3841,7 @@ sets: Schema.Array(Schema.Array(Comparator)) }) {
3841
3841
  */
3842
3842
  static FromString = Schema.String.pipe(Schema.decodeTo(Range, SchemaTransformation.transformOrFail({
3843
3843
  decode: (input) => {
3844
- const result = parseRange$2(input);
3844
+ const result = parseRange$1(input);
3845
3845
  return result.ok ? Effect.succeed({ sets: normalizeSets(result.value) }) : Effect.fail(new SchemaIssue.InvalidValue(Option.some(input), { message: `Invalid range expression: "${result.input}" at position ${result.position}` }));
3846
3846
  },
3847
3847
  encode: (parts) => Effect.succeed(formatRange(parts.sets))
@@ -3872,7 +3872,7 @@ sets: Schema.Array(Schema.Array(Comparator)) }) {
3872
3872
  * with {@link InvalidRangeError}.
3873
3873
  */
3874
3874
  static parseResult(input) {
3875
- const result = parseRange$2(input);
3875
+ const result = parseRange$1(input);
3876
3876
  if (!result.ok) return Result.fail(new InvalidRangeError({
3877
3877
  input: result.input,
3878
3878
  position: result.position
@@ -4161,50 +4161,50 @@ const isComparatorSetSubset = (sub, sup) => {
4161
4161
  *
4162
4162
  * @public
4163
4163
  */
4164
- var InvalidDependencySpecifierError$1 = class extends Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
4164
+ var InvalidDependencySpecifierError = class extends Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
4165
4165
  /** The raw input string that failed validation. */
4166
4166
  input: Schema.String }) {
4167
4167
  get message() {
4168
4168
  return `Invalid dependency specifier "${this.input}": not a recognized specifier`;
4169
4169
  }
4170
4170
  };
4171
- const CATALOG_PREFIX$1 = "catalog:";
4172
- const WORKSPACE_PREFIX$1 = "workspace:";
4173
- const isBarePath$1 = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4174
- const isGitHubShorthand$1 = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4175
- 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);
4176
- const isLocal$1 = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath$1(value);
4177
- const isLink$1 = (value) => value.startsWith("link:");
4178
- const isPortal$1 = (value) => value.startsWith("portal:");
4179
- const isCatalog$1 = (value) => value.startsWith(CATALOG_PREFIX$1);
4180
- const isWorkspace$1 = (value) => value.startsWith(WORKSPACE_PREFIX$1);
4181
- const isUrl$2 = (value) => value.startsWith("http://") || value.startsWith("https://");
4182
- const parseRange$1 = (value) => {
4171
+ const CATALOG_PREFIX = "catalog:";
4172
+ const WORKSPACE_PREFIX = "workspace:";
4173
+ const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
4174
+ const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
4175
+ const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
4176
+ const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath(value);
4177
+ const isLink = (value) => value.startsWith("link:");
4178
+ const isPortal = (value) => value.startsWith("portal:");
4179
+ const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
4180
+ const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
4181
+ const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
4182
+ const parseRange = (value) => {
4183
4183
  const exit = Schema.decodeUnknownExit(Range$1.FromString)(value);
4184
4184
  return Exit.isSuccess(exit) ? Option.some(exit.value) : Option.none();
4185
4185
  };
4186
- const isRange$1 = (value) => Option.isSome(parseRange$1(value));
4187
- const protocolOf$1 = (value) => {
4188
- if (value.startsWith(CATALOG_PREFIX$1)) return "catalog";
4189
- if (value.startsWith(WORKSPACE_PREFIX$1)) return "workspace";
4186
+ const isRange = (value) => Option.isSome(parseRange(value));
4187
+ const protocolOf = (value) => {
4188
+ if (value.startsWith(CATALOG_PREFIX)) return "catalog";
4189
+ if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
4190
4190
  if (value.startsWith("link:")) return "link";
4191
4191
  if (value.startsWith("portal:")) return "portal";
4192
- if (value.startsWith("file:") || isBarePath$1(value)) return "file";
4192
+ if (value.startsWith("file:") || isBarePath(value)) return "file";
4193
4193
  if (value.startsWith("npm:")) return "npm";
4194
- if (isGit$1(value)) return "git";
4195
- if (isUrl$2(value)) return "url";
4196
- if (isRange$1(value)) return "range";
4194
+ if (isGit(value)) return "git";
4195
+ if (isUrl$1(value)) return "url";
4196
+ if (isRange(value)) return "range";
4197
4197
  if (/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(value)) return "tag";
4198
4198
  return "unknown";
4199
4199
  };
4200
- const isTag$1 = (value) => protocolOf$1(value) === "tag";
4201
- const catalogNameOf$2 = (specifier) => {
4202
- if (!isCatalog$1(specifier)) return Option.none();
4200
+ const isTag = (value) => protocolOf(value) === "tag";
4201
+ const catalogNameOf$1 = (specifier) => {
4202
+ if (!isCatalog(specifier)) return Option.none();
4203
4203
  const rest = specifier.slice(8).trim();
4204
4204
  return rest.length === 0 ? Option.none() : Option.some(rest);
4205
4205
  };
4206
- const projectRangeModifier$1 = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
4207
- const splitWorkspaceRest$1 = (rest) => {
4206
+ const projectRangeModifier = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
4207
+ const splitWorkspaceRest = (rest) => {
4208
4208
  const at = rest.lastIndexOf("@");
4209
4209
  return at > 0 ? {
4210
4210
  target: rest.slice(0, at),
@@ -4214,15 +4214,15 @@ const splitWorkspaceRest$1 = (rest) => {
4214
4214
  range: rest
4215
4215
  };
4216
4216
  };
4217
- const projectWorkspaceRange$1 = (rest, version) => {
4218
- const { target, range } = splitWorkspaceRest$1(rest);
4219
- const projected = projectRangeModifier$1(range, version);
4217
+ const projectWorkspaceRange = (rest, version) => {
4218
+ const { target, range } = splitWorkspaceRest(rest);
4219
+ const projected = projectRangeModifier(range, version);
4220
4220
  return target === void 0 ? projected : `npm:${target}@${projected}`;
4221
4221
  };
4222
- const resolveWorkspace$1 = (specifier, version) => isWorkspace$1(specifier) ? projectWorkspaceRange$1(specifier.slice(10), version) : specifier;
4223
- const workspaceTargetOf$1 = (specifier) => {
4224
- if (!isWorkspace$1(specifier)) return Option.none();
4225
- const { target } = splitWorkspaceRest$1(specifier.slice(10));
4222
+ const resolveWorkspace = (specifier, version) => isWorkspace(specifier) ? projectWorkspaceRange(specifier.slice(10), version) : specifier;
4223
+ const workspaceTargetOf = (specifier) => {
4224
+ if (!isWorkspace(specifier)) return Option.none();
4225
+ const { target } = splitWorkspaceRest(specifier.slice(10));
4226
4226
  return target === void 0 ? Option.none() : Option.some(target);
4227
4227
  };
4228
4228
  /**
@@ -4232,14 +4232,14 @@ const workspaceTargetOf$1 = (specifier) => {
4232
4232
  *
4233
4233
  * @public
4234
4234
  */
4235
- const isValidDependencySpecifier$1 = (value) => value.length > 0 && protocolOf$1(value) !== "unknown";
4235
+ const isValidDependencySpecifier = (value) => value.length > 0 && protocolOf(value) !== "unknown";
4236
4236
  /**
4237
4237
  * A `catalog:` reference. `name` carries the catalog name, or `Option.none()`
4238
4238
  * for the default catalog (`catalog:`).
4239
4239
  *
4240
4240
  * @public
4241
4241
  */
4242
- var CatalogSpecifier$1 = class extends Schema.TaggedClass()("catalog", {
4242
+ var CatalogSpecifier = class extends Schema.TaggedClass()("catalog", {
4243
4243
  /** The original specifier string. */
4244
4244
  raw: Schema.String,
4245
4245
  /** The catalog name, or `Option.none()` for the default catalog. */
@@ -4251,7 +4251,7 @@ var CatalogSpecifier$1 = class extends Schema.TaggedClass()("catalog", {
4251
4251
  *
4252
4252
  * @public
4253
4253
  */
4254
- var WorkspaceSpecifier$1 = class extends Schema.TaggedClass()("workspace", {
4254
+ var WorkspaceSpecifier = class extends Schema.TaggedClass()("workspace", {
4255
4255
  /** The original specifier string. */
4256
4256
  raw: Schema.String,
4257
4257
  /** The part after `workspace:` (e.g. `*`, `^1.2.3`, or an alias form). */
@@ -4275,7 +4275,7 @@ var WorkspaceSpecifier$1 = class extends Schema.TaggedClass()("workspace", {
4275
4275
  * specifier points at (the alias target's version for the alias form).
4276
4276
  */
4277
4277
  resolve(version) {
4278
- return projectWorkspaceRange$1(this.range, version);
4278
+ return projectWorkspaceRange(this.range, version);
4279
4279
  }
4280
4280
  };
4281
4281
  /**
@@ -4283,7 +4283,7 @@ var WorkspaceSpecifier$1 = class extends Schema.TaggedClass()("workspace", {
4283
4283
  *
4284
4284
  * @public
4285
4285
  */
4286
- var RangeSpecifier$1 = class extends Schema.TaggedClass()("range", {
4286
+ var RangeSpecifier = class extends Schema.TaggedClass()("range", {
4287
4287
  /** The original specifier string. */
4288
4288
  raw: Schema.String }) {};
4289
4289
  /**
@@ -4291,7 +4291,7 @@ raw: Schema.String }) {};
4291
4291
  *
4292
4292
  * @public
4293
4293
  */
4294
- var DistTagSpecifier$1 = class extends Schema.TaggedClass()("dist-tag", {
4294
+ var DistTagSpecifier = class extends Schema.TaggedClass()("dist-tag", {
4295
4295
  /** The original specifier string (also the tag name). */
4296
4296
  raw: Schema.String }) {};
4297
4297
  /**
@@ -4300,35 +4300,35 @@ raw: Schema.String }) {};
4300
4300
  *
4301
4301
  * @public
4302
4302
  */
4303
- var RawSpecifier$1 = class extends Schema.TaggedClass()("raw", {
4303
+ var RawSpecifier = class extends Schema.TaggedClass()("raw", {
4304
4304
  /** The original specifier string. */
4305
4305
  raw: Schema.String }) {};
4306
- const Classified$1 = Schema.Union([
4307
- CatalogSpecifier$1,
4308
- WorkspaceSpecifier$1,
4309
- RangeSpecifier$1,
4310
- DistTagSpecifier$1,
4311
- RawSpecifier$1
4306
+ const Classified = Schema.Union([
4307
+ CatalogSpecifier,
4308
+ WorkspaceSpecifier,
4309
+ RangeSpecifier,
4310
+ DistTagSpecifier,
4311
+ RawSpecifier
4312
4312
  ]);
4313
- const classify$2 = (value) => {
4314
- if (isCatalog$1(value)) return CatalogSpecifier$1.make({
4313
+ const classify$1 = (value) => {
4314
+ if (isCatalog(value)) return CatalogSpecifier.make({
4315
4315
  raw: value,
4316
- name: catalogNameOf$2(value)
4316
+ name: catalogNameOf$1(value)
4317
4317
  });
4318
- if (isWorkspace$1(value)) return WorkspaceSpecifier$1.make({
4318
+ if (isWorkspace(value)) return WorkspaceSpecifier.make({
4319
4319
  raw: value,
4320
4320
  range: value.slice(10)
4321
4321
  });
4322
- if (isRange$1(value)) return RangeSpecifier$1.make({ raw: value });
4323
- if (isTag$1(value)) return DistTagSpecifier$1.make({ raw: value });
4324
- return RawSpecifier$1.make({ raw: value });
4322
+ if (isRange(value)) return RangeSpecifier.make({ raw: value });
4323
+ if (isTag(value)) return DistTagSpecifier.make({ raw: value });
4324
+ return RawSpecifier.make({ raw: value });
4325
4325
  };
4326
- const fromString$1 = Schema.String.pipe(Schema.decodeTo(Classified$1, SchemaTransformation.transformOrFail({
4327
- decode: (input) => isValidDependencySpecifier$1(input) ? Effect.succeed(classify$2(input)) : Effect.fail(new SchemaIssue.InvalidValue(Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
4326
+ const fromString = Schema.String.pipe(Schema.decodeTo(Classified, SchemaTransformation.transformOrFail({
4327
+ decode: (input) => isValidDependencySpecifier(input) ? Effect.succeed(classify$1(input)) : Effect.fail(new SchemaIssue.InvalidValue(Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
4328
4328
  encode: (classified) => Effect.succeed(classified.raw)
4329
4329
  })));
4330
- const brandedSpecifier$1 = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => isValidDependencySpecifier$1(value) ? void 0 : "Expected a valid dependency specifier")), Schema.brand("DependencySpecifier"));
4331
- const decode$5 = (input) => Schema.decodeUnknownEffect(brandedSpecifier$1)(input).pipe(Effect.mapError(() => new InvalidDependencySpecifierError$1({ input })));
4330
+ const brandedSpecifier = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => isValidDependencySpecifier(value) ? void 0 : "Expected a valid dependency specifier")), Schema.brand("DependencySpecifier"));
4331
+ const decode$3 = (input) => Schema.decodeUnknownEffect(brandedSpecifier)(input).pipe(Effect.mapError(() => new InvalidDependencySpecifierError({ input })));
4332
4332
  /**
4333
4333
  * A valid dependency version specifier, carrying the protocol taxonomy statics
4334
4334
  * (`DependencySpecifier.protocolOf` and friends) that classify any specifier
@@ -4339,44 +4339,44 @@ const decode$5 = (input) => Schema.decodeUnknownEffect(brandedSpecifier$1)(input
4339
4339
  *
4340
4340
  * @public
4341
4341
  */
4342
- const DependencySpecifier$1 = Object.assign(brandedSpecifier$1, {
4343
- protocolOf: protocolOf$1,
4344
- parseRange: parseRange$1,
4345
- isRange: isRange$1,
4346
- isTag: isTag$1,
4347
- isGit: isGit$1,
4348
- isUrl: isUrl$2,
4349
- isLocal: isLocal$1,
4350
- isLink: isLink$1,
4351
- isPortal: isPortal$1,
4352
- isCatalog: isCatalog$1,
4353
- isWorkspace: isWorkspace$1,
4354
- catalogNameOf: catalogNameOf$2,
4355
- resolveWorkspace: resolveWorkspace$1,
4356
- workspaceTargetOf: workspaceTargetOf$1,
4357
- isValid: isValidDependencySpecifier$1,
4358
- decode: decode$5,
4359
- FromString: fromString$1
4342
+ const DependencySpecifier = Object.assign(brandedSpecifier, {
4343
+ protocolOf,
4344
+ parseRange,
4345
+ isRange,
4346
+ isTag,
4347
+ isGit,
4348
+ isUrl: isUrl$1,
4349
+ isLocal,
4350
+ isLink,
4351
+ isPortal,
4352
+ isCatalog,
4353
+ isWorkspace,
4354
+ catalogNameOf: catalogNameOf$1,
4355
+ resolveWorkspace,
4356
+ workspaceTargetOf,
4357
+ isValid: isValidDependencySpecifier,
4358
+ decode: decode$3,
4359
+ FromString: fromString
4360
4360
  });
4361
4361
 
4362
4362
  //#endregion
4363
4363
  //#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
4364
- const SRI_RE$1 = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4365
- const COREPACK_RE$1 = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4366
- const YARN_RE$1 = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
4367
- const isSri$1 = (value) => SRI_RE$1.test(value);
4368
- const isCorepack$1 = (value) => COREPACK_RE$1.test(value);
4369
- const isYarnChecksum$1 = (value) => YARN_RE$1.test(value);
4364
+ const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4365
+ const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4366
+ const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
4367
+ const isSri = (value) => SRI_RE.test(value);
4368
+ const isCorepack = (value) => COREPACK_RE.test(value);
4369
+ const isYarnChecksum = (value) => YARN_RE.test(value);
4370
4370
  /**
4371
4371
  * Whether a string is a valid integrity hash in the SRI (`<algo>-<base64>`),
4372
4372
  * corepack (`<algo>.<hex>`) or yarn (`<cachekey>/<hex>`) form.
4373
4373
  *
4374
4374
  * @public
4375
4375
  */
4376
- const isValidIntegrityHash$1 = (value) => isSri$1(value) || isCorepack$1(value) || isYarnChecksum$1(value);
4377
- const algorithmOf$1 = (value) => {
4378
- if (isSri$1(value)) return Option.some(value.slice(0, value.indexOf("-")));
4379
- if (isCorepack$1(value)) return Option.some(value.slice(0, value.indexOf(".")));
4376
+ const isValidIntegrityHash = (value) => isSri(value) || isCorepack(value) || isYarnChecksum(value);
4377
+ const algorithmOf = (value) => {
4378
+ if (isSri(value)) return Option.some(value.slice(0, value.indexOf("-")));
4379
+ if (isCorepack(value)) return Option.some(value.slice(0, value.indexOf(".")));
4380
4380
  return Option.none();
4381
4381
  };
4382
4382
  /**
@@ -4387,15 +4387,15 @@ const algorithmOf$1 = (value) => {
4387
4387
  *
4388
4388
  * @public
4389
4389
  */
4390
- var InvalidIntegrityHashError$1 = class extends Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
4390
+ var InvalidIntegrityHashError = class extends Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
4391
4391
  /** The raw input string that failed validation. */
4392
4392
  input: Schema.String }) {
4393
4393
  get message() {
4394
4394
  return `Invalid integrity hash "${this.input}": expected an SRI (<algo>-<base64>), corepack (<algo>.<hex>) or yarn (<cachekey>/<hex>) form`;
4395
4395
  }
4396
4396
  };
4397
- const brandedIntegrity$1 = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => isValidIntegrityHash$1(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), Schema.brand("IntegrityHash"));
4398
- const decode$4 = (input) => Schema.decodeUnknownEffect(brandedIntegrity$1)(input).pipe(Effect.mapError(() => new InvalidIntegrityHashError$1({ input })));
4397
+ const brandedIntegrity = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => isValidIntegrityHash(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), Schema.brand("IntegrityHash"));
4398
+ const decode$2 = (input) => Schema.decodeUnknownEffect(brandedIntegrity)(input).pipe(Effect.mapError(() => new InvalidIntegrityHashError({ input })));
4399
4399
  /**
4400
4400
  * A subresource-integrity hash, covering the SRI (`sha512-<base64>`), corepack
4401
4401
  * (`sha512.<hex>`) and yarn (`10c0/<hex>`) textual forms, carrying taxonomy
@@ -4404,13 +4404,13 @@ const decode$4 = (input) => Schema.decodeUnknownEffect(brandedIntegrity$1)(input
4404
4404
  *
4405
4405
  * @public
4406
4406
  */
4407
- const IntegrityHash$1 = Object.assign(brandedIntegrity$1, {
4408
- isSri: isSri$1,
4409
- isCorepack: isCorepack$1,
4410
- isYarnChecksum: isYarnChecksum$1,
4411
- isValid: isValidIntegrityHash$1,
4412
- algorithmOf: algorithmOf$1,
4413
- decode: decode$4
4407
+ const IntegrityHash = Object.assign(brandedIntegrity, {
4408
+ isSri,
4409
+ isCorepack,
4410
+ isYarnChecksum,
4411
+ isValid: isValidIntegrityHash,
4412
+ algorithmOf,
4413
+ decode: decode$2
4414
4414
  });
4415
4415
  /**
4416
4416
  * {@link (IntegrityHash:variable)} narrowed to the corepack `<algo>.<hex>` form
@@ -4463,7 +4463,7 @@ const IntegrityHash$1 = Object.assign(brandedIntegrity$1, {
4463
4463
  *
4464
4464
  * @public
4465
4465
  */
4466
- const CorepackIntegrityHash$1 = brandedIntegrity$1.pipe(Schema.check(Schema.makeFilter((value) => isCorepack$1(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
4466
+ const CorepackIntegrityHash = brandedIntegrity.pipe(Schema.check(Schema.makeFilter((value) => isCorepack(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
4467
4467
 
4468
4468
  //#endregion
4469
4469
  //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/LocalExec.js
@@ -5552,10 +5552,10 @@ var ReleaseAgeGate = class ReleaseAgeGate extends Schema.Class("ReleaseAgeGate")
5552
5552
  */
5553
5553
  var ImporterDependency = class extends Schema.Class("ImporterDependency")({
5554
5554
  name: Schema.NonEmptyString,
5555
- specifier: DependencySpecifier$1.FromString,
5555
+ specifier: DependencySpecifier.FromString,
5556
5556
  version: Schema.optionalKey(Schema.String),
5557
5557
  peerSuffix: Schema.optionalKey(Schema.String),
5558
- depType: DependencyField$1
5558
+ depType: DependencyField
5559
5559
  }) {};
5560
5560
 
5561
5561
  //#endregion
@@ -5613,7 +5613,7 @@ const EMPTY_DEPENDENCIES = {};
5613
5613
  var ResolvedPackage = class extends Schema.Class("ResolvedPackage")({
5614
5614
  name: Schema.NonEmptyString,
5615
5615
  version: Schema.String,
5616
- integrity: Schema.optionalKey(IntegrityHash$1),
5616
+ integrity: Schema.optionalKey(IntegrityHash),
5617
5617
  isWorkspace: Schema.Boolean,
5618
5618
  relativePath: Schema.optionalKey(Schema.String),
5619
5619
  dependencies: Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY_DEPENDENCIES)), Schema.withConstructorDefault(Effect.succeed(EMPTY_DEPENDENCIES)))
@@ -5638,7 +5638,7 @@ var ResolvedPackage = class extends Schema.Class("ResolvedPackage")({
5638
5638
  var WorkspaceDependency = class extends Schema.Class("WorkspaceDependency")({
5639
5639
  from: Schema.NonEmptyString,
5640
5640
  to: Schema.NonEmptyString,
5641
- depType: DependencyField$1,
5641
+ depType: DependencyField,
5642
5642
  constraint: Schema.String
5643
5643
  }) {};
5644
5644
 
@@ -5743,9 +5743,9 @@ const DEP_TYPES = [
5743
5743
  */
5744
5744
  const toIntegrityHash = (raw) => {
5745
5745
  if (raw === void 0) return Effect.succeed(void 0);
5746
- return Schema.decodeUnknownEffect(IntegrityHash$1)(raw).pipe(Effect.mapError(validationFailure));
5746
+ return Schema.decodeUnknownEffect(IntegrityHash)(raw).pipe(Effect.mapError(validationFailure));
5747
5747
  };
5748
- const decodeSpecifier = Schema.decodeUnknownExit(DependencySpecifier$1.FromString);
5748
+ const decodeSpecifier = Schema.decodeUnknownExit(DependencySpecifier.FromString);
5749
5749
  /**
5750
5750
  * Split pnpm's peer-disambiguation suffix off a recorded string: everything
5751
5751
  * from the first `(` on is suffix, since package names and versions never
@@ -15416,7 +15416,7 @@ var LockfileIntegrity = class LockfileIntegrity extends Schema.Class("LockfileIn
15416
15416
  dependency: Schema.String,
15417
15417
  constraint: Schema.String,
15418
15418
  resolved: Schema.String,
15419
- depType: DependencyField$1
15419
+ depType: DependencyField
15420
15420
  }))
15421
15421
  }) {
15422
15422
  /**
@@ -15485,565 +15485,108 @@ var LockfileIntegrity = class LockfileIntegrity extends Schema.Class("LockfileIn
15485
15485
  };
15486
15486
 
15487
15487
  //#endregion
15488
- //#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
15488
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
15489
15489
  /**
15490
- * Contract for resolving pnpm `catalog:` dependency specifiers to concrete
15491
- * version ranges.
15492
- *
15493
- * `rangeOf` takes a package name and an optional catalog name
15494
- * (`Option.none()` selects the default catalog) and returns the configured
15495
- * range as `Option.some`, or `Option.none()` when the specifier is absent
15496
- * from the catalog. By convention the error channel is reserved for a
15497
- * failure in the resolution mechanism itself — an unmatched package or
15498
- * catalog name is an `Option.none()` success, never an error. A failure to
15499
- * *assemble* the catalogs (an unreadable or malformed catalog source)
15500
- * surfaces typed as a {@link CatalogAssemblyError}; any other mechanism
15501
- * failure is a {@link DependencyResolutionError}.
15502
- *
15503
- * This is a contract-only service: {@link CatalogResolver.noop} is the sole
15504
- * implementation this package ships, and it resolves nothing. Real consumers
15505
- * (e.g. `@effected/workspaces`) provide a working implementation at the
15506
- * application boundary.
15507
- *
15508
- * @example
15509
- * ```ts
15510
- * import { Effect, Option } from "effect";
15511
- * import { CatalogResolver } from "@effected/npm";
15512
- *
15513
- * const program = Effect.gen(function* () {
15514
- * const resolver = yield* CatalogResolver;
15515
- * return yield* resolver.rangeOf("effect", Option.none());
15516
- * });
15517
- *
15518
- * Effect.runPromise(Effect.provide(program, CatalogResolver.noop));
15519
- * // => Option.none()
15520
- * ```
15490
+ * A resolved dependency entry pairing a package name with its version
15491
+ * specifier and the `kind` of map it came from (`@effected/npm`'s
15492
+ * `DependencyKind`). The protocol predicates delegate to `DependencySpecifier`.
15521
15493
  *
15522
15494
  * @public
15523
15495
  */
15524
- var CatalogResolver = class CatalogResolver extends Context.Service()("@effected/npm/CatalogResolver") {
15525
- /**
15526
- * No-op default: `rangeOf` always succeeds with `Option.none()`, never
15527
- * consulting an actual catalog. A pure `Layer.succeed`, bound to a const
15528
- * so it memoizes by reference — the layer is built once, not once per
15529
- * reference to `CatalogResolver.noop`.
15530
- */
15531
- static noop = Layer.succeed(CatalogResolver, { rangeOf: () => Effect.succeed(Option.none()) });
15496
+ var Dependency = class extends Schema.Class("Dependency")({
15497
+ /** The package name. */
15498
+ name: Schema.String,
15499
+ /** The raw version specifier. */
15500
+ specifier: Schema.String,
15501
+ /** Which dependency map this entry came from. */
15502
+ kind: DependencyKind,
15503
+ /** For `peer` dependencies, whether the peer is optional (from `peerDependenciesMeta`). */
15504
+ isOptional: Schema.optionalKey(Schema.Boolean)
15505
+ }) {
15506
+ /** The classified protocol, or `None` for an empty specifier. */
15507
+ get protocol() {
15508
+ return this.specifier.length === 0 ? Option.none() : Option.some(DependencySpecifier.protocolOf(this.specifier));
15509
+ }
15510
+ /** Parse the specifier as a semver `Range`, `None` when it is not a range. */
15511
+ get range() {
15512
+ return DependencySpecifier.parseRange(this.specifier);
15513
+ }
15514
+ /** Whether the specifier points to a local path. */
15515
+ get isLocal() {
15516
+ return DependencySpecifier.isLocal(this.specifier);
15517
+ }
15518
+ /** Whether the specifier uses the `link:` protocol. */
15519
+ get isLink() {
15520
+ return DependencySpecifier.isLink(this.specifier);
15521
+ }
15522
+ /** Whether the specifier uses the `portal:` protocol. */
15523
+ get isPortal() {
15524
+ return DependencySpecifier.isPortal(this.specifier);
15525
+ }
15526
+ /** Whether the specifier uses the `catalog:` protocol. */
15527
+ get isCatalog() {
15528
+ return DependencySpecifier.isCatalog(this.specifier);
15529
+ }
15530
+ /** Whether the specifier uses the `workspace:` protocol. */
15531
+ get isWorkspace() {
15532
+ return DependencySpecifier.isWorkspace(this.specifier);
15533
+ }
15534
+ /** Whether the specifier is an unresolved `catalog:` or `workspace:` protocol. */
15535
+ get isUnresolved() {
15536
+ return this.isCatalog || this.isWorkspace;
15537
+ }
15538
+ /** Whether the specifier resolves to a git source. */
15539
+ get isGit() {
15540
+ return DependencySpecifier.isGit(this.specifier);
15541
+ }
15542
+ /** Whether the specifier is a parseable semver range. */
15543
+ get isRange() {
15544
+ return DependencySpecifier.isRange(this.specifier);
15545
+ }
15546
+ /** Whether the specifier is a dist-tag. */
15547
+ get isTag() {
15548
+ return DependencySpecifier.isTag(this.specifier);
15549
+ }
15532
15550
  };
15533
15551
 
15534
15552
  //#endregion
15535
- //#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/WorkspaceResolver.js
15553
+ //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/DevEngines.js
15536
15554
  /**
15537
- * Raised when a `catalog:` or `workspace:` specifier cannot be resolved
15538
- * because the resolution mechanism itself failed — not for an ordinary
15539
- * unmatched specifier, which resolves to `Option.none()` instead. Both
15540
- * {@link CatalogResolver} and {@link WorkspaceResolver} fail with it.
15541
- *
15542
- * `cause` preserves the originating failure on a structured `Schema.Defect`
15543
- * field rather than folding it into a string, so callers can branch on the
15544
- * original value (an `Error`, a parsed diagnostic, anything); `specifier`
15545
- * records the specifier string that failed to resolve.
15555
+ * A single `devEngines` constraint with a name and optional `version` / `onFail`.
15546
15556
  *
15547
15557
  * @public
15548
15558
  */
15549
- var DependencyResolutionError = class extends Schema.TaggedErrorClass()("DependencyResolutionError", {
15550
- specifier: Schema.String,
15551
- cause: Schema.Defect()
15552
- }) {
15553
- /** Renders `specifier` into a one-line failure message. */
15554
- get message() {
15555
- return `Failed to resolve dependency specifier "${this.specifier}"`;
15556
- }
15557
- };
15559
+ var DevEngine = class extends Schema.Class("DevEngine")({
15560
+ /** The engine name (e.g. `node`, `pnpm`). */
15561
+ name: Schema.String,
15562
+ /** The optional version constraint. */
15563
+ version: Schema.optionalKey(Schema.String),
15564
+ /** The optional behavior when the constraint is unmet. */
15565
+ onFail: Schema.optionalKey(Schema.Literals([
15566
+ "warn",
15567
+ "error",
15568
+ "ignore"
15569
+ ]))
15570
+ }) {};
15558
15571
  /**
15559
- * Contract for resolving pnpm `workspace:` dependency specifiers to concrete
15560
- * versions.
15561
- *
15562
- * `versionOf` takes a workspace package name and returns its concrete
15563
- * version (the range modifier stripped) as `Option.some`, or
15564
- * `Option.none()` when the name is not a known workspace member.
15565
- *
15566
- * This is a contract-only service: {@link WorkspaceResolver.noop} is the
15567
- * sole implementation this package ships, and it resolves nothing. Real
15568
- * consumers (e.g. `@effected/workspaces`) provide a working implementation
15569
- * at the application boundary.
15572
+ * A `devEngines` constraint slot: a single {@link DevEngine} or an array of them.
15570
15573
  *
15571
- * @example
15572
- * ```ts
15573
- * import { Effect } from "effect";
15574
- * import { WorkspaceResolver } from "@effected/npm";
15575
- *
15576
- * const program = Effect.gen(function* () {
15577
- * const resolver = yield* WorkspaceResolver;
15578
- * return yield* resolver.versionOf("@effected/semver");
15579
- * });
15580
- *
15581
- * Effect.runPromise(Effect.provide(program, WorkspaceResolver.noop));
15582
- * // => Option.none()
15583
- * ```
15584
- *
15585
- * @public
15586
- */
15587
- var WorkspaceResolver = class WorkspaceResolver extends Context.Service()("@effected/npm/WorkspaceResolver") {
15588
- /**
15589
- * No-op default: `versionOf` always succeeds with `Option.none()`, never
15590
- * consulting an actual workspace. A pure `Layer.succeed`, bound to a
15591
- * const so it memoizes by reference.
15592
- */
15593
- static noop = Layer.succeed(WorkspaceResolver, { versionOf: () => Effect.succeed(Option.none()) });
15594
- };
15595
-
15596
- //#endregion
15597
- //#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
15598
- /**
15599
- * The short dependency kind: which dependency map an entry came from, named the
15600
- * way consumers branch on it.
15601
- *
15602
- * @public
15603
- */
15604
- const DependencyKind = Schema.Literals([
15605
- "prod",
15606
- "dev",
15607
- "peer",
15608
- "optional"
15609
- ]);
15610
- /**
15611
- * The manifest field name a dependency is declared under, matching the
15612
- * `package.json` / `package-lock.json` key exactly.
15574
+ * @public
15575
+ */
15576
+ const DevEngineOrArray = Schema.Union([DevEngine, Schema.Array(DevEngine)]);
15577
+ /**
15578
+ * The `devEngines` field schema, modeling runtime and package-manager
15579
+ * constraints as optional {@link DevEngine} slots.
15613
15580
  *
15614
15581
  * @public
15615
15582
  */
15616
- const DependencyField = Schema.Literals([
15617
- "dependencies",
15618
- "devDependencies",
15619
- "peerDependencies",
15620
- "optionalDependencies"
15621
- ]);
15622
- const KIND_TO_FIELD = {
15623
- prod: "dependencies",
15624
- dev: "devDependencies",
15625
- peer: "peerDependencies",
15626
- optional: "optionalDependencies"
15627
- };
15628
- const FIELD_TO_KIND = Object.fromEntries(Object.entries(KIND_TO_FIELD).map(([kind, field]) => [field, kind]));
15629
-
15630
- //#endregion
15631
- //#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
15632
- /**
15633
- * Indicates that a string could not be parsed as a valid dependency specifier.
15634
- *
15635
- * Raised by {@link DependencySpecifier.decode}. The offending string is
15636
- * preserved on `input`.
15637
- *
15638
- * @public
15639
- */
15640
- var InvalidDependencySpecifierError = class extends Schema.TaggedErrorClass()("InvalidDependencySpecifierError", {
15641
- /** The raw input string that failed validation. */
15642
- input: Schema.String }) {
15643
- get message() {
15644
- return `Invalid dependency specifier "${this.input}": not a recognized specifier`;
15645
- }
15646
- };
15647
- const CATALOG_PREFIX = "catalog:";
15648
- const WORKSPACE_PREFIX = "workspace:";
15649
- const isBarePath = (value) => value.startsWith("./") || value.startsWith("../") || value.startsWith("~/") || value.startsWith("/");
15650
- const isGitHubShorthand = (value) => !value.startsWith(".") && !value.startsWith("~") && !value.startsWith("/") && /^[a-zA-Z0-9_.-]+\/[a-zA-Z0-9_.-]+(#.*)?$/.test(value);
15651
- const isGit = (value) => value.startsWith("git+") || value.startsWith("git://") || value.startsWith("github:") || value.startsWith("gist:") || value.startsWith("bitbucket:") || value.startsWith("gitlab:") || isGitHubShorthand(value);
15652
- const isLocal = (value) => value.startsWith("file:") || value.startsWith("link:") || value.startsWith("portal:") || isBarePath(value);
15653
- const isLink = (value) => value.startsWith("link:");
15654
- const isPortal = (value) => value.startsWith("portal:");
15655
- const isCatalog = (value) => value.startsWith(CATALOG_PREFIX);
15656
- const isWorkspace = (value) => value.startsWith(WORKSPACE_PREFIX);
15657
- const isUrl$1 = (value) => value.startsWith("http://") || value.startsWith("https://");
15658
- const parseRange = (value) => {
15659
- const exit = Schema.decodeUnknownExit(Range$1.FromString)(value);
15660
- return Exit.isSuccess(exit) ? Option.some(exit.value) : Option.none();
15661
- };
15662
- const isRange = (value) => Option.isSome(parseRange(value));
15663
- const protocolOf = (value) => {
15664
- if (value.startsWith(CATALOG_PREFIX)) return "catalog";
15665
- if (value.startsWith(WORKSPACE_PREFIX)) return "workspace";
15666
- if (value.startsWith("link:")) return "link";
15667
- if (value.startsWith("portal:")) return "portal";
15668
- if (value.startsWith("file:") || isBarePath(value)) return "file";
15669
- if (value.startsWith("npm:")) return "npm";
15670
- if (isGit(value)) return "git";
15671
- if (isUrl$1(value)) return "url";
15672
- if (isRange(value)) return "range";
15673
- if (/^[a-zA-Z][a-zA-Z0-9._-]*$/.test(value)) return "tag";
15674
- return "unknown";
15675
- };
15676
- const isTag = (value) => protocolOf(value) === "tag";
15677
- const catalogNameOf$1 = (specifier) => {
15678
- if (!isCatalog(specifier)) return Option.none();
15679
- const rest = specifier.slice(8).trim();
15680
- return rest.length === 0 ? Option.none() : Option.some(rest);
15681
- };
15682
- const projectRangeModifier = (range, version) => range === "*" || range === "" ? version : range === "~" ? `~${version}` : range === "^" ? `^${version}` : range;
15683
- const splitWorkspaceRest = (rest) => {
15684
- const at = rest.lastIndexOf("@");
15685
- return at > 0 ? {
15686
- target: rest.slice(0, at),
15687
- range: rest.slice(at + 1)
15688
- } : {
15689
- target: void 0,
15690
- range: rest
15691
- };
15692
- };
15693
- const projectWorkspaceRange = (rest, version) => {
15694
- const { target, range } = splitWorkspaceRest(rest);
15695
- const projected = projectRangeModifier(range, version);
15696
- return target === void 0 ? projected : `npm:${target}@${projected}`;
15697
- };
15698
- const resolveWorkspace = (specifier, version) => isWorkspace(specifier) ? projectWorkspaceRange(specifier.slice(10), version) : specifier;
15699
- const workspaceTargetOf = (specifier) => {
15700
- if (!isWorkspace(specifier)) return Option.none();
15701
- const { target } = splitWorkspaceRest(specifier.slice(10));
15702
- return target === void 0 ? Option.none() : Option.some(target);
15703
- };
15704
- /**
15705
- * Whether a string is a recognized dependency specifier: a semver range, exact
15706
- * version, dist-tag, URL, git ref, GitHub shorthand, file path, or an
15707
- * `npm:` / `catalog:` / `workspace:` protocol.
15708
- *
15709
- * @public
15710
- */
15711
- const isValidDependencySpecifier = (value) => value.length > 0 && protocolOf(value) !== "unknown";
15712
- /**
15713
- * A `catalog:` reference. `name` carries the catalog name, or `Option.none()`
15714
- * for the default catalog (`catalog:`).
15715
- *
15716
- * @public
15717
- */
15718
- var CatalogSpecifier = class extends Schema.TaggedClass()("catalog", {
15719
- /** The original specifier string. */
15720
- raw: Schema.String,
15721
- /** The catalog name, or `Option.none()` for the default catalog. */
15722
- name: Schema.Option(Schema.String)
15723
- }) {};
15724
- /**
15725
- * A `workspace:` reference. `range` carries the part after `workspace:` — a
15726
- * range modifier (`*`, `^`, `~`), a concrete range, or an alias form.
15727
- *
15728
- * @public
15729
- */
15730
- var WorkspaceSpecifier = class extends Schema.TaggedClass()("workspace", {
15731
- /** The original specifier string. */
15732
- raw: Schema.String,
15733
- /** The part after `workspace:` (e.g. `*`, `^1.2.3`, or an alias form). */
15734
- range: Schema.String
15735
- }) {
15736
- /**
15737
- * The pnpm publish-time projection of this specifier against a concrete
15738
- * workspace version: `*` (or an empty range) becomes `version`, `~` becomes
15739
- * `~version`, `^` becomes `^version`, and a pinned range passes through
15740
- * unchanged. The alias form (`workspace:<name>@<range>`) becomes pnpm's
15741
- * publish-time aliased dependency `npm:<name>@<projected>`, with the range
15742
- * modifier projected the same way — `version` must then be the TARGET
15743
- * package's version (see `DependencySpecifier.workspaceTargetOf`).
15744
- *
15745
- * @remarks
15746
- * The same projection as `DependencySpecifier.resolveWorkspace`, applied to
15747
- * this instance's already-extracted `range`; the two share one internal
15748
- * implementation.
15749
- *
15750
- * @param version - The concrete version of the workspace package the
15751
- * specifier points at (the alias target's version for the alias form).
15752
- */
15753
- resolve(version) {
15754
- return projectWorkspaceRange(this.range, version);
15755
- }
15756
- };
15757
- /**
15758
- * A plain semver range or exact version (e.g. `^1.2.3`, `1.x`, `>=1 <2`).
15759
- *
15760
- * @public
15761
- */
15762
- var RangeSpecifier = class extends Schema.TaggedClass()("range", {
15763
- /** The original specifier string. */
15764
- raw: Schema.String }) {};
15765
- /**
15766
- * A bare dist-tag (e.g. `latest`, `next`).
15767
- *
15768
- * @public
15769
- */
15770
- var DistTagSpecifier = class extends Schema.TaggedClass()("dist-tag", {
15771
- /** The original specifier string (also the tag name). */
15772
- raw: Schema.String }) {};
15773
- /**
15774
- * The honest fallback for `file:` / `link:` / `portal:` / git / URL / `npm:`
15775
- * forms this concept does not further interpret.
15776
- *
15777
- * @public
15778
- */
15779
- var RawSpecifier = class extends Schema.TaggedClass()("raw", {
15780
- /** The original specifier string. */
15781
- raw: Schema.String }) {};
15782
- const Classified = Schema.Union([
15783
- CatalogSpecifier,
15784
- WorkspaceSpecifier,
15785
- RangeSpecifier,
15786
- DistTagSpecifier,
15787
- RawSpecifier
15788
- ]);
15789
- const classify$1 = (value) => {
15790
- if (isCatalog(value)) return CatalogSpecifier.make({
15791
- raw: value,
15792
- name: catalogNameOf$1(value)
15793
- });
15794
- if (isWorkspace(value)) return WorkspaceSpecifier.make({
15795
- raw: value,
15796
- range: value.slice(10)
15797
- });
15798
- if (isRange(value)) return RangeSpecifier.make({ raw: value });
15799
- if (isTag(value)) return DistTagSpecifier.make({ raw: value });
15800
- return RawSpecifier.make({ raw: value });
15801
- };
15802
- const fromString = Schema.String.pipe(Schema.decodeTo(Classified, SchemaTransformation.transformOrFail({
15803
- decode: (input) => isValidDependencySpecifier(input) ? Effect.succeed(classify$1(input)) : Effect.fail(new SchemaIssue.InvalidValue(Option.some(input), { message: `Invalid dependency specifier: "${input}"` })),
15804
- encode: (classified) => Effect.succeed(classified.raw)
15805
- })));
15806
- const brandedSpecifier = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => isValidDependencySpecifier(value) ? void 0 : "Expected a valid dependency specifier")), Schema.brand("DependencySpecifier"));
15807
- const decode$3 = (input) => Schema.decodeUnknownEffect(brandedSpecifier)(input).pipe(Effect.mapError(() => new InvalidDependencySpecifierError({ input })));
15808
- /**
15809
- * A valid dependency version specifier, carrying the protocol taxonomy statics
15810
- * (`DependencySpecifier.protocolOf` and friends) that classify any specifier
15811
- * string, plus the {@link (DependencySpecifier:variable).FromString} codec that
15812
- * decodes a string into a {@link ClassifiedSpecifier} tagged union. Use it as a
15813
- * schema for a specifier field and reach for the statics to inspect a raw
15814
- * string.
15815
- *
15816
- * @public
15817
- */
15818
- const DependencySpecifier = Object.assign(brandedSpecifier, {
15819
- protocolOf,
15820
- parseRange,
15821
- isRange,
15822
- isTag,
15823
- isGit,
15824
- isUrl: isUrl$1,
15825
- isLocal,
15826
- isLink,
15827
- isPortal,
15828
- isCatalog,
15829
- isWorkspace,
15830
- catalogNameOf: catalogNameOf$1,
15831
- resolveWorkspace,
15832
- workspaceTargetOf,
15833
- isValid: isValidDependencySpecifier,
15834
- decode: decode$3,
15835
- FromString: fromString
15836
- });
15837
-
15838
- //#endregion
15839
- //#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
15840
- const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
15841
- const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
15842
- const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
15843
- const isSri = (value) => SRI_RE.test(value);
15844
- const isCorepack = (value) => COREPACK_RE.test(value);
15845
- const isYarnChecksum = (value) => YARN_RE.test(value);
15846
- /**
15847
- * Whether a string is a valid integrity hash in the SRI (`<algo>-<base64>`),
15848
- * corepack (`<algo>.<hex>`) or yarn (`<cachekey>/<hex>`) form.
15849
- *
15850
- * @public
15851
- */
15852
- const isValidIntegrityHash = (value) => isSri(value) || isCorepack(value) || isYarnChecksum(value);
15853
- const algorithmOf = (value) => {
15854
- if (isSri(value)) return Option.some(value.slice(0, value.indexOf("-")));
15855
- if (isCorepack(value)) return Option.some(value.slice(0, value.indexOf(".")));
15856
- return Option.none();
15857
- };
15858
- /**
15859
- * Indicates that a string could not be parsed as a valid integrity hash.
15860
- *
15861
- * Raised by {@link IntegrityHash.decode}. The offending string is preserved on
15862
- * `input`.
15863
- *
15864
- * @public
15865
- */
15866
- var InvalidIntegrityHashError = class extends Schema.TaggedErrorClass()("InvalidIntegrityHashError", {
15867
- /** The raw input string that failed validation. */
15868
- input: Schema.String }) {
15869
- get message() {
15870
- return `Invalid integrity hash "${this.input}": expected an SRI (<algo>-<base64>), corepack (<algo>.<hex>) or yarn (<cachekey>/<hex>) form`;
15871
- }
15872
- };
15873
- const brandedIntegrity = Schema.String.pipe(Schema.check(Schema.makeFilter((value) => isValidIntegrityHash(value) ? void 0 : "Expected an SRI, corepack or yarn integrity hash")), Schema.brand("IntegrityHash"));
15874
- const decode$2 = (input) => Schema.decodeUnknownEffect(brandedIntegrity)(input).pipe(Effect.mapError(() => new InvalidIntegrityHashError({ input })));
15875
- /**
15876
- * A subresource-integrity hash, covering the SRI (`sha512-<base64>`), corepack
15877
- * (`sha512.<hex>`) and yarn (`10c0/<hex>`) textual forms, carrying taxonomy
15878
- * statics (`IntegrityHash.algorithmOf` and friends). Use it as a schema for an
15879
- * integrity field and reach for the statics to inspect a raw string.
15880
- *
15881
- * @public
15882
- */
15883
- const IntegrityHash = Object.assign(brandedIntegrity, {
15884
- isSri,
15885
- isCorepack,
15886
- isYarnChecksum,
15887
- isValid: isValidIntegrityHash,
15888
- algorithmOf,
15889
- decode: decode$2
15890
- });
15891
- /**
15892
- * {@link (IntegrityHash:variable)} narrowed to the corepack `<algo>.<hex>` form
15893
- * — `sha512.deadbeef`, and corepack's own sha224 default pins
15894
- * (`sha224.877304e3…`). An SRI (`sha512-<base64>`) or yarn (`10c0/<hex>`)
15895
- * hash, both valid `IntegrityHash` values, fails this schema.
15896
- *
15897
- * @remarks
15898
- * The corepack pin tail (`<name>@<version>+<integrity>`) is the one place the
15899
- * kit meets this form, and two schemas name it: `PackageManagerPin.integrity`
15900
- * here and `@effected/package-json`'s `PackageManager.integrity`. Both consume
15901
- * **this** schema — the restriction existed privately in each module until they
15902
- * were consolidated, and a private copy is exactly how the two drift (the
15903
- * widening that admitted sha224 had to be made twice).
15904
- *
15905
- * It decodes to the same {@link IntegrityHashBrand} the unrestricted schema
15906
- * does, so a corepack-validated value assigns anywhere an `IntegrityHash` is
15907
- * expected; there is no second brand. Reach for
15908
- * `IntegrityHash.isCorepack(value)` to ask the same question about a raw
15909
- * string without decoding.
15910
- *
15911
- * That single brand is also why sharing this schema is not type-enforced, and
15912
- * the consequence is sharper than it looks: a `Schema.check` is **erased from
15913
- * the built type**, so this schema and the unrestricted one are the same
15914
- * declared type. A consumer that quietly reverts to a private copy compiles
15915
- * clean, and — if the copy is faithful — passes every rejection test too.
15916
- * Neither `tsc` nor behaviour can see the re-fork.
15917
- *
15918
- * What does see it is **object identity**, so each consumer's suite asserts
15919
- * that its field schema IS this export:
15920
- * `PackageManagerPin.fields.integrity.schema === CorepackIntegrityHash` (an
15921
- * `optionalKey` field keeps the inner schema on `.schema`), and
15922
- * `PackageManager.fields.integrity.value === CorepackIntegrityHash` on the
15923
- * `@effected/package-json` side (a `Schema.Option` keeps it on `.value`). Both
15924
- * assertions carry a control against the unrestricted brand, so they discriminate
15925
- * rather than passing on any schema at all. That identity assertion is the only
15926
- * thing standing between the two surfaces and a silent re-fork; do not replace
15927
- * it with a behavioural test, which cannot fail.
15928
- *
15929
- * @example
15930
- * ```ts
15931
- * import { CorepackIntegrityHash } from "@effected/npm";
15932
- * import { Schema } from "effect";
15933
- *
15934
- * const decode = Schema.decodeUnknownExit(CorepackIntegrityHash);
15935
- *
15936
- * decode("sha512.deadbeef"); // success
15937
- * decode("sha512-3q2+7w=="); // failure — SRI form
15938
- * ```
15939
- *
15940
- * @public
15941
- */
15942
- const CorepackIntegrityHash = brandedIntegrity.pipe(Schema.check(Schema.makeFilter((value) => isCorepack(value) ? void 0 : "Expected a corepack (<algo>.<hex>) integrity hash")));
15943
-
15944
- //#endregion
15945
- //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/Dependency.js
15946
- /**
15947
- * A resolved dependency entry pairing a package name with its version
15948
- * specifier and the `kind` of map it came from (`@effected/npm`'s
15949
- * `DependencyKind`). The protocol predicates delegate to `DependencySpecifier`.
15950
- *
15951
- * @public
15952
- */
15953
- var Dependency = class extends Schema.Class("Dependency")({
15954
- /** The package name. */
15955
- name: Schema.String,
15956
- /** The raw version specifier. */
15957
- specifier: Schema.String,
15958
- /** Which dependency map this entry came from. */
15959
- kind: DependencyKind,
15960
- /** For `peer` dependencies, whether the peer is optional (from `peerDependenciesMeta`). */
15961
- isOptional: Schema.optionalKey(Schema.Boolean)
15962
- }) {
15963
- /** The classified protocol, or `None` for an empty specifier. */
15964
- get protocol() {
15965
- return this.specifier.length === 0 ? Option.none() : Option.some(DependencySpecifier.protocolOf(this.specifier));
15966
- }
15967
- /** Parse the specifier as a semver `Range`, `None` when it is not a range. */
15968
- get range() {
15969
- return DependencySpecifier.parseRange(this.specifier);
15970
- }
15971
- /** Whether the specifier points to a local path. */
15972
- get isLocal() {
15973
- return DependencySpecifier.isLocal(this.specifier);
15974
- }
15975
- /** Whether the specifier uses the `link:` protocol. */
15976
- get isLink() {
15977
- return DependencySpecifier.isLink(this.specifier);
15978
- }
15979
- /** Whether the specifier uses the `portal:` protocol. */
15980
- get isPortal() {
15981
- return DependencySpecifier.isPortal(this.specifier);
15982
- }
15983
- /** Whether the specifier uses the `catalog:` protocol. */
15984
- get isCatalog() {
15985
- return DependencySpecifier.isCatalog(this.specifier);
15986
- }
15987
- /** Whether the specifier uses the `workspace:` protocol. */
15988
- get isWorkspace() {
15989
- return DependencySpecifier.isWorkspace(this.specifier);
15990
- }
15991
- /** Whether the specifier is an unresolved `catalog:` or `workspace:` protocol. */
15992
- get isUnresolved() {
15993
- return this.isCatalog || this.isWorkspace;
15994
- }
15995
- /** Whether the specifier resolves to a git source. */
15996
- get isGit() {
15997
- return DependencySpecifier.isGit(this.specifier);
15998
- }
15999
- /** Whether the specifier is a parseable semver range. */
16000
- get isRange() {
16001
- return DependencySpecifier.isRange(this.specifier);
16002
- }
16003
- /** Whether the specifier is a dist-tag. */
16004
- get isTag() {
16005
- return DependencySpecifier.isTag(this.specifier);
16006
- }
16007
- };
16008
-
16009
- //#endregion
16010
- //#region ../../node_modules/.pnpm/@effected+package-json@0.7.3_effect@4.0.0-beta.101/node_modules/@effected/package-json/DevEngines.js
16011
- /**
16012
- * A single `devEngines` constraint with a name and optional `version` / `onFail`.
16013
- *
16014
- * @public
16015
- */
16016
- var DevEngine = class extends Schema.Class("DevEngine")({
16017
- /** The engine name (e.g. `node`, `pnpm`). */
16018
- name: Schema.String,
16019
- /** The optional version constraint. */
16020
- version: Schema.optionalKey(Schema.String),
16021
- /** The optional behavior when the constraint is unmet. */
16022
- onFail: Schema.optionalKey(Schema.Literals([
16023
- "warn",
16024
- "error",
16025
- "ignore"
16026
- ]))
16027
- }) {};
16028
- /**
16029
- * A `devEngines` constraint slot: a single {@link DevEngine} or an array of them.
16030
- *
16031
- * @public
16032
- */
16033
- const DevEngineOrArray = Schema.Union([DevEngine, Schema.Array(DevEngine)]);
16034
- /**
16035
- * The `devEngines` field schema, modeling runtime and package-manager
16036
- * constraints as optional {@link DevEngine} slots.
16037
- *
16038
- * @public
16039
- */
16040
- const DevEnginesSchema = Schema.Struct({
16041
- packageManager: Schema.optionalKey(DevEngineOrArray),
16042
- runtime: Schema.optionalKey(DevEngineOrArray),
16043
- os: Schema.optionalKey(DevEngineOrArray),
16044
- cpu: Schema.optionalKey(DevEngineOrArray),
16045
- libc: Schema.optionalKey(DevEngineOrArray)
16046
- });
15583
+ const DevEnginesSchema = Schema.Struct({
15584
+ packageManager: Schema.optionalKey(DevEngineOrArray),
15585
+ runtime: Schema.optionalKey(DevEngineOrArray),
15586
+ os: Schema.optionalKey(DevEngineOrArray),
15587
+ cpu: Schema.optionalKey(DevEngineOrArray),
15588
+ libc: Schema.optionalKey(DevEngineOrArray)
15589
+ });
16047
15590
 
16048
15591
  //#endregion
16049
15592
  //#region ../../node_modules/.pnpm/@effected+spdx@0.1.2_effect@4.0.0-beta.101/node_modules/@effected/spdx/internal/licenseIds.js
@@ -18686,7 +18229,7 @@ var Package = class Package extends Schema.Class("Package")({
18686
18229
  };
18687
18230
 
18688
18231
  //#endregion
18689
- //#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
18232
+ //#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
18690
18233
  const EMPTY$1 = Object.freeze(Object.create(null));
18691
18234
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
18692
18235
  /**
@@ -19288,7 +18831,7 @@ var Walker$1 = class {
19288
18831
  };
19289
18832
 
19290
18833
  //#endregion
19291
- //#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
18834
+ //#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
19292
18835
  /**
19293
18836
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
19294
18837
  *
@@ -19476,7 +19019,7 @@ var WorkspaceRoot = class WorkspaceRoot extends Context.Service()("@effected/wor
19476
19019
  };
19477
19020
 
19478
19021
  //#endregion
19479
- //#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
19022
+ //#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
19480
19023
  /**
19481
19024
  * Hard ceiling on directories the enumerator will visit for one pattern set.
19482
19025
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -19495,7 +19038,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
19495
19038
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
19496
19039
 
19497
19040
  //#endregion
19498
- //#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
19041
+ //#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
19499
19042
  /** Directory names never descended into. */
19500
19043
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
19501
19044
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -19586,7 +19129,7 @@ var Traversal = class {
19586
19129
  };
19587
19130
 
19588
19131
  //#endregion
19589
- //#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
19132
+ //#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
19590
19133
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
19591
19134
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
19592
19135
  /**
@@ -19657,7 +19200,7 @@ const enumerate = (root, globs, options) => Effect.gen(function* () {
19657
19200
  });
19658
19201
 
19659
19202
  //#endregion
19660
- //#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
19203
+ //#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
19661
19204
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
19662
19205
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
19663
19206
  const pnpmPatternsOf = (document) => {
@@ -19715,7 +19258,7 @@ const readPatterns = (root) => Effect.gen(function* () {
19715
19258
  });
19716
19259
 
19717
19260
  //#endregion
19718
- //#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
19261
+ //#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
19719
19262
  /**
19720
19263
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
19721
19264
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -20152,7 +19695,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends Context.Service()("@ef
20152
19695
  * // `Package.resolve` now resolves `workspace:*` for real.
20153
19696
  * ```
20154
19697
  */
20155
- static workspaceResolver = Layer.effect(WorkspaceResolver$1, Effect.gen(function* () {
19698
+ static workspaceResolver = Layer.effect(WorkspaceResolver, Effect.gen(function* () {
20156
19699
  const discovery = yield* WorkspaceDiscovery;
20157
19700
  const versionIndexes = /* @__PURE__ */ new WeakMap();
20158
19701
  const versionsByName = (all) => {
@@ -20163,7 +19706,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends Context.Service()("@ef
20163
19706
  versionIndexes.set(all, index);
20164
19707
  return index;
20165
19708
  };
20166
- return { versionOf: (packageName) => discovery.listPackages().pipe(Effect.map((all) => Option.fromUndefinedOr(versionsByName(all).get(packageName))), Effect.mapError((cause) => new DependencyResolutionError$1({
19709
+ return { versionOf: (packageName) => discovery.listPackages().pipe(Effect.map((all) => Option.fromUndefinedOr(versionsByName(all).get(packageName))), Effect.mapError((cause) => new DependencyResolutionError({
20167
19710
  specifier: `workspace:${packageName}`,
20168
19711
  cause
20169
19712
  }))) };
@@ -20172,7 +19715,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends Context.Service()("@ef
20172
19715
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
20173
19716
 
20174
19717
  //#endregion
20175
- //#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
19718
+ //#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
20176
19719
  /**
20177
19720
  * Raised when the workspace dependency graph cannot be topologically ordered
20178
19721
  * because it contains a cycle.
@@ -20406,10 +19949,32 @@ const kahn = (edges) => {
20406
19949
  };
20407
19950
 
20408
19951
  //#endregion
20409
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
19952
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
19953
+ /** The mask every whole-value sensitive positional is replaced with. */
19954
+ const REDACTED = "<redacted>";
19955
+ const secretValue = (value) => ({
19956
+ redact: "value",
19957
+ value
19958
+ });
19959
+ const secretUrl = (value) => ({
19960
+ redact: "url",
19961
+ value
19962
+ });
19963
+ /**
19964
+ * Masks the userinfo component of a URL (`scheme://user:token@host/...` →
19965
+ * `scheme://<redacted>@host/...`). A value carrying no embedded userinfo — a
19966
+ * remote name, a credential-free URL, an scp-style `host:path` — passes
19967
+ * through untouched, so the common case stays fully debuggable.
19968
+ *
19969
+ * The userinfo match is greedy (`[^/]*@` — everything through the LAST `@`
19970
+ * before the first path slash): URL authorities split at the last `@`, so a
19971
+ * password containing a literal `@` (`user:p\@ss\@host/...`) must be
19972
+ * consumed whole or its tail would survive into `redactedArgs`.
19973
+ */
19974
+ const redactUrlUserinfo = (value) => value.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/]*@/i, `$1${REDACTED}@`);
20410
19975
  /**
20411
- * Builds a `git` `ChildProcess.StandardCommand` with the argv this package
20412
- * classifies against.
19976
+ * Builds a `git` {@link GitInvocation} with the argv this package classifies
19977
+ * against.
20413
19978
  *
20414
19979
  * @remarks
20415
19980
  * `LC_ALL=C` is pinned on every invocation because git's stderr
@@ -20425,10 +19990,18 @@ const kahn = (edges) => {
20425
19990
  * the working directory per invocation via `ChildProcess.setCwd`, which
20426
19991
  * returns a new command and leaves this one unchanged.
20427
19992
  */
20428
- const git = (args) => ChildProcess.make("git", args, {
20429
- env: { LC_ALL: "C" },
20430
- extendEnv: true
20431
- });
19993
+ const git = (args, stdin) => {
19994
+ const raw = args.map((arg) => typeof arg === "string" ? arg : arg.value);
19995
+ const redactedArgs = args.map((arg) => typeof arg === "string" ? arg : arg.redact === "value" ? REDACTED : redactUrlUserinfo(arg.value));
19996
+ return {
19997
+ command: ChildProcess.make("git", raw, {
19998
+ env: { LC_ALL: "C" },
19999
+ extendEnv: true,
20000
+ ...stdin !== void 0 ? { stdin: Stream.make(new TextEncoder().encode(stdin)) } : {}
20001
+ }),
20002
+ redactedArgs
20003
+ };
20004
+ };
20432
20005
  const show = (ref, path) => git(["show", `${ref}:${path}`]);
20433
20006
  const lsTree = (ref, pathspec = []) => git([
20434
20007
  "ls-tree",
@@ -20487,7 +20060,7 @@ const checkout = (ref, detach = false) => git([
20487
20060
  const fetch$1 = (remote, ref, depth, tag = false) => git([
20488
20061
  "fetch",
20489
20062
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
20490
- remote,
20063
+ secretUrl(remote),
20491
20064
  ...tag ? ["tag"] : [],
20492
20065
  ref
20493
20066
  ]);
@@ -20503,7 +20076,7 @@ const submoduleAdd = (url, path, depth) => git([
20503
20076
  "add",
20504
20077
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
20505
20078
  "--",
20506
- url,
20079
+ secretUrl(url),
20507
20080
  path
20508
20081
  ]);
20509
20082
  const sparseCheckoutSet = (patterns, cone) => git([
@@ -20516,13 +20089,55 @@ const configSet = (key, value, file) => git([
20516
20089
  "config",
20517
20090
  ...file !== void 0 ? ["-f", file] : [],
20518
20091
  key,
20519
- value
20092
+ secretValue(value)
20520
20093
  ]);
20521
20094
  const add = (paths) => git([
20522
20095
  "add",
20523
20096
  "--",
20524
20097
  ...paths
20525
20098
  ]);
20099
+ const reset = (mode = "mixed", ref) => git([
20100
+ "reset",
20101
+ `--${mode}`,
20102
+ ...ref !== void 0 ? [ref] : []
20103
+ ]);
20104
+ const clean = (directories = false, ignored = false, paths = []) => git([
20105
+ "clean",
20106
+ "--force",
20107
+ ...directories ? ["-d"] : [],
20108
+ ...ignored ? ["-x"] : [],
20109
+ ...paths.length > 0 ? ["--", ...paths] : []
20110
+ ]);
20111
+ const restore = (paths, source, staged = false, worktree = false) => git([
20112
+ "restore",
20113
+ ...source !== void 0 ? ["--source", source] : [],
20114
+ ...staged ? ["--staged"] : [],
20115
+ ...worktree ? ["--worktree"] : [],
20116
+ "--",
20117
+ ...paths
20118
+ ]);
20119
+ const branchCreate = (name, startPoint, checkout = false, force = false) => checkout ? git([
20120
+ "checkout",
20121
+ force ? "-B" : "-b",
20122
+ name,
20123
+ ...startPoint !== void 0 ? [startPoint] : []
20124
+ ]) : git([
20125
+ "branch",
20126
+ ...force ? ["-f"] : [],
20127
+ name,
20128
+ ...startPoint !== void 0 ? [startPoint] : []
20129
+ ]);
20130
+ const branchDelete = (name, force = false) => git([
20131
+ "branch",
20132
+ force ? "-D" : "-d",
20133
+ name
20134
+ ]);
20135
+ const isShallow = () => git(["rev-parse", "--is-shallow-repository"]);
20136
+ const fetchUnshallow = (remote = "origin") => git([
20137
+ "fetch",
20138
+ "--unshallow",
20139
+ secretUrl(remote)
20140
+ ]);
20526
20141
  const nameStatus = (base, head, relative = false) => git([
20527
20142
  "diff",
20528
20143
  "--name-status",
@@ -20563,26 +20178,262 @@ const status = () => git([
20563
20178
  "--porcelain",
20564
20179
  "-z"
20565
20180
  ]);
20566
- /**
20567
- * Pure constructors for the `git` `ChildProcess.Command` values this package
20568
- * spawns.
20569
- *
20570
- * @remarks
20571
- * Every constructor returns a cwd-less, argv-only `Command` — no spawning,
20572
- * no working directory baked in. `Git` applies the working directory per
20573
- * call with `ChildProcess.setCwd` and owns the actual spawn, timeout, and
20574
- * error classification.
20575
- *
20576
- * @public
20577
- */
20578
- var GitCommand = class {
20579
- constructor() {}
20580
- /**
20581
- * `git show <ref>:<path>` the contents of `path` as it existed at `ref`,
20582
- * without checking anything out.
20583
- */
20584
- static show = show;
20585
- /**
20181
+ const submoduleStatus = (paths = [], recursive = false) => git([
20182
+ "submodule",
20183
+ "status",
20184
+ ...recursive ? ["--recursive"] : [],
20185
+ ...paths.length > 0 ? ["--", ...paths] : []
20186
+ ]);
20187
+ const submoduleInit = (paths = []) => git([
20188
+ "submodule",
20189
+ "init",
20190
+ ...paths.length > 0 ? ["--", ...paths] : []
20191
+ ]);
20192
+ const submoduleDeinit = (paths, all = false, force = false) => git([
20193
+ "submodule",
20194
+ "deinit",
20195
+ ...force ? ["--force"] : [],
20196
+ ...all ? ["--all"] : ["--", ...paths]
20197
+ ]);
20198
+ const submoduleSync = (paths = [], recursive = false) => git([
20199
+ "submodule",
20200
+ "sync",
20201
+ ...recursive ? ["--recursive"] : [],
20202
+ ...paths.length > 0 ? ["--", ...paths] : []
20203
+ ]);
20204
+ const submoduleSetUrl = (path, url) => git([
20205
+ "submodule",
20206
+ "set-url",
20207
+ "--",
20208
+ path,
20209
+ secretUrl(url)
20210
+ ]);
20211
+ const submoduleSetBranch = (path, branch) => git([
20212
+ "submodule",
20213
+ "set-branch",
20214
+ ...branch === void 0 ? ["--default"] : ["--branch", branch],
20215
+ "--",
20216
+ path
20217
+ ]);
20218
+ const submoduleAbsorbgitdirs = (paths = []) => git([
20219
+ "submodule",
20220
+ "absorbgitdirs",
20221
+ ...paths.length > 0 ? ["--", ...paths] : []
20222
+ ]);
20223
+ const submoduleForeach = (command, recursive = false) => git([
20224
+ "submodule",
20225
+ "foreach",
20226
+ ...recursive ? ["--recursive"] : [],
20227
+ command
20228
+ ]);
20229
+ const lsRemote = (remote, heads = false, tags = false, patterns = []) => git([
20230
+ "ls-remote",
20231
+ ...heads ? ["--heads"] : [],
20232
+ ...tags ? ["--tags"] : [],
20233
+ secretUrl(remote),
20234
+ ...patterns
20235
+ ]);
20236
+ const remoteAdd = (name, url) => git([
20237
+ "remote",
20238
+ "add",
20239
+ name,
20240
+ secretUrl(url)
20241
+ ]);
20242
+ const remoteRemove = (name) => git([
20243
+ "remote",
20244
+ "remove",
20245
+ name
20246
+ ]);
20247
+ const remoteSetUrl = (name, url) => git([
20248
+ "remote",
20249
+ "set-url",
20250
+ name,
20251
+ secretUrl(url)
20252
+ ]);
20253
+ const stashRef = (index) => `stash@{${index}}`;
20254
+ const stashPush = (message, includeUntracked = false, paths = []) => git([
20255
+ "stash",
20256
+ "push",
20257
+ ...includeUntracked ? ["--include-untracked"] : [],
20258
+ ...message !== void 0 ? ["-m", message] : [],
20259
+ ...paths.length > 0 ? ["--", ...paths] : []
20260
+ ]);
20261
+ const stashPop = (index) => git([
20262
+ "stash",
20263
+ "pop",
20264
+ ...index !== void 0 ? [stashRef(index)] : []
20265
+ ]);
20266
+ const stashApply = (index) => git([
20267
+ "stash",
20268
+ "apply",
20269
+ ...index !== void 0 ? [stashRef(index)] : []
20270
+ ]);
20271
+ const stashDrop = (index) => git([
20272
+ "stash",
20273
+ "drop",
20274
+ ...index !== void 0 ? [stashRef(index)] : []
20275
+ ]);
20276
+ const stashList = () => git([
20277
+ "stash",
20278
+ "list",
20279
+ "-z",
20280
+ "--format=%gd%x1f%H%x1f%gs"
20281
+ ]);
20282
+ const branchList = (remotes = false, all = false) => git([
20283
+ "branch",
20284
+ "--list",
20285
+ ...all ? ["--all"] : remotes ? ["--remotes"] : [],
20286
+ "--format=%(HEAD)%00%(refname:short)%00%(objectname)"
20287
+ ]);
20288
+ const tagCreate = (name, ref, message, force = false) => git([
20289
+ "tag",
20290
+ ...force ? ["--force"] : [],
20291
+ ...message !== void 0 ? ["-m", message] : [],
20292
+ name,
20293
+ ...ref !== void 0 ? [ref] : []
20294
+ ]);
20295
+ const tagDelete = (name) => git([
20296
+ "tag",
20297
+ "--delete",
20298
+ name
20299
+ ]);
20300
+ const tagList = (pattern) => git([
20301
+ "tag",
20302
+ "--list",
20303
+ ...pattern !== void 0 ? [pattern] : []
20304
+ ]);
20305
+ const forEachRef = (patterns = []) => git([
20306
+ "for-each-ref",
20307
+ "--format=%(refname)%00%(objectname)%00%(objecttype)",
20308
+ ...patterns
20309
+ ]);
20310
+ const revList = (ref, limit, firstParent = false) => git([
20311
+ "rev-list",
20312
+ ...limit !== void 0 ? [`--max-count=${limit}`] : [],
20313
+ ...firstParent ? ["--first-parent"] : [],
20314
+ ref
20315
+ ]);
20316
+ const commit = (message, all = false, allowEmpty = false, amend = false, author) => git([
20317
+ "commit",
20318
+ ...all ? ["--all"] : [],
20319
+ ...allowEmpty ? ["--allow-empty"] : [],
20320
+ ...amend ? ["--amend"] : [],
20321
+ ...author !== void 0 ? [`--author=${author}`] : [],
20322
+ "-m",
20323
+ message
20324
+ ]);
20325
+ const push$1 = (remote, refspec, force = false, forceWithLease = false, tags = false, setUpstream = false) => git([
20326
+ "push",
20327
+ ...force ? ["--force"] : [],
20328
+ ...forceWithLease ? ["--force-with-lease"] : [],
20329
+ ...tags ? ["--tags"] : [],
20330
+ ...setUpstream ? ["--set-upstream"] : [],
20331
+ secretUrl(remote),
20332
+ ...refspec !== void 0 ? [refspec] : []
20333
+ ]);
20334
+ const pull = (remote, ref, rebase = false, ffOnly = false) => git([
20335
+ "pull",
20336
+ ...rebase ? ["--rebase"] : [],
20337
+ ...ffOnly ? ["--ff-only"] : [],
20338
+ secretUrl(remote),
20339
+ ...ref !== void 0 ? [ref] : []
20340
+ ]);
20341
+ const configList = (file) => git([
20342
+ "config",
20343
+ ...file !== void 0 ? ["-f", file] : [],
20344
+ "--list",
20345
+ "-z"
20346
+ ]);
20347
+ const configGetAll = (key, file) => git([
20348
+ "config",
20349
+ ...file !== void 0 ? ["-f", file] : [],
20350
+ "--get-all",
20351
+ "-z",
20352
+ key
20353
+ ]);
20354
+ const configUnset = (key, file, all = false) => git([
20355
+ "config",
20356
+ ...file !== void 0 ? ["-f", file] : [],
20357
+ all ? "--unset-all" : "--unset",
20358
+ key
20359
+ ]);
20360
+ const rm = (paths, cached = false, recursive = false, force = false) => git([
20361
+ "rm",
20362
+ ...cached ? ["--cached"] : [],
20363
+ ...recursive ? ["-r"] : [],
20364
+ ...force ? ["--force"] : [],
20365
+ "--",
20366
+ ...paths
20367
+ ]);
20368
+ const mv = (source, destination, force = false) => git([
20369
+ "mv",
20370
+ ...force ? ["--force"] : [],
20371
+ "--",
20372
+ source,
20373
+ destination
20374
+ ]);
20375
+ const checkIgnore = (paths) => git([
20376
+ "check-ignore",
20377
+ "-z",
20378
+ "--stdin"
20379
+ ], paths.map((path) => `${path}\0`).join(""));
20380
+ const worktreeAdd = (path, ref, detach = false, force = false) => git([
20381
+ "worktree",
20382
+ "add",
20383
+ ...force ? ["--force"] : [],
20384
+ ...detach ? ["--detach"] : [],
20385
+ path,
20386
+ ...ref !== void 0 ? [ref] : []
20387
+ ]);
20388
+ const worktreeList = () => git([
20389
+ "worktree",
20390
+ "list",
20391
+ "--porcelain",
20392
+ "-z"
20393
+ ]);
20394
+ const worktreeRemove = (path, force = false) => git([
20395
+ "worktree",
20396
+ "remove",
20397
+ ...force ? ["--force"] : [],
20398
+ path
20399
+ ]);
20400
+ const lsFiles = (pathspec = []) => git([
20401
+ "ls-files",
20402
+ "--stage",
20403
+ "-z",
20404
+ ...pathspec.length > 0 ? ["--", ...pathspec] : []
20405
+ ]);
20406
+ /**
20407
+ * Pure constructors for the `git` {@link GitInvocation} values this package
20408
+ * spawns.
20409
+ *
20410
+ * @remarks
20411
+ * Every constructor returns a cwd-less, argv-only {@link GitInvocation} — no
20412
+ * spawning, no working directory baked in. `Git` applies the working
20413
+ * directory per call with `ChildProcess.setCwd` on `invocation.command` and
20414
+ * owns the actual spawn, timeout, and error classification.
20415
+ *
20416
+ * **Redaction policy.** A constructor whose argv carries a sensitive
20417
+ * positional — a config value (`configSet`), or a URL that may embed
20418
+ * userinfo (the remote of `fetch`, `fetchUnshallow`, `lsRemote`, `push` and
20419
+ * `pull`, and the url of `submoduleAdd`, `submoduleSetUrl`, `remoteAdd` and
20420
+ * `remoteSetUrl`) —
20421
+ * masks it in {@link GitInvocation.redactedArgs}: a config value becomes
20422
+ * `<redacted>` wholesale, a URL keeps everything but its `userinfo@`
20423
+ * component. The `Git` service persists only the redacted argv in error
20424
+ * values, and its span annotations carry stable identifiers only (`cwd`,
20425
+ * keys, paths, remote/ref names) — never config values, never URLs.
20426
+ *
20427
+ * @public
20428
+ */
20429
+ var GitCommand = class {
20430
+ constructor() {}
20431
+ /**
20432
+ * `git show <ref>:<path>` — the contents of `path` as it existed at `ref`,
20433
+ * without checking anything out.
20434
+ */
20435
+ static show = show;
20436
+ /**
20586
20437
  * `git ls-tree -r -z <ref> [-- <pathspec>...]` — every path in the tree at
20587
20438
  * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
20588
20439
  *
@@ -20669,9 +20520,106 @@ var GitCommand = class {
20669
20520
  /**
20670
20521
  * Mutating: `git fetch [--depth <n>] <remote> [tag] <ref>` — fetches the given
20671
20522
  * ref from a remote, optionally with a depth limit and the `tag` keyword.
20523
+ *
20524
+ * @remarks
20525
+ * `remote` may be a URL as well as a remote name; an embedded
20526
+ * `userinfo@` credential is masked in {@link GitInvocation.redactedArgs}.
20672
20527
  */
20673
20528
  static fetch = fetch$1;
20674
20529
  /**
20530
+ * Mutating: `git fetch --unshallow <remote>` — converts a shallow clone
20531
+ * into a complete one by fetching the missing history.
20532
+ *
20533
+ * @remarks
20534
+ * `--unshallow` is a distinct MODE, not a depth value: git rejects it
20535
+ * outright in a repository that is not shallow, with
20536
+ * `--unshallow on a complete repository does not make sense`, so it
20537
+ * cannot be expressed as `fetch`'s `depth` option. The caller decides
20538
+ * whether to run it — probe with `Git.isShallow` first.
20539
+ *
20540
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20541
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20542
+ */
20543
+ static fetchUnshallow = fetchUnshallow;
20544
+ /**
20545
+ * `git rev-parse --is-shallow-repository` — prints `true` when the
20546
+ * repository is a shallow clone, `false` otherwise.
20547
+ *
20548
+ * @remarks
20549
+ * A dedicated probe constructor, deliberately separate from
20550
+ * {@link GitCommand.revParse}: `revParse` takes a REF and resolves it,
20551
+ * while this takes nothing and answers a repository-shape question.
20552
+ * Folding the flag into `revParse` would make that constructor
20553
+ * sometimes-takes-a-ref, sometimes-takes-a-flag.
20554
+ */
20555
+ static isShallow = isShallow;
20556
+ /**
20557
+ * Mutating: `git reset --soft|--mixed|--hard [<ref>]` — moves `HEAD` (and,
20558
+ * per mode, the index and working tree) to `ref`.
20559
+ *
20560
+ * @remarks
20561
+ * The mode flag is always explicit — `--mixed` is emitted for the default
20562
+ * rather than omitted — so the argv states what runs. `ref` may be any
20563
+ * commit-ish, including a gitlink sha.
20564
+ */
20565
+ static reset = reset;
20566
+ /**
20567
+ * Mutating: `git clean --force [-d] [-x] [-- <paths>...]` — deletes
20568
+ * untracked files from the working tree.
20569
+ *
20570
+ * @remarks
20571
+ * `--force` is unconditional: this constructor exists so a consumer can
20572
+ * restore a tree to a known state (e.g. before retrying a non-idempotent
20573
+ * operation), and without `--force` git refuses to clean at all under the
20574
+ * default `clean.requireForce` config — a clean that silently did nothing
20575
+ * would hand the retry the same dirty tree. `-d` removes untracked
20576
+ * directories too; `-x` removes ignored files as well. The literal `--`
20577
+ * separator makes the optional pathspec injection-safe by construction.
20578
+ */
20579
+ static clean = clean;
20580
+ /**
20581
+ * Mutating: `git restore [--source <ref>] [--staged] [--worktree] -- <paths...>`
20582
+ * — restores the given paths from the index (or from `source`), the
20583
+ * `checkout -- <paths>`-shaped operation.
20584
+ *
20585
+ * @remarks
20586
+ * This is a separate constructor precisely because {@link GitCommand.checkout}'s
20587
+ * service guard refuses `--` and option-like refs by design — `restore` is
20588
+ * git's own verb for pathspec restoration, and its paths always sit behind
20589
+ * a literal `--`, so they are injection-safe by construction. With neither
20590
+ * `staged` nor `worktree` set, git defaults to restoring the working tree.
20591
+ */
20592
+ static restore = restore;
20593
+ /**
20594
+ * Mutating: `git branch [-f] <name> [<start-point>]`, or
20595
+ * `git checkout (-b | -B) <name> [<start-point>]` when `checkout` is true —
20596
+ * creates a branch, optionally from an explicit start point, optionally
20597
+ * switching to it, optionally force-resetting an existing branch.
20598
+ *
20599
+ * @remarks
20600
+ * Branch creation is a branch-member concern, NOT a widening of
20601
+ * {@link GitCommand.checkout}: `checkout`'s contract stays "move to an
20602
+ * existing ref" and its option-like-ref refusal stays intact. The `-b` /
20603
+ * `-B` here is this constructor's own literal, never caller data.
20604
+ *
20605
+ * `force` with `checkout` exists because the delete-then-create longhand
20606
+ * (`branch -D` swallowed, then `checkout -b`) papers over a real edge:
20607
+ * `git branch -D` refuses to delete the currently checked-out branch,
20608
+ * while `checkout -B` resets it fine — one invocation handles both
20609
+ * states.
20610
+ */
20611
+ static branchCreate = branchCreate;
20612
+ /**
20613
+ * Mutating: `git branch -d <name>` (or `-D` when `force` is true) —
20614
+ * deletes a local branch.
20615
+ *
20616
+ * @remarks
20617
+ * The default `-d` refuses to delete a branch not fully merged — a typed
20618
+ * failure, which is usually the honest answer. `force: true` emits `-D`
20619
+ * and deletes regardless.
20620
+ */
20621
+ static branchDelete = branchDelete;
20622
+ /**
20675
20623
  * Mutating: `git submodule update [--init] [--depth <n>] [-- <paths>...]` — updates
20676
20624
  * registered submodules, optionally initializing them, with an optional depth limit,
20677
20625
  * and scoped to specific paths. The literal `--` separator makes the pathspec
@@ -20682,6 +20630,10 @@ var GitCommand = class {
20682
20630
  * Mutating: `git submodule add [--depth <n>] -- <url> <path>` — registers and
20683
20631
  * initializes a new submodule. The literal `--` separator makes the url and path
20684
20632
  * injection-safe by construction.
20633
+ *
20634
+ * @remarks
20635
+ * An embedded `userinfo@` credential in `url` is masked in
20636
+ * {@link GitInvocation.redactedArgs}.
20685
20637
  */
20686
20638
  static submoduleAdd = submoduleAdd;
20687
20639
  /**
@@ -20694,6 +20646,13 @@ var GitCommand = class {
20694
20646
  /**
20695
20647
  * Mutating: `git config [-f <file>] <key> <value>` — writes a configuration value,
20696
20648
  * optionally into an explicit configuration file (e.g., `.gitmodules`).
20649
+ *
20650
+ * @remarks
20651
+ * `value` may be a secret (a token, a credential-bearing URL), so it is
20652
+ * masked wholesale — as `<redacted>` — in
20653
+ * {@link GitInvocation.redactedArgs}. The key and file stay visible: they
20654
+ * are stable identifiers, and they are what a caller debugging a failed
20655
+ * write actually needs.
20697
20656
  */
20698
20657
  static configSet = configSet;
20699
20658
  /**
@@ -20776,10 +20735,305 @@ var GitCommand = class {
20776
20735
  * Each entry is a pair of status codes followed by a space and the path.
20777
20736
  */
20778
20737
  static status = status;
20738
+ /**
20739
+ * `git submodule status [--recursive] [-- <paths>...]` — one line per
20740
+ * registered submodule: a state prefix, the checked-out (or gitlink) sha,
20741
+ * the path, and — when the submodule is initialized — a `git describe`
20742
+ * suffix in parentheses.
20743
+ *
20744
+ * @remarks
20745
+ * `git submodule status` has no `-z` mode, so its output is line-based —
20746
+ * the one path-emitting constructor in this package that cannot follow
20747
+ * the `-z` rule. A submodule path containing a newline would corrupt the
20748
+ * parse; accepted as a git-imposed limitation.
20749
+ */
20750
+ static submoduleStatus = submoduleStatus;
20751
+ /**
20752
+ * Mutating: `git submodule init [-- <paths>...]` — registers the
20753
+ * submodules from `.gitmodules` into `.git/config` (all of them, or only
20754
+ * `paths`), without cloning or checking anything out.
20755
+ */
20756
+ static submoduleInit = submoduleInit;
20757
+ /**
20758
+ * Mutating: `git submodule deinit [--force] (--all | -- <paths>...)` —
20759
+ * unregisters submodules: clears their working trees and removes their
20760
+ * `.git/config` registration. The literal `--` separator makes the
20761
+ * pathspec injection-safe by construction.
20762
+ */
20763
+ static submoduleDeinit = submoduleDeinit;
20764
+ /**
20765
+ * Mutating: `git submodule sync [--recursive] [-- <paths>...]` —
20766
+ * re-copies each submodule's URL from `.gitmodules` into `.git/config`
20767
+ * (and into the submodule's own `remote.origin.url`), so a `.gitmodules`
20768
+ * URL change actually reaches git's live configuration.
20769
+ */
20770
+ static submoduleSync = submoduleSync;
20771
+ /**
20772
+ * Mutating: `git submodule set-url -- <path> <url>` — rewrites the
20773
+ * submodule's URL in `.gitmodules` and synchronizes it into
20774
+ * `.git/config`. The literal `--` separator makes the path and url
20775
+ * injection-safe by construction.
20776
+ *
20777
+ * @remarks
20778
+ * An embedded `userinfo@` credential in `url` is masked in
20779
+ * {@link GitInvocation.redactedArgs}.
20780
+ */
20781
+ static submoduleSetUrl = submoduleSetUrl;
20782
+ /**
20783
+ * Mutating: `git submodule set-branch (--branch <branch> | --default) -- <path>`
20784
+ * — records (or clears, when `branch` is omitted) the branch a submodule
20785
+ * tracks in `.gitmodules`. The literal `--` separator makes the path
20786
+ * injection-safe by construction.
20787
+ */
20788
+ static submoduleSetBranch = submoduleSetBranch;
20789
+ /**
20790
+ * Mutating: `git submodule absorbgitdirs [-- <paths>...]` — moves each
20791
+ * submodule's embedded `.git` directory into the superproject's
20792
+ * `.git/modules/` and leaves a gitfile pointer behind.
20793
+ */
20794
+ static submoduleAbsorbgitdirs = submoduleAbsorbgitdirs;
20795
+ /**
20796
+ * Mutating: `git submodule foreach [--recursive] <command>` — runs a shell
20797
+ * command in every checked-out submodule. `command` is a single shell
20798
+ * string, evaluated by git in each submodule's directory; it can mutate
20799
+ * anything, which is why the constructor is marked mutating regardless of
20800
+ * what the command does.
20801
+ *
20802
+ * @remarks
20803
+ * This is the ONE constructor whose argument cannot be made injection-safe
20804
+ * by construction: git evaluates `command` with `sh -c`, so every character
20805
+ * of it is shell code — a `--` separator or quoting cannot help. Callers
20806
+ * must treat `command` as a trusted literal and never interpolate untrusted
20807
+ * data into it.
20808
+ */
20809
+ static submoduleForeach = submoduleForeach;
20810
+ /**
20811
+ * `git ls-remote [--heads] [--tags] <remote> [<patterns>...]` — the refs a
20812
+ * remote advertises (sha + refname), optionally filtered to branch heads,
20813
+ * tags, and/or shell-glob patterns.
20814
+ *
20815
+ * @remarks
20816
+ * A read that talks to the NETWORK, not to the local repository — the one
20817
+ * non-mutating constructor in this package that does. An embedded
20818
+ * `userinfo@` credential in `remote` is masked in
20819
+ * {@link GitInvocation.redactedArgs}. An annotated tag advertises two
20820
+ * entries: `refs/tags/<name>` (the tag object) and `refs/tags/<name>^{}`
20821
+ * (the peeled commit).
20822
+ */
20823
+ static lsRemote = lsRemote;
20824
+ /**
20825
+ * Mutating: `git remote add <name> <url>` — registers a new remote.
20826
+ *
20827
+ * @remarks
20828
+ * An embedded `userinfo@` credential in `url` is masked in
20829
+ * {@link GitInvocation.redactedArgs}.
20830
+ */
20831
+ static remoteAdd = remoteAdd;
20832
+ /**
20833
+ * Mutating: `git remote remove <name>` — deletes a remote and its
20834
+ * remote-tracking refs and configuration.
20835
+ */
20836
+ static remoteRemove = remoteRemove;
20837
+ /**
20838
+ * Mutating: `git remote set-url <name> <url>` — rewrites a remote's fetch
20839
+ * URL.
20840
+ *
20841
+ * @remarks
20842
+ * An embedded `userinfo@` credential in `url` is masked in
20843
+ * {@link GitInvocation.redactedArgs}.
20844
+ */
20845
+ static remoteSetUrl = remoteSetUrl;
20846
+ /**
20847
+ * Mutating: `git stash push [--include-untracked] [-m <message>] [-- <paths>...]`
20848
+ * — saves the working tree (and index) state onto the stash stack. The
20849
+ * literal `--` separator makes the optional pathspec injection-safe by
20850
+ * construction; the message rides behind `-m`, which git consumes as a
20851
+ * value even when it begins with `-`.
20852
+ */
20853
+ static stashPush = stashPush;
20854
+ /**
20855
+ * Mutating: `git stash pop [stash@{n}]` — applies a stash entry and drops
20856
+ * it on success. The stash ref is rendered from an INTEGER index by this
20857
+ * package, never caller text.
20858
+ */
20859
+ static stashPop = stashPop;
20860
+ /**
20861
+ * Mutating: `git stash apply [stash@{n}]` — applies a stash entry and
20862
+ * keeps it on the stack. The stash ref is rendered from an INTEGER index
20863
+ * by this package, never caller text.
20864
+ */
20865
+ static stashApply = stashApply;
20866
+ /**
20867
+ * Mutating: `git stash drop [stash@{n}]` — deletes a stash entry without
20868
+ * applying it. The stash ref is rendered from an INTEGER index by this
20869
+ * package, never caller text.
20870
+ */
20871
+ static stashDrop = stashDrop;
20872
+ /**
20873
+ * `git stash list -z --format=%gd%x1f%H%x1f%gs` — every stash entry as a
20874
+ * NUL-terminated record of unit-separated fields: the reflog selector
20875
+ * (`stash@{0}`), the stash commit sha, and the reflog subject.
20876
+ *
20877
+ * @remarks
20878
+ * The `%x1f` (ASCII unit separator) field separator plus `-z` record
20879
+ * terminator keeps the parse split-safe: a stash message cannot contain
20880
+ * either byte (reflog subjects are single-line).
20881
+ */
20882
+ static stashList = stashList;
20883
+ /**
20884
+ * `git branch --list [--remotes | --all] --format=%(HEAD)%00%(refname:short)%00%(objectname)`
20885
+ * — every branch as a NUL-separated triple: the current-branch marker, the
20886
+ * short name, and the tip sha.
20887
+ *
20888
+ * @remarks
20889
+ * Records are newline-separated, which is split-safe here: git refnames
20890
+ * cannot contain a newline (or a space), so the only NUL bytes are the
20891
+ * format's own field separators. `all` wins over `remotes` when both are
20892
+ * set.
20893
+ */
20894
+ static branchList = branchList;
20895
+ /**
20896
+ * Mutating: `git tag [--force] [-m <message>] <name> [<ref>]` — creates a
20897
+ * lightweight tag, or an annotated one when `message` is given (`-m`
20898
+ * implies `-a`).
20899
+ */
20900
+ static tagCreate = tagCreate;
20901
+ /** Mutating: `git tag --delete <name>` — deletes a local tag. */
20902
+ static tagDelete = tagDelete;
20903
+ /**
20904
+ * `git tag --list [<pattern>]` — tag names, optionally filtered by a
20905
+ * shell-glob pattern, one per line (refnames cannot contain newlines).
20906
+ */
20907
+ static tagList = tagList;
20908
+ /**
20909
+ * `git for-each-ref --format=%(refname)%00%(objectname)%00%(objecttype) [<patterns>...]`
20910
+ * — every matching ref as a NUL-separated triple: full refname, sha, and
20911
+ * object type.
20912
+ *
20913
+ * @remarks
20914
+ * The format is this package's own fixed triple — the parse contract and
20915
+ * the argv are decided together, so the format string is a constructor
20916
+ * literal, never caller data. An annotated tag's `objecttype` is `tag`
20917
+ * (the tag object), not `commit`.
20918
+ */
20919
+ static forEachRef = forEachRef;
20920
+ /**
20921
+ * `git rev-list [--max-count=<n>] [--first-parent] <ref-or-range>` — commit
20922
+ * shas reachable from the ref (or range, e.g. `main..feat`), newest first.
20923
+ */
20924
+ static revList = revList;
20925
+ /**
20926
+ * Mutating: `git commit [--all] [--allow-empty] [--amend] [--author=<author>] -m <message>`
20927
+ * — records a commit. The message always rides argv behind `-m` (git
20928
+ * consumes it as a value even when it begins with `-`); committer identity
20929
+ * comes from the caller's environment — this constructor sets no
20930
+ * `GIT_AUTHOR_*`/`GIT_COMMITTER_*` variables, and the optional `author`
20931
+ * override is the fused `--author=` form.
20932
+ */
20933
+ static commit = commit;
20934
+ /**
20935
+ * Mutating: `git push [--force | --force-with-lease] [--tags] [--set-upstream] <remote> [<refspec>]`
20936
+ * — updates remote refs.
20937
+ *
20938
+ * @remarks
20939
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20940
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20941
+ */
20942
+ static push = push$1;
20943
+ /**
20944
+ * Mutating: `git pull [--rebase] [--ff-only] <remote> [<ref>]` — fetches
20945
+ * and integrates.
20946
+ *
20947
+ * @remarks
20948
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20949
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20950
+ */
20951
+ static pull = pull;
20952
+ /**
20953
+ * `git config [-f <file>] --list -z` — every configuration entry in scope
20954
+ * (or in the given file only), NUL-terminated, the key separated from the
20955
+ * value by a newline within each record.
20956
+ *
20957
+ * @remarks
20958
+ * `-z` is load-bearing: a config VALUE may contain newlines; only the NUL
20959
+ * record terminator plus first-newline field split parses it losslessly.
20960
+ * A valueless key (git's boolean-true shorthand) emits no newline at all.
20961
+ */
20962
+ static configList = configList;
20963
+ /**
20964
+ * `git config [-f <file>] --get-all -z <key>` — every value of a
20965
+ * (possibly multi-valued) key, NUL-terminated. An unset key exits 1 with
20966
+ * silent stderr.
20967
+ */
20968
+ static configGetAll = configGetAll;
20969
+ /**
20970
+ * Mutating: `git config [-f <file>] (--unset | --unset-all) <key>` —
20971
+ * removes a key (or, with `all`, every value of a multi-valued key).
20972
+ *
20973
+ * @remarks
20974
+ * git exits 5, silently, when the key was not set — a loud failure by
20975
+ * this package's classification, deliberately: an unset that silently did
20976
+ * nothing is indistinguishable from one that worked.
20977
+ */
20978
+ static configUnset = configUnset;
20979
+ /**
20980
+ * Mutating: `git rm [--cached] [-r] [--force] -- <paths...>` — removes
20981
+ * paths from the index (and, without `cached`, the working tree). The
20982
+ * literal `--` separator makes the pathspec injection-safe by
20983
+ * construction.
20984
+ */
20985
+ static rm = rm;
20986
+ /**
20987
+ * Mutating: `git mv [--force] -- <source> <destination>` — moves or
20988
+ * renames a tracked path. The literal `--` separator makes both positionals
20989
+ * injection-safe by construction.
20990
+ */
20991
+ static mv = mv;
20992
+ /**
20993
+ * `git check-ignore -z --stdin` — which of the given paths git would
20994
+ * ignore, paths fed NUL-separated via stdin and answers returned
20995
+ * NUL-separated.
20996
+ *
20997
+ * @remarks
20998
+ * The `--stdin -z` form is the only fully robust one: `-z` without
20999
+ * `--stdin` is rejected by git outright, and the non-`-z` output C-quotes
21000
+ * special-character paths. Feeding paths via stdin also makes them
21001
+ * injection-safe by construction — nothing caller-controlled enters the
21002
+ * argv. When NO path is ignored, git exits 1 with silent stderr.
21003
+ */
21004
+ static checkIgnore = checkIgnore;
21005
+ /**
21006
+ * Mutating: `git worktree add [--force] [--detach] <path> [<ref>]` —
21007
+ * creates a linked working tree at `path`, checked out at `ref` (or the
21008
+ * branch named after `path`'s basename).
21009
+ */
21010
+ static worktreeAdd = worktreeAdd;
21011
+ /**
21012
+ * `git worktree list --porcelain -z` — every working tree as a block of
21013
+ * NUL-terminated attributes (`worktree <path>`, `HEAD <sha>`,
21014
+ * `branch <ref>` / `detached`, `bare`, `locked [<reason>]`,
21015
+ * `prunable [<reason>]`), blocks separated by an empty attribute.
21016
+ */
21017
+ static worktreeList = worktreeList;
21018
+ /** Mutating: `git worktree remove [--force] <path>` — removes a linked working tree. */
21019
+ static worktreeRemove = worktreeRemove;
21020
+ /**
21021
+ * `git ls-files --stage -z [-- <pathspec>...]` — every INDEX entry (mode,
21022
+ * oid, stage number, path), NUL-terminated, optionally scoped to
21023
+ * `pathspec`.
21024
+ *
21025
+ * @remarks
21026
+ * The index-side sibling of {@link GitCommand.lsTree}: `lsTree` reads a
21027
+ * COMMITTED tree at a ref, while this reads the staging area — the only
21028
+ * place a staged-but-uncommitted gitlink (`160000 <oid> 0 <path>`) is
21029
+ * visible. `-z` is load-bearing twice over: paths may contain newlines,
21030
+ * and the non-`-z` output C-quotes special-character paths.
21031
+ */
21032
+ static lsFiles = lsFiles;
20779
21033
  };
20780
21034
 
20781
21035
  //#endregion
20782
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
21036
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
20783
21037
  /**
20784
21038
  * Spawns `command` and collects its stdout, stderr, and exit code as a single
20785
21039
  * triple.
@@ -20807,7 +21061,7 @@ const runCollected = (command) => Effect.scoped(Effect.gen(function* () {
20807
21061
  }));
20808
21062
 
20809
21063
  //#endregion
20810
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
21064
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
20811
21065
  /** git's own ceiling: a run that has not answered in 30s is not going to. */
20812
21066
  const GIT_TIMEOUT = Duration.seconds(30);
20813
21067
  /**
@@ -20835,7 +21089,16 @@ var GitCommandError = class extends Schema.TaggedErrorClass()("GitCommandError",
20835
21089
  * logic routes on this instead of matching `detail` prose.
20836
21090
  */
20837
21091
  kind: Schema.Literals(["refused", "failed"]),
20838
- /** The argument vector, without the leading `git`. */
21092
+ /**
21093
+ * The REDACTED argument vector, without the leading `git`.
21094
+ *
21095
+ * Sensitive positionals — config values, a URL's embedded userinfo — are
21096
+ * already masked by the constructor's redaction mask before this error is
21097
+ * constructed (`configSet`'s value reads `<redacted>`; a
21098
+ * `https://user:token@host/...` remote keeps everything but its
21099
+ * `userinfo@`). The raw argv is never persisted in an error value, and
21100
+ * `message` renders this redacted vector.
21101
+ */
20839
21102
  args: Schema.Array(Schema.String),
20840
21103
  /** The working directory the command ran in. */
20841
21104
  cwd: Schema.String,
@@ -20881,20 +21144,85 @@ var UnknownRefError = class extends Schema.TaggedErrorClass()("UnknownRefError",
20881
21144
  }
20882
21145
  };
20883
21146
  /**
20884
- * One entry of a `git ls-tree` listing.
21147
+ * A `git push` was rejected because the remote ref has moved: the classic
21148
+ * non-fast-forward rejection (`fetch first` / `non-fast-forward`), or a
21149
+ * `--force-with-lease` lease failure (`stale info`).
21150
+ *
21151
+ * @remarks
21152
+ * The typed signal a fetch-then-retry (or rebase-then-retry) fallback
21153
+ * branches on — every other push failure stays a {@link GitCommandError}.
21154
+ * Only `Git.push` can fail with this error.
20885
21155
  *
20886
21156
  * @public
20887
21157
  */
20888
- var LsTreeEntry = class extends Schema.Class("LsTreeEntry")({
20889
- /** The entry's file mode, e.g. `100644`. */
20890
- mode: Schema.String,
20891
- /** The kind of object the entry points at. */
20892
- type: Schema.Literals([
20893
- "blob",
20894
- "tree",
20895
- "commit"
20896
- ]),
20897
- /** The object id the entry points at. */
21158
+ var NonFastForwardError = class extends Schema.TaggedErrorClass()("NonFastForwardError", {
21159
+ /** The working directory the push ran in. */
21160
+ cwd: Schema.String,
21161
+ /** The refspec that was rejected, when the caller passed one. */
21162
+ refspec: Schema.optionalKey(Schema.String)
21163
+ }) {
21164
+ /** Renders the rejected push into a one-line message. */
21165
+ get message() {
21166
+ 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}`;
21167
+ }
21168
+ };
21169
+ /**
21170
+ * A merge-shaped operation (`pull`, `stash pop`, `stash apply`) stopped with
21171
+ * conflict markers in the working tree.
21172
+ *
21173
+ * @remarks
21174
+ * The typed signal a resolve-or-abort recovery branches on. The conflicted
21175
+ * state is REAL: git has already written conflict markers, and (for `pull`)
21176
+ * `MERGE_HEAD` is set — the caller owns resolving or aborting. Detection
21177
+ * matches git's conflict report, which lands on STDOUT for a merge and on
21178
+ * stderr for a rebase-mode pull; both streams are inspected.
21179
+ *
21180
+ * @public
21181
+ */
21182
+ var MergeConflictError = class extends Schema.TaggedErrorClass()("MergeConflictError", {
21183
+ /** The working directory the merge ran in. */
21184
+ cwd: Schema.String }) {
21185
+ /** Renders the conflicted merge into a one-line message. */
21186
+ get message() {
21187
+ return `merge conflict in ${this.cwd}: fix conflicts (or abort) before continuing`;
21188
+ }
21189
+ };
21190
+ /**
21191
+ * A merge-shaped operation refused to start because local modifications would
21192
+ * be overwritten — git's refusal reads
21193
+ * `Your local changes ... would be overwritten by merge`.
21194
+ *
21195
+ * @remarks
21196
+ * The typed "commit or stash first" signal. Unlike {@link MergeConflictError}
21197
+ * the working tree is UNTOUCHED — git aborted before changing anything.
21198
+ * Only the merge-shaped methods (`pull`, `stashPop`, `stashApply`) can fail
21199
+ * with this error.
21200
+ *
21201
+ * @public
21202
+ */
21203
+ var DirtyWorktreeError = class extends Schema.TaggedErrorClass()("DirtyWorktreeError", {
21204
+ /** The working directory whose local changes blocked the operation. */
21205
+ cwd: Schema.String }) {
21206
+ /** Renders the blocked operation into a one-line message. */
21207
+ get message() {
21208
+ return `local changes would be overwritten in ${this.cwd}: commit or stash them first`;
21209
+ }
21210
+ };
21211
+ /**
21212
+ * One entry of a `git ls-tree` listing.
21213
+ *
21214
+ * @public
21215
+ */
21216
+ var LsTreeEntry = class extends Schema.Class("LsTreeEntry")({
21217
+ /** The entry's file mode, e.g. `100644`. */
21218
+ mode: Schema.String,
21219
+ /** The kind of object the entry points at. */
21220
+ type: Schema.Literals([
21221
+ "blob",
21222
+ "tree",
21223
+ "commit"
21224
+ ]),
21225
+ /** The object id the entry points at. */
20898
21226
  oid: Schema.String,
20899
21227
  /** The entry's path, relative to the tree root. May contain spaces or newlines. */
20900
21228
  path: Schema.String
@@ -20941,11 +21269,26 @@ const UNKNOWN_REF_PATTERNS = [
20941
21269
  "couldn't find remote ref"
20942
21270
  ];
20943
21271
  const ABSENT_AT_REF_PATTERNS = ["does not exist in", "exists on disk, but not in"];
21272
+ const PUSH_REJECTED_PATTERNS = [
21273
+ "non-fast-forward",
21274
+ "fetch first",
21275
+ "stale info"
21276
+ ];
21277
+ const MERGE_CONFLICT_PATTERNS = [
21278
+ "CONFLICT (",
21279
+ "Automatic merge failed",
21280
+ "could not apply"
21281
+ ];
21282
+ const DIRTY_WORKTREE_PATTERN = "would be overwritten by";
20944
21283
  const matchesAny = (stderr, patterns) => patterns.some((pattern) => stderr.includes(pattern));
20945
21284
  /**
20946
21285
  * Classifies one completed run (or spawn-level `PlatformError`) against
20947
21286
  * git's stderr taxonomy. Written once — every `Git` method funnels through
20948
21287
  * this before deciding its own return value.
21288
+ *
21289
+ * `args` is the invocation's REDACTED argv: it is the only argv this
21290
+ * function may persist into a `GitCommandError`, per the #86 redaction
21291
+ * policy.
20949
21292
  */
20950
21293
  const classify = (cwd, args, outcome, kind) => {
20951
21294
  if (outcome instanceof PlatformError.PlatformError) {
@@ -20968,6 +21311,11 @@ const classify = (cwd, args, outcome, kind) => {
20968
21311
  };
20969
21312
  if (stderr.includes(NOT_A_REPOSITORY)) return { _tag: "notARepository" };
20970
21313
  if (matchesAny(stderr, UNKNOWN_REF_PATTERNS)) return { _tag: "unknownRef" };
21314
+ if (kind === "push" && stderr.includes("[rejected]") && matchesAny(stderr, PUSH_REJECTED_PATTERNS)) return { _tag: "nonFastForward" };
21315
+ if (kind === "merge") {
21316
+ if (stderr.includes(DIRTY_WORKTREE_PATTERN)) return { _tag: "dirtyWorktree" };
21317
+ if (matchesAny(stdout, MERGE_CONFLICT_PATTERNS) || matchesAny(stderr, MERGE_CONFLICT_PATTERNS)) return { _tag: "mergeConflict" };
21318
+ }
20971
21319
  if (kind === "quiet" && exitCode === 1 && stderr === "") return { _tag: "absent" };
20972
21320
  if (kind === "noSuchRemote" && stderr.includes("No such remote")) return { _tag: "absent" };
20973
21321
  if (kind === "show" && matchesAny(stderr, ABSENT_AT_REF_PATTERNS)) return { _tag: "absent" };
@@ -20984,13 +21332,19 @@ const classify = (cwd, args, outcome, kind) => {
20984
21332
  };
20985
21333
  };
20986
21334
  /**
20987
- * Runs `command`, classifies the outcome, and never fails: a spawn-level
20988
- * `PlatformError` and a per-run timeout are both absorbed into the
20989
- * `"failure"` classification rather than escaping the effect's error
20990
- * channel.
21335
+ * Runs an invocation's command in `cwd`, classifies the outcome, and never
21336
+ * fails: a spawn-level `PlatformError` and a per-run timeout are both
21337
+ * absorbed into the `"failure"` classification rather than escaping the
21338
+ * effect's error channel.
21339
+ *
21340
+ * The argv handed to `classify` — and therefore persisted into any
21341
+ * `GitCommandError` — is the invocation's REDACTED argv, never the raw one:
21342
+ * the redaction mask the pure constructor carries is applied here, at the
21343
+ * single classification choke point (the #86 redaction policy).
20991
21344
  */
20992
- const runClassified = (command, cwd, kind) => {
20993
- const args = ChildProcess.isStandardCommand(command) ? command.args : [];
21345
+ const runClassified = (invocation, cwd, kind) => {
21346
+ const args = invocation.redactedArgs;
21347
+ const command = ChildProcess.setCwd(invocation.command, cwd);
20994
21348
  return runCollected(command).pipe(Effect.map((collected) => classify(cwd, args, collected, kind)), Effect.catch((platformError) => Effect.succeed(classify(cwd, args, platformError, kind))), Effect.timeoutOrElse({
20995
21349
  duration: GIT_TIMEOUT,
20996
21350
  orElse: () => Effect.succeed({
@@ -21022,414 +21376,1417 @@ const parseLsTree = (output) => parseNulSeparated(output).map((entry) => {
21022
21376
  oid: header[2] ?? "",
21023
21377
  path
21024
21378
  });
21025
- });
21026
- /** git's one-letter name-status codes, score digits stripped (`R100` → `R`). */
21027
- const NAME_STATUS_CODES = {
21028
- A: "added",
21029
- B: "broken",
21030
- C: "copied",
21031
- D: "deleted",
21032
- M: "modified",
21033
- R: "renamed",
21034
- T: "typeChanged",
21035
- U: "unmerged",
21036
- X: "unknown"
21037
- };
21038
- /**
21039
- * Parses `git diff --name-status -z` output. A plain entry is two NUL tokens
21040
- * (`<code>`, `<path>`); a rename/copy entry is three (`<R|C><score>`,
21041
- * `<oldPath>`, `<newPath>`), and only the code's first character carries the
21042
- * status — the similarity score digits are dropped.
21043
- */
21044
- const parseNameStatus = (output) => {
21045
- const tokens = output.split("\0");
21046
- const entries = [];
21047
- let index = 0;
21048
- while (index < tokens.length) {
21049
- const code = tokens[index] ?? "";
21050
- if (code === "") {
21051
- index += 1;
21052
- continue;
21379
+ });
21380
+ /** git's one-letter name-status codes, score digits stripped (`R100` → `R`). */
21381
+ const NAME_STATUS_CODES = {
21382
+ A: "added",
21383
+ B: "broken",
21384
+ C: "copied",
21385
+ D: "deleted",
21386
+ M: "modified",
21387
+ R: "renamed",
21388
+ T: "typeChanged",
21389
+ U: "unmerged",
21390
+ X: "unknown"
21391
+ };
21392
+ /**
21393
+ * Parses `git diff --name-status -z` output. A plain entry is two NUL tokens
21394
+ * (`<code>`, `<path>`); a rename/copy entry is three (`<R|C><score>`,
21395
+ * `<oldPath>`, `<newPath>`), and only the code's first character carries the
21396
+ * status — the similarity score digits are dropped.
21397
+ */
21398
+ const parseNameStatus = (output) => {
21399
+ const tokens = output.split("\0");
21400
+ const entries = [];
21401
+ let index = 0;
21402
+ while (index < tokens.length) {
21403
+ const code = tokens[index] ?? "";
21404
+ if (code === "") {
21405
+ index += 1;
21406
+ continue;
21407
+ }
21408
+ const letter = code.charAt(0);
21409
+ const status = NAME_STATUS_CODES[letter] ?? "unknown";
21410
+ if (letter === "R" || letter === "C") {
21411
+ entries.push(NameStatusEntry.make({
21412
+ status,
21413
+ path: tokens[index + 2] ?? "",
21414
+ oldPath: tokens[index + 1] ?? ""
21415
+ }));
21416
+ index += 3;
21417
+ } else {
21418
+ entries.push(NameStatusEntry.make({
21419
+ status,
21420
+ path: tokens[index + 1] ?? ""
21421
+ }));
21422
+ index += 2;
21423
+ }
21424
+ }
21425
+ return entries;
21426
+ };
21427
+ /**
21428
+ * The metadata of a single commit, read via `git log -1` with NUL-separated
21429
+ * `%H` / `%G?` / `%B` placeholders.
21430
+ *
21431
+ * @public
21432
+ */
21433
+ var CommitInfo = class extends Schema.Class("CommitInfo")({
21434
+ /** The commit's full object id (`%H`). */
21435
+ sha: Schema.String,
21436
+ /** git's `%G?` signature verdict: Good, Bad, Unknown validity, eXpired, expired-key (Y), Revoked, cannot-check (E), None. */
21437
+ signatureStatus: Schema.Literals([
21438
+ "G",
21439
+ "B",
21440
+ "U",
21441
+ "X",
21442
+ "Y",
21443
+ "R",
21444
+ "E",
21445
+ "N"
21446
+ ]),
21447
+ /** The raw commit message (`%B`), untrimmed — includes git's trailing format newline. */
21448
+ message: Schema.String
21449
+ }) {};
21450
+ /** One two-letter porcelain v1 status axis code. */
21451
+ const porcelainCode = Schema.Literals([
21452
+ " ",
21453
+ "M",
21454
+ "T",
21455
+ "A",
21456
+ "D",
21457
+ "R",
21458
+ "C",
21459
+ "U",
21460
+ "?",
21461
+ "!"
21462
+ ]);
21463
+ /**
21464
+ * One entry of a `git status --porcelain -z` listing.
21465
+ *
21466
+ * @public
21467
+ */
21468
+ var StatusEntry = class extends Schema.Class("StatusEntry")({
21469
+ /** The index-side status code (first porcelain column). */
21470
+ x: porcelainCode,
21471
+ /** The working-tree-side status code (second porcelain column). */
21472
+ y: porcelainCode,
21473
+ /** The entry's path — for a rename or copy, the NEW path. */
21474
+ path: Schema.String,
21475
+ /** The original path; present only on rename/copy entries. */
21476
+ origPath: Schema.optionalKey(Schema.String)
21477
+ }) {
21478
+ /**
21479
+ * Renders this entry back to one porcelain-shaped line: `XY <path>`.
21480
+ *
21481
+ * @remarks
21482
+ * **The rename convention is decided here, once, for every consumer.** By
21483
+ * default a rename/copy entry renders its NEW path only — `path` IS the
21484
+ * entry's current path, the one a line-oriented downstream can actually
21485
+ * open — which is a deliberate divergence from git's own non-`-z`
21486
+ * rendering (`orig -> new`). The arrow form is ambiguous to naive
21487
+ * line/whitespace splitters (paths may contain spaces, or a literal
21488
+ * `" -> "`), so it is opt-in via `renames: "arrow"` for consumers that
21489
+ * want git parity.
21490
+ *
21491
+ * A second recorded divergence: git's non-`-z` porcelain C-quotes paths
21492
+ * containing special characters; this renderer emits paths raw. It exists
21493
+ * for whitespace-insensitive text consumers — a machine parser should
21494
+ * consume the decoded {@link StatusEntry} values (or `-z` output)
21495
+ * directly, never re-parse this rendering.
21496
+ */
21497
+ toLine(options) {
21498
+ const rendered = options?.renames === "arrow" && this.origPath !== void 0 ? `${this.origPath} -> ${this.path}` : this.path;
21499
+ return `${this.x}${this.y} ${rendered}`;
21500
+ }
21501
+ /**
21502
+ * Renders entries back to porcelain-shaped text: one {@link StatusEntry.toLine}
21503
+ * line per entry, newline-joined, no trailing newline.
21504
+ *
21505
+ * @remarks
21506
+ * The route back from `Git.status`'s parsed entries to line-oriented text,
21507
+ * so a consumer whose downstream contract is porcelain-shaped text does
21508
+ * not hand-roll its own renderer (and re-decide the rename convention —
21509
+ * see {@link StatusEntry.toLine} for that decision). An empty array
21510
+ * renders as the empty string.
21511
+ */
21512
+ static format = (entries, options) => entries.map((entry) => entry.toLine(options)).join("\n");
21513
+ };
21514
+ /**
21515
+ * Parses `git log -1 --format=%H%x00%G?%x00%B` output: exactly two NUL
21516
+ * separators, everything after the second is the raw message, untrimmed.
21517
+ * Only ever called on the successful output of this package's own format
21518
+ * string, so the separators are guaranteed present.
21519
+ */
21520
+ const parseCommitInfo = (output) => {
21521
+ const first = output.indexOf("\0");
21522
+ const second = output.indexOf("\0", first + 1);
21523
+ return CommitInfo.make({
21524
+ sha: output.slice(0, first),
21525
+ signatureStatus: output.slice(first + 1, second),
21526
+ message: output.slice(second + 1)
21527
+ });
21528
+ };
21529
+ /**
21530
+ * Parses `git status --porcelain -z` output: each entry is `XY <path>`, and a
21531
+ * rename/copy entry appends the ORIGINAL path as one extra NUL token AFTER
21532
+ * the new path — the opposite order from `diff --name-status`.
21533
+ */
21534
+ const parseStatus = (output) => {
21535
+ const tokens = output.split("\0");
21536
+ const entries = [];
21537
+ let index = 0;
21538
+ while (index < tokens.length) {
21539
+ const token = tokens[index] ?? "";
21540
+ if (token === "") {
21541
+ index += 1;
21542
+ continue;
21543
+ }
21544
+ const x = token.charAt(0);
21545
+ const y = token.charAt(1);
21546
+ const path = token.slice(3);
21547
+ if (x === "R" || x === "C" || y === "R" || y === "C") {
21548
+ entries.push(StatusEntry.make({
21549
+ x,
21550
+ y,
21551
+ path,
21552
+ origPath: tokens[index + 1] ?? ""
21553
+ }));
21554
+ index += 2;
21555
+ } else {
21556
+ entries.push(StatusEntry.make({
21557
+ x,
21558
+ y,
21559
+ path
21560
+ }));
21561
+ index += 1;
21562
+ }
21563
+ }
21564
+ return entries;
21565
+ };
21566
+ /**
21567
+ * One line of a `git submodule status` listing.
21568
+ *
21569
+ * @remarks
21570
+ * The `state` decodes git's one-character prefix: `" "` → `"current"` (the
21571
+ * checked-out commit matches the index gitlink), `"-"` → `"uninitialized"`,
21572
+ * `"+"` → `"outOfSync"` (the checked-out commit differs from the gitlink),
21573
+ * `"U"` → `"conflict"` (merge conflicts). `describe` carries the
21574
+ * parenthesized `git describe` suffix git appends for initialized
21575
+ * submodules.
21576
+ *
21577
+ * @public
21578
+ */
21579
+ var SubmoduleStatusEntry = class extends Schema.Class("SubmoduleStatusEntry")({
21580
+ /** The decoded state prefix. */
21581
+ state: Schema.Literals([
21582
+ "current",
21583
+ "uninitialized",
21584
+ "outOfSync",
21585
+ "conflict"
21586
+ ]),
21587
+ /** The submodule's checked-out (or, uninitialized, gitlink) commit sha. */
21588
+ sha: Schema.String,
21589
+ /** The submodule's path relative to the superproject root. */
21590
+ path: Schema.String,
21591
+ /** The `git describe` suffix, present only for initialized submodules. */
21592
+ describe: Schema.optionalKey(Schema.String)
21593
+ }) {};
21594
+ /**
21595
+ * Parses `git submodule status` output. Line-based — the one parser in this
21596
+ * package without a `-z` mode to lean on, because git does not offer one for
21597
+ * `submodule status`; a submodule path containing a newline (or a literal
21598
+ * ` (` suffix mimicking the describe parenthesis) would corrupt the parse.
21599
+ * Accepted as a git-imposed limitation.
21600
+ */
21601
+ const parseSubmoduleStatus = (output) => {
21602
+ const entries = [];
21603
+ for (const line of output.split("\n")) {
21604
+ const trimmedEnd = line.endsWith("\r") ? line.slice(0, -1) : line;
21605
+ if (trimmedEnd === "") continue;
21606
+ const prefix = trimmedEnd.charAt(0);
21607
+ const state = prefix === "-" ? "uninitialized" : prefix === "+" ? "outOfSync" : prefix === "U" ? "conflict" : "current";
21608
+ const rest = prefix === " " || prefix === "-" || prefix === "+" || prefix === "U" ? trimmedEnd.slice(1) : trimmedEnd;
21609
+ const shaEnd = rest.indexOf(" ");
21610
+ const sha = shaEnd === -1 ? rest : rest.slice(0, shaEnd);
21611
+ const remainder = shaEnd === -1 ? "" : rest.slice(shaEnd + 1);
21612
+ const describeStart = remainder.endsWith(")") ? remainder.lastIndexOf(" (") : -1;
21613
+ if (describeStart === -1) entries.push(SubmoduleStatusEntry.make({
21614
+ state,
21615
+ sha,
21616
+ path: remainder
21617
+ }));
21618
+ else entries.push(SubmoduleStatusEntry.make({
21619
+ state,
21620
+ sha,
21621
+ path: remainder.slice(0, describeStart),
21622
+ describe: remainder.slice(describeStart + 2, -1)
21623
+ }));
21624
+ }
21625
+ return entries;
21626
+ };
21627
+ /**
21628
+ * One ref a remote advertises, from `git ls-remote`.
21629
+ *
21630
+ * @remarks
21631
+ * `ref` is the FULL refname as advertised (`refs/heads/main`,
21632
+ * `refs/tags/v1`), including the `^{}` suffix on an annotated tag's peeled
21633
+ * entry — an annotated tag appears twice, once as the tag object and once
21634
+ * peeled to its commit.
21635
+ *
21636
+ * @public
21637
+ */
21638
+ var LsRemoteEntry = class LsRemoteEntry extends Schema.Class("LsRemoteEntry")({
21639
+ /** The sha the advertised ref points at. */
21640
+ sha: Schema.String,
21641
+ /** The full advertised refname, `^{}` peel suffix included. */
21642
+ ref: Schema.String
21643
+ }) {
21644
+ /**
21645
+ * The human-facing short name of an advertised refname: the
21646
+ * `refs/heads/` / `refs/tags/` / `refs/remotes/` prefix and any `^{}`
21647
+ * peel suffix stripped (`refs/tags/v1^{}` → `v1`).
21648
+ */
21649
+ static shortName = (ref) => {
21650
+ const base = ref.endsWith("^{}") ? ref.slice(0, -3) : ref;
21651
+ for (const prefix of [
21652
+ "refs/heads/",
21653
+ "refs/tags/",
21654
+ "refs/remotes/"
21655
+ ]) if (base.startsWith(prefix)) return base.slice(prefix.length);
21656
+ return base;
21657
+ };
21658
+ /**
21659
+ * The entries whose short name is a NEAR MISS for `ref`: not an exact
21660
+ * match, but ending in `ref` right behind a separator (`@`, `/`, `-`,
21661
+ * `_`) — the monorepo-prefixed-tag case, where a caller asks for
21662
+ * `4.0.0-beta.101` and the remote advertises `effect@4.0.0-beta.101`.
21663
+ *
21664
+ * @remarks
21665
+ * A pure, decode-side helper for validate-before-mutate flows: run
21666
+ * `lsRemote`, look for the wanted ref, and when it is absent hand the
21667
+ * listing to this to compute a suggestion. Deliberately a helper on the
21668
+ * ENTRY value rather than behavior baked into the service — the service
21669
+ * returns the full listing and the caller owns the matching policy. An
21670
+ * annotated tag's peeled `^{}` entry shares its base short name, so a
21671
+ * near miss on such a tag can surface both of its entries.
21672
+ */
21673
+ static nearMatches = (entries, ref) => {
21674
+ const separators = [
21675
+ "@",
21676
+ "/",
21677
+ "-",
21678
+ "_"
21679
+ ];
21680
+ return entries.filter((entry) => {
21681
+ const short = LsRemoteEntry.shortName(entry.ref);
21682
+ if (short === ref || !short.endsWith(ref)) return false;
21683
+ return separators.includes(short.charAt(short.length - ref.length - 1));
21684
+ });
21685
+ };
21686
+ };
21687
+ /**
21688
+ * Parses `git ls-remote` output: one `<sha>\t<refname>` line per advertised
21689
+ * ref. Line-based deliberately — refnames cannot contain a newline (or a
21690
+ * tab), so the split is safe without a `-z` mode (which `ls-remote` does not
21691
+ * offer).
21692
+ */
21693
+ const parseLsRemote = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21694
+ const tabIndex = line.indexOf(" ");
21695
+ return LsRemoteEntry.make({
21696
+ sha: line.slice(0, tabIndex),
21697
+ ref: line.slice(tabIndex + 1)
21698
+ });
21699
+ });
21700
+ /**
21701
+ * One stash entry, from `git stash list`.
21702
+ *
21703
+ * @public
21704
+ */
21705
+ var StashEntry = class extends Schema.Class("StashEntry")({
21706
+ /** The reflog selector (`stash@{0}`) — the index other stash methods take. */
21707
+ ref: Schema.String,
21708
+ /** The stash commit's sha. */
21709
+ sha: Schema.String,
21710
+ /** The reflog subject: `WIP on <branch>: ...` or `On <branch>: <message>`. */
21711
+ message: Schema.String
21712
+ }) {};
21713
+ /**
21714
+ * Parses `git stash list -z --format=%gd%x1f%H%x1f%gs` output: NUL-terminated
21715
+ * records of unit-separated (`\x1f`) fields. Reflog subjects are single-line
21716
+ * and cannot contain either separator byte.
21717
+ */
21718
+ const parseStashList = (output) => parseNulSeparated(output).map((record) => {
21719
+ const [ref = "", sha = "", ...rest] = record.split("");
21720
+ return StashEntry.make({
21721
+ ref,
21722
+ sha,
21723
+ message: rest.join("")
21724
+ });
21725
+ });
21726
+ /**
21727
+ * One local (or remote-tracking) branch, from `git branch --list`.
21728
+ *
21729
+ * @public
21730
+ */
21731
+ var BranchEntry = class extends Schema.Class("BranchEntry")({
21732
+ /** The short branch name (`main`, or `origin/main` for a remote branch). */
21733
+ name: Schema.String,
21734
+ /** The branch tip's sha. */
21735
+ sha: Schema.String,
21736
+ /** Whether this branch is checked out in the current working tree. */
21737
+ current: Schema.Boolean
21738
+ }) {};
21739
+ /**
21740
+ * Parses `git branch --list --format=%(HEAD)%00%(refname:short)%00%(objectname)`
21741
+ * output: newline-separated records (refnames cannot contain newlines) of
21742
+ * NUL-separated fields. The `%(HEAD)` marker is `*` for the checked-out
21743
+ * branch; anything else (` `, or `+` for a branch checked out in a linked
21744
+ * worktree) is not-current.
21745
+ */
21746
+ const parseBranchList = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21747
+ const [marker = "", name = "", sha = ""] = line.split("\0");
21748
+ return BranchEntry.make({
21749
+ name,
21750
+ sha,
21751
+ current: marker === "*"
21752
+ });
21753
+ });
21754
+ /**
21755
+ * One ref, from `git for-each-ref`.
21756
+ *
21757
+ * @public
21758
+ */
21759
+ var RefEntry = class extends Schema.Class("RefEntry")({
21760
+ /** The full refname (`refs/tags/v1`). */
21761
+ ref: Schema.String,
21762
+ /** The sha of the object the ref points at. */
21763
+ sha: Schema.String,
21764
+ /**
21765
+ * The pointed-at object's type. An annotated tag is `tag` (the tag
21766
+ * object itself, not its target commit).
21767
+ */
21768
+ objectType: Schema.Literals([
21769
+ "commit",
21770
+ "tag",
21771
+ "tree",
21772
+ "blob"
21773
+ ])
21774
+ }) {};
21775
+ /**
21776
+ * Parses `git for-each-ref --format=%(refname)%00%(objectname)%00%(objecttype)`
21777
+ * output: newline-separated records (refnames cannot contain newlines) of
21778
+ * NUL-separated fields.
21779
+ */
21780
+ const parseForEachRef = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21781
+ const [ref = "", sha = "", objectType = "commit"] = line.split("\0");
21782
+ return RefEntry.make({
21783
+ ref,
21784
+ sha,
21785
+ objectType
21786
+ });
21787
+ });
21788
+ /**
21789
+ * One configuration entry, from `git config --list`.
21790
+ *
21791
+ * @public
21792
+ */
21793
+ var ConfigListEntry = class extends Schema.Class("ConfigListEntry")({
21794
+ /** The canonical dotted key (`section.subsection.key`). */
21795
+ key: Schema.String,
21796
+ /**
21797
+ * The raw value. A valueless key (git's boolean-true shorthand,
21798
+ * `[section]` + bare `key`) surfaces as the empty string — distinguish it
21799
+ * with `configGetAll` if the difference matters.
21800
+ */
21801
+ value: Schema.String
21802
+ }) {};
21803
+ /**
21804
+ * Parses `git config --list -z` output: NUL-terminated records, key separated
21805
+ * from value by the FIRST newline (a config value may itself contain
21806
+ * newlines — the reason `-z` is load-bearing). A record with no newline is a
21807
+ * valueless boolean-shorthand key.
21808
+ */
21809
+ const parseConfigList = (output) => parseNulSeparated(output).map((record) => {
21810
+ const newlineIndex = record.indexOf("\n");
21811
+ return newlineIndex === -1 ? ConfigListEntry.make({
21812
+ key: record,
21813
+ value: ""
21814
+ }) : ConfigListEntry.make({
21815
+ key: record.slice(0, newlineIndex),
21816
+ value: record.slice(newlineIndex + 1)
21817
+ });
21818
+ });
21819
+ /**
21820
+ * One working tree, from `git worktree list --porcelain`.
21821
+ *
21822
+ * @public
21823
+ */
21824
+ var WorktreeEntry = class extends Schema.Class("WorktreeEntry")({
21825
+ /** The working tree's absolute path. */
21826
+ path: Schema.String,
21827
+ /** The checked-out commit sha; absent for a bare repository entry. */
21828
+ head: Schema.optionalKey(Schema.String),
21829
+ /** The checked-out branch's full refname; absent when detached or bare. */
21830
+ branch: Schema.optionalKey(Schema.String),
21831
+ /** Whether the working tree is in detached-HEAD state. */
21832
+ detached: Schema.Boolean,
21833
+ /** Whether the entry is the bare repository itself. */
21834
+ bare: Schema.Boolean,
21835
+ /** Present when the worktree is locked; holds the lock reason (possibly empty). */
21836
+ locked: Schema.optionalKey(Schema.String),
21837
+ /** Present when the worktree is prunable; holds the reason (possibly empty). */
21838
+ prunable: Schema.optionalKey(Schema.String)
21839
+ }) {};
21840
+ /**
21841
+ * Parses `git worktree list --porcelain -z` output: NUL-terminated attribute
21842
+ * lines, one blank attribute terminating each entry. Attribute vocabulary:
21843
+ * `worktree <path>`, `HEAD <sha>`, `branch <ref>`, and the flag/annotation
21844
+ * attributes `detached`, `bare`, `locked [<reason>]`, `prunable [<reason>]`.
21845
+ */
21846
+ const parseWorktreeList = (output) => {
21847
+ const entries = [];
21848
+ let path;
21849
+ let head;
21850
+ let branch;
21851
+ let detached = false;
21852
+ let bare = false;
21853
+ let locked;
21854
+ let prunable;
21855
+ const flush = () => {
21856
+ if (path !== void 0) entries.push(WorktreeEntry.make({
21857
+ path,
21858
+ detached,
21859
+ bare,
21860
+ ...head !== void 0 ? { head } : {},
21861
+ ...branch !== void 0 ? { branch } : {},
21862
+ ...locked !== void 0 ? { locked } : {},
21863
+ ...prunable !== void 0 ? { prunable } : {}
21864
+ }));
21865
+ path = void 0;
21866
+ head = void 0;
21867
+ branch = void 0;
21868
+ detached = false;
21869
+ bare = false;
21870
+ locked = void 0;
21871
+ prunable = void 0;
21872
+ };
21873
+ for (const attribute of output.split("\0")) if (attribute === "") flush();
21874
+ else if (attribute.startsWith("worktree ")) path = attribute.slice(9);
21875
+ else if (attribute.startsWith("HEAD ")) head = attribute.slice(5);
21876
+ else if (attribute.startsWith("branch ")) branch = attribute.slice(7);
21877
+ else if (attribute === "detached") detached = true;
21878
+ else if (attribute === "bare") bare = true;
21879
+ else if (attribute === "locked" || attribute.startsWith("locked ")) locked = attribute === "locked" ? "" : attribute.slice(7);
21880
+ else if (attribute === "prunable" || attribute.startsWith("prunable ")) prunable = attribute === "prunable" ? "" : attribute.slice(9);
21881
+ flush();
21882
+ return entries;
21883
+ };
21884
+ /**
21885
+ * One index (staging area) entry, from `git ls-files --stage`.
21886
+ *
21887
+ * @remarks
21888
+ * The index-side sibling of {@link LsTreeEntry}: this is the ONLY place a
21889
+ * staged-but-uncommitted gitlink (`mode` `160000`) is visible — `lsTree`
21890
+ * reads the committed tree and misses exactly that window.
21891
+ *
21892
+ * @public
21893
+ */
21894
+ var LsFilesEntry = class extends Schema.Class("LsFilesEntry")({
21895
+ /** The entry's file mode, e.g. `100644` — `160000` for a gitlink. */
21896
+ mode: Schema.String,
21897
+ /** The staged object id. */
21898
+ oid: Schema.String,
21899
+ /** The merge stage: `0` normally; `1`/`2`/`3` during an unresolved merge. */
21900
+ stage: Schema.Number,
21901
+ /** The entry's path, relative to `cwd`. May contain spaces or newlines. */
21902
+ path: Schema.String
21903
+ }) {};
21904
+ /**
21905
+ * Parses `git ls-files --stage -z` output: each NUL-terminated entry is
21906
+ * `<mode> <oid> <stage>\t<path>`. `path` is everything after the first tab,
21907
+ * so a path containing spaces or newlines is preserved intact — the same
21908
+ * split rule as `parseLsTree`.
21909
+ */
21910
+ const parseLsFiles = (output) => parseNulSeparated(output).map((entry) => {
21911
+ const tabIndex = entry.indexOf(" ");
21912
+ const header = entry.slice(0, tabIndex).split(" ");
21913
+ return LsFilesEntry.make({
21914
+ mode: header[0] ?? "",
21915
+ oid: header[1] ?? "",
21916
+ stage: Number(header[2] ?? "0"),
21917
+ path: entry.slice(tabIndex + 1)
21918
+ });
21919
+ });
21920
+ /**
21921
+ * Refuse a caller-supplied ref or range that git would parse as an option.
21922
+ *
21923
+ * Refs are caller-controlled and land in git's argv as positional entries; a
21924
+ * value beginning with `-` is read as a flag instead — `checkout("-b")` would
21925
+ * CREATE a branch. A bare `--` separator is not a safe fix for every command
21926
+ * (it switches `checkout` into pathspec mode), so option-like values are
21927
+ * refused outright, before any spawn, as a typed {@link GitCommandError}.
21928
+ * `show`'s `path` needs no guard: it is fused after the ref into one
21929
+ * `ref:path` token, which cannot begin with `-` unless the ref does.
21930
+ *
21931
+ * `sensitive` values get the same check but a REDACTED report: a refused
21932
+ * sensitive positional (a `configSet` value) must not leak into
21933
+ * `GitCommandError.args`/`detail` any more than a spawned one may — the #86
21934
+ * redaction policy applies to guard rejections too.
21935
+ */
21936
+ const rejectOptionLikeRefs = (cwd, refs, sensitive = []) => {
21937
+ const offending = refs.find((ref) => ref.startsWith("-"));
21938
+ if (offending !== void 0) return Effect.fail(new GitCommandError({
21939
+ kind: "refused",
21940
+ args: [offending],
21941
+ cwd,
21942
+ stderr: "",
21943
+ detail: `refused a ref argument git would parse as an option: ${JSON.stringify(offending)}`
21944
+ }));
21945
+ return sensitive.find((value) => value.startsWith("-")) === void 0 ? Effect.void : Effect.fail(new GitCommandError({
21946
+ kind: "refused",
21947
+ args: ["<redacted>"],
21948
+ cwd,
21949
+ stderr: "",
21950
+ detail: "refused a sensitive argument git would parse as an option (value redacted)"
21951
+ }));
21952
+ };
21953
+ /**
21954
+ * Refuse a caller-supplied numeric index/limit that is not a non-negative
21955
+ * integer.
21956
+ *
21957
+ * Every relational comparison against `NaN` is `false`, so a bare
21958
+ * `value < 0` guard admits `NaN` (and a fractional value truncates nothing —
21959
+ * it rides straight into the argv as `stash@{1.5}` / `--max-count=NaN`).
21960
+ * Integrality and range are therefore checked together, pre-spawn, as a
21961
+ * typed refusal.
21962
+ */
21963
+ const rejectNonNaturalNumber = (cwd, label, value) => value === void 0 || Number.isInteger(value) && value >= 0 ? Effect.void : Effect.fail(new GitCommandError({
21964
+ kind: "refused",
21965
+ args: [String(value)],
21966
+ cwd,
21967
+ stderr: "",
21968
+ detail: `refused ${label}: expected a non-negative integer, received ${value}`
21969
+ }));
21970
+ /** Builds the `Git.Service` shape over an already-resolved `ChildProcessSpawner`. */
21971
+ const make = (spawner) => {
21972
+ const runFor = (invocation, cwd, kind) => runClassified(invocation, cwd, kind).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner));
21973
+ const show = Effect.fn("Git.show")(function* (cwd, ref, path) {
21974
+ yield* Effect.annotateCurrentSpan({
21975
+ cwd,
21976
+ ref,
21977
+ path
21978
+ });
21979
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21980
+ const classified = yield* runFor(GitCommand.show(ref, path), cwd, "show");
21981
+ switch (classified._tag) {
21982
+ case "success": return Option.some(classified.output);
21983
+ case "absent": return Option.none();
21984
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21985
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21986
+ ref,
21987
+ cwd
21988
+ }));
21989
+ case "failure": return yield* Effect.fail(classified.error);
21990
+ default: return yield* Effect.die(`Git.show: unexpected classification "${classified._tag}"`);
21991
+ }
21992
+ });
21993
+ const lsTree = Effect.fn("Git.lsTree")(function* (cwd, ref, options) {
21994
+ yield* Effect.annotateCurrentSpan({
21995
+ cwd,
21996
+ ref
21997
+ });
21998
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21999
+ const classified = yield* runFor(GitCommand.lsTree(ref, options?.pathspec ?? []), cwd, "generic");
22000
+ switch (classified._tag) {
22001
+ case "success": return parseLsTree(classified.output);
22002
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22003
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22004
+ ref,
22005
+ cwd
22006
+ }));
22007
+ case "failure": return yield* Effect.fail(classified.error);
22008
+ default: return yield* Effect.die(`Git.lsTree: unexpected classification "${classified._tag}"`);
22009
+ }
22010
+ });
22011
+ const refExists = Effect.fn("Git.refExists")(function* (cwd, ref) {
22012
+ yield* Effect.annotateCurrentSpan({
22013
+ cwd,
22014
+ ref
22015
+ });
22016
+ yield* rejectOptionLikeRefs(cwd, [ref]);
22017
+ const classified = yield* runFor(GitCommand.refExists(ref), cwd, "refExists");
22018
+ switch (classified._tag) {
22019
+ case "success": return true;
22020
+ case "refMissing": return false;
22021
+ case "unknownRef": return false;
22022
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22023
+ case "failure": return yield* Effect.fail(classified.error);
22024
+ default: return yield* Effect.die(`Git.refExists: unexpected classification "${classified._tag}"`);
22025
+ }
22026
+ });
22027
+ const mergeBase = Effect.fn("Git.mergeBase")(function* (cwd, a, b) {
22028
+ yield* Effect.annotateCurrentSpan({
22029
+ cwd,
22030
+ a,
22031
+ b
22032
+ });
22033
+ yield* rejectOptionLikeRefs(cwd, [a, b]);
22034
+ const classified = yield* runFor(GitCommand.mergeBase(a, b), cwd, "generic");
22035
+ switch (classified._tag) {
22036
+ case "success": return classified.output.trim();
22037
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22038
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22039
+ ref: `${a}...${b}`,
22040
+ cwd
22041
+ }));
22042
+ case "failure": return yield* Effect.fail(classified.error);
22043
+ default: return yield* Effect.die(`Git.mergeBase: unexpected classification "${classified._tag}"`);
22044
+ }
22045
+ });
22046
+ const changedFiles = Effect.fn("Git.changedFiles")(function* (cwd, options) {
22047
+ const relative = options.relative ?? false;
22048
+ yield* Effect.annotateCurrentSpan({
22049
+ cwd,
22050
+ base: options.base,
22051
+ head: options.head,
22052
+ relative
22053
+ });
22054
+ yield* rejectOptionLikeRefs(cwd, [options.base, options.head]);
22055
+ const classified = yield* runFor(GitCommand.changedFiles(options.base, options.head, relative), cwd, "generic");
22056
+ switch (classified._tag) {
22057
+ case "success": return parseNulSeparated(classified.output);
22058
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22059
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22060
+ ref: `${options.base}...${options.head}`,
22061
+ cwd
22062
+ }));
22063
+ case "failure": return yield* Effect.fail(classified.error);
22064
+ default: return yield* Effect.die(`Git.changedFiles: unexpected classification "${classified._tag}"`);
22065
+ }
22066
+ });
22067
+ const collectPaths = (method, invocation, cwd) => Effect.gen(function* () {
22068
+ const classified = yield* runFor(invocation, cwd, "generic");
22069
+ switch (classified._tag) {
22070
+ case "success": return parseNulSeparated(classified.output);
22071
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22072
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22073
+ ref: "working tree",
22074
+ cwd
22075
+ }));
22076
+ case "failure": return yield* Effect.fail(classified.error);
22077
+ default: return yield* Effect.die(`${method}: unexpected classification "${classified._tag}"`);
22078
+ }
22079
+ });
22080
+ const unstagedChanges = Effect.fn("Git.unstagedChanges")(function* (cwd, options) {
22081
+ const relative = options?.relative ?? false;
22082
+ yield* Effect.annotateCurrentSpan({
22083
+ cwd,
22084
+ relative
22085
+ });
22086
+ return yield* collectPaths("Git.unstagedChanges", GitCommand.unstagedChanges(relative), cwd);
22087
+ });
22088
+ const stagedChanges = Effect.fn("Git.stagedChanges")(function* (cwd, options) {
22089
+ const relative = options?.relative ?? false;
22090
+ yield* Effect.annotateCurrentSpan({
22091
+ cwd,
22092
+ relative
22093
+ });
22094
+ return yield* collectPaths("Git.stagedChanges", GitCommand.stagedChanges(relative), cwd);
22095
+ });
22096
+ const untrackedFiles = Effect.fn("Git.untrackedFiles")(function* (cwd, options) {
22097
+ const relative = options?.relative ?? false;
22098
+ yield* Effect.annotateCurrentSpan({
22099
+ cwd,
22100
+ relative
22101
+ });
22102
+ return yield* collectPaths("Git.untrackedFiles", GitCommand.untrackedFiles(relative), cwd);
22103
+ });
22104
+ const workingChanges = Effect.fn("Git.workingChanges")(function* (cwd, options) {
22105
+ yield* Effect.annotateCurrentSpan({
22106
+ cwd,
22107
+ relative: options?.relative ?? false
22108
+ });
22109
+ const unstaged = yield* unstagedChanges(cwd, options);
22110
+ const staged = yield* stagedChanges(cwd, options);
22111
+ const untracked = yield* untrackedFiles(cwd, options);
22112
+ return [.../* @__PURE__ */ new Set([
22113
+ ...unstaged,
22114
+ ...staged,
22115
+ ...untracked
22116
+ ])];
22117
+ });
22118
+ const nameStatus = Effect.fn("Git.nameStatus")(function* (cwd, options) {
22119
+ const relative = options.relative ?? false;
22120
+ yield* Effect.annotateCurrentSpan({
22121
+ cwd,
22122
+ base: options.base,
22123
+ head: options.head ?? "(working tree)",
22124
+ relative
22125
+ });
22126
+ yield* rejectOptionLikeRefs(cwd, options.head === void 0 ? [options.base] : [options.base, options.head]);
22127
+ const classified = yield* runFor(GitCommand.nameStatus(options.base, options.head, relative), cwd, "generic");
22128
+ switch (classified._tag) {
22129
+ case "success": return parseNameStatus(classified.output);
22130
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22131
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22132
+ ref: options.head === void 0 ? options.base : `${options.base}...${options.head}`,
22133
+ cwd
22134
+ }));
22135
+ case "failure": return yield* Effect.fail(classified.error);
22136
+ default: return yield* Effect.die(`Git.nameStatus: unexpected classification "${classified._tag}"`);
22137
+ }
22138
+ });
22139
+ const revParse = Effect.fn("Git.revParse")(function* (cwd, ref) {
22140
+ yield* Effect.annotateCurrentSpan({
22141
+ cwd,
22142
+ ref
22143
+ });
22144
+ yield* rejectOptionLikeRefs(cwd, [ref]);
22145
+ const classified = yield* runFor(GitCommand.revParse(ref), cwd, "generic");
22146
+ switch (classified._tag) {
22147
+ case "success": return classified.output.trim();
22148
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22149
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22150
+ ref,
22151
+ cwd
22152
+ }));
22153
+ case "failure": return yield* Effect.fail(classified.error);
22154
+ default: return yield* Effect.die(`Git.revParse: unexpected classification "${classified._tag}"`);
22155
+ }
22156
+ });
22157
+ const checkout = Effect.fn("Git.checkout")(function* (cwd, ref, options) {
22158
+ const detach = options?.detach ?? false;
22159
+ yield* Effect.annotateCurrentSpan({
22160
+ cwd,
22161
+ ref,
22162
+ detach
22163
+ });
22164
+ yield* rejectOptionLikeRefs(cwd, [ref]);
22165
+ const classified = yield* runFor(GitCommand.checkout(ref, detach), cwd, "generic");
22166
+ switch (classified._tag) {
22167
+ case "success": return;
22168
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22169
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22170
+ ref,
22171
+ cwd
22172
+ }));
22173
+ case "failure": return yield* Effect.fail(classified.error);
22174
+ default: return yield* Effect.die(`Git.checkout: unexpected classification "${classified._tag}"`);
22175
+ }
22176
+ });
22177
+ const reset = Effect.fn("Git.reset")(function* (cwd, options) {
22178
+ const mode = options?.mode ?? "mixed";
22179
+ yield* Effect.annotateCurrentSpan({
22180
+ cwd,
22181
+ mode,
22182
+ ref: options?.ref ?? "HEAD"
22183
+ });
22184
+ if (options?.ref !== void 0) yield* rejectOptionLikeRefs(cwd, [options.ref]);
22185
+ const classified = yield* runFor(GitCommand.reset(mode, options?.ref), cwd, "generic");
22186
+ switch (classified._tag) {
22187
+ case "success": return;
22188
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22189
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22190
+ ref: options?.ref ?? "HEAD",
22191
+ cwd
22192
+ }));
22193
+ case "failure": return yield* Effect.fail(classified.error);
22194
+ default: return yield* Effect.die(`Git.reset: unexpected classification "${classified._tag}"`);
22195
+ }
22196
+ });
22197
+ const clean = Effect.fn("Git.clean")(function* (cwd, options) {
22198
+ const directories = options?.directories ?? false;
22199
+ const ignored = options?.ignored ?? false;
22200
+ yield* Effect.annotateCurrentSpan({
22201
+ cwd,
22202
+ directories,
22203
+ ignored
22204
+ });
22205
+ const classified = yield* runFor(GitCommand.clean(directories, ignored, options?.paths ?? []), cwd, "generic");
22206
+ switch (classified._tag) {
22207
+ case "success": return;
22208
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22209
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22210
+ ref: "working tree",
22211
+ cwd
22212
+ }));
22213
+ case "failure": return yield* Effect.fail(classified.error);
22214
+ default: return yield* Effect.die(`Git.clean: unexpected classification "${classified._tag}"`);
22215
+ }
22216
+ });
22217
+ const restore = Effect.fn("Git.restore")(function* (cwd, paths, options) {
22218
+ yield* Effect.annotateCurrentSpan({
22219
+ cwd,
22220
+ count: paths.length,
22221
+ source: options?.source ?? "(index)"
22222
+ });
22223
+ if (options?.source !== void 0) yield* rejectOptionLikeRefs(cwd, [options.source]);
22224
+ const classified = yield* runFor(GitCommand.restore(paths, options?.source, options?.staged ?? false, options?.worktree ?? false), cwd, "generic");
22225
+ switch (classified._tag) {
22226
+ case "success": return;
22227
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22228
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22229
+ ref: options?.source ?? "working tree",
22230
+ cwd
22231
+ }));
22232
+ case "failure": return yield* Effect.fail(classified.error);
22233
+ default: return yield* Effect.die(`Git.restore: unexpected classification "${classified._tag}"`);
22234
+ }
22235
+ });
22236
+ const branchCreate = Effect.fn("Git.branchCreate")(function* (cwd, name, options) {
22237
+ const checkoutBranch = options?.checkout ?? false;
22238
+ const force = options?.force ?? false;
22239
+ yield* Effect.annotateCurrentSpan({
22240
+ cwd,
22241
+ name,
22242
+ startPoint: options?.startPoint ?? "HEAD",
22243
+ checkout: checkoutBranch,
22244
+ force
22245
+ });
22246
+ yield* rejectOptionLikeRefs(cwd, [name, ...options?.startPoint !== void 0 ? [options.startPoint] : []]);
22247
+ const classified = yield* runFor(GitCommand.branchCreate(name, options?.startPoint, checkoutBranch, force), cwd, "generic");
22248
+ switch (classified._tag) {
22249
+ case "success": return;
22250
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22251
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22252
+ ref: options?.startPoint ?? name,
22253
+ cwd
22254
+ }));
22255
+ case "failure": return yield* Effect.fail(classified.error);
22256
+ default: return yield* Effect.die(`Git.branchCreate: unexpected classification "${classified._tag}"`);
22257
+ }
22258
+ });
22259
+ const branchDelete = Effect.fn("Git.branchDelete")(function* (cwd, name, options) {
22260
+ yield* Effect.annotateCurrentSpan({
22261
+ cwd,
22262
+ name,
22263
+ force: options?.force ?? false
22264
+ });
22265
+ yield* rejectOptionLikeRefs(cwd, [name]);
22266
+ const classified = yield* runFor(GitCommand.branchDelete(name, options?.force ?? false), cwd, "generic");
22267
+ switch (classified._tag) {
22268
+ case "success": return;
22269
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22270
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22271
+ ref: name,
22272
+ cwd
22273
+ }));
22274
+ case "failure": return yield* Effect.fail(classified.error);
22275
+ default: return yield* Effect.die(`Git.branchDelete: unexpected classification "${classified._tag}"`);
22276
+ }
22277
+ });
22278
+ const isShallow = Effect.fn("Git.isShallow")(function* (cwd) {
22279
+ yield* Effect.annotateCurrentSpan({ cwd });
22280
+ const classified = yield* runFor(GitCommand.isShallow(), cwd, "generic");
22281
+ switch (classified._tag) {
22282
+ case "success": return classified.output.trim() === "true";
22283
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22284
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22285
+ ref: "HEAD",
22286
+ cwd
22287
+ }));
22288
+ case "failure": return yield* Effect.fail(classified.error);
22289
+ default: return yield* Effect.die(`Git.isShallow: unexpected classification "${classified._tag}"`);
22290
+ }
22291
+ });
22292
+ const fetchUnshallow = Effect.fn("Git.fetchUnshallow")(function* (cwd, options) {
22293
+ const remote = options?.remote ?? "origin";
22294
+ yield* Effect.annotateCurrentSpan({ cwd });
22295
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22296
+ const classified = yield* runFor(GitCommand.fetchUnshallow(remote), cwd, "generic");
22297
+ switch (classified._tag) {
22298
+ case "success": return;
22299
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22300
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22301
+ ref: "--unshallow",
22302
+ cwd
22303
+ }));
22304
+ case "failure": return yield* Effect.fail(classified.error);
22305
+ default: return yield* Effect.die(`Git.fetchUnshallow: unexpected classification "${classified._tag}"`);
22306
+ }
22307
+ });
22308
+ const fetch = Effect.fn("Git.fetch")(function* (cwd, options) {
22309
+ const remote = options.remote ?? "origin";
22310
+ const tag = options.tag ?? false;
22311
+ yield* Effect.annotateCurrentSpan({
22312
+ cwd,
22313
+ ref: options.ref,
22314
+ tag
22315
+ });
22316
+ yield* rejectOptionLikeRefs(cwd, [remote, options.ref]);
22317
+ yield* rejectNonNaturalNumber(cwd, "a fetch depth", options.depth);
22318
+ const classified = yield* runFor(GitCommand.fetch(remote, options.ref, options.depth, tag), cwd, "generic");
22319
+ switch (classified._tag) {
22320
+ case "success": return;
22321
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22322
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22323
+ ref: options.ref,
22324
+ cwd
22325
+ }));
22326
+ case "failure": return yield* Effect.fail(classified.error);
22327
+ default: return yield* Effect.die(`Git.fetch: unexpected classification "${classified._tag}"`);
22328
+ }
22329
+ });
22330
+ const fetchAny = Effect.fn("Git.fetchAny")(function* (cwd, options) {
22331
+ yield* Effect.annotateCurrentSpan({
22332
+ cwd,
22333
+ ref: options.ref
22334
+ });
22335
+ return yield* fetch(cwd, {
22336
+ ...options,
22337
+ tag: true
22338
+ }).pipe(Effect.catchTag(["UnknownRefError", "GitCommandError"], (error) => error._tag === "GitCommandError" && error.kind === "refused" ? Effect.fail(error) : fetch(cwd, options)));
22339
+ });
22340
+ const submoduleUpdate = Effect.fn("Git.submoduleUpdate")(function* (cwd, options) {
22341
+ const init = options?.init ?? false;
22342
+ yield* Effect.annotateCurrentSpan({
22343
+ cwd,
22344
+ init
22345
+ });
22346
+ yield* rejectNonNaturalNumber(cwd, "a submodule update depth", options?.depth);
22347
+ const classified = yield* runFor(GitCommand.submoduleUpdate(init, options?.depth, options?.paths ?? []), cwd, "generic");
22348
+ switch (classified._tag) {
22349
+ case "success": return;
22350
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22351
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22352
+ ref: "submodule update",
22353
+ cwd
22354
+ }));
22355
+ case "failure": return yield* Effect.fail(classified.error);
22356
+ default: return yield* Effect.die(`Git.submoduleUpdate: unexpected classification "${classified._tag}"`);
22357
+ }
22358
+ });
22359
+ const submoduleAdd = Effect.fn("Git.submoduleAdd")(function* (cwd, options) {
22360
+ yield* Effect.annotateCurrentSpan({
22361
+ cwd,
22362
+ path: options.path
22363
+ });
22364
+ yield* rejectNonNaturalNumber(cwd, "a submodule add depth", options.depth);
22365
+ const classified = yield* runFor(GitCommand.submoduleAdd(options.url, options.path, options.depth), cwd, "generic");
22366
+ switch (classified._tag) {
22367
+ case "success": return;
22368
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22369
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22370
+ ref: options.path,
22371
+ cwd
22372
+ }));
22373
+ case "failure": return yield* Effect.fail(classified.error);
22374
+ default: return yield* Effect.die(`Git.submoduleAdd: unexpected classification "${classified._tag}"`);
22375
+ }
22376
+ });
22377
+ const sparseCheckoutSet = Effect.fn("Git.sparseCheckoutSet")(function* (cwd, patterns, options) {
22378
+ yield* Effect.annotateCurrentSpan({
22379
+ cwd,
22380
+ cone: options.cone
22381
+ });
22382
+ yield* rejectOptionLikeRefs(cwd, patterns);
22383
+ const classified = yield* runFor(GitCommand.sparseCheckoutSet(patterns, options.cone), cwd, "generic");
22384
+ switch (classified._tag) {
22385
+ case "success": return;
22386
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22387
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22388
+ ref: "sparse-checkout",
22389
+ cwd
22390
+ }));
22391
+ case "failure": return yield* Effect.fail(classified.error);
22392
+ default: return yield* Effect.die(`Git.sparseCheckoutSet: unexpected classification "${classified._tag}"`);
22393
+ }
22394
+ });
22395
+ const configSet = Effect.fn("Git.configSet")(function* (cwd, key, value, options) {
22396
+ yield* Effect.annotateCurrentSpan({
22397
+ cwd,
22398
+ key,
22399
+ file: options?.file ?? "(repository config)"
22400
+ });
22401
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []], [value]);
22402
+ const classified = yield* runFor(GitCommand.configSet(key, value, options?.file), cwd, "generic");
22403
+ switch (classified._tag) {
22404
+ case "success": return;
22405
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22406
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22407
+ ref: key,
22408
+ cwd
22409
+ }));
22410
+ case "failure": return yield* Effect.fail(classified.error);
22411
+ default: return yield* Effect.die(`Git.configSet: unexpected classification "${classified._tag}"`);
22412
+ }
22413
+ });
22414
+ const add = Effect.fn("Git.add")(function* (cwd, paths) {
22415
+ yield* Effect.annotateCurrentSpan({
22416
+ cwd,
22417
+ count: paths.length
22418
+ });
22419
+ const classified = yield* runFor(GitCommand.add(paths), cwd, "generic");
22420
+ switch (classified._tag) {
22421
+ case "success": return;
22422
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22423
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22424
+ ref: "working tree",
22425
+ cwd
22426
+ }));
22427
+ case "failure": return yield* Effect.fail(classified.error);
22428
+ default: return yield* Effect.die(`Git.add: unexpected classification "${classified._tag}"`);
22429
+ }
22430
+ });
22431
+ const defaultBranch = Effect.fn("Git.defaultBranch")(function* (cwd, options) {
22432
+ const remote = options?.remote ?? "origin";
22433
+ yield* Effect.annotateCurrentSpan({
22434
+ cwd,
22435
+ remote
22436
+ });
22437
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22438
+ const classified = yield* runFor(GitCommand.defaultBranch(remote), cwd, "quiet");
22439
+ switch (classified._tag) {
22440
+ case "success": {
22441
+ const short = classified.output.trim();
22442
+ const prefix = `${remote}/`;
22443
+ return Option.some(short.startsWith(prefix) ? short.slice(prefix.length) : short);
22444
+ }
22445
+ case "absent": return Option.none();
22446
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22447
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22448
+ ref: `refs/remotes/${remote}/HEAD`,
22449
+ cwd
22450
+ }));
22451
+ case "failure": return yield* Effect.fail(classified.error);
22452
+ default: return yield* Effect.die(`Git.defaultBranch: unexpected classification "${classified._tag}"`);
22453
+ }
22454
+ });
22455
+ const currentBranch = Effect.fn("Git.currentBranch")(function* (cwd) {
22456
+ yield* Effect.annotateCurrentSpan({ cwd });
22457
+ const classified = yield* runFor(GitCommand.currentBranch(), cwd, "generic");
22458
+ switch (classified._tag) {
22459
+ case "success": {
22460
+ const name = classified.output.trim();
22461
+ return name === "HEAD" ? Option.none() : Option.some(name);
22462
+ }
22463
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22464
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22465
+ ref: "HEAD",
22466
+ cwd
22467
+ }));
22468
+ case "failure": return yield* Effect.fail(classified.error);
22469
+ default: return yield* Effect.die(`Git.currentBranch: unexpected classification "${classified._tag}"`);
22470
+ }
22471
+ });
22472
+ const repoRoot = Effect.fn("Git.repoRoot")(function* (cwd) {
22473
+ yield* Effect.annotateCurrentSpan({ cwd });
22474
+ const classified = yield* runFor(GitCommand.repoRoot(), cwd, "generic");
22475
+ switch (classified._tag) {
22476
+ case "success": return classified.output.trim();
22477
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22478
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22479
+ ref: "working tree",
22480
+ cwd
22481
+ }));
22482
+ case "failure": return yield* Effect.fail(classified.error);
22483
+ default: return yield* Effect.die(`Git.repoRoot: unexpected classification "${classified._tag}"`);
22484
+ }
22485
+ });
22486
+ const configGet = Effect.fn("Git.configGet")(function* (cwd, key) {
22487
+ yield* Effect.annotateCurrentSpan({
22488
+ cwd,
22489
+ key
22490
+ });
22491
+ yield* rejectOptionLikeRefs(cwd, [key]);
22492
+ const classified = yield* runFor(GitCommand.configGet(key), cwd, "quiet");
22493
+ switch (classified._tag) {
22494
+ case "success": return Option.some(classified.output.trim());
22495
+ case "absent": return Option.none();
22496
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22497
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22498
+ ref: key,
22499
+ cwd
22500
+ }));
22501
+ case "failure": return yield* Effect.fail(classified.error);
22502
+ default: return yield* Effect.die(`Git.configGet: unexpected classification "${classified._tag}"`);
22503
+ }
22504
+ });
22505
+ const remoteUrl = Effect.fn("Git.remoteUrl")(function* (cwd, options) {
22506
+ const remote = options?.remote ?? "origin";
22507
+ yield* Effect.annotateCurrentSpan({
22508
+ cwd,
22509
+ remote
22510
+ });
22511
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22512
+ const classified = yield* runFor(GitCommand.remoteUrl(remote), cwd, "noSuchRemote");
22513
+ switch (classified._tag) {
22514
+ case "success": return Option.some(classified.output.trim());
22515
+ case "absent": return Option.none();
22516
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22517
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22518
+ ref: remote,
22519
+ cwd
22520
+ }));
22521
+ case "failure": return yield* Effect.fail(classified.error);
22522
+ default: return yield* Effect.die(`Git.remoteUrl: unexpected classification "${classified._tag}"`);
21053
22523
  }
21054
- const letter = code.charAt(0);
21055
- const status = NAME_STATUS_CODES[letter] ?? "unknown";
21056
- if (letter === "R" || letter === "C") {
21057
- entries.push(NameStatusEntry.make({
21058
- status,
21059
- path: tokens[index + 2] ?? "",
21060
- oldPath: tokens[index + 1] ?? ""
22524
+ });
22525
+ const commitInfo = Effect.fn("Git.commitInfo")(function* (cwd, ref) {
22526
+ const target = ref ?? "HEAD";
22527
+ yield* Effect.annotateCurrentSpan({
22528
+ cwd,
22529
+ ref: target
22530
+ });
22531
+ yield* rejectOptionLikeRefs(cwd, [target]);
22532
+ const classified = yield* runFor(GitCommand.commitInfo(target), cwd, "generic");
22533
+ switch (classified._tag) {
22534
+ case "success": return parseCommitInfo(classified.output);
22535
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22536
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22537
+ ref: target,
22538
+ cwd
21061
22539
  }));
21062
- index += 3;
21063
- } else {
21064
- entries.push(NameStatusEntry.make({
21065
- status,
21066
- path: tokens[index + 1] ?? ""
22540
+ case "failure": return yield* Effect.fail(classified.error);
22541
+ default: return yield* Effect.die(`Git.commitInfo: unexpected classification "${classified._tag}"`);
22542
+ }
22543
+ });
22544
+ const status = Effect.fn("Git.status")(function* (cwd) {
22545
+ yield* Effect.annotateCurrentSpan({ cwd });
22546
+ const classified = yield* runFor(GitCommand.status(), cwd, "generic");
22547
+ switch (classified._tag) {
22548
+ case "success": return parseStatus(classified.output);
22549
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22550
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22551
+ ref: "working tree",
22552
+ cwd
21067
22553
  }));
21068
- index += 2;
22554
+ case "failure": return yield* Effect.fail(classified.error);
22555
+ default: return yield* Effect.die(`Git.status: unexpected classification "${classified._tag}"`);
21069
22556
  }
21070
- }
21071
- return entries;
21072
- };
21073
- /**
21074
- * The metadata of a single commit, read via `git log -1` with NUL-separated
21075
- * `%H` / `%G?` / `%B` placeholders.
21076
- *
21077
- * @public
21078
- */
21079
- var CommitInfo = class extends Schema.Class("CommitInfo")({
21080
- /** The commit's full object id (`%H`). */
21081
- sha: Schema.String,
21082
- /** git's `%G?` signature verdict: Good, Bad, Unknown validity, eXpired, expired-key (Y), Revoked, cannot-check (E), None. */
21083
- signatureStatus: Schema.Literals([
21084
- "G",
21085
- "B",
21086
- "U",
21087
- "X",
21088
- "Y",
21089
- "R",
21090
- "E",
21091
- "N"
21092
- ]),
21093
- /** The raw commit message (`%B`), untrimmed — includes git's trailing format newline. */
21094
- message: Schema.String
21095
- }) {};
21096
- /** One two-letter porcelain v1 status axis code. */
21097
- const porcelainCode = Schema.Literals([
21098
- " ",
21099
- "M",
21100
- "T",
21101
- "A",
21102
- "D",
21103
- "R",
21104
- "C",
21105
- "U",
21106
- "?",
21107
- "!"
21108
- ]);
21109
- /**
21110
- * One entry of a `git status --porcelain -z` listing.
21111
- *
21112
- * @public
21113
- */
21114
- var StatusEntry = class extends Schema.Class("StatusEntry")({
21115
- /** The index-side status code (first porcelain column). */
21116
- x: porcelainCode,
21117
- /** The working-tree-side status code (second porcelain column). */
21118
- y: porcelainCode,
21119
- /** The entry's path — for a rename or copy, the NEW path. */
21120
- path: Schema.String,
21121
- /** The original path; present only on rename/copy entries. */
21122
- origPath: Schema.optionalKey(Schema.String)
21123
- }) {};
21124
- /**
21125
- * Parses `git log -1 --format=%H%x00%G?%x00%B` output: exactly two NUL
21126
- * separators, everything after the second is the raw message, untrimmed.
21127
- * Only ever called on the successful output of this package's own format
21128
- * string, so the separators are guaranteed present.
21129
- */
21130
- const parseCommitInfo = (output) => {
21131
- const first = output.indexOf("\0");
21132
- const second = output.indexOf("\0", first + 1);
21133
- return CommitInfo.make({
21134
- sha: output.slice(0, first),
21135
- signatureStatus: output.slice(first + 1, second),
21136
- message: output.slice(second + 1)
21137
22557
  });
21138
- };
21139
- /**
21140
- * Parses `git status --porcelain -z` output: each entry is `XY <path>`, and a
21141
- * rename/copy entry appends the ORIGINAL path as one extra NUL token AFTER
21142
- * the new path — the opposite order from `diff --name-status`.
21143
- */
21144
- const parseStatus = (output) => {
21145
- const tokens = output.split("\0");
21146
- const entries = [];
21147
- let index = 0;
21148
- while (index < tokens.length) {
21149
- const token = tokens[index] ?? "";
21150
- if (token === "") {
21151
- index += 1;
21152
- continue;
22558
+ const submoduleStatus = Effect.fn("Git.submoduleStatus")(function* (cwd, options) {
22559
+ yield* Effect.annotateCurrentSpan({
22560
+ cwd,
22561
+ recursive: options?.recursive ?? false
22562
+ });
22563
+ const classified = yield* runFor(GitCommand.submoduleStatus(options?.paths ?? [], options?.recursive ?? false), cwd, "generic");
22564
+ switch (classified._tag) {
22565
+ case "success": return parseSubmoduleStatus(classified.output);
22566
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22567
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22568
+ ref: "submodule status",
22569
+ cwd
22570
+ }));
22571
+ case "failure": return yield* Effect.fail(classified.error);
22572
+ default: return yield* Effect.die(`Git.submoduleStatus: unexpected classification "${classified._tag}"`);
21153
22573
  }
21154
- const x = token.charAt(0);
21155
- const y = token.charAt(1);
21156
- const path = token.slice(3);
21157
- if (x === "R" || x === "C" || y === "R" || y === "C") {
21158
- entries.push(StatusEntry.make({
21159
- x,
21160
- y,
21161
- path,
21162
- origPath: tokens[index + 1] ?? ""
22574
+ });
22575
+ const submoduleInit = Effect.fn("Git.submoduleInit")(function* (cwd, options) {
22576
+ yield* Effect.annotateCurrentSpan({ cwd });
22577
+ const classified = yield* runFor(GitCommand.submoduleInit(options?.paths ?? []), cwd, "generic");
22578
+ switch (classified._tag) {
22579
+ case "success": return;
22580
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22581
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22582
+ ref: "submodule init",
22583
+ cwd
21163
22584
  }));
21164
- index += 2;
21165
- } else {
21166
- entries.push(StatusEntry.make({
21167
- x,
21168
- y,
21169
- path
22585
+ case "failure": return yield* Effect.fail(classified.error);
22586
+ default: return yield* Effect.die(`Git.submoduleInit: unexpected classification "${classified._tag}"`);
22587
+ }
22588
+ });
22589
+ const submoduleDeinit = Effect.fn("Git.submoduleDeinit")(function* (cwd, options) {
22590
+ const paths = options.paths ?? [];
22591
+ const all = options.all ?? false;
22592
+ yield* Effect.annotateCurrentSpan({
22593
+ cwd,
22594
+ all,
22595
+ count: paths.length
22596
+ });
22597
+ if (!all && paths.length === 0) return yield* Effect.fail(new GitCommandError({
22598
+ kind: "refused",
22599
+ args: ["submodule", "deinit"],
22600
+ cwd,
22601
+ stderr: "",
22602
+ detail: "refused: submoduleDeinit needs either paths or all: true"
22603
+ }));
22604
+ const classified = yield* runFor(GitCommand.submoduleDeinit(paths, all, options.force ?? false), cwd, "generic");
22605
+ switch (classified._tag) {
22606
+ case "success": return;
22607
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22608
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22609
+ ref: "submodule deinit",
22610
+ cwd
21170
22611
  }));
21171
- index += 1;
22612
+ case "failure": return yield* Effect.fail(classified.error);
22613
+ default: return yield* Effect.die(`Git.submoduleDeinit: unexpected classification "${classified._tag}"`);
21172
22614
  }
21173
- }
21174
- return entries;
21175
- };
21176
- /**
21177
- * Refuse a caller-supplied ref or range that git would parse as an option.
21178
- *
21179
- * Refs are caller-controlled and land in git's argv as positional entries; a
21180
- * value beginning with `-` is read as a flag instead — `checkout("-b")` would
21181
- * CREATE a branch. A bare `--` separator is not a safe fix for every command
21182
- * (it switches `checkout` into pathspec mode), so option-like values are
21183
- * refused outright, before any spawn, as a typed {@link GitCommandError}.
21184
- * `show`'s `path` needs no guard: it is fused after the ref into one
21185
- * `ref:path` token, which cannot begin with `-` unless the ref does.
21186
- */
21187
- const rejectOptionLikeRefs = (cwd, refs) => {
21188
- const offending = refs.find((ref) => ref.startsWith("-"));
21189
- return offending === void 0 ? Effect.void : Effect.fail(new GitCommandError({
21190
- kind: "refused",
21191
- args: [offending],
21192
- cwd,
21193
- stderr: "",
21194
- detail: `refused a ref argument git would parse as an option: ${JSON.stringify(offending)}`
21195
- }));
21196
- };
21197
- /** Builds the `Git.Service` shape over an already-resolved `ChildProcessSpawner`. */
21198
- const make = (spawner) => {
21199
- const runFor = (command, cwd, kind) => runClassified(command, cwd, kind).pipe(Effect.provideService(ChildProcessSpawner.ChildProcessSpawner, spawner));
21200
- const show = Effect.fn("Git.show")(function* (cwd, ref, path) {
22615
+ });
22616
+ const submoduleSync = Effect.fn("Git.submoduleSync")(function* (cwd, options) {
21201
22617
  yield* Effect.annotateCurrentSpan({
21202
22618
  cwd,
21203
- ref,
21204
- path
22619
+ recursive: options?.recursive ?? false
21205
22620
  });
21206
- yield* rejectOptionLikeRefs(cwd, [ref]);
21207
- const command = ChildProcess.setCwd(GitCommand.show(ref, path), cwd);
21208
- const classified = yield* runFor(command, cwd, "show");
22621
+ const classified = yield* runFor(GitCommand.submoduleSync(options?.paths ?? [], options?.recursive ?? false), cwd, "generic");
21209
22622
  switch (classified._tag) {
21210
- case "success": return Option.some(classified.output);
21211
- case "absent": return Option.none();
22623
+ case "success": return;
21212
22624
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21213
22625
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21214
- ref,
22626
+ ref: "submodule sync",
21215
22627
  cwd
21216
22628
  }));
21217
22629
  case "failure": return yield* Effect.fail(classified.error);
21218
- default: return yield* Effect.die(`Git.show: unexpected classification "${classified._tag}"`);
22630
+ default: return yield* Effect.die(`Git.submoduleSync: unexpected classification "${classified._tag}"`);
21219
22631
  }
21220
22632
  });
21221
- const lsTree = Effect.fn("Git.lsTree")(function* (cwd, ref, options) {
22633
+ const submoduleSetUrl = Effect.fn("Git.submoduleSetUrl")(function* (cwd, path, url) {
21222
22634
  yield* Effect.annotateCurrentSpan({
21223
22635
  cwd,
21224
- ref
22636
+ path
21225
22637
  });
21226
- yield* rejectOptionLikeRefs(cwd, [ref]);
21227
- const command = ChildProcess.setCwd(GitCommand.lsTree(ref, options?.pathspec ?? []), cwd);
21228
- const classified = yield* runFor(command, cwd, "generic");
22638
+ const classified = yield* runFor(GitCommand.submoduleSetUrl(path, url), cwd, "generic");
21229
22639
  switch (classified._tag) {
21230
- case "success": return parseLsTree(classified.output);
22640
+ case "success": return;
21231
22641
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21232
22642
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21233
- ref,
22643
+ ref: path,
21234
22644
  cwd
21235
22645
  }));
21236
22646
  case "failure": return yield* Effect.fail(classified.error);
21237
- default: return yield* Effect.die(`Git.lsTree: unexpected classification "${classified._tag}"`);
22647
+ default: return yield* Effect.die(`Git.submoduleSetUrl: unexpected classification "${classified._tag}"`);
21238
22648
  }
21239
22649
  });
21240
- const refExists = Effect.fn("Git.refExists")(function* (cwd, ref) {
22650
+ const submoduleSetBranch = Effect.fn("Git.submoduleSetBranch")(function* (cwd, path, options) {
22651
+ const branch = options?.branch;
21241
22652
  yield* Effect.annotateCurrentSpan({
21242
22653
  cwd,
21243
- ref
22654
+ path,
22655
+ branch: branch ?? "(default)"
21244
22656
  });
21245
- yield* rejectOptionLikeRefs(cwd, [ref]);
21246
- const command = ChildProcess.setCwd(GitCommand.refExists(ref), cwd);
21247
- const classified = yield* runFor(command, cwd, "refExists");
22657
+ if (branch !== void 0) yield* rejectOptionLikeRefs(cwd, [branch]);
22658
+ const classified = yield* runFor(GitCommand.submoduleSetBranch(path, branch), cwd, "generic");
22659
+ switch (classified._tag) {
22660
+ case "success": return;
22661
+ case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22662
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22663
+ ref: branch ?? path,
22664
+ cwd
22665
+ }));
22666
+ case "failure": return yield* Effect.fail(classified.error);
22667
+ default: return yield* Effect.die(`Git.submoduleSetBranch: unexpected classification "${classified._tag}"`);
22668
+ }
22669
+ });
22670
+ const submoduleAbsorbgitdirs = Effect.fn("Git.submoduleAbsorbgitdirs")(function* (cwd, options) {
22671
+ yield* Effect.annotateCurrentSpan({ cwd });
22672
+ const classified = yield* runFor(GitCommand.submoduleAbsorbgitdirs(options?.paths ?? []), cwd, "generic");
21248
22673
  switch (classified._tag) {
21249
- case "success": return true;
21250
- case "refMissing": return false;
21251
- case "unknownRef": return false;
22674
+ case "success": return;
21252
22675
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
22676
+ case "unknownRef": return yield* Effect.fail(new UnknownRefError({
22677
+ ref: "submodule absorbgitdirs",
22678
+ cwd
22679
+ }));
21253
22680
  case "failure": return yield* Effect.fail(classified.error);
21254
- default: return yield* Effect.die(`Git.refExists: unexpected classification "${classified._tag}"`);
22681
+ default: return yield* Effect.die(`Git.submoduleAbsorbgitdirs: unexpected classification "${classified._tag}"`);
21255
22682
  }
21256
22683
  });
21257
- const mergeBase = Effect.fn("Git.mergeBase")(function* (cwd, a, b) {
22684
+ const submoduleForeach = Effect.fn("Git.submoduleForeach")(function* (cwd, command, options) {
21258
22685
  yield* Effect.annotateCurrentSpan({
21259
22686
  cwd,
21260
- a,
21261
- b
22687
+ recursive: options?.recursive ?? false
21262
22688
  });
21263
- yield* rejectOptionLikeRefs(cwd, [a, b]);
21264
- const command = ChildProcess.setCwd(GitCommand.mergeBase(a, b), cwd);
21265
- const classified = yield* runFor(command, cwd, "generic");
22689
+ yield* rejectOptionLikeRefs(cwd, [command]);
22690
+ const classified = yield* runFor(GitCommand.submoduleForeach(command, options?.recursive ?? false), cwd, "generic");
21266
22691
  switch (classified._tag) {
21267
- case "success": return classified.output.trim();
22692
+ case "success": return classified.output;
21268
22693
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21269
22694
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21270
- ref: `${a}...${b}`,
22695
+ ref: "submodule foreach",
21271
22696
  cwd
21272
22697
  }));
21273
22698
  case "failure": return yield* Effect.fail(classified.error);
21274
- default: return yield* Effect.die(`Git.mergeBase: unexpected classification "${classified._tag}"`);
22699
+ default: return yield* Effect.die(`Git.submoduleForeach: unexpected classification "${classified._tag}"`);
21275
22700
  }
21276
22701
  });
21277
- const changedFiles = Effect.fn("Git.changedFiles")(function* (cwd, options) {
21278
- const relative = options.relative ?? false;
21279
- yield* Effect.annotateCurrentSpan({
21280
- cwd,
21281
- base: options.base,
21282
- head: options.head,
21283
- relative
21284
- });
21285
- yield* rejectOptionLikeRefs(cwd, [options.base, options.head]);
21286
- const command = ChildProcess.setCwd(GitCommand.changedFiles(options.base, options.head, relative), cwd);
21287
- const classified = yield* runFor(command, cwd, "generic");
22702
+ const runVoid = (method, invocation, cwd, refLabel) => Effect.gen(function* () {
22703
+ const classified = yield* runFor(invocation, cwd, "generic");
21288
22704
  switch (classified._tag) {
21289
- case "success": return parseNulSeparated(classified.output);
22705
+ case "success": return;
21290
22706
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21291
22707
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21292
- ref: `${options.base}...${options.head}`,
22708
+ ref: refLabel,
21293
22709
  cwd
21294
22710
  }));
21295
22711
  case "failure": return yield* Effect.fail(classified.error);
21296
- default: return yield* Effect.die(`Git.changedFiles: unexpected classification "${classified._tag}"`);
22712
+ default: return yield* Effect.die(`${method}: unexpected classification "${classified._tag}"`);
21297
22713
  }
21298
22714
  });
21299
- const collectPaths = (method, command, cwd) => Effect.gen(function* () {
21300
- const classified = yield* runFor(command, cwd, "generic");
22715
+ const runParsed = (method, invocation, cwd, refLabel, kind, parse, absent) => Effect.gen(function* () {
22716
+ const classified = yield* runFor(invocation, cwd, kind);
21301
22717
  switch (classified._tag) {
21302
- case "success": return parseNulSeparated(classified.output);
22718
+ case "success": return parse(classified.output);
22719
+ case "absent":
22720
+ if (absent !== void 0) return absent();
22721
+ return yield* Effect.die(`${method}: unexpected classification "absent"`);
21303
22722
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21304
22723
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21305
- ref: "working tree",
22724
+ ref: refLabel,
21306
22725
  cwd
21307
22726
  }));
21308
22727
  case "failure": return yield* Effect.fail(classified.error);
21309
22728
  default: return yield* Effect.die(`${method}: unexpected classification "${classified._tag}"`);
21310
22729
  }
21311
22730
  });
21312
- const unstagedChanges = Effect.fn("Git.unstagedChanges")(function* (cwd, options) {
21313
- const relative = options?.relative ?? false;
21314
- yield* Effect.annotateCurrentSpan({
21315
- cwd,
21316
- relative
21317
- });
21318
- return yield* collectPaths("Git.unstagedChanges", ChildProcess.setCwd(GitCommand.unstagedChanges(relative), cwd), cwd);
21319
- });
21320
- const stagedChanges = Effect.fn("Git.stagedChanges")(function* (cwd, options) {
21321
- const relative = options?.relative ?? false;
21322
- yield* Effect.annotateCurrentSpan({
21323
- cwd,
21324
- relative
21325
- });
21326
- return yield* collectPaths("Git.stagedChanges", ChildProcess.setCwd(GitCommand.stagedChanges(relative), cwd), cwd);
21327
- });
21328
- const untrackedFiles = Effect.fn("Git.untrackedFiles")(function* (cwd, options) {
21329
- const relative = options?.relative ?? false;
22731
+ const lsRemote = Effect.fn("Git.lsRemote")(function* (cwd, remote, options) {
21330
22732
  yield* Effect.annotateCurrentSpan({
21331
22733
  cwd,
21332
- relative
22734
+ heads: options?.heads ?? false,
22735
+ tags: options?.tags ?? false,
22736
+ patterns: (options?.patterns ?? []).length
21333
22737
  });
21334
- return yield* collectPaths("Git.untrackedFiles", ChildProcess.setCwd(GitCommand.untrackedFiles(relative), cwd), cwd);
22738
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.patterns ?? []]);
22739
+ return yield* runParsed("Git.lsRemote", GitCommand.lsRemote(remote, options?.heads ?? false, options?.tags ?? false, options?.patterns ?? []), cwd, "ls-remote", "generic", parseLsRemote);
21335
22740
  });
21336
- const workingChanges = Effect.fn("Git.workingChanges")(function* (cwd, options) {
22741
+ const remoteAdd = Effect.fn("Git.remoteAdd")(function* (cwd, name, url) {
21337
22742
  yield* Effect.annotateCurrentSpan({
21338
22743
  cwd,
21339
- relative: options?.relative ?? false
22744
+ name
21340
22745
  });
21341
- const unstaged = yield* unstagedChanges(cwd, options);
21342
- const staged = yield* stagedChanges(cwd, options);
21343
- const untracked = yield* untrackedFiles(cwd, options);
21344
- return [.../* @__PURE__ */ new Set([
21345
- ...unstaged,
21346
- ...staged,
21347
- ...untracked
21348
- ])];
22746
+ yield* rejectOptionLikeRefs(cwd, [name, url]);
22747
+ return yield* runVoid("Git.remoteAdd", GitCommand.remoteAdd(name, url), cwd, name);
21349
22748
  });
21350
- const nameStatus = Effect.fn("Git.nameStatus")(function* (cwd, options) {
21351
- const relative = options.relative ?? false;
22749
+ const remoteRemove = Effect.fn("Git.remoteRemove")(function* (cwd, name) {
21352
22750
  yield* Effect.annotateCurrentSpan({
21353
22751
  cwd,
21354
- base: options.base,
21355
- head: options.head ?? "(working tree)",
21356
- relative
22752
+ name
21357
22753
  });
21358
- yield* rejectOptionLikeRefs(cwd, options.head === void 0 ? [options.base] : [options.base, options.head]);
21359
- const command = ChildProcess.setCwd(GitCommand.nameStatus(options.base, options.head, relative), cwd);
21360
- const classified = yield* runFor(command, cwd, "generic");
21361
- switch (classified._tag) {
21362
- case "success": return parseNameStatus(classified.output);
21363
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21364
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21365
- ref: options.head === void 0 ? options.base : `${options.base}...${options.head}`,
21366
- cwd
21367
- }));
21368
- case "failure": return yield* Effect.fail(classified.error);
21369
- default: return yield* Effect.die(`Git.nameStatus: unexpected classification "${classified._tag}"`);
21370
- }
22754
+ yield* rejectOptionLikeRefs(cwd, [name]);
22755
+ return yield* runVoid("Git.remoteRemove", GitCommand.remoteRemove(name), cwd, name);
21371
22756
  });
21372
- const revParse = Effect.fn("Git.revParse")(function* (cwd, ref) {
22757
+ const remoteSetUrl = Effect.fn("Git.remoteSetUrl")(function* (cwd, name, url) {
21373
22758
  yield* Effect.annotateCurrentSpan({
21374
22759
  cwd,
21375
- ref
22760
+ name
21376
22761
  });
21377
- yield* rejectOptionLikeRefs(cwd, [ref]);
21378
- const command = ChildProcess.setCwd(GitCommand.revParse(ref), cwd);
21379
- const classified = yield* runFor(command, cwd, "generic");
21380
- switch (classified._tag) {
21381
- case "success": return classified.output.trim();
21382
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21383
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21384
- ref,
21385
- cwd
21386
- }));
21387
- case "failure": return yield* Effect.fail(classified.error);
21388
- default: return yield* Effect.die(`Git.revParse: unexpected classification "${classified._tag}"`);
21389
- }
22762
+ yield* rejectOptionLikeRefs(cwd, [name, url]);
22763
+ return yield* runVoid("Git.remoteSetUrl", GitCommand.remoteSetUrl(name, url), cwd, name);
21390
22764
  });
21391
- const checkout = Effect.fn("Git.checkout")(function* (cwd, ref, options) {
21392
- const detach = options?.detach ?? false;
22765
+ const stashPush = Effect.fn("Git.stashPush")(function* (cwd, options) {
21393
22766
  yield* Effect.annotateCurrentSpan({
21394
22767
  cwd,
21395
- ref,
21396
- detach
22768
+ includeUntracked: options?.includeUntracked ?? false
21397
22769
  });
21398
- yield* rejectOptionLikeRefs(cwd, [ref]);
21399
- const command = ChildProcess.setCwd(GitCommand.checkout(ref, detach), cwd);
21400
- const classified = yield* runFor(command, cwd, "generic");
21401
- switch (classified._tag) {
21402
- case "success": return;
21403
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21404
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21405
- ref,
21406
- cwd
21407
- }));
21408
- case "failure": return yield* Effect.fail(classified.error);
21409
- default: return yield* Effect.die(`Git.checkout: unexpected classification "${classified._tag}"`);
21410
- }
22770
+ return yield* runVoid("Git.stashPush", GitCommand.stashPush(options?.message, options?.includeUntracked ?? false, options?.paths ?? []), cwd, "stash");
21411
22771
  });
21412
- const fetch = Effect.fn("Git.fetch")(function* (cwd, options) {
21413
- const remote = options.remote ?? "origin";
21414
- const tag = options.tag ?? false;
22772
+ const stashRestore = (method, invocation) => Effect.fn(method)(function* (cwd, options) {
21415
22773
  yield* Effect.annotateCurrentSpan({
21416
22774
  cwd,
21417
- remote,
21418
- ref: options.ref,
21419
- tag
22775
+ index: options?.index ?? 0
21420
22776
  });
21421
- yield* rejectOptionLikeRefs(cwd, [remote, options.ref]);
21422
- const command = ChildProcess.setCwd(GitCommand.fetch(remote, options.ref, options.depth, tag), cwd);
21423
- const classified = yield* runFor(command, cwd, "generic");
22777
+ yield* rejectNonNaturalNumber(cwd, "a stash index", options?.index);
22778
+ const classified = yield* runFor(invocation(options?.index), cwd, "merge");
21424
22779
  switch (classified._tag) {
21425
22780
  case "success": return;
22781
+ case "dirtyWorktree": return yield* Effect.fail(new DirtyWorktreeError({ cwd }));
22782
+ case "mergeConflict": return yield* Effect.fail(new MergeConflictError({ cwd }));
21426
22783
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21427
22784
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21428
- ref: options.ref,
22785
+ ref: "stash",
21429
22786
  cwd
21430
22787
  }));
21431
22788
  case "failure": return yield* Effect.fail(classified.error);
21432
- default: return yield* Effect.die(`Git.fetch: unexpected classification "${classified._tag}"`);
22789
+ default: return yield* Effect.die(`${method}: unexpected classification "${classified._tag}"`);
21433
22790
  }
21434
22791
  });
21435
22792
  return {
@@ -21442,254 +22799,235 @@ const make = (spawner) => {
21442
22799
  revParse,
21443
22800
  checkout,
21444
22801
  fetch,
21445
- fetchAny: Effect.fn("Git.fetchAny")(function* (cwd, options) {
21446
- const remote = options.remote ?? "origin";
22802
+ fetchAny,
22803
+ fetchUnshallow,
22804
+ isShallow,
22805
+ reset,
22806
+ clean,
22807
+ restore,
22808
+ branchCreate,
22809
+ branchDelete,
22810
+ submoduleUpdate,
22811
+ submoduleAdd,
22812
+ submoduleStatus,
22813
+ submoduleInit,
22814
+ submoduleDeinit,
22815
+ submoduleSync,
22816
+ submoduleSetUrl,
22817
+ submoduleSetBranch,
22818
+ submoduleAbsorbgitdirs,
22819
+ submoduleForeach,
22820
+ sparseCheckoutSet,
22821
+ configSet,
22822
+ add,
22823
+ nameStatus,
22824
+ unstagedChanges,
22825
+ stagedChanges,
22826
+ untrackedFiles,
22827
+ defaultBranch,
22828
+ currentBranch,
22829
+ repoRoot,
22830
+ configGet,
22831
+ remoteUrl,
22832
+ commitInfo,
22833
+ status,
22834
+ lsRemote,
22835
+ remoteAdd,
22836
+ remoteRemove,
22837
+ remoteSetUrl,
22838
+ stashPush,
22839
+ stashPop: stashRestore("Git.stashPop", GitCommand.stashPop),
22840
+ stashApply: stashRestore("Git.stashApply", GitCommand.stashApply),
22841
+ stashDrop: Effect.fn("Git.stashDrop")(function* (cwd, options) {
21447
22842
  yield* Effect.annotateCurrentSpan({
21448
22843
  cwd,
21449
- remote,
21450
- ref: options.ref
22844
+ index: options?.index ?? 0
21451
22845
  });
21452
- return yield* fetch(cwd, {
21453
- ...options,
21454
- tag: true
21455
- }).pipe(Effect.catchTag(["UnknownRefError", "GitCommandError"], (error) => error._tag === "GitCommandError" && error.kind === "refused" ? Effect.fail(error) : fetch(cwd, options)));
22846
+ yield* rejectNonNaturalNumber(cwd, "a stash index", options?.index);
22847
+ return yield* runVoid("Git.stashDrop", GitCommand.stashDrop(options?.index), cwd, "stash");
21456
22848
  }),
21457
- submoduleUpdate: Effect.fn("Git.submoduleUpdate")(function* (cwd, options) {
21458
- const init = options?.init ?? false;
22849
+ stashList: Effect.fn("Git.stashList")(function* (cwd) {
22850
+ yield* Effect.annotateCurrentSpan({ cwd });
22851
+ return yield* runParsed("Git.stashList", GitCommand.stashList(), cwd, "stash", "generic", parseStashList);
22852
+ }),
22853
+ branchList: Effect.fn("Git.branchList")(function* (cwd, options) {
21459
22854
  yield* Effect.annotateCurrentSpan({
21460
22855
  cwd,
21461
- init
22856
+ remotes: options?.remotes ?? false,
22857
+ all: options?.all ?? false
21462
22858
  });
21463
- const command = ChildProcess.setCwd(GitCommand.submoduleUpdate(init, options?.depth, options?.paths ?? []), cwd);
21464
- const classified = yield* runFor(command, cwd, "generic");
21465
- switch (classified._tag) {
21466
- case "success": return;
21467
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21468
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21469
- ref: "submodule update",
21470
- cwd
21471
- }));
21472
- case "failure": return yield* Effect.fail(classified.error);
21473
- default: return yield* Effect.die(`Git.submoduleUpdate: unexpected classification "${classified._tag}"`);
21474
- }
22859
+ return yield* runParsed("Git.branchList", GitCommand.branchList(options?.remotes ?? false, options?.all ?? false), cwd, "branches", "generic", parseBranchList);
21475
22860
  }),
21476
- submoduleAdd: Effect.fn("Git.submoduleAdd")(function* (cwd, options) {
22861
+ tagCreate: Effect.fn("Git.tagCreate")(function* (cwd, name, options) {
21477
22862
  yield* Effect.annotateCurrentSpan({
21478
22863
  cwd,
21479
- url: options.url,
21480
- path: options.path
22864
+ name,
22865
+ ref: options?.ref ?? "HEAD",
22866
+ force: options?.force ?? false
21481
22867
  });
21482
- const command = ChildProcess.setCwd(GitCommand.submoduleAdd(options.url, options.path, options.depth), cwd);
21483
- const classified = yield* runFor(command, cwd, "generic");
21484
- switch (classified._tag) {
21485
- case "success": return;
21486
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21487
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21488
- ref: options.url,
21489
- cwd
21490
- }));
21491
- case "failure": return yield* Effect.fail(classified.error);
21492
- default: return yield* Effect.die(`Git.submoduleAdd: unexpected classification "${classified._tag}"`);
21493
- }
22868
+ yield* rejectOptionLikeRefs(cwd, [name, ...options?.ref !== void 0 ? [options.ref] : []]);
22869
+ return yield* runVoid("Git.tagCreate", GitCommand.tagCreate(name, options?.ref, options?.message, options?.force ?? false), cwd, options?.ref ?? name);
21494
22870
  }),
21495
- sparseCheckoutSet: Effect.fn("Git.sparseCheckoutSet")(function* (cwd, patterns, options) {
22871
+ tagDelete: Effect.fn("Git.tagDelete")(function* (cwd, name) {
21496
22872
  yield* Effect.annotateCurrentSpan({
21497
22873
  cwd,
21498
- cone: options.cone
22874
+ name
21499
22875
  });
21500
- yield* rejectOptionLikeRefs(cwd, patterns);
21501
- const command = ChildProcess.setCwd(GitCommand.sparseCheckoutSet(patterns, options.cone), cwd);
21502
- const classified = yield* runFor(command, cwd, "generic");
21503
- switch (classified._tag) {
21504
- case "success": return;
21505
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21506
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21507
- ref: "sparse-checkout",
21508
- cwd
21509
- }));
21510
- case "failure": return yield* Effect.fail(classified.error);
21511
- default: return yield* Effect.die(`Git.sparseCheckoutSet: unexpected classification "${classified._tag}"`);
21512
- }
22876
+ yield* rejectOptionLikeRefs(cwd, [name]);
22877
+ return yield* runVoid("Git.tagDelete", GitCommand.tagDelete(name), cwd, name);
22878
+ }),
22879
+ tagList: Effect.fn("Git.tagList")(function* (cwd, options) {
22880
+ yield* Effect.annotateCurrentSpan({ cwd });
22881
+ yield* rejectOptionLikeRefs(cwd, options?.pattern !== void 0 ? [options.pattern] : []);
22882
+ return yield* runParsed("Git.tagList", GitCommand.tagList(options?.pattern), cwd, "tags", "generic", (output) => output.split("\n").filter((line) => line.length > 0));
21513
22883
  }),
21514
- configSet: Effect.fn("Git.configSet")(function* (cwd, key, value, options) {
22884
+ forEachRef: Effect.fn("Git.forEachRef")(function* (cwd, options) {
21515
22885
  yield* Effect.annotateCurrentSpan({
21516
22886
  cwd,
21517
- key,
21518
- file: options?.file ?? "(repository config)"
22887
+ patterns: (options?.patterns ?? []).length
21519
22888
  });
21520
- yield* rejectOptionLikeRefs(cwd, [
21521
- key,
21522
- value,
21523
- ...options?.file !== void 0 ? [options.file] : []
21524
- ]);
21525
- const command = ChildProcess.setCwd(GitCommand.configSet(key, value, options?.file), cwd);
21526
- const classified = yield* runFor(command, cwd, "generic");
21527
- switch (classified._tag) {
21528
- case "success": return;
21529
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21530
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21531
- ref: key,
21532
- cwd
21533
- }));
21534
- case "failure": return yield* Effect.fail(classified.error);
21535
- default: return yield* Effect.die(`Git.configSet: unexpected classification "${classified._tag}"`);
21536
- }
22889
+ yield* rejectOptionLikeRefs(cwd, options?.patterns ?? []);
22890
+ return yield* runParsed("Git.forEachRef", GitCommand.forEachRef(options?.patterns ?? []), cwd, "for-each-ref", "generic", parseForEachRef);
21537
22891
  }),
21538
- add: Effect.fn("Git.add")(function* (cwd, paths) {
22892
+ revList: Effect.fn("Git.revList")(function* (cwd, ref, options) {
21539
22893
  yield* Effect.annotateCurrentSpan({
21540
22894
  cwd,
21541
- count: paths.length
22895
+ ref,
22896
+ firstParent: options?.firstParent ?? false
21542
22897
  });
21543
- const command = ChildProcess.setCwd(GitCommand.add(paths), cwd);
21544
- const classified = yield* runFor(command, cwd, "generic");
22898
+ yield* rejectOptionLikeRefs(cwd, [ref]);
22899
+ yield* rejectNonNaturalNumber(cwd, "a rev-list limit", options?.limit);
22900
+ 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));
22901
+ }),
22902
+ commit: Effect.fn("Git.commit")(function* (cwd, message, options) {
22903
+ yield* Effect.annotateCurrentSpan({
22904
+ cwd,
22905
+ amend: options?.amend ?? false
22906
+ });
22907
+ return yield* runVoid("Git.commit", GitCommand.commit(message, options?.all ?? false, options?.allowEmpty ?? false, options?.amend ?? false, options?.author), cwd, "HEAD");
22908
+ }),
22909
+ push: Effect.fn("Git.push")(function* (cwd, options) {
22910
+ const remote = options?.remote ?? "origin";
22911
+ yield* Effect.annotateCurrentSpan({
22912
+ cwd,
22913
+ refspec: options?.refspec ?? "(current branch)",
22914
+ forceWithLease: options?.forceWithLease ?? false
22915
+ });
22916
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.refspec !== void 0 ? [options.refspec] : []]);
22917
+ const classified = yield* runFor(GitCommand.push(remote, options?.refspec, options?.force ?? false, options?.forceWithLease ?? false, options?.tags ?? false, options?.setUpstream ?? false), cwd, "push");
21545
22918
  switch (classified._tag) {
21546
22919
  case "success": return;
22920
+ case "nonFastForward": return yield* Effect.fail(new NonFastForwardError({
22921
+ cwd,
22922
+ ...options?.refspec !== void 0 ? { refspec: options.refspec } : {}
22923
+ }));
21547
22924
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21548
22925
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21549
- ref: "working tree",
22926
+ ref: options?.refspec ?? "HEAD",
21550
22927
  cwd
21551
22928
  }));
21552
22929
  case "failure": return yield* Effect.fail(classified.error);
21553
- default: return yield* Effect.die(`Git.add: unexpected classification "${classified._tag}"`);
22930
+ default: return yield* Effect.die(`Git.push: unexpected classification "${classified._tag}"`);
21554
22931
  }
21555
22932
  }),
21556
- nameStatus,
21557
- unstagedChanges,
21558
- stagedChanges,
21559
- untrackedFiles,
21560
- defaultBranch: Effect.fn("Git.defaultBranch")(function* (cwd, options) {
22933
+ pull: Effect.fn("Git.pull")(function* (cwd, options) {
21561
22934
  const remote = options?.remote ?? "origin";
21562
22935
  yield* Effect.annotateCurrentSpan({
21563
22936
  cwd,
21564
- remote
22937
+ ref: options?.ref ?? "(upstream)",
22938
+ rebase: options?.rebase ?? false
21565
22939
  });
21566
- yield* rejectOptionLikeRefs(cwd, [remote]);
21567
- const command = ChildProcess.setCwd(GitCommand.defaultBranch(remote), cwd);
21568
- const classified = yield* runFor(command, cwd, "quiet");
22940
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.ref !== void 0 ? [options.ref] : []]);
22941
+ const classified = yield* runFor(GitCommand.pull(remote, options?.ref, options?.rebase ?? false, options?.ffOnly ?? false), cwd, "merge");
21569
22942
  switch (classified._tag) {
21570
- case "success": {
21571
- const short = classified.output.trim();
21572
- const prefix = `${remote}/`;
21573
- return Option.some(short.startsWith(prefix) ? short.slice(prefix.length) : short);
21574
- }
21575
- case "absent": return Option.none();
22943
+ case "success": return;
22944
+ case "dirtyWorktree": return yield* Effect.fail(new DirtyWorktreeError({ cwd }));
22945
+ case "mergeConflict": return yield* Effect.fail(new MergeConflictError({ cwd }));
21576
22946
  case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21577
22947
  case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21578
- ref: `refs/remotes/${remote}/HEAD`,
22948
+ ref: options?.ref ?? "(upstream)",
21579
22949
  cwd
21580
22950
  }));
21581
22951
  case "failure": return yield* Effect.fail(classified.error);
21582
- default: return yield* Effect.die(`Git.defaultBranch: unexpected classification "${classified._tag}"`);
22952
+ default: return yield* Effect.die(`Git.pull: unexpected classification "${classified._tag}"`);
21583
22953
  }
21584
22954
  }),
21585
- currentBranch: Effect.fn("Git.currentBranch")(function* (cwd) {
21586
- yield* Effect.annotateCurrentSpan({ cwd });
21587
- const command = ChildProcess.setCwd(GitCommand.currentBranch(), cwd);
21588
- const classified = yield* runFor(command, cwd, "generic");
21589
- switch (classified._tag) {
21590
- case "success": {
21591
- const name = classified.output.trim();
21592
- return name === "HEAD" ? Option.none() : Option.some(name);
21593
- }
21594
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21595
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21596
- ref: "HEAD",
21597
- cwd
21598
- }));
21599
- case "failure": return yield* Effect.fail(classified.error);
21600
- default: return yield* Effect.die(`Git.currentBranch: unexpected classification "${classified._tag}"`);
21601
- }
22955
+ configList: Effect.fn("Git.configList")(function* (cwd, options) {
22956
+ yield* Effect.annotateCurrentSpan({
22957
+ cwd,
22958
+ file: options?.file ?? "(repository config)"
22959
+ });
22960
+ yield* rejectOptionLikeRefs(cwd, options?.file !== void 0 ? [options.file] : []);
22961
+ return yield* runParsed("Git.configList", GitCommand.configList(options?.file), cwd, "config", "generic", parseConfigList);
21602
22962
  }),
21603
- repoRoot: Effect.fn("Git.repoRoot")(function* (cwd) {
21604
- yield* Effect.annotateCurrentSpan({ cwd });
21605
- const command = ChildProcess.setCwd(GitCommand.repoRoot(), cwd);
21606
- const classified = yield* runFor(command, cwd, "generic");
21607
- switch (classified._tag) {
21608
- case "success": return classified.output.trim();
21609
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21610
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21611
- ref: "working tree",
21612
- cwd
21613
- }));
21614
- case "failure": return yield* Effect.fail(classified.error);
21615
- default: return yield* Effect.die(`Git.repoRoot: unexpected classification "${classified._tag}"`);
21616
- }
22963
+ configGetAll: Effect.fn("Git.configGetAll")(function* (cwd, key, options) {
22964
+ yield* Effect.annotateCurrentSpan({
22965
+ cwd,
22966
+ key,
22967
+ file: options?.file ?? "(repository config)"
22968
+ });
22969
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []]);
22970
+ return yield* runParsed("Git.configGetAll", GitCommand.configGetAll(key, options?.file), cwd, key, "quiet", parseNulSeparated, () => []);
21617
22971
  }),
21618
- configGet: Effect.fn("Git.configGet")(function* (cwd, key) {
22972
+ configUnset: Effect.fn("Git.configUnset")(function* (cwd, key, options) {
21619
22973
  yield* Effect.annotateCurrentSpan({
21620
22974
  cwd,
21621
- key
22975
+ key,
22976
+ file: options?.file ?? "(repository config)"
21622
22977
  });
21623
- yield* rejectOptionLikeRefs(cwd, [key]);
21624
- const command = ChildProcess.setCwd(GitCommand.configGet(key), cwd);
21625
- const classified = yield* runFor(command, cwd, "quiet");
21626
- switch (classified._tag) {
21627
- case "success": return Option.some(classified.output.trim());
21628
- case "absent": return Option.none();
21629
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21630
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21631
- ref: key,
21632
- cwd
21633
- }));
21634
- case "failure": return yield* Effect.fail(classified.error);
21635
- default: return yield* Effect.die(`Git.configGet: unexpected classification "${classified._tag}"`);
21636
- }
22978
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []]);
22979
+ return yield* runVoid("Git.configUnset", GitCommand.configUnset(key, options?.file, options?.all ?? false), cwd, key);
21637
22980
  }),
21638
- remoteUrl: Effect.fn("Git.remoteUrl")(function* (cwd, options) {
21639
- const remote = options?.remote ?? "origin";
22981
+ rm: Effect.fn("Git.rm")(function* (cwd, paths, options) {
21640
22982
  yield* Effect.annotateCurrentSpan({
21641
22983
  cwd,
21642
- remote
22984
+ count: paths.length,
22985
+ cached: options?.cached ?? false
21643
22986
  });
21644
- yield* rejectOptionLikeRefs(cwd, [remote]);
21645
- const command = ChildProcess.setCwd(GitCommand.remoteUrl(remote), cwd);
21646
- const classified = yield* runFor(command, cwd, "noSuchRemote");
21647
- switch (classified._tag) {
21648
- case "success": return Option.some(classified.output.trim());
21649
- case "absent": return Option.none();
21650
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21651
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21652
- ref: remote,
21653
- cwd
21654
- }));
21655
- case "failure": return yield* Effect.fail(classified.error);
21656
- default: return yield* Effect.die(`Git.remoteUrl: unexpected classification "${classified._tag}"`);
21657
- }
22987
+ return yield* runVoid("Git.rm", GitCommand.rm(paths, options?.cached ?? false, options?.recursive ?? false, options?.force ?? false), cwd, "working tree");
21658
22988
  }),
21659
- commitInfo: Effect.fn("Git.commitInfo")(function* (cwd, ref) {
21660
- const target = ref ?? "HEAD";
22989
+ mv: Effect.fn("Git.mv")(function* (cwd, source, destination, options) {
21661
22990
  yield* Effect.annotateCurrentSpan({
21662
22991
  cwd,
21663
- ref: target
22992
+ source,
22993
+ destination
21664
22994
  });
21665
- yield* rejectOptionLikeRefs(cwd, [target]);
21666
- const command = ChildProcess.setCwd(GitCommand.commitInfo(target), cwd);
21667
- const classified = yield* runFor(command, cwd, "generic");
21668
- switch (classified._tag) {
21669
- case "success": return parseCommitInfo(classified.output);
21670
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21671
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21672
- ref: target,
21673
- cwd
21674
- }));
21675
- case "failure": return yield* Effect.fail(classified.error);
21676
- default: return yield* Effect.die(`Git.commitInfo: unexpected classification "${classified._tag}"`);
21677
- }
22995
+ return yield* runVoid("Git.mv", GitCommand.mv(source, destination, options?.force ?? false), cwd, "working tree");
22996
+ }),
22997
+ checkIgnore: Effect.fn("Git.checkIgnore")(function* (cwd, paths) {
22998
+ yield* Effect.annotateCurrentSpan({
22999
+ cwd,
23000
+ count: paths.length
23001
+ });
23002
+ return yield* runParsed("Git.checkIgnore", GitCommand.checkIgnore(paths), cwd, "check-ignore", "quiet", parseNulSeparated, () => []);
21678
23003
  }),
21679
- status: Effect.fn("Git.status")(function* (cwd) {
23004
+ worktreeAdd: Effect.fn("Git.worktreeAdd")(function* (cwd, path, options) {
23005
+ yield* Effect.annotateCurrentSpan({
23006
+ cwd,
23007
+ path,
23008
+ ref: options?.ref ?? "(default)"
23009
+ });
23010
+ yield* rejectOptionLikeRefs(cwd, [path, ...options?.ref !== void 0 ? [options.ref] : []]);
23011
+ return yield* runVoid("Git.worktreeAdd", GitCommand.worktreeAdd(path, options?.ref, options?.detach ?? false, options?.force ?? false), cwd, options?.ref ?? path);
23012
+ }),
23013
+ worktreeList: Effect.fn("Git.worktreeList")(function* (cwd) {
21680
23014
  yield* Effect.annotateCurrentSpan({ cwd });
21681
- const command = ChildProcess.setCwd(GitCommand.status(), cwd);
21682
- const classified = yield* runFor(command, cwd, "generic");
21683
- switch (classified._tag) {
21684
- case "success": return parseStatus(classified.output);
21685
- case "notARepository": return yield* Effect.fail(new NotARepositoryError({ cwd }));
21686
- case "unknownRef": return yield* Effect.fail(new UnknownRefError({
21687
- ref: "working tree",
21688
- cwd
21689
- }));
21690
- case "failure": return yield* Effect.fail(classified.error);
21691
- default: return yield* Effect.die(`Git.status: unexpected classification "${classified._tag}"`);
21692
- }
23015
+ return yield* runParsed("Git.worktreeList", GitCommand.worktreeList(), cwd, "worktrees", "generic", parseWorktreeList);
23016
+ }),
23017
+ worktreeRemove: Effect.fn("Git.worktreeRemove")(function* (cwd, path, options) {
23018
+ yield* Effect.annotateCurrentSpan({
23019
+ cwd,
23020
+ path
23021
+ });
23022
+ yield* rejectOptionLikeRefs(cwd, [path]);
23023
+ return yield* runVoid("Git.worktreeRemove", GitCommand.worktreeRemove(path, options?.force ?? false), cwd, path);
23024
+ }),
23025
+ lsFiles: Effect.fn("Git.lsFiles")(function* (cwd, options) {
23026
+ yield* Effect.annotateCurrentSpan({
23027
+ cwd,
23028
+ patterns: (options?.pathspec ?? []).length
23029
+ });
23030
+ return yield* runParsed("Git.lsFiles", GitCommand.lsFiles(options?.pathspec ?? []), cwd, "index", "generic", parseLsFiles);
21693
23031
  })
21694
23032
  };
21695
23033
  };
@@ -21701,17 +23039,23 @@ const make = (spawner) => {
21701
23039
  const notStubbed = (method) => () => 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.`));
21702
23040
  /**
21703
23041
  * Typed git introspection over core's `ChildProcessSpawner`: read a
21704
- * repository's state at any ref without checking it out, plus the mutating
21705
- * tier (`checkout`, `fetch`, `fetchAny`, `submoduleUpdate`, `submoduleAdd`,
21706
- * `sparseCheckoutSet`, `configSet`, `add`) that changes it.
23042
+ * repository's state at any ref without checking it out (including the
23043
+ * network read `lsRemote` and the index read `lsFiles`), plus the mutating
23044
+ * tier checkout/fetch, the working-tree restore trio and stash, branches
23045
+ * and tags, remotes, worktrees, commit/push/pull, submodules,
23046
+ * sparse-checkout, config writes and staging — that changes it. Every
23047
+ * mutating method's TSDoc opens with the literal word `Mutating:`.
21707
23048
  *
21708
23049
  * @remarks
21709
23050
  * Every method takes `cwd` explicitly and classifies git's stderr/exit-code
21710
23051
  * taxonomy exactly once, in this module's private `classify` step — a
21711
23052
  * spawn-level `PlatformError` and `Cause.TimeoutError` never escape a `Git`
21712
23053
  * method; every failure surfaces as {@link GitCommandError},
21713
- * {@link NotARepositoryError}, or {@link UnknownRefError}, or degrades to
21714
- * the documented non-error (`Option.none`, `false`).
23054
+ * {@link NotARepositoryError}, {@link UnknownRefError}, or one of the three
23055
+ * consumer-branchable classifications ({@link NonFastForwardError} from
23056
+ * `push`; {@link MergeConflictError} and {@link DirtyWorktreeError} from the
23057
+ * merge-shaped `pull` / `stashPop` / `stashApply`), or degrades to the
23058
+ * documented non-error (`Option.none`, `false`, the empty array).
21715
23059
  *
21716
23060
  * Every method whose TSDoc opens "Mutating:" changes the working tree,
21717
23061
  * `HEAD`, the index, the repository config, the object database and
@@ -21720,6 +23064,12 @@ const notStubbed = (method) => () => Effect.die(/* @__PURE__ */ new Error(`Git.m
21720
23064
  * that — a caller running two mutating calls (or a mutating call alongside a
21721
23065
  * read) against one `cwd` at once owns the race.
21722
23066
  *
23067
+ * **Redaction policy (documented, not just convention).** Error values
23068
+ * persist only the constructor's REDACTED argv (see `GitCommandError.args`),
23069
+ * and span annotations carry stable identifiers only — `cwd`, refs, keys,
23070
+ * paths, remote names — never config values and never URLs, which can embed
23071
+ * userinfo. A new method must follow both halves before it ships.
23072
+ *
21723
23073
  * @public
21724
23074
  */
21725
23075
  var Git = class Git extends Context.Service()("@effected/git/Git") {
@@ -21734,7 +23084,7 @@ var Git = class Git extends Context.Service()("@effected/git/Git") {
21734
23084
  *
21735
23085
  * @remarks
21736
23086
  * Unlike `WorkspaceDiscovery.makeTest`, **no method here has an honest
21737
- * default** — the shape is twenty-six unrelated git operations, and a
23087
+ * default** — the shape is unrelated git operations, and a
21738
23088
  * fabricated answer for any of them (an empty tree, a made-up sha, a silent
21739
23089
  * no-op `checkout`) would leak into consumer logic as fact. So every
21740
23090
  * unstubbed method fails loudly as a defect
@@ -21773,8 +23123,23 @@ var Git = class Git extends Context.Service()("@effected/git/Git") {
21773
23123
  checkout: notStubbed("checkout"),
21774
23124
  fetch: notStubbed("fetch"),
21775
23125
  fetchAny: notStubbed("fetchAny"),
23126
+ fetchUnshallow: notStubbed("fetchUnshallow"),
23127
+ isShallow: notStubbed("isShallow"),
23128
+ reset: notStubbed("reset"),
23129
+ clean: notStubbed("clean"),
23130
+ restore: notStubbed("restore"),
23131
+ branchCreate: notStubbed("branchCreate"),
23132
+ branchDelete: notStubbed("branchDelete"),
21776
23133
  submoduleUpdate: notStubbed("submoduleUpdate"),
21777
23134
  submoduleAdd: notStubbed("submoduleAdd"),
23135
+ submoduleStatus: notStubbed("submoduleStatus"),
23136
+ submoduleInit: notStubbed("submoduleInit"),
23137
+ submoduleDeinit: notStubbed("submoduleDeinit"),
23138
+ submoduleSync: notStubbed("submoduleSync"),
23139
+ submoduleSetUrl: notStubbed("submoduleSetUrl"),
23140
+ submoduleSetBranch: notStubbed("submoduleSetBranch"),
23141
+ submoduleAbsorbgitdirs: notStubbed("submoduleAbsorbgitdirs"),
23142
+ submoduleForeach: notStubbed("submoduleForeach"),
21778
23143
  sparseCheckoutSet: notStubbed("sparseCheckoutSet"),
21779
23144
  configSet: notStubbed("configSet"),
21780
23145
  add: notStubbed("add"),
@@ -21789,6 +23154,34 @@ var Git = class Git extends Context.Service()("@effected/git/Git") {
21789
23154
  remoteUrl: notStubbed("remoteUrl"),
21790
23155
  commitInfo: notStubbed("commitInfo"),
21791
23156
  status: notStubbed("status"),
23157
+ lsRemote: notStubbed("lsRemote"),
23158
+ remoteAdd: notStubbed("remoteAdd"),
23159
+ remoteRemove: notStubbed("remoteRemove"),
23160
+ remoteSetUrl: notStubbed("remoteSetUrl"),
23161
+ stashPush: notStubbed("stashPush"),
23162
+ stashPop: notStubbed("stashPop"),
23163
+ stashApply: notStubbed("stashApply"),
23164
+ stashDrop: notStubbed("stashDrop"),
23165
+ stashList: notStubbed("stashList"),
23166
+ branchList: notStubbed("branchList"),
23167
+ tagCreate: notStubbed("tagCreate"),
23168
+ tagDelete: notStubbed("tagDelete"),
23169
+ tagList: notStubbed("tagList"),
23170
+ forEachRef: notStubbed("forEachRef"),
23171
+ revList: notStubbed("revList"),
23172
+ commit: notStubbed("commit"),
23173
+ push: notStubbed("push"),
23174
+ pull: notStubbed("pull"),
23175
+ configList: notStubbed("configList"),
23176
+ configGetAll: notStubbed("configGetAll"),
23177
+ configUnset: notStubbed("configUnset"),
23178
+ rm: notStubbed("rm"),
23179
+ mv: notStubbed("mv"),
23180
+ checkIgnore: notStubbed("checkIgnore"),
23181
+ worktreeAdd: notStubbed("worktreeAdd"),
23182
+ worktreeList: notStubbed("worktreeList"),
23183
+ worktreeRemove: notStubbed("worktreeRemove"),
23184
+ lsFiles: notStubbed("lsFiles"),
21792
23185
  ...overrides
21793
23186
  });
21794
23187
  /**
@@ -21818,7 +23211,7 @@ var Git = class Git extends Context.Service()("@effected/git/Git") {
21818
23211
  };
21819
23212
 
21820
23213
  //#endregion
21821
- //#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
23214
+ //#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
21822
23215
  /**
21823
23216
  * Which git refs to compare, and whether to fold in the working tree.
21824
23217
  *
@@ -22118,7 +23511,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
22118
23511
  }
22119
23512
 
22120
23513
  //#endregion
22121
- //#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
23514
+ //#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
22122
23515
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
22123
23516
  const inlineCatalogs = (manifest) => {
22124
23517
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -22184,7 +23577,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
22184
23577
  };
22185
23578
 
22186
23579
  //#endregion
22187
- //#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
23580
+ //#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
22188
23581
  /** Whether `value` is a non-null, non-array object. */
22189
23582
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
22190
23583
  /**
@@ -22386,8 +23779,12 @@ process.stdout.write("\\n" + JSON.stringify(payload) + "\\n", () => process.exit
22386
23779
  */
22387
23780
  const REPLAY_TIMEOUT = Duration.seconds(30);
22388
23781
  /**
22389
- * The subprocess protocol payload — the child's final stdout line, framed and
22390
- * parsed by `Run.jsonLine`. The envelope is strict (a payload without a usable
23782
+ * The subprocess protocol payload — a single JSON line near the end of the
23783
+ * child's stdout, framed and parsed by `Run.jsonLine`, which scans lines from
23784
+ * the end for the first that decodes (so a hook logging after the payload —
23785
+ * e.g. from `process.on("exit", ...)` — cannot displace it). The `ok`
23786
+ * discriminant is what keeps an accidental log line from satisfying the
23787
+ * envelope. The envelope is strict (a payload without a usable
22391
23788
  * `ok` discriminant is a mechanism failure, typed); the `config` slice inside a
22392
23789
  * success stays `Unknown` because a hook's returned *data* is tolerantly
22393
23790
  * threaded (`configOf`), never fatal.
@@ -22592,7 +23989,7 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends Context.Service(
22592
23989
  };
22593
23990
 
22594
23991
  //#endregion
22595
- //#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
23992
+ //#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
22596
23993
  /**
22597
23994
  * The four package managers this package understands.
22598
23995
  *
@@ -22921,7 +24318,7 @@ var PackageManagerDetector = class PackageManagerDetector extends Context.Servic
22921
24318
  };
22922
24319
 
22923
24320
  //#endregion
22924
- //#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
24321
+ //#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
22925
24322
  /**
22926
24323
  * Raised when the workspace's lockfile cannot be read off disk.
22927
24324
  *
@@ -23102,7 +24499,7 @@ var LockfileReader = class LockfileReader extends Context.Service()("@effected/w
23102
24499
  };
23103
24500
 
23104
24501
  //#endregion
23105
- //#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
24502
+ //#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
23106
24503
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
23107
24504
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
23108
24505
  /**
@@ -23262,7 +24659,7 @@ var PublishabilityDetector = class extends Context.Service()("@effected/workspac
23262
24659
  };
23263
24660
 
23264
24661
  //#endregion
23265
- //#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
24662
+ //#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
23266
24663
  /**
23267
24664
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
23268
24665
  *
@@ -23349,7 +24746,7 @@ const unanimousVersionOf = (index, dependency) => {
23349
24746
  };
23350
24747
 
23351
24748
  //#endregion
23352
- //#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
24749
+ //#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
23353
24750
  /**
23354
24751
  * An immutable, fully-normalized catalog collection — the one catalog
23355
24752
  * resolution semantic in the package.
@@ -23864,9 +25261,9 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
23864
25261
  * consumers to `_tag`-sniff `unknown`); only the remaining mechanism failure,
23865
25262
  * an unfindable workspace root, is wrapped as `DependencyResolutionError`.
23866
25263
  */
23867
- static catalogResolver = Layer.effect(CatalogResolver$1, Effect.gen(function* () {
25264
+ static catalogResolver = Layer.effect(CatalogResolver, Effect.gen(function* () {
23868
25265
  const catalogs = yield* WorkspaceCatalogs;
23869
- return { rangeOf: (packageName, catalog) => catalogs.set().pipe(Effect.map((set) => set.rangeOf(packageName, catalog)), Effect.catchTag("WorkspaceRootNotFoundError", (cause) => Effect.fail(new DependencyResolutionError$1({
25266
+ return { rangeOf: (packageName, catalog) => catalogs.set().pipe(Effect.map((set) => set.rangeOf(packageName, catalog)), Effect.catchTag("WorkspaceRootNotFoundError", (cause) => Effect.fail(new DependencyResolutionError({
23870
25267
  specifier: Option.match(catalog, {
23871
25268
  onNone: () => "catalog:",
23872
25269
  onSome: (name) => `catalog:${name}`
@@ -23877,7 +25274,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends Context.Service()("@effe
23877
25274
  };
23878
25275
 
23879
25276
  //#endregion
23880
- //#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
25277
+ //#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
23881
25278
  const EMPTY = Object.freeze(Object.create(null));
23882
25279
  const DependencyMap = Schema.Record(Schema.String, Schema.String).pipe(Schema.withDecodingDefaultKey(Effect.succeed(EMPTY)), Schema.withConstructorDefault(Effect.succeed(EMPTY)));
23883
25280
  /**
@@ -24056,7 +25453,7 @@ var WorkspaceStateSnapshot = class extends Schema.Class("WorkspaceStateSnapshot"
24056
25453
  * resolving to `Option.none()` so the caller falls back to the raw string.
24057
25454
  */
24058
25455
  #resolveWith(dependency, specifier, onUnresolvedCatalog) {
24059
- const exit = Schema.decodeUnknownExit(DependencySpecifier$1.FromString)(specifier);
25456
+ const exit = Schema.decodeUnknownExit(DependencySpecifier.FromString)(specifier);
24060
25457
  if (!Exit.isSuccess(exit)) return Option.none();
24061
25458
  const classified = exit.value;
24062
25459
  switch (classified._tag) {
@@ -24081,7 +25478,7 @@ var WorkspaceStateSnapshot = class extends Schema.Class("WorkspaceStateSnapshot"
24081
25478
  * `rangeOf` never fails.
24082
25479
  */
24083
25480
  get catalogResolver() {
24084
- if (this.#catalogResolver === void 0) this.#catalogResolver = Layer.succeed(CatalogResolver$1, { rangeOf: (packageName, catalog) => Effect.succeed(this.catalogs.rangeOf(packageName, catalog)) });
25481
+ if (this.#catalogResolver === void 0) this.#catalogResolver = Layer.succeed(CatalogResolver, { rangeOf: (packageName, catalog) => Effect.succeed(this.catalogs.rangeOf(packageName, catalog)) });
24085
25482
  return this.#catalogResolver;
24086
25483
  }
24087
25484
  /**
@@ -24090,7 +25487,7 @@ var WorkspaceStateSnapshot = class extends Schema.Class("WorkspaceStateSnapshot"
24090
25487
  * `workspace:` specifiers as of this ref. Built once per instance and cached.
24091
25488
  */
24092
25489
  get workspaceResolver() {
24093
- if (this.#workspaceResolver === void 0) this.#workspaceResolver = Layer.succeed(WorkspaceResolver$1, { versionOf: (packageName) => Effect.succeed(Option.fromUndefinedOr(this.#versions().get(packageName))) });
25490
+ if (this.#workspaceResolver === void 0) this.#workspaceResolver = Layer.succeed(WorkspaceResolver, { versionOf: (packageName) => Effect.succeed(Option.fromUndefinedOr(this.#versions().get(packageName))) });
24094
25491
  return this.#workspaceResolver;
24095
25492
  }
24096
25493
  /** Both snapshot-scoped resolver layers merged. Built once per instance and cached. */
@@ -24101,7 +25498,7 @@ var WorkspaceStateSnapshot = class extends Schema.Class("WorkspaceStateSnapshot"
24101
25498
  };
24102
25499
 
24103
25500
  //#endregion
24104
- //#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
25501
+ //#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
24105
25502
  /** Whether `value` is a non-null, non-array object. */
24106
25503
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
24107
25504
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -24379,7 +25776,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends Context.Service()("@ef
24379
25776
  };
24380
25777
 
24381
25778
  //#endregion
24382
- //#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
25779
+ //#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
24383
25780
  const compose = (options, catalogsFactory) => {
24384
25781
  const roots = WorkspaceRoot.layer;
24385
25782
  const detector = PackageManagerDetector.layer;
@@ -24513,7 +25910,8 @@ var Workspaces = class {
24513
25910
  * never detects changes or reads at a ref should not have to be able to
24514
25911
  * spawn a subprocess. The consumer provides `ChildProcessSpawner` once at
24515
25912
  * the edge (`@effect/platform-node`'s `NodeServices.layer`); a test
24516
- * provides `Layer.succeed(Git, …)` and needs no repository on disk.
25913
+ * provides `Git.layerTest({ })` git's own shipped double, whose
25914
+ * unstubbed members die named — and needs no repository on disk.
24517
25915
  */
24518
25916
  static layerWithGit = layerWithGit;
24519
25917
  /**
@@ -24562,9 +25960,14 @@ var Workspaces = class {
24562
25960
  * import { Workspaces } from "@effected/workspaces";
24563
25961
  * import { Layer } from "effect";
24564
25962
  *
25963
+ * // Bound to consts per the warning above: each factory call mints a
25964
+ * // fresh layer reference, and layers memoize by reference.
25965
+ * const LocalExecLayer = Workspaces.localExecLayer();
25966
+ * const WorkspacesLayer = Workspaces.layer();
25967
+ *
24565
25968
  * const AppLayer = ToolDiscovery.layer.pipe(
24566
- * Layer.provide(Workspaces.localExecLayer()),
24567
- * Layer.provide(Workspaces.layer()),
25969
+ * Layer.provide(LocalExecLayer),
25970
+ * Layer.provide(WorkspacesLayer),
24568
25971
  * Layer.provide(NodeServices.layer),
24569
25972
  * );
24570
25973
  * ```