@savvy-web/silk 3.4.1 → 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.
@@ -2334,7 +2334,7 @@ var GlobSet = class GlobSet extends effect.Schema.Class("GlobSet")(effect.Schema
2334
2334
  }
2335
2335
  };
2336
2336
  //#endregion
2337
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/BunExtension.js
2337
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/BunExtension.js
2338
2338
  /**
2339
2339
  * Extension data specific to bun lockfiles, attached to `Lockfile.extension`
2340
2340
  * when the format is `"bun"`.
@@ -2355,7 +2355,7 @@ var BunExtension = class extends effect.Schema.Class("BunExtension")({
2355
2355
  trustedDependencies: effect.Schema.optionalKey(effect.Schema.Array(effect.Schema.String))
2356
2356
  }) {};
2357
2357
  //#endregion
2358
- //#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
2358
+ //#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/CatalogResolver.js
2359
2359
  /**
2360
2360
  * Contract for resolving pnpm `catalog:` dependency specifiers to concrete
2361
2361
  * version ranges.
@@ -2401,7 +2401,7 @@ var CatalogResolver = class CatalogResolver extends effect.Context.Service()("@e
2401
2401
  static noop = effect.Layer.succeed(CatalogResolver, { rangeOf: () => effect.Effect.succeed(effect.Option.none()) });
2402
2402
  };
2403
2403
  //#endregion
2404
- //#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
2404
+ //#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/WorkspaceResolver.js
2405
2405
  /**
2406
2406
  * Raised when a `catalog:` or `workspace:` specifier cannot be resolved
2407
2407
  * because the resolution mechanism itself failed — not for an ordinary
@@ -2462,7 +2462,7 @@ var WorkspaceResolver = class WorkspaceResolver extends effect.Context.Service()
2462
2462
  static noop = effect.Layer.succeed(WorkspaceResolver, { versionOf: () => effect.Effect.succeed(effect.Option.none()) });
2463
2463
  };
2464
2464
  //#endregion
2465
- //#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/CatalogAssemblyError.js
2465
+ //#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/CatalogAssemblyError.js
2466
2466
  /**
2467
2467
  * Raised when a workspace's catalogs cannot be assembled — a `pnpm-workspace.yaml`
2468
2468
  * that is unreadable or not valid YAML, a root `package.json` `workspaces` field
@@ -2506,7 +2506,7 @@ var CatalogAssemblyError = class extends effect.Schema.TaggedErrorClass()("Catal
2506
2506
  }
2507
2507
  };
2508
2508
  //#endregion
2509
- //#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
2509
+ //#region ../../node_modules/.pnpm/@effected+npm@0.8.3_@effected+semver@0.3.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/npm/DependencySection.js
2510
2510
  /**
2511
2511
  * The short dependency kind: which dependency map an entry came from, named the
2512
2512
  * way consumers branch on it.
@@ -4121,7 +4121,7 @@ const isComparatorSetSubset = (sub, sup) => {
4121
4121
  return true;
4122
4122
  };
4123
4123
  //#endregion
4124
- //#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
4124
+ //#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/DependencySpecifier.js
4125
4125
  /**
4126
4126
  * Indicates that a string could not be parsed as a valid dependency specifier.
4127
4127
  *
@@ -4328,7 +4328,7 @@ const DependencySpecifier = Object.assign(brandedSpecifier, {
4328
4328
  FromString: fromString
4329
4329
  });
4330
4330
  //#endregion
4331
- //#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
4331
+ //#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
4332
4332
  const SRI_RE = /^(sha1|sha256|sha384|sha512)-[A-Za-z0-9+/]+={0,2}$/;
4333
4333
  const COREPACK_RE = /^(sha1|sha224|sha256|sha384|sha512)\.[0-9a-f]+$/;
4334
4334
  const YARN_RE = /^[0-9]+(c[0-9]+)?\/[0-9a-f]+$/;
@@ -4627,7 +4627,678 @@ var LocalExec = class LocalExec extends effect.Context.Service()("@effected/comm
4627
4627
  static layerTest = (overrides = {}) => effect.Layer.succeed(LocalExec, LocalExec.makeTest(overrides));
4628
4628
  };
4629
4629
  //#endregion
4630
- //#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/ReleaseAgeGate.js
4630
+ //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/Redaction.js
4631
+ /**
4632
+ * Argument tokens whose *following* positional (or `=`-joined value) is a
4633
+ * secret. Lowercase; matching is case-insensitive.
4634
+ *
4635
+ * @remarks
4636
+ * This is the heuristic backstop, not the primary mechanism — it can only know
4637
+ * about flags someone thought to list. The primary mechanism is
4638
+ * {@link Redaction.applyArgs}, which redacts by **value**: the caller says what
4639
+ * its secrets are and every occurrence goes, whatever flag carried it.
4640
+ *
4641
+ * @public
4642
+ */
4643
+ const SECRET_FLAGS = /* @__PURE__ */ new Set([
4644
+ "--access-token",
4645
+ "--api-key",
4646
+ "--auth",
4647
+ "--auth-token",
4648
+ "--otp",
4649
+ "--password",
4650
+ "--registry-token",
4651
+ "--token"
4652
+ ]);
4653
+ /**
4654
+ * npm config keys whose value is a credential (`//registry/:_authToken`,
4655
+ * `//registry/:_password`).
4656
+ */
4657
+ const AUTH_KEY = /:(?:_authtoken|_password)$/i;
4658
+ /**
4659
+ * The distinct, non-empty secret values, longest first.
4660
+ *
4661
+ * @remarks
4662
+ * Longest-first is load-bearing: redacting `"ab"` before `"abcd"` rewrites
4663
+ * `"abcd"` to `"***cd"`, leaking `"cd"` — a fragment of the longer secret.
4664
+ * Empty values are dropped because `"abc".split("").join("***")` would insert
4665
+ * the placeholder between every character.
4666
+ */
4667
+ const prepare = (secrets) => [...new Set(secrets.map(effect.Redacted.value))].filter((value) => value.length > 0).sort((a, b) => b.length - a.length);
4668
+ /** Replaces each prepared value with {@link REDACTED}, literally (never as a pattern). */
4669
+ const replaceAll = (text, values) => {
4670
+ let out = text;
4671
+ for (const value of values) out = out.split(value).join("***");
4672
+ return out;
4673
+ };
4674
+ const apply = (text, secrets) => secrets.length === 0 ? text : replaceAll(text, prepare(secrets));
4675
+ const applyArgs = (args, secrets) => {
4676
+ if (secrets.length === 0) return args;
4677
+ const values = prepare(secrets);
4678
+ return args.map((arg) => replaceAll(arg, values));
4679
+ };
4680
+ /** Whether `name` introduces a credential value. */
4681
+ const isSecretName = (name, extra) => {
4682
+ const lower = name.toLowerCase();
4683
+ return SECRET_FLAGS.has(lower) || extra.has(lower) || AUTH_KEY.test(name);
4684
+ };
4685
+ const scrubArgs = (args, options) => {
4686
+ const extra = new Set((options?.flags ?? []).map((flag) => flag.toLowerCase()));
4687
+ const out = [];
4688
+ for (let index = 0; index < args.length; index++) {
4689
+ const arg = args[index] ?? "";
4690
+ const equals = arg.indexOf("=");
4691
+ if (equals > 0 && isSecretName(arg.slice(0, equals), extra)) {
4692
+ out.push(`${arg.slice(0, equals)}=***`);
4693
+ continue;
4694
+ }
4695
+ out.push(arg);
4696
+ if (isSecretName(arg, extra) && index + 1 < args.length) {
4697
+ out.push("***");
4698
+ index++;
4699
+ }
4700
+ }
4701
+ return out;
4702
+ };
4703
+ /**
4704
+ * Secret scrubbing for command arguments and captured output.
4705
+ *
4706
+ * @remarks
4707
+ * Two mechanisms, deliberately layered. {@link Redaction.apply} and
4708
+ * {@link Redaction.applyArgs} redact **by value** — the caller declares its
4709
+ * secrets as `Redacted` and every occurrence is removed wherever it appears.
4710
+ * {@link Redaction.scrubArgs} is a **flag heuristic** that runs in addition, for
4711
+ * the secrets a caller forgot to declare.
4712
+ *
4713
+ * @public
4714
+ */
4715
+ var Redaction = class {
4716
+ constructor() {}
4717
+ /**
4718
+ * Replaces every occurrence of every secret's value in `text` with
4719
+ * {@link REDACTED}.
4720
+ *
4721
+ * @remarks
4722
+ * Exact, literal matching — no pattern compilation, no encoding-aware search. A
4723
+ * secret that reaches the text base64-encoded, URL-encoded, or split across a
4724
+ * line break is **not** found; declare the encoded form as a secret too if that
4725
+ * is a real risk.
4726
+ *
4727
+ * A secret composed only of the placeholder's own characters (`*`, `**`, `***`)
4728
+ * cannot be fully removed, because the replacement reintroduces it. That is a
4729
+ * documented limitation, not a defect.
4730
+ */
4731
+ static apply = apply;
4732
+ /**
4733
+ * {@link Redaction.apply} over each entry of an argv array. An entry is
4734
+ * redacted whether it *is* a secret or merely *contains* one
4735
+ * (`--url=https://u:s3cr3t@host`).
4736
+ */
4737
+ static applyArgs = applyArgs;
4738
+ /**
4739
+ * Heuristic backstop: redact any argv value that is introduced by a known
4740
+ * secret-bearing flag or npm auth key, in either the separated
4741
+ * (`--token abc`) or inline (`--token=abc`) form.
4742
+ *
4743
+ * @remarks
4744
+ * This catches secrets the caller forgot to declare; it cannot catch a flag
4745
+ * nobody listed. Prefer {@link Redaction.applyArgs} with the actual
4746
+ * `Redacted` values — this runs *in addition*, never instead.
4747
+ */
4748
+ static scrubArgs = scrubArgs;
4749
+ /** Flags treated as secret-bearing by {@link Redaction.scrubArgs}. See {@link SECRET_FLAGS}. */
4750
+ static SECRET_FLAGS = SECRET_FLAGS;
4751
+ };
4752
+ //#endregion
4753
+ //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/internal/capture.js
4754
+ /**
4755
+ * Raised when a captured stream exceeds its byte budget.
4756
+ *
4757
+ * @remarks
4758
+ * Internal and never exported from the package: `Run` maps it to the public
4759
+ * `CommandOutputError`. `Data.TaggedError` is appropriate precisely because it
4760
+ * never escapes — it is an in-process signal, not a contract.
4761
+ */
4762
+ var OutputTooLarge = class extends effect.Data.TaggedError("OutputTooLarge") {};
4763
+ /**
4764
+ * Collects a byte stream into a string, failing once more than `limit` bytes
4765
+ * have arrived.
4766
+ *
4767
+ * @remarks
4768
+ * The budget is enforced **during** accumulation, not after: checking the
4769
+ * length of an already-collected string would mean the memory was already
4770
+ * spent, which is the exact failure the budget exists to prevent. Counting is
4771
+ * on raw bytes, before decoding, because bytes are what the process actually
4772
+ * produced.
4773
+ */
4774
+ const collectBounded = (stream, limit) => effect.Effect.gen(function* () {
4775
+ const seen = yield* effect.Ref.make(0);
4776
+ const bounded = effect.Stream.mapEffect(stream, (chunk) => effect.Effect.flatMap(effect.Ref.updateAndGet(seen, (total) => total + chunk.length), (total) => total > limit ? effect.Effect.fail(new OutputTooLarge({ limit })) : effect.Effect.succeed(chunk)));
4777
+ return yield* effect.Stream.mkString(effect.Stream.decodeText(bounded));
4778
+ });
4779
+ //#endregion
4780
+ //#region ../../node_modules/.pnpm/@effected+commands@0.3.1_effect@4.0.0-beta.101/node_modules/@effected/commands/Run.js
4781
+ /**
4782
+ * Default ceiling on captured bytes per stream (16 MiB).
4783
+ *
4784
+ * @remarks
4785
+ * Collecting a child's output without a bound is a memory-exhaustion vector.
4786
+ * Output genuinely larger than this belongs on {@link Run.stream}, which never
4787
+ * accumulates.
4788
+ *
4789
+ * @public
4790
+ */
4791
+ const DEFAULT_MAX_OUTPUT_BYTES = 16777216;
4792
+ /** Characters shown from the tail of captured output in an error message. */
4793
+ const MAX_MESSAGE_CHARS = 2e3;
4794
+ /**
4795
+ * What one completed run produced.
4796
+ *
4797
+ * @public
4798
+ */
4799
+ var CommandOutput = class extends effect.Schema.Class("CommandOutput")({
4800
+ /** Captured standard output, redacted. */
4801
+ stdout: effect.Schema.String,
4802
+ /** Captured standard error, redacted. */
4803
+ stderr: effect.Schema.String,
4804
+ /** The process exit code. A non-zero value is NOT an error at this level. */
4805
+ exitCode: effect.Schema.Number
4806
+ }) {
4807
+ /** Whether the process exited zero. */
4808
+ get succeeded() {
4809
+ return this.exitCode === 0;
4810
+ }
4811
+ };
4812
+ /** The executable and argv an error should report for `command`. */
4813
+ const describeCommand = (command) => {
4814
+ if (effect_unstable_process.ChildProcess.isStandardCommand(command)) return {
4815
+ command: command.command,
4816
+ args: command.args
4817
+ };
4818
+ const left = describeCommand(command.left);
4819
+ const right = describeCommand(command.right);
4820
+ return {
4821
+ command: `${left.command} | ${right.command}`,
4822
+ args: []
4823
+ };
4824
+ };
4825
+ /** argv as an error should store it: declared secrets removed, then the flag heuristic. */
4826
+ const safeArgs = (args, secrets) => Redaction.scrubArgs(Redaction.applyArgs(args, secrets ?? []));
4827
+ /** Captured text as an error should store it. */
4828
+ const safeText = (text, secrets) => Redaction.apply(text, secrets ?? []);
4829
+ /** Tail-bounded rendering: tools write warnings first and the real error last. */
4830
+ const tail = (text) => {
4831
+ const trimmed = text.trim();
4832
+ if (trimmed.length <= MAX_MESSAGE_CHARS) return trimmed;
4833
+ return `...[${trimmed.length - MAX_MESSAGE_CHARS} chars truncated from head]...\n${trimmed.slice(-2e3)}`;
4834
+ };
4835
+ /**
4836
+ * A command that could not be run, or that ran and failed.
4837
+ *
4838
+ * @remarks
4839
+ * `kind` is the routing surface, never the message: `"nonZero"` (the process
4840
+ * ran and exited non-zero), `"spawn"` (it never started — the executable is
4841
+ * missing, or the platform refused), `"timeout"` (a caller-supplied ceiling
4842
+ * elapsed). Composed retry and fallback logic branches on `kind`; nothing in
4843
+ * this package asks a caller to match on prose.
4844
+ *
4845
+ * `args` is **always** stored redacted.
4846
+ *
4847
+ * @public
4848
+ */
4849
+ var CommandFailedError = class CommandFailedError extends effect.Schema.TaggedErrorClass()("CommandFailedError", {
4850
+ /** Why it failed. */
4851
+ kind: effect.Schema.Literals([
4852
+ "nonZero",
4853
+ "spawn",
4854
+ "timeout"
4855
+ ]),
4856
+ /** The executable (or `"a | b"` for a pipeline). */
4857
+ command: effect.Schema.String,
4858
+ /** argv, redacted. */
4859
+ args: effect.Schema.Array(effect.Schema.String),
4860
+ /** The exit code, when the process ran. */
4861
+ exitCode: effect.Schema.optionalKey(effect.Schema.Number),
4862
+ /** Captured standard error, redacted, when the process ran. */
4863
+ stderr: effect.Schema.optionalKey(effect.Schema.String),
4864
+ /** Captured standard output, redacted, when the process ran. */
4865
+ stdout: effect.Schema.optionalKey(effect.Schema.String),
4866
+ /** The absorbed platform failure, for `"spawn"`. */
4867
+ cause: effect.Schema.optionalKey(effect.Schema.Defect())
4868
+ }) {
4869
+ /** The process ran and exited non-zero. */
4870
+ static nonZero = (command, output, secrets) => {
4871
+ const described = describeCommand(command);
4872
+ return new CommandFailedError({
4873
+ kind: "nonZero",
4874
+ command: described.command,
4875
+ args: safeArgs(described.args, secrets),
4876
+ exitCode: output.exitCode,
4877
+ stderr: output.stderr,
4878
+ stdout: output.stdout
4879
+ });
4880
+ };
4881
+ /** The process never started. */
4882
+ static spawn = (command, cause, secrets) => {
4883
+ const described = describeCommand(command);
4884
+ return new CommandFailedError({
4885
+ kind: "spawn",
4886
+ command: described.command,
4887
+ args: safeArgs(described.args, secrets),
4888
+ cause
4889
+ });
4890
+ };
4891
+ /** A caller-supplied ceiling elapsed; the child was killed with its scope. */
4892
+ static timedOut = (command, secrets) => {
4893
+ const described = describeCommand(command);
4894
+ return new CommandFailedError({
4895
+ kind: "timeout",
4896
+ command: described.command,
4897
+ args: safeArgs(described.args, secrets)
4898
+ });
4899
+ };
4900
+ /**
4901
+ * Whether this is a spawn failure caused by the executable not existing —
4902
+ * the structural "tool is not installed" signal.
4903
+ */
4904
+ get notFound() {
4905
+ return this.kind === "spawn" && this.cause instanceof effect.PlatformError.PlatformError && this.cause.reason._tag === "NotFound";
4906
+ }
4907
+ /** Names the command and surfaces the tail of whichever stream carries the cause. */
4908
+ get message() {
4909
+ const parts = [`Command "${this.args.length > 0 ? `${this.command} ${this.args.join(" ")}` : this.command}" failed`];
4910
+ if (this.kind === "timeout") parts.push("(timed out)");
4911
+ if (this.exitCode !== void 0) parts.push(`(exit ${this.exitCode})`);
4912
+ const stream = this.stderr?.trim() ? this.stderr : this.stdout?.trim() ? this.stdout : void 0;
4913
+ if (stream !== void 0) parts.push(`:\n${tail(stream)}`);
4914
+ return parts.join(" ");
4915
+ }
4916
+ };
4917
+ /**
4918
+ * A command ran, but its output could not be used.
4919
+ *
4920
+ * @remarks
4921
+ * Separate from {@link CommandFailedError} because the process itself
4922
+ * succeeded: `"notJson"` (stdout is not JSON), `"schema"` (it is JSON but does
4923
+ * not decode), `"tooLarge"` (capture exceeded its byte budget). Keeping the two
4924
+ * distinguishable is the point — a schema drift and a crashed tool call for
4925
+ * different responses.
4926
+ *
4927
+ * The context fields (`exitCode`, `stderr`, `stdout`) are populated by
4928
+ * {@link Run.jsonLine}, whose payload framing parses regardless of exit code —
4929
+ * when no payload arrives, the exit code and captured streams are the only
4930
+ * evidence of what actually went wrong. Both streams are **always** stored
4931
+ * redacted.
4932
+ *
4933
+ * @public
4934
+ */
4935
+ var CommandOutputError = class extends effect.Schema.TaggedErrorClass()("CommandOutputError", {
4936
+ /** Which way the output was unusable. */
4937
+ kind: effect.Schema.Literals([
4938
+ "notJson",
4939
+ "schema",
4940
+ "tooLarge"
4941
+ ]),
4942
+ /** The executable that produced it. */
4943
+ command: effect.Schema.String,
4944
+ /** The underlying parse or decode failure. */
4945
+ cause: effect.Schema.optionalKey(effect.Schema.Defect()),
4946
+ /** The exit code, when the combinator parses independently of it. */
4947
+ exitCode: effect.Schema.optionalKey(effect.Schema.Number),
4948
+ /** Captured standard error, redacted, when the process ran. */
4949
+ stderr: effect.Schema.optionalKey(effect.Schema.String),
4950
+ /** Captured standard output, redacted, when the process ran. */
4951
+ stdout: effect.Schema.optionalKey(effect.Schema.String)
4952
+ }) {
4953
+ get message() {
4954
+ const parts = [];
4955
+ if (this.kind === "notJson") parts.push(`Command "${this.command}" did not produce JSON`);
4956
+ else if (this.kind === "schema") parts.push(`Command "${this.command}" produced JSON that did not match the expected schema`);
4957
+ else parts.push(`Command "${this.command}" produced more output than the configured limit`);
4958
+ if (this.exitCode !== void 0) parts.push(`(exit ${this.exitCode})`);
4959
+ if (this.stderr !== void 0 && this.stderr.trim().length > 0) parts.push(`:\n${tail(this.stderr)}`);
4960
+ return parts.join(" ");
4961
+ }
4962
+ };
4963
+ /** Spawns, collects both streams concurrently, and awaits exit. */
4964
+ const collectRaw = (command, options, tee) => effect.Effect.scoped(effect.Effect.gen(function* () {
4965
+ const handle = yield* (yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner).spawn(command);
4966
+ const limit = options?.maxOutputBytes ?? 16777216;
4967
+ const out = tee === void 0 ? handle.stdout : effect.Stream.tapSink(handle.stdout, tee.stdout());
4968
+ const err = tee === void 0 ? handle.stderr : effect.Stream.tapSink(handle.stderr, tee.stderr());
4969
+ const [stdout, stderr, exitCode] = yield* effect.Effect.all([
4970
+ collectBounded(out, limit),
4971
+ collectBounded(err, limit),
4972
+ handle.exitCode
4973
+ ], { concurrency: "unbounded" });
4974
+ const secrets = options?.redact;
4975
+ return CommandOutput.make({
4976
+ stdout: safeText(stdout, secrets),
4977
+ stderr: safeText(stderr, secrets),
4978
+ exitCode: Number(exitCode)
4979
+ });
4980
+ }));
4981
+ /** Maps the raw failure modes onto this package's taxonomy, and applies any ceiling. */
4982
+ const collectClassified = (command, options, tee) => {
4983
+ const described = describeCommand(command);
4984
+ const classified = collectRaw(command, options, tee).pipe(effect.Effect.catch((error) => effect.Effect.fail(error instanceof OutputTooLarge ? new CommandOutputError({
4985
+ kind: "tooLarge",
4986
+ command: described.command,
4987
+ cause: error
4988
+ }) : CommandFailedError.spawn(command, error, options?.redact))));
4989
+ return options?.timeout === void 0 ? classified : effect.Effect.timeoutOrElse(classified, {
4990
+ duration: options.timeout,
4991
+ orElse: () => effect.Effect.fail(CommandFailedError.timedOut(command, options.redact))
4992
+ });
4993
+ };
4994
+ /** Fails a run whose process exited non-zero. */
4995
+ const requireZero = (command, output, options) => output.succeeded ? effect.Effect.succeed(output) : effect.Effect.fail(CommandFailedError.nonZero(command, output, options?.redact));
4996
+ /** Span attributes: what ran and how many arguments — never the arguments. */
4997
+ const annotate = (command) => {
4998
+ const described = describeCommand(command);
4999
+ return effect.Effect.annotateCurrentSpan({
5000
+ command: described.command,
5001
+ argc: described.args.length
5002
+ });
5003
+ };
5004
+ const collect = effect.Effect.fn("Run.collect")(function* (command, options) {
5005
+ yield* annotate(command);
5006
+ return yield* collectClassified(command, options, void 0);
5007
+ });
5008
+ const collectTee = effect.Effect.fn("Run.collectTee")(function* (command, options) {
5009
+ yield* annotate(command);
5010
+ const stdio = yield* effect.Stdio.Stdio;
5011
+ return yield* collectClassified(command, options, stdio);
5012
+ });
5013
+ const text$4 = effect.Effect.fn("Run.text")(function* (command, options) {
5014
+ yield* annotate(command);
5015
+ const output = yield* collectClassified(command, options, void 0);
5016
+ return (yield* requireZero(command, output, options)).stdout.trim();
5017
+ });
5018
+ const lines = effect.Effect.fn("Run.lines")(function* (command, options) {
5019
+ yield* annotate(command);
5020
+ const output = yield* collectClassified(command, options, void 0);
5021
+ return (yield* requireZero(command, output, options)).stdout.split(/\r?\n/).map((line) => line.trim()).filter((line) => line.length > 0);
5022
+ });
5023
+ const json = effect.Effect.fn("Run.json")(function* (command, schema, options) {
5024
+ yield* annotate(command);
5025
+ const described = describeCommand(command);
5026
+ const output = yield* collectClassified(command, options, void 0);
5027
+ const checked = yield* requireZero(command, output, options);
5028
+ const parsed = yield* effect.Effect.try({
5029
+ try: () => JSON.parse(checked.stdout),
5030
+ catch: (cause) => new CommandOutputError({
5031
+ kind: "notJson",
5032
+ command: described.command,
5033
+ cause
5034
+ })
5035
+ });
5036
+ return yield* effect.Schema.decodeUnknownEffect(schema)(parsed).pipe(effect.Effect.catch((cause) => effect.Effect.fail(new CommandOutputError({
5037
+ kind: "schema",
5038
+ command: described.command,
5039
+ cause
5040
+ }))));
5041
+ });
5042
+ const jsonLine = effect.Effect.fn("Run.jsonLine")(function* (command, schema, options) {
5043
+ yield* annotate(command);
5044
+ const described = describeCommand(command);
5045
+ const output = yield* collectClassified(command, options, void 0);
5046
+ const context = {
5047
+ exitCode: output.exitCode,
5048
+ stderr: output.stderr,
5049
+ stdout: output.stdout
5050
+ };
5051
+ const candidates = output.stdout.split(/\r?\n/).filter((candidate) => candidate.trim().length > 0);
5052
+ if (candidates.length === 0) return yield* effect.Effect.fail(new CommandOutputError({
5053
+ kind: "notJson",
5054
+ command: described.command,
5055
+ cause: /* @__PURE__ */ new Error("stdout carried no non-empty line"),
5056
+ ...context
5057
+ }));
5058
+ let notJsonCause;
5059
+ let schemaCause;
5060
+ for (let index = candidates.length - 1; index >= 0; index--) {
5061
+ const candidate = candidates[index];
5062
+ if (candidate === void 0) continue;
5063
+ let parsed;
5064
+ try {
5065
+ parsed = JSON.parse(candidate);
5066
+ } catch (cause) {
5067
+ notJsonCause ??= cause;
5068
+ continue;
5069
+ }
5070
+ const decoded = yield* effect.Effect.result(effect.Schema.decodeUnknownEffect(schema)(parsed));
5071
+ if (effect.Result.isSuccess(decoded)) return decoded.success;
5072
+ schemaCause ??= decoded.failure;
5073
+ }
5074
+ return yield* effect.Effect.fail(schemaCause !== void 0 ? new CommandOutputError({
5075
+ kind: "schema",
5076
+ command: described.command,
5077
+ cause: schemaCause,
5078
+ ...context
5079
+ }) : new CommandOutputError({
5080
+ kind: "notJson",
5081
+ command: described.command,
5082
+ cause: notJsonCause,
5083
+ ...context
5084
+ }));
5085
+ });
5086
+ const exitCode = effect.Effect.fn("Run.exitCode")(function* (command, options) {
5087
+ yield* annotate(command);
5088
+ return (yield* collectClassified(command, options, void 0)).exitCode;
5089
+ });
5090
+ const succeeds = effect.Effect.fn("Run.succeeds")(function* (command, options) {
5091
+ yield* annotate(command);
5092
+ return yield* collectClassified(command, options, void 0).pipe(effect.Effect.map((output) => output.succeeded), effect.Effect.catch(() => effect.Effect.succeed(false)));
5093
+ });
5094
+ const detach = effect.Effect.fn("Run.detach")(function* (command) {
5095
+ yield* annotate(command);
5096
+ return yield* effect.Effect.scoped(effect.Effect.gen(function* () {
5097
+ const handle = yield* (yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner).spawn(command);
5098
+ yield* handle.unref;
5099
+ return handle.pid;
5100
+ })).pipe(effect.Effect.catch((error) => effect.Effect.fail(CommandFailedError.spawn(command, error))));
5101
+ });
5102
+ const stream = (command, options) => effect.Stream.unwrap(effect.Effect.map(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, (spawner) => spawner.streamLines(command, { includeStderr: options?.includeStderr ?? false }))).pipe(effect.Stream.mapError((error) => CommandFailedError.spawn(command, error)));
5103
+ const extendEnv = effect.Function.dual(2, (self, env) => {
5104
+ if (effect_unstable_process.ChildProcess.isStandardCommand(self)) {
5105
+ const merged = self.options.env === void 0 ? env : {
5106
+ ...self.options.env,
5107
+ ...env
5108
+ };
5109
+ return effect_unstable_process.ChildProcess.make(self.command, self.args, {
5110
+ ...self.options,
5111
+ env: merged,
5112
+ extendEnv: true
5113
+ });
5114
+ }
5115
+ return effect_unstable_process.ChildProcess.pipeTo(extendEnv(self.left, env), extendEnv(self.right, env), self.options);
5116
+ });
5117
+ /**
5118
+ * Structured running of core `ChildProcess.Command` values.
5119
+ *
5120
+ * @remarks
5121
+ * These are free functions over core's contract, **not** a service: core's
5122
+ * `ChildProcessSpawner` already is the subprocess service, and wrapping it in a
5123
+ * second one is the re-declaration this package exists not to repeat. Tests
5124
+ * stub the spawner (`ChildProcessSpawner.make(mockSpawn)`), not these.
5125
+ *
5126
+ * A non-zero exit is a *result* for {@link Run.collect}, {@link Run.exitCode},
5127
+ * {@link Run.succeeds} and {@link Run.jsonLine}, and a typed *failure* for
5128
+ * {@link Run.text}, {@link Run.lines} and {@link Run.json} — the split is
5129
+ * deliberate, matching core (where a non-zero exit is a success) at the
5130
+ * reporting level while giving the interpreting helpers the ergonomics callers
5131
+ * actually want.
5132
+ *
5133
+ * The interpreting helpers also **trim**: {@link Run.text} strips leading and
5134
+ * trailing whitespace from the whole result — not just a trailing newline —
5135
+ * and {@link Run.lines} trims each line. Fixed-column output whose first
5136
+ * column can be whitespace (`git status --porcelain`) silently loses that
5137
+ * column through either, producing plausible wrong values rather than an
5138
+ * error. Parse that kind of output from the untrimmed `stdout` of
5139
+ * {@link Run.collect}'s {@link CommandOutput} instead.
5140
+ *
5141
+ * @public
5142
+ */
5143
+ var Run = class {
5144
+ constructor() {}
5145
+ /**
5146
+ * Spawns `command`, collects stdout and stderr concurrently, and resolves
5147
+ * with the {@link CommandOutput} once the process exits.
5148
+ *
5149
+ * @remarks
5150
+ * A non-zero exit is a *result* here, not a failure — see {@link Run}'s
5151
+ * remarks for the split against {@link Run.text}, {@link Run.lines} and
5152
+ * {@link Run.json}.
5153
+ */
5154
+ static collect = collect;
5155
+ /**
5156
+ * Like {@link Run.collect}, but also tees each stream to the `Stdio` in `R`
5157
+ * as it arrives, for a caller that wants live output alongside the captured
5158
+ * {@link CommandOutput}.
5159
+ */
5160
+ static collectTee = collectTee;
5161
+ /**
5162
+ * Runs `command` and resolves with trimmed stdout on a zero exit.
5163
+ *
5164
+ * @remarks
5165
+ * A non-zero exit is a typed failure here — {@link CommandFailedError} —
5166
+ * unlike {@link Run.collect}, {@link Run.exitCode} and {@link Run.succeeds},
5167
+ * which treat it as a result.
5168
+ *
5169
+ * The trim strips **leading and trailing whitespace**, not just the trailing
5170
+ * newline. For parse-sensitive output where leading whitespace is data
5171
+ * (`git status --porcelain`, whose first entry's status column it would
5172
+ * silently eat), use {@link Run.collect} and read its {@link CommandOutput}'s
5173
+ * untrimmed `stdout` instead.
5174
+ */
5175
+ static text = text$4;
5176
+ /**
5177
+ * Runs `command` and resolves with stdout split into trimmed, non-empty
5178
+ * lines on a zero exit.
5179
+ *
5180
+ * @remarks
5181
+ * A non-zero exit is a typed failure here — {@link CommandFailedError} —
5182
+ * matching {@link Run.text} and {@link Run.json}.
5183
+ */
5184
+ static lines = lines;
5185
+ /**
5186
+ * Runs `command`, parses stdout as JSON and decodes it against `schema` on
5187
+ * a zero exit.
5188
+ *
5189
+ * @remarks
5190
+ * Fails with {@link CommandOutputError} when stdout is not JSON or does not
5191
+ * decode; a non-zero exit fails with {@link CommandFailedError}, matching
5192
+ * {@link Run.text} and {@link Run.lines}.
5193
+ *
5194
+ * This parses the **whole** of stdout and requires a zero exit. For a
5195
+ * protocol payload located by scanning stdout lines from the end — tolerant
5196
+ * of noise around it and of a non-zero exit — use {@link Run.jsonLine}
5197
+ * instead.
5198
+ */
5199
+ static json = json;
5200
+ /**
5201
+ * Runs `command` and, **scanning stdout lines from the end**, resolves with
5202
+ * the first line that both parses as JSON and decodes against `schema` —
5203
+ * the framing variant of {@link Run.json}, for a child that reports through
5204
+ * a single JSON protocol payload near the end of its output.
5205
+ *
5206
+ * @remarks
5207
+ * The framing tolerates noise on **both sides** of the payload: noise before
5208
+ * it (a subprocess-loaded hook's own `console.log`, a tool's warnings) and
5209
+ * noise after it (a hook logging from `process.on("exit", ...)` fires after
5210
+ * the payload has flushed — the trigger for widening the old "last non-empty
5211
+ * line must decode" contract, spencerbeggs/effected#292). Lines are split on
5212
+ * `\r?\n`, whitespace-only lines are dropped, and the scan runs from the last
5213
+ * line backwards until one decodes. The tolerance is positional, not
5214
+ * volumetric: the whole of stdout is still captured under
5215
+ * {@link RunOptions.maxOutputBytes} (default
5216
+ * {@link DEFAULT_MAX_OUTPUT_BYTES}, 16 MiB), so a child whose noise exceeds
5217
+ * the ceiling fails typed as `"tooLarge"` before any line is examined —
5218
+ * raise the ceiling for a child known to be loud in volume.
5219
+ *
5220
+ * The scan's consequence: when **multiple** lines decode under `schema`, the
5221
+ * **last** one wins. A child must therefore never emit two schema-valid
5222
+ * lines, and a consumer schema should be shaped so an accidental log line
5223
+ * cannot satisfy it — a discriminated envelope with a required literal field
5224
+ * (`ok: true | false`, the shape `@effected/workspaces`' `ReplayPayload`
5225
+ * uses) rather than a permissive record a stray `console.log(someObject)`
5226
+ * might match.
5227
+ *
5228
+ * Unlike {@link Run.json}, this parses **regardless of the exit code** — a
5229
+ * deliberate posture, not an oversight. A protocol payload discriminates
5230
+ * success in-band (its own `ok` field, its own error shape), so the payload
5231
+ * outranks the exit code: a child that crashes *after* flushing its payload
5232
+ * still reported, and a caller that wants exit-code semantics has
5233
+ * {@link Run.json}. When no line decodes anywhere, the typed
5234
+ * {@link CommandOutputError} carries the exit code and both captured streams
5235
+ * (redacted) as context, so the failure is diagnosable without re-running.
5236
+ * Its `kind` preserves the near-miss diagnostic: `"schema"` when at least
5237
+ * one line parsed as JSON but none decoded — with the **last parseable
5238
+ * line's** decode failure as `cause`, that line being the most probable
5239
+ * intended payload — and `"notJson"` only when no non-empty line was JSON at
5240
+ * all (carrying the last non-empty line's parse error). A spawn failure or
5241
+ * an opted-in timeout still fails with {@link CommandFailedError}.
5242
+ */
5243
+ static jsonLine = jsonLine;
5244
+ /**
5245
+ * Runs `command` and resolves with its exit code alone.
5246
+ *
5247
+ * @remarks
5248
+ * A non-zero exit is a *result* here, not a failure — see {@link Run}'s
5249
+ * remarks for the split against {@link Run.text}, {@link Run.lines} and
5250
+ * {@link Run.json}.
5251
+ */
5252
+ static exitCode = exitCode;
5253
+ /**
5254
+ * Runs `command` and resolves with whether it exited zero, collapsing a
5255
+ * spawn or other classified failure to `false` rather than propagating it.
5256
+ */
5257
+ static succeeds = succeeds;
5258
+ /** Decoded stdout lines as they arrive, for output too large or too long-lived to collect. */
5259
+ static stream = stream;
5260
+ /**
5261
+ * Spawns `command` and resolves with its pid without waiting for exit.
5262
+ *
5263
+ * @remarks
5264
+ * Unrefs the child **before** this scope closes, so it survives the
5265
+ * caller's scope closing — the Node backend's release skips the kill for an
5266
+ * unref'd child, and reversing that order kills it with the scope instead.
5267
+ * Fails with {@link CommandFailedError} if the process never starts.
5268
+ */
5269
+ static detach = detach;
5270
+ /**
5271
+ * Adds environment variables to a command WITHOUT losing the parent
5272
+ * environment: merges `env` over any existing command environment (new values
5273
+ * win, matching core's `ChildProcess.setEnv`) and sets `extendEnv: true`.
5274
+ *
5275
+ * @remarks
5276
+ * This combinator exists because of a core trap: `ChildProcess.setEnv` merges
5277
+ * into `options.env` but never sets `extendEnv`, and the Node spawner resolves
5278
+ * the child environment as `extendEnv ? { ...process.env, ...env } : env` — so
5279
+ * a command built with bare `setEnv({ SOME_VAR: x })` spawns a child whose
5280
+ * ENTIRE environment is that one variable: no `PATH`, no `HOME`. The failure is
5281
+ * silent at the type level and surfaces as "spawned tool cannot find its own
5282
+ * binary" at runtime.
5283
+ *
5284
+ * Deliberately forces `extendEnv: true` even where construction set it `false`
5285
+ * — inheriting the parent environment is this combinator's entire purpose. A
5286
+ * caller who wants a hermetic environment uses core's `setEnv` or construction
5287
+ * options (`ChildProcess.make(cmd, args, { env, extendEnv: false })`) directly.
5288
+ *
5289
+ * For a pipeline, applies to every command in the pipeline (mirroring core's
5290
+ * `setEnv`), preserving the pipe's own options. Composes core's public
5291
+ * vocabulary (`ChildProcess.make`, `ChildProcess.pipeTo`) — it re-declares
5292
+ * nothing.
5293
+ */
5294
+ static extendEnv = extendEnv;
5295
+ /** Default ceiling on captured bytes per stream. See {@link DEFAULT_MAX_OUTPUT_BYTES}. */
5296
+ static DEFAULT_MAX_OUTPUT_BYTES = DEFAULT_MAX_OUTPUT_BYTES;
5297
+ /** The placeholder written in place of a redacted secret. See {@link REDACTED}. */
5298
+ static REDACTED = "***";
5299
+ };
5300
+ //#endregion
5301
+ //#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/ReleaseAgeGate.js
4631
5302
  const MS_PER_MINUTE = 6e4;
4632
5303
  /**
4633
5304
  * A source's partial contribution to a {@link ReleaseAgeGate}: the effective
@@ -4797,7 +5468,7 @@ var ReleaseAgeGate = class ReleaseAgeGate extends effect.Schema.Class("ReleaseAg
4797
5468
  }
4798
5469
  };
4799
5470
  //#endregion
4800
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/ImporterDependency.js
5471
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/ImporterDependency.js
4801
5472
  /**
4802
5473
  * One declared dependency of one workspace importer, as the lockfile records it.
4803
5474
  *
@@ -4835,7 +5506,7 @@ var ImporterDependency = class extends effect.Schema.Class("ImporterDependency")
4835
5506
  depType: DependencyField
4836
5507
  }) {};
4837
5508
  //#endregion
4838
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/LockfileImporter.js
5509
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileImporter.js
4839
5510
  /**
4840
5511
  * One workspace importer's declared dependencies, as the lockfile records them.
4841
5512
  *
@@ -4859,7 +5530,7 @@ var LockfileImporter = class extends effect.Schema.Class("LockfileImporter")({
4859
5530
  dependencies: effect.Schema.Array(ImporterDependency)
4860
5531
  }) {};
4861
5532
  //#endregion
4862
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/ResolvedPackage.js
5533
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/ResolvedPackage.js
4863
5534
  const EMPTY_DEPENDENCIES = {};
4864
5535
  /**
4865
5536
  * A package resolved from a lockfile.
@@ -4894,7 +5565,7 @@ var ResolvedPackage = class extends effect.Schema.Class("ResolvedPackage")({
4894
5565
  dependencies: effect.Schema.Record(effect.Schema.String, effect.Schema.String).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed(EMPTY_DEPENDENCIES)), effect.Schema.withConstructorDefault(effect.Effect.succeed(EMPTY_DEPENDENCIES)))
4895
5566
  }) {};
4896
5567
  //#endregion
4897
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/WorkspaceDependency.js
5568
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/WorkspaceDependency.js
4898
5569
  /**
4899
5570
  * A directed dependency edge between two workspace packages as recorded in
4900
5571
  * the lockfile.
@@ -4916,7 +5587,7 @@ var WorkspaceDependency = class extends effect.Schema.Class("WorkspaceDependency
4916
5587
  constraint: effect.Schema.String
4917
5588
  }) {};
4918
5589
  //#endregion
4919
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/PnpmExtension.js
5590
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/PnpmExtension.js
4920
5591
  /**
4921
5592
  * Extension data specific to pnpm lockfiles, attached to `Lockfile.extension`
4922
5593
  * when the format is `"pnpm"`.
@@ -4941,7 +5612,7 @@ var PnpmExtension = class extends effect.Schema.Class("PnpmExtension")({
4941
5612
  }))
4942
5613
  }) {};
4943
5614
  //#endregion
4944
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/LockfileFormat.js
5615
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileFormat.js
4945
5616
  /**
4946
5617
  * The lockfile formats this package parses: bun's `bun.lock` (JSONC), npm's
4947
5618
  * `package-lock.json` (v2/v3 JSON), pnpm's `pnpm-lock.yaml` and yarn Berry's
@@ -4979,7 +5650,7 @@ const FILENAMES = {
4979
5650
  */
4980
5651
  const filenameFor = (format) => FILENAMES[format][0];
4981
5652
  //#endregion
4982
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/shared.js
5653
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/shared.js
4983
5654
  /**
4984
5655
  * The four dependency sections of a manifest, in a stable order — the shared
4985
5656
  * dependency-sections table (v3's `DEP_SECTIONS`). Each entry is both the
@@ -6908,7 +7579,7 @@ var JsoncModifier = class {
6908
7579
  });
6909
7580
  };
6910
7581
  //#endregion
6911
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/bun.js
7582
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/bun.js
6912
7583
  const DepRecord$2 = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
6913
7584
  const BunWorkspaceEntry = effect.Schema.Struct({
6914
7585
  name: effect.Schema.optionalKey(effect.Schema.String),
@@ -7001,7 +7672,7 @@ const toFields$3 = (raw) => effect.Effect.gen(function* () {
7001
7672
  };
7002
7673
  });
7003
7674
  //#endregion
7004
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/npm.js
7675
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/npm.js
7005
7676
  const DepRecord$1 = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
7006
7677
  const NpmPackageEntry = effect.Schema.Struct({
7007
7678
  name: effect.Schema.optionalKey(effect.Schema.String),
@@ -13923,7 +14594,7 @@ function deepEqualValues(a, b) {
13923
14594
  return false;
13924
14595
  }
13925
14596
  //#endregion
13926
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/documents.js
14597
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/documents.js
13927
14598
  /**
13928
14599
  * An empty YAML document composes to `null` (`Yaml.parseAll("")` is `[null]`,
13929
14600
  * and the trailing document of an env-only `pnpm-lock.yaml` is `null` too).
@@ -13993,7 +14664,7 @@ const selectSoleDocument = (content) => effect.Effect.gen(function* () {
13993
14664
  };
13994
14665
  });
13995
14666
  //#endregion
13996
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/pnpm.js
14667
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/pnpm.js
13997
14668
  const PnpmImporterDeps = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.Struct({
13998
14669
  specifier: effect.Schema.String,
13999
14670
  version: effect.Schema.String
@@ -14118,7 +14789,7 @@ const toFields$1 = (raw) => effect.Effect.gen(function* () {
14118
14789
  };
14119
14790
  });
14120
14791
  //#endregion
14121
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/internal/yarn.js
14792
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/internal/yarn.js
14122
14793
  const YarnLockfileRaw = effect.Schema.Record(effect.Schema.String, effect.Schema.Unknown);
14123
14794
  const DepRecord = effect.Schema.optionalKey(effect.Schema.Record(effect.Schema.String, effect.Schema.String));
14124
14795
  const YarnEntry = effect.Schema.Struct({
@@ -14241,7 +14912,7 @@ const cleanYarnDeps = (deps) => {
14241
14912
  return Object.fromEntries(Object.entries(deps).map(([name, value]) => [name, value.startsWith("npm:") ? value.slice(4) : value]));
14242
14913
  };
14243
14914
  //#endregion
14244
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/Lockfile.js
14915
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/Lockfile.js
14245
14916
  const EMPTY_IMPORTERS = [];
14246
14917
  /**
14247
14918
  * Failure of `Lockfile.parse`: the given content is not a valid lockfile of
@@ -14485,7 +15156,7 @@ var Lockfile = class Lockfile extends effect.Schema.Class("Lockfile")({
14485
15156
  }
14486
15157
  };
14487
15158
  //#endregion
14488
- //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._ff048038a9678f5144f817ad24d8f96e/node_modules/@effected/lockfiles/LockfileIntegrity.js
15159
+ //#region ../../node_modules/.pnpm/@effected+lockfiles@0.3.2_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__@effected+npm@0._3c1784fba62fde9a5bac4cf15387fd04/node_modules/@effected/lockfiles/LockfileIntegrity.js
14489
15160
  /**
14490
15161
  * The minimal manifest shape {@link LockfileIntegrity.compare} checks a
14491
15162
  * lockfile against: a package name plus the four optional dependency maps.
@@ -17284,7 +17955,7 @@ var Package = class Package extends effect.Schema.Class("Package")({
17284
17955
  }
17285
17956
  };
17286
17957
  //#endregion
17287
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspacePackage.js
17958
+ //#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
17288
17959
  const EMPTY$1 = Object.freeze(Object.create(null));
17289
17960
  const EMPTY_MANIFEST = Object.freeze(Object.create(null));
17290
17961
  /**
@@ -17882,7 +18553,7 @@ var Walker$1 = class {
17882
18553
  static findRoot = findRoot$1;
17883
18554
  };
17884
18555
  //#endregion
17885
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceRoot.js
18556
+ //#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
17886
18557
  /**
17887
18558
  * The marker filenames {@link WorkspaceRoot} probes for, in priority order.
17888
18559
  *
@@ -18069,7 +18740,7 @@ var WorkspaceRoot = class WorkspaceRoot extends effect.Context.Service()("@effec
18069
18740
  static layerTest = (root) => effect.Layer.effect(WorkspaceRoot, WorkspaceRoot.makeTest(root)).pipe(effect.Layer.provide(effect.Path.layer));
18070
18741
  };
18071
18742
  //#endregion
18072
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/limits.js
18743
+ //#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
18073
18744
  /**
18074
18745
  * Hard ceiling on directories the enumerator will visit for one pattern set.
18075
18746
  * Guards the pathological case a depth cap alone does not: a wide, shallow
@@ -18087,7 +18758,7 @@ const MAX_ENUMERATION_ENTRIES = 1e5;
18087
18758
  */
18088
18759
  const PRUNED_DIRECTORIES = /* @__PURE__ */ new Set([".git", "node_modules"]);
18089
18760
  //#endregion
18090
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/traverse.js
18761
+ //#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
18091
18762
  /** Directory names never descended into. */
18092
18763
  const isPruned = (entry) => PRUNED_DIRECTORIES.has(entry);
18093
18764
  /** Join root-relative POSIX segments; `""` is the root itself. */
@@ -18177,7 +18848,7 @@ var Traversal = class {
18177
18848
  }
18178
18849
  };
18179
18850
  //#endregion
18180
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/enumerate.js
18851
+ //#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
18181
18852
  /** Strip a trailing slash from `GlobPattern.enumerationPrefix` to get a relative directory. */
18182
18853
  const baseOf = (pattern) => pattern.enumerationPrefix.replace(/\/$/, "");
18183
18854
  /**
@@ -18247,7 +18918,7 @@ const enumerate = (root, globs, options) => effect.Effect.gen(function* () {
18247
18918
  return results;
18248
18919
  });
18249
18920
  //#endregion
18250
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/patterns.js
18921
+ //#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
18251
18922
  const stringsOf = (value) => Array.isArray(value) ? value.filter((entry) => typeof entry === "string") : void 0;
18252
18923
  /** The `packages:` list of a `pnpm-workspace.yaml` document. Total on a parsed document. */
18253
18924
  const pnpmPatternsOf = (document) => {
@@ -18304,7 +18975,7 @@ const readPatterns = (root) => effect.Effect.gen(function* () {
18304
18975
  return manifestPatternsOf(manifest);
18305
18976
  });
18306
18977
  //#endregion
18307
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceDiscovery.js
18978
+ //#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
18308
18979
  /**
18309
18980
  * Raised when a workspace member's `package.json` cannot be read, parsed, or
18310
18981
  * used — it is missing, malformed, or lacks a `name` or `version`.
@@ -18557,6 +19228,15 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18557
19228
  for (const entry of index) if (filePath.startsWith(entry.prefix)) return effect.Option.some(entry.package);
18558
19229
  return effect.Option.none();
18559
19230
  };
19231
+ const packageIndexes = /* @__PURE__ */ new WeakMap();
19232
+ const packagesByName = (all) => {
19233
+ const cached = packageIndexes.get(all);
19234
+ if (cached !== void 0) return cached;
19235
+ const index = /* @__PURE__ */ new Map();
19236
+ for (const pkg of all) if (!index.has(pkg.name)) index.set(pkg.name, pkg);
19237
+ packageIndexes.set(all, index);
19238
+ return index;
19239
+ };
18560
19240
  return {
18561
19241
  info: effect.Effect.fn("WorkspaceDiscovery.info")(function* () {
18562
19242
  return (yield* memo).info;
@@ -18570,7 +19250,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18570
19250
  }),
18571
19251
  getPackage: effect.Effect.fn("WorkspaceDiscovery.getPackage")(function* (name) {
18572
19252
  const all = yield* packages;
18573
- const found = all.find((pkg) => pkg.name === name);
19253
+ const found = packagesByName(all).get(name);
18574
19254
  if (found !== void 0) return found;
18575
19255
  return yield* effect.Effect.fail(new PackageNotFoundError({
18576
19256
  name,
@@ -18734,7 +19414,16 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18734
19414
  */
18735
19415
  static workspaceResolver = effect.Layer.effect(WorkspaceResolver, effect.Effect.gen(function* () {
18736
19416
  const discovery = yield* WorkspaceDiscovery;
18737
- return { versionOf: (packageName) => discovery.listPackages().pipe(effect.Effect.map((all) => effect.Option.fromUndefinedOr(all.find((pkg) => pkg.name === packageName)?.version)), effect.Effect.mapError((cause) => new DependencyResolutionError({
19417
+ const versionIndexes = /* @__PURE__ */ new WeakMap();
19418
+ const versionsByName = (all) => {
19419
+ const cached = versionIndexes.get(all);
19420
+ if (cached !== void 0) return cached;
19421
+ const index = /* @__PURE__ */ new Map();
19422
+ for (const pkg of all) if (!index.has(pkg.name)) index.set(pkg.name, pkg.version);
19423
+ versionIndexes.set(all, index);
19424
+ return index;
19425
+ };
19426
+ return { versionOf: (packageName) => discovery.listPackages().pipe(effect.Effect.map((all) => effect.Option.fromUndefinedOr(versionsByName(all).get(packageName))), effect.Effect.mapError((cause) => new DependencyResolutionError({
18738
19427
  specifier: `workspace:${packageName}`,
18739
19428
  cause
18740
19429
  }))) };
@@ -18742,7 +19431,7 @@ var WorkspaceDiscovery = class WorkspaceDiscovery extends effect.Context.Service
18742
19431
  };
18743
19432
  const isStringRecord$2 = (value) => value !== null && typeof value === "object" && !Array.isArray(value) && Object.values(value).every((entry) => typeof entry === "string");
18744
19433
  //#endregion
18745
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/DependencyGraph.js
19434
+ //#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
18746
19435
  /**
18747
19436
  * Raised when the workspace dependency graph cannot be topologically ordered
18748
19437
  * because it contains a cycle.
@@ -18975,10 +19664,32 @@ const kahn = (edges) => {
18975
19664
  };
18976
19665
  };
18977
19666
  //#endregion
18978
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
19667
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/GitCommand.js
19668
+ /** The mask every whole-value sensitive positional is replaced with. */
19669
+ const REDACTED = "<redacted>";
19670
+ const secretValue = (value) => ({
19671
+ redact: "value",
19672
+ value
19673
+ });
19674
+ const secretUrl = (value) => ({
19675
+ redact: "url",
19676
+ value
19677
+ });
19678
+ /**
19679
+ * Masks the userinfo component of a URL (`scheme://user:token@host/...` →
19680
+ * `scheme://<redacted>@host/...`). A value carrying no embedded userinfo — a
19681
+ * remote name, a credential-free URL, an scp-style `host:path` — passes
19682
+ * through untouched, so the common case stays fully debuggable.
19683
+ *
19684
+ * The userinfo match is greedy (`[^/]*@` — everything through the LAST `@`
19685
+ * before the first path slash): URL authorities split at the last `@`, so a
19686
+ * password containing a literal `@` (`user:p\@ss\@host/...`) must be
19687
+ * consumed whole or its tail would survive into `redactedArgs`.
19688
+ */
19689
+ const redactUrlUserinfo = (value) => value.replace(/^([a-z][a-z0-9+.-]*:\/\/)[^/]*@/i, `$1${REDACTED}@`);
18979
19690
  /**
18980
- * Builds a `git` `ChildProcess.StandardCommand` with the argv this package
18981
- * classifies against.
19691
+ * Builds a `git` {@link GitInvocation} with the argv this package classifies
19692
+ * against.
18982
19693
  *
18983
19694
  * @remarks
18984
19695
  * `LC_ALL=C` is pinned on every invocation because git's stderr
@@ -18994,10 +19705,18 @@ const kahn = (edges) => {
18994
19705
  * the working directory per invocation via `ChildProcess.setCwd`, which
18995
19706
  * returns a new command and leaves this one unchanged.
18996
19707
  */
18997
- const git = (args) => effect_unstable_process.ChildProcess.make("git", args, {
18998
- env: { LC_ALL: "C" },
18999
- extendEnv: true
19000
- });
19708
+ const git = (args, stdin) => {
19709
+ const raw = args.map((arg) => typeof arg === "string" ? arg : arg.value);
19710
+ const redactedArgs = args.map((arg) => typeof arg === "string" ? arg : arg.redact === "value" ? REDACTED : redactUrlUserinfo(arg.value));
19711
+ return {
19712
+ command: effect_unstable_process.ChildProcess.make("git", raw, {
19713
+ env: { LC_ALL: "C" },
19714
+ extendEnv: true,
19715
+ ...stdin !== void 0 ? { stdin: effect.Stream.make(new TextEncoder().encode(stdin)) } : {}
19716
+ }),
19717
+ redactedArgs
19718
+ };
19719
+ };
19001
19720
  const show = (ref, path) => git(["show", `${ref}:${path}`]);
19002
19721
  const lsTree = (ref, pathspec = []) => git([
19003
19722
  "ls-tree",
@@ -19056,7 +19775,7 @@ const checkout = (ref, detach = false) => git([
19056
19775
  const fetch$1 = (remote, ref, depth, tag = false) => git([
19057
19776
  "fetch",
19058
19777
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
19059
- remote,
19778
+ secretUrl(remote),
19060
19779
  ...tag ? ["tag"] : [],
19061
19780
  ref
19062
19781
  ]);
@@ -19072,7 +19791,7 @@ const submoduleAdd = (url, path, depth) => git([
19072
19791
  "add",
19073
19792
  ...depth !== void 0 ? ["--depth", String(depth)] : [],
19074
19793
  "--",
19075
- url,
19794
+ secretUrl(url),
19076
19795
  path
19077
19796
  ]);
19078
19797
  const sparseCheckoutSet = (patterns, cone) => git([
@@ -19085,13 +19804,55 @@ const configSet = (key, value, file) => git([
19085
19804
  "config",
19086
19805
  ...file !== void 0 ? ["-f", file] : [],
19087
19806
  key,
19088
- value
19807
+ secretValue(value)
19089
19808
  ]);
19090
19809
  const add = (paths) => git([
19091
19810
  "add",
19092
19811
  "--",
19093
19812
  ...paths
19094
19813
  ]);
19814
+ const reset = (mode = "mixed", ref) => git([
19815
+ "reset",
19816
+ `--${mode}`,
19817
+ ...ref !== void 0 ? [ref] : []
19818
+ ]);
19819
+ const clean = (directories = false, ignored = false, paths = []) => git([
19820
+ "clean",
19821
+ "--force",
19822
+ ...directories ? ["-d"] : [],
19823
+ ...ignored ? ["-x"] : [],
19824
+ ...paths.length > 0 ? ["--", ...paths] : []
19825
+ ]);
19826
+ const restore = (paths, source, staged = false, worktree = false) => git([
19827
+ "restore",
19828
+ ...source !== void 0 ? ["--source", source] : [],
19829
+ ...staged ? ["--staged"] : [],
19830
+ ...worktree ? ["--worktree"] : [],
19831
+ "--",
19832
+ ...paths
19833
+ ]);
19834
+ const branchCreate = (name, startPoint, checkout = false, force = false) => checkout ? git([
19835
+ "checkout",
19836
+ force ? "-B" : "-b",
19837
+ name,
19838
+ ...startPoint !== void 0 ? [startPoint] : []
19839
+ ]) : git([
19840
+ "branch",
19841
+ ...force ? ["-f"] : [],
19842
+ name,
19843
+ ...startPoint !== void 0 ? [startPoint] : []
19844
+ ]);
19845
+ const branchDelete = (name, force = false) => git([
19846
+ "branch",
19847
+ force ? "-D" : "-d",
19848
+ name
19849
+ ]);
19850
+ const isShallow = () => git(["rev-parse", "--is-shallow-repository"]);
19851
+ const fetchUnshallow = (remote = "origin") => git([
19852
+ "fetch",
19853
+ "--unshallow",
19854
+ secretUrl(remote)
19855
+ ]);
19095
19856
  const nameStatus = (base, head, relative = false) => git([
19096
19857
  "diff",
19097
19858
  "--name-status",
@@ -19132,40 +19893,276 @@ const status = () => git([
19132
19893
  "--porcelain",
19133
19894
  "-z"
19134
19895
  ]);
19135
- /**
19136
- * Pure constructors for the `git` `ChildProcess.Command` values this package
19137
- * spawns.
19138
- *
19139
- * @remarks
19140
- * Every constructor returns a cwd-less, argv-only `Command` — no spawning,
19141
- * no working directory baked in. `Git` applies the working directory per
19142
- * call with `ChildProcess.setCwd` and owns the actual spawn, timeout, and
19143
- * error classification.
19144
- *
19145
- * @public
19146
- */
19147
- var GitCommand = class {
19148
- constructor() {}
19149
- /**
19150
- * `git show <ref>:<path>` the contents of `path` as it existed at `ref`,
19151
- * without checking anything out.
19152
- */
19153
- static show = show;
19154
- /**
19155
- * `git ls-tree -r -z <ref> [-- <pathspec>...]` every path in the tree at
19156
- * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
19157
- *
19158
- * @remarks
19159
- * `-z` is load-bearing: git paths may themselves contain newlines, so the
19160
- * caller must split on `"\0"`, never on `"\n"`. When `pathspec` is provided,
19161
- * a literal `--` separator is inserted before the pathspec entries to prevent
19162
- * git from interpreting pathspec values as options.
19163
- */
19164
- static lsTree = lsTree;
19165
- /**
19166
- * `git cat-file -e <ref>` — checks whether `ref` resolves to an existing
19167
- * object, without printing it. A non-zero exit means the ref does not exist.
19168
- */
19896
+ const submoduleStatus = (paths = [], recursive = false) => git([
19897
+ "submodule",
19898
+ "status",
19899
+ ...recursive ? ["--recursive"] : [],
19900
+ ...paths.length > 0 ? ["--", ...paths] : []
19901
+ ]);
19902
+ const submoduleInit = (paths = []) => git([
19903
+ "submodule",
19904
+ "init",
19905
+ ...paths.length > 0 ? ["--", ...paths] : []
19906
+ ]);
19907
+ const submoduleDeinit = (paths, all = false, force = false) => git([
19908
+ "submodule",
19909
+ "deinit",
19910
+ ...force ? ["--force"] : [],
19911
+ ...all ? ["--all"] : ["--", ...paths]
19912
+ ]);
19913
+ const submoduleSync = (paths = [], recursive = false) => git([
19914
+ "submodule",
19915
+ "sync",
19916
+ ...recursive ? ["--recursive"] : [],
19917
+ ...paths.length > 0 ? ["--", ...paths] : []
19918
+ ]);
19919
+ const submoduleSetUrl = (path, url) => git([
19920
+ "submodule",
19921
+ "set-url",
19922
+ "--",
19923
+ path,
19924
+ secretUrl(url)
19925
+ ]);
19926
+ const submoduleSetBranch = (path, branch) => git([
19927
+ "submodule",
19928
+ "set-branch",
19929
+ ...branch === void 0 ? ["--default"] : ["--branch", branch],
19930
+ "--",
19931
+ path
19932
+ ]);
19933
+ const submoduleAbsorbgitdirs = (paths = []) => git([
19934
+ "submodule",
19935
+ "absorbgitdirs",
19936
+ ...paths.length > 0 ? ["--", ...paths] : []
19937
+ ]);
19938
+ const submoduleForeach = (command, recursive = false) => git([
19939
+ "submodule",
19940
+ "foreach",
19941
+ ...recursive ? ["--recursive"] : [],
19942
+ command
19943
+ ]);
19944
+ const lsRemote = (remote, heads = false, tags = false, patterns = []) => git([
19945
+ "ls-remote",
19946
+ ...heads ? ["--heads"] : [],
19947
+ ...tags ? ["--tags"] : [],
19948
+ secretUrl(remote),
19949
+ ...patterns
19950
+ ]);
19951
+ const remoteAdd = (name, url) => git([
19952
+ "remote",
19953
+ "add",
19954
+ name,
19955
+ secretUrl(url)
19956
+ ]);
19957
+ const remoteRemove = (name) => git([
19958
+ "remote",
19959
+ "remove",
19960
+ name
19961
+ ]);
19962
+ const remoteSetUrl = (name, url) => git([
19963
+ "remote",
19964
+ "set-url",
19965
+ name,
19966
+ secretUrl(url)
19967
+ ]);
19968
+ const stashRef = (index) => `stash@{${index}}`;
19969
+ const stashPush = (message, includeUntracked = false, paths = []) => git([
19970
+ "stash",
19971
+ "push",
19972
+ ...includeUntracked ? ["--include-untracked"] : [],
19973
+ ...message !== void 0 ? ["-m", message] : [],
19974
+ ...paths.length > 0 ? ["--", ...paths] : []
19975
+ ]);
19976
+ const stashPop = (index) => git([
19977
+ "stash",
19978
+ "pop",
19979
+ ...index !== void 0 ? [stashRef(index)] : []
19980
+ ]);
19981
+ const stashApply = (index) => git([
19982
+ "stash",
19983
+ "apply",
19984
+ ...index !== void 0 ? [stashRef(index)] : []
19985
+ ]);
19986
+ const stashDrop = (index) => git([
19987
+ "stash",
19988
+ "drop",
19989
+ ...index !== void 0 ? [stashRef(index)] : []
19990
+ ]);
19991
+ const stashList = () => git([
19992
+ "stash",
19993
+ "list",
19994
+ "-z",
19995
+ "--format=%gd%x1f%H%x1f%gs"
19996
+ ]);
19997
+ const branchList = (remotes = false, all = false) => git([
19998
+ "branch",
19999
+ "--list",
20000
+ ...all ? ["--all"] : remotes ? ["--remotes"] : [],
20001
+ "--format=%(HEAD)%00%(refname:short)%00%(objectname)"
20002
+ ]);
20003
+ const tagCreate = (name, ref, message, force = false) => git([
20004
+ "tag",
20005
+ ...force ? ["--force"] : [],
20006
+ ...message !== void 0 ? ["-m", message] : [],
20007
+ name,
20008
+ ...ref !== void 0 ? [ref] : []
20009
+ ]);
20010
+ const tagDelete = (name) => git([
20011
+ "tag",
20012
+ "--delete",
20013
+ name
20014
+ ]);
20015
+ const tagList = (pattern) => git([
20016
+ "tag",
20017
+ "--list",
20018
+ ...pattern !== void 0 ? [pattern] : []
20019
+ ]);
20020
+ const forEachRef = (patterns = []) => git([
20021
+ "for-each-ref",
20022
+ "--format=%(refname)%00%(objectname)%00%(objecttype)",
20023
+ ...patterns
20024
+ ]);
20025
+ const revList = (ref, limit, firstParent = false) => git([
20026
+ "rev-list",
20027
+ ...limit !== void 0 ? [`--max-count=${limit}`] : [],
20028
+ ...firstParent ? ["--first-parent"] : [],
20029
+ ref
20030
+ ]);
20031
+ const commit = (message, all = false, allowEmpty = false, amend = false, author) => git([
20032
+ "commit",
20033
+ ...all ? ["--all"] : [],
20034
+ ...allowEmpty ? ["--allow-empty"] : [],
20035
+ ...amend ? ["--amend"] : [],
20036
+ ...author !== void 0 ? [`--author=${author}`] : [],
20037
+ "-m",
20038
+ message
20039
+ ]);
20040
+ const push$1 = (remote, refspec, force = false, forceWithLease = false, tags = false, setUpstream = false) => git([
20041
+ "push",
20042
+ ...force ? ["--force"] : [],
20043
+ ...forceWithLease ? ["--force-with-lease"] : [],
20044
+ ...tags ? ["--tags"] : [],
20045
+ ...setUpstream ? ["--set-upstream"] : [],
20046
+ secretUrl(remote),
20047
+ ...refspec !== void 0 ? [refspec] : []
20048
+ ]);
20049
+ const pull = (remote, ref, rebase = false, ffOnly = false) => git([
20050
+ "pull",
20051
+ ...rebase ? ["--rebase"] : [],
20052
+ ...ffOnly ? ["--ff-only"] : [],
20053
+ secretUrl(remote),
20054
+ ...ref !== void 0 ? [ref] : []
20055
+ ]);
20056
+ const configList = (file) => git([
20057
+ "config",
20058
+ ...file !== void 0 ? ["-f", file] : [],
20059
+ "--list",
20060
+ "-z"
20061
+ ]);
20062
+ const configGetAll = (key, file) => git([
20063
+ "config",
20064
+ ...file !== void 0 ? ["-f", file] : [],
20065
+ "--get-all",
20066
+ "-z",
20067
+ key
20068
+ ]);
20069
+ const configUnset = (key, file, all = false) => git([
20070
+ "config",
20071
+ ...file !== void 0 ? ["-f", file] : [],
20072
+ all ? "--unset-all" : "--unset",
20073
+ key
20074
+ ]);
20075
+ const rm = (paths, cached = false, recursive = false, force = false) => git([
20076
+ "rm",
20077
+ ...cached ? ["--cached"] : [],
20078
+ ...recursive ? ["-r"] : [],
20079
+ ...force ? ["--force"] : [],
20080
+ "--",
20081
+ ...paths
20082
+ ]);
20083
+ const mv = (source, destination, force = false) => git([
20084
+ "mv",
20085
+ ...force ? ["--force"] : [],
20086
+ "--",
20087
+ source,
20088
+ destination
20089
+ ]);
20090
+ const checkIgnore = (paths) => git([
20091
+ "check-ignore",
20092
+ "-z",
20093
+ "--stdin"
20094
+ ], paths.map((path) => `${path}\0`).join(""));
20095
+ const worktreeAdd = (path, ref, detach = false, force = false) => git([
20096
+ "worktree",
20097
+ "add",
20098
+ ...force ? ["--force"] : [],
20099
+ ...detach ? ["--detach"] : [],
20100
+ path,
20101
+ ...ref !== void 0 ? [ref] : []
20102
+ ]);
20103
+ const worktreeList = () => git([
20104
+ "worktree",
20105
+ "list",
20106
+ "--porcelain",
20107
+ "-z"
20108
+ ]);
20109
+ const worktreeRemove = (path, force = false) => git([
20110
+ "worktree",
20111
+ "remove",
20112
+ ...force ? ["--force"] : [],
20113
+ path
20114
+ ]);
20115
+ const lsFiles = (pathspec = []) => git([
20116
+ "ls-files",
20117
+ "--stage",
20118
+ "-z",
20119
+ ...pathspec.length > 0 ? ["--", ...pathspec] : []
20120
+ ]);
20121
+ /**
20122
+ * Pure constructors for the `git` {@link GitInvocation} values this package
20123
+ * spawns.
20124
+ *
20125
+ * @remarks
20126
+ * Every constructor returns a cwd-less, argv-only {@link GitInvocation} — no
20127
+ * spawning, no working directory baked in. `Git` applies the working
20128
+ * directory per call with `ChildProcess.setCwd` on `invocation.command` and
20129
+ * owns the actual spawn, timeout, and error classification.
20130
+ *
20131
+ * **Redaction policy.** A constructor whose argv carries a sensitive
20132
+ * positional — a config value (`configSet`), or a URL that may embed
20133
+ * userinfo (the remote of `fetch`, `fetchUnshallow`, `lsRemote`, `push` and
20134
+ * `pull`, and the url of `submoduleAdd`, `submoduleSetUrl`, `remoteAdd` and
20135
+ * `remoteSetUrl`) —
20136
+ * masks it in {@link GitInvocation.redactedArgs}: a config value becomes
20137
+ * `<redacted>` wholesale, a URL keeps everything but its `userinfo@`
20138
+ * component. The `Git` service persists only the redacted argv in error
20139
+ * values, and its span annotations carry stable identifiers only (`cwd`,
20140
+ * keys, paths, remote/ref names) — never config values, never URLs.
20141
+ *
20142
+ * @public
20143
+ */
20144
+ var GitCommand = class {
20145
+ constructor() {}
20146
+ /**
20147
+ * `git show <ref>:<path>` — the contents of `path` as it existed at `ref`,
20148
+ * without checking anything out.
20149
+ */
20150
+ static show = show;
20151
+ /**
20152
+ * `git ls-tree -r -z <ref> [-- <pathspec>...]` — every path in the tree at
20153
+ * `ref`, recursively, NUL-terminated, optionally scoped to `pathspec`.
20154
+ *
20155
+ * @remarks
20156
+ * `-z` is load-bearing: git paths may themselves contain newlines, so the
20157
+ * caller must split on `"\0"`, never on `"\n"`. When `pathspec` is provided,
20158
+ * a literal `--` separator is inserted before the pathspec entries to prevent
20159
+ * git from interpreting pathspec values as options.
20160
+ */
20161
+ static lsTree = lsTree;
20162
+ /**
20163
+ * `git cat-file -e <ref>` — checks whether `ref` resolves to an existing
20164
+ * object, without printing it. A non-zero exit means the ref does not exist.
20165
+ */
19169
20166
  static refExists = refExists;
19170
20167
  /**
19171
20168
  * `git merge-base <a> <b>` — the best common ancestor commit of `a` and `b`.
@@ -19238,9 +20235,106 @@ var GitCommand = class {
19238
20235
  /**
19239
20236
  * Mutating: `git fetch [--depth <n>] <remote> [tag] <ref>` — fetches the given
19240
20237
  * ref from a remote, optionally with a depth limit and the `tag` keyword.
20238
+ *
20239
+ * @remarks
20240
+ * `remote` may be a URL as well as a remote name; an embedded
20241
+ * `userinfo@` credential is masked in {@link GitInvocation.redactedArgs}.
19241
20242
  */
19242
20243
  static fetch = fetch$1;
19243
20244
  /**
20245
+ * Mutating: `git fetch --unshallow <remote>` — converts a shallow clone
20246
+ * into a complete one by fetching the missing history.
20247
+ *
20248
+ * @remarks
20249
+ * `--unshallow` is a distinct MODE, not a depth value: git rejects it
20250
+ * outright in a repository that is not shallow, with
20251
+ * `--unshallow on a complete repository does not make sense`, so it
20252
+ * cannot be expressed as `fetch`'s `depth` option. The caller decides
20253
+ * whether to run it — probe with `Git.isShallow` first.
20254
+ *
20255
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20256
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20257
+ */
20258
+ static fetchUnshallow = fetchUnshallow;
20259
+ /**
20260
+ * `git rev-parse --is-shallow-repository` — prints `true` when the
20261
+ * repository is a shallow clone, `false` otherwise.
20262
+ *
20263
+ * @remarks
20264
+ * A dedicated probe constructor, deliberately separate from
20265
+ * {@link GitCommand.revParse}: `revParse` takes a REF and resolves it,
20266
+ * while this takes nothing and answers a repository-shape question.
20267
+ * Folding the flag into `revParse` would make that constructor
20268
+ * sometimes-takes-a-ref, sometimes-takes-a-flag.
20269
+ */
20270
+ static isShallow = isShallow;
20271
+ /**
20272
+ * Mutating: `git reset --soft|--mixed|--hard [<ref>]` — moves `HEAD` (and,
20273
+ * per mode, the index and working tree) to `ref`.
20274
+ *
20275
+ * @remarks
20276
+ * The mode flag is always explicit — `--mixed` is emitted for the default
20277
+ * rather than omitted — so the argv states what runs. `ref` may be any
20278
+ * commit-ish, including a gitlink sha.
20279
+ */
20280
+ static reset = reset;
20281
+ /**
20282
+ * Mutating: `git clean --force [-d] [-x] [-- <paths>...]` — deletes
20283
+ * untracked files from the working tree.
20284
+ *
20285
+ * @remarks
20286
+ * `--force` is unconditional: this constructor exists so a consumer can
20287
+ * restore a tree to a known state (e.g. before retrying a non-idempotent
20288
+ * operation), and without `--force` git refuses to clean at all under the
20289
+ * default `clean.requireForce` config — a clean that silently did nothing
20290
+ * would hand the retry the same dirty tree. `-d` removes untracked
20291
+ * directories too; `-x` removes ignored files as well. The literal `--`
20292
+ * separator makes the optional pathspec injection-safe by construction.
20293
+ */
20294
+ static clean = clean;
20295
+ /**
20296
+ * Mutating: `git restore [--source <ref>] [--staged] [--worktree] -- <paths...>`
20297
+ * — restores the given paths from the index (or from `source`), the
20298
+ * `checkout -- <paths>`-shaped operation.
20299
+ *
20300
+ * @remarks
20301
+ * This is a separate constructor precisely because {@link GitCommand.checkout}'s
20302
+ * service guard refuses `--` and option-like refs by design — `restore` is
20303
+ * git's own verb for pathspec restoration, and its paths always sit behind
20304
+ * a literal `--`, so they are injection-safe by construction. With neither
20305
+ * `staged` nor `worktree` set, git defaults to restoring the working tree.
20306
+ */
20307
+ static restore = restore;
20308
+ /**
20309
+ * Mutating: `git branch [-f] <name> [<start-point>]`, or
20310
+ * `git checkout (-b | -B) <name> [<start-point>]` when `checkout` is true —
20311
+ * creates a branch, optionally from an explicit start point, optionally
20312
+ * switching to it, optionally force-resetting an existing branch.
20313
+ *
20314
+ * @remarks
20315
+ * Branch creation is a branch-member concern, NOT a widening of
20316
+ * {@link GitCommand.checkout}: `checkout`'s contract stays "move to an
20317
+ * existing ref" and its option-like-ref refusal stays intact. The `-b` /
20318
+ * `-B` here is this constructor's own literal, never caller data.
20319
+ *
20320
+ * `force` with `checkout` exists because the delete-then-create longhand
20321
+ * (`branch -D` swallowed, then `checkout -b`) papers over a real edge:
20322
+ * `git branch -D` refuses to delete the currently checked-out branch,
20323
+ * while `checkout -B` resets it fine — one invocation handles both
20324
+ * states.
20325
+ */
20326
+ static branchCreate = branchCreate;
20327
+ /**
20328
+ * Mutating: `git branch -d <name>` (or `-D` when `force` is true) —
20329
+ * deletes a local branch.
20330
+ *
20331
+ * @remarks
20332
+ * The default `-d` refuses to delete a branch not fully merged — a typed
20333
+ * failure, which is usually the honest answer. `force: true` emits `-D`
20334
+ * and deletes regardless.
20335
+ */
20336
+ static branchDelete = branchDelete;
20337
+ /**
19244
20338
  * Mutating: `git submodule update [--init] [--depth <n>] [-- <paths>...]` — updates
19245
20339
  * registered submodules, optionally initializing them, with an optional depth limit,
19246
20340
  * and scoped to specific paths. The literal `--` separator makes the pathspec
@@ -19251,6 +20345,10 @@ var GitCommand = class {
19251
20345
  * Mutating: `git submodule add [--depth <n>] -- <url> <path>` — registers and
19252
20346
  * initializes a new submodule. The literal `--` separator makes the url and path
19253
20347
  * injection-safe by construction.
20348
+ *
20349
+ * @remarks
20350
+ * An embedded `userinfo@` credential in `url` is masked in
20351
+ * {@link GitInvocation.redactedArgs}.
19254
20352
  */
19255
20353
  static submoduleAdd = submoduleAdd;
19256
20354
  /**
@@ -19263,6 +20361,13 @@ var GitCommand = class {
19263
20361
  /**
19264
20362
  * Mutating: `git config [-f <file>] <key> <value>` — writes a configuration value,
19265
20363
  * optionally into an explicit configuration file (e.g., `.gitmodules`).
20364
+ *
20365
+ * @remarks
20366
+ * `value` may be a secret (a token, a credential-bearing URL), so it is
20367
+ * masked wholesale — as `<redacted>` — in
20368
+ * {@link GitInvocation.redactedArgs}. The key and file stay visible: they
20369
+ * are stable identifiers, and they are what a caller debugging a failed
20370
+ * write actually needs.
19266
20371
  */
19267
20372
  static configSet = configSet;
19268
20373
  /**
@@ -19345,9 +20450,304 @@ var GitCommand = class {
19345
20450
  * Each entry is a pair of status codes followed by a space and the path.
19346
20451
  */
19347
20452
  static status = status;
20453
+ /**
20454
+ * `git submodule status [--recursive] [-- <paths>...]` — one line per
20455
+ * registered submodule: a state prefix, the checked-out (or gitlink) sha,
20456
+ * the path, and — when the submodule is initialized — a `git describe`
20457
+ * suffix in parentheses.
20458
+ *
20459
+ * @remarks
20460
+ * `git submodule status` has no `-z` mode, so its output is line-based —
20461
+ * the one path-emitting constructor in this package that cannot follow
20462
+ * the `-z` rule. A submodule path containing a newline would corrupt the
20463
+ * parse; accepted as a git-imposed limitation.
20464
+ */
20465
+ static submoduleStatus = submoduleStatus;
20466
+ /**
20467
+ * Mutating: `git submodule init [-- <paths>...]` — registers the
20468
+ * submodules from `.gitmodules` into `.git/config` (all of them, or only
20469
+ * `paths`), without cloning or checking anything out.
20470
+ */
20471
+ static submoduleInit = submoduleInit;
20472
+ /**
20473
+ * Mutating: `git submodule deinit [--force] (--all | -- <paths>...)` —
20474
+ * unregisters submodules: clears their working trees and removes their
20475
+ * `.git/config` registration. The literal `--` separator makes the
20476
+ * pathspec injection-safe by construction.
20477
+ */
20478
+ static submoduleDeinit = submoduleDeinit;
20479
+ /**
20480
+ * Mutating: `git submodule sync [--recursive] [-- <paths>...]` —
20481
+ * re-copies each submodule's URL from `.gitmodules` into `.git/config`
20482
+ * (and into the submodule's own `remote.origin.url`), so a `.gitmodules`
20483
+ * URL change actually reaches git's live configuration.
20484
+ */
20485
+ static submoduleSync = submoduleSync;
20486
+ /**
20487
+ * Mutating: `git submodule set-url -- <path> <url>` — rewrites the
20488
+ * submodule's URL in `.gitmodules` and synchronizes it into
20489
+ * `.git/config`. The literal `--` separator makes the path and url
20490
+ * injection-safe by construction.
20491
+ *
20492
+ * @remarks
20493
+ * An embedded `userinfo@` credential in `url` is masked in
20494
+ * {@link GitInvocation.redactedArgs}.
20495
+ */
20496
+ static submoduleSetUrl = submoduleSetUrl;
20497
+ /**
20498
+ * Mutating: `git submodule set-branch (--branch <branch> | --default) -- <path>`
20499
+ * — records (or clears, when `branch` is omitted) the branch a submodule
20500
+ * tracks in `.gitmodules`. The literal `--` separator makes the path
20501
+ * injection-safe by construction.
20502
+ */
20503
+ static submoduleSetBranch = submoduleSetBranch;
20504
+ /**
20505
+ * Mutating: `git submodule absorbgitdirs [-- <paths>...]` — moves each
20506
+ * submodule's embedded `.git` directory into the superproject's
20507
+ * `.git/modules/` and leaves a gitfile pointer behind.
20508
+ */
20509
+ static submoduleAbsorbgitdirs = submoduleAbsorbgitdirs;
20510
+ /**
20511
+ * Mutating: `git submodule foreach [--recursive] <command>` — runs a shell
20512
+ * command in every checked-out submodule. `command` is a single shell
20513
+ * string, evaluated by git in each submodule's directory; it can mutate
20514
+ * anything, which is why the constructor is marked mutating regardless of
20515
+ * what the command does.
20516
+ *
20517
+ * @remarks
20518
+ * This is the ONE constructor whose argument cannot be made injection-safe
20519
+ * by construction: git evaluates `command` with `sh -c`, so every character
20520
+ * of it is shell code — a `--` separator or quoting cannot help. Callers
20521
+ * must treat `command` as a trusted literal and never interpolate untrusted
20522
+ * data into it.
20523
+ */
20524
+ static submoduleForeach = submoduleForeach;
20525
+ /**
20526
+ * `git ls-remote [--heads] [--tags] <remote> [<patterns>...]` — the refs a
20527
+ * remote advertises (sha + refname), optionally filtered to branch heads,
20528
+ * tags, and/or shell-glob patterns.
20529
+ *
20530
+ * @remarks
20531
+ * A read that talks to the NETWORK, not to the local repository — the one
20532
+ * non-mutating constructor in this package that does. An embedded
20533
+ * `userinfo@` credential in `remote` is masked in
20534
+ * {@link GitInvocation.redactedArgs}. An annotated tag advertises two
20535
+ * entries: `refs/tags/<name>` (the tag object) and `refs/tags/<name>^{}`
20536
+ * (the peeled commit).
20537
+ */
20538
+ static lsRemote = lsRemote;
20539
+ /**
20540
+ * Mutating: `git remote add <name> <url>` — registers a new remote.
20541
+ *
20542
+ * @remarks
20543
+ * An embedded `userinfo@` credential in `url` is masked in
20544
+ * {@link GitInvocation.redactedArgs}.
20545
+ */
20546
+ static remoteAdd = remoteAdd;
20547
+ /**
20548
+ * Mutating: `git remote remove <name>` — deletes a remote and its
20549
+ * remote-tracking refs and configuration.
20550
+ */
20551
+ static remoteRemove = remoteRemove;
20552
+ /**
20553
+ * Mutating: `git remote set-url <name> <url>` — rewrites a remote's fetch
20554
+ * URL.
20555
+ *
20556
+ * @remarks
20557
+ * An embedded `userinfo@` credential in `url` is masked in
20558
+ * {@link GitInvocation.redactedArgs}.
20559
+ */
20560
+ static remoteSetUrl = remoteSetUrl;
20561
+ /**
20562
+ * Mutating: `git stash push [--include-untracked] [-m <message>] [-- <paths>...]`
20563
+ * — saves the working tree (and index) state onto the stash stack. The
20564
+ * literal `--` separator makes the optional pathspec injection-safe by
20565
+ * construction; the message rides behind `-m`, which git consumes as a
20566
+ * value even when it begins with `-`.
20567
+ */
20568
+ static stashPush = stashPush;
20569
+ /**
20570
+ * Mutating: `git stash pop [stash@{n}]` — applies a stash entry and drops
20571
+ * it on success. The stash ref is rendered from an INTEGER index by this
20572
+ * package, never caller text.
20573
+ */
20574
+ static stashPop = stashPop;
20575
+ /**
20576
+ * Mutating: `git stash apply [stash@{n}]` — applies a stash entry and
20577
+ * keeps it on the stack. The stash ref is rendered from an INTEGER index
20578
+ * by this package, never caller text.
20579
+ */
20580
+ static stashApply = stashApply;
20581
+ /**
20582
+ * Mutating: `git stash drop [stash@{n}]` — deletes a stash entry without
20583
+ * applying it. The stash ref is rendered from an INTEGER index by this
20584
+ * package, never caller text.
20585
+ */
20586
+ static stashDrop = stashDrop;
20587
+ /**
20588
+ * `git stash list -z --format=%gd%x1f%H%x1f%gs` — every stash entry as a
20589
+ * NUL-terminated record of unit-separated fields: the reflog selector
20590
+ * (`stash@{0}`), the stash commit sha, and the reflog subject.
20591
+ *
20592
+ * @remarks
20593
+ * The `%x1f` (ASCII unit separator) field separator plus `-z` record
20594
+ * terminator keeps the parse split-safe: a stash message cannot contain
20595
+ * either byte (reflog subjects are single-line).
20596
+ */
20597
+ static stashList = stashList;
20598
+ /**
20599
+ * `git branch --list [--remotes | --all] --format=%(HEAD)%00%(refname:short)%00%(objectname)`
20600
+ * — every branch as a NUL-separated triple: the current-branch marker, the
20601
+ * short name, and the tip sha.
20602
+ *
20603
+ * @remarks
20604
+ * Records are newline-separated, which is split-safe here: git refnames
20605
+ * cannot contain a newline (or a space), so the only NUL bytes are the
20606
+ * format's own field separators. `all` wins over `remotes` when both are
20607
+ * set.
20608
+ */
20609
+ static branchList = branchList;
20610
+ /**
20611
+ * Mutating: `git tag [--force] [-m <message>] <name> [<ref>]` — creates a
20612
+ * lightweight tag, or an annotated one when `message` is given (`-m`
20613
+ * implies `-a`).
20614
+ */
20615
+ static tagCreate = tagCreate;
20616
+ /** Mutating: `git tag --delete <name>` — deletes a local tag. */
20617
+ static tagDelete = tagDelete;
20618
+ /**
20619
+ * `git tag --list [<pattern>]` — tag names, optionally filtered by a
20620
+ * shell-glob pattern, one per line (refnames cannot contain newlines).
20621
+ */
20622
+ static tagList = tagList;
20623
+ /**
20624
+ * `git for-each-ref --format=%(refname)%00%(objectname)%00%(objecttype) [<patterns>...]`
20625
+ * — every matching ref as a NUL-separated triple: full refname, sha, and
20626
+ * object type.
20627
+ *
20628
+ * @remarks
20629
+ * The format is this package's own fixed triple — the parse contract and
20630
+ * the argv are decided together, so the format string is a constructor
20631
+ * literal, never caller data. An annotated tag's `objecttype` is `tag`
20632
+ * (the tag object), not `commit`.
20633
+ */
20634
+ static forEachRef = forEachRef;
20635
+ /**
20636
+ * `git rev-list [--max-count=<n>] [--first-parent] <ref-or-range>` — commit
20637
+ * shas reachable from the ref (or range, e.g. `main..feat`), newest first.
20638
+ */
20639
+ static revList = revList;
20640
+ /**
20641
+ * Mutating: `git commit [--all] [--allow-empty] [--amend] [--author=<author>] -m <message>`
20642
+ * — records a commit. The message always rides argv behind `-m` (git
20643
+ * consumes it as a value even when it begins with `-`); committer identity
20644
+ * comes from the caller's environment — this constructor sets no
20645
+ * `GIT_AUTHOR_*`/`GIT_COMMITTER_*` variables, and the optional `author`
20646
+ * override is the fused `--author=` form.
20647
+ */
20648
+ static commit = commit;
20649
+ /**
20650
+ * Mutating: `git push [--force | --force-with-lease] [--tags] [--set-upstream] <remote> [<refspec>]`
20651
+ * — updates remote refs.
20652
+ *
20653
+ * @remarks
20654
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20655
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20656
+ */
20657
+ static push = push$1;
20658
+ /**
20659
+ * Mutating: `git pull [--rebase] [--ff-only] <remote> [<ref>]` — fetches
20660
+ * and integrates.
20661
+ *
20662
+ * @remarks
20663
+ * `remote` may be a URL as well as a remote name; an embedded `userinfo@`
20664
+ * credential is masked in {@link GitInvocation.redactedArgs}.
20665
+ */
20666
+ static pull = pull;
20667
+ /**
20668
+ * `git config [-f <file>] --list -z` — every configuration entry in scope
20669
+ * (or in the given file only), NUL-terminated, the key separated from the
20670
+ * value by a newline within each record.
20671
+ *
20672
+ * @remarks
20673
+ * `-z` is load-bearing: a config VALUE may contain newlines; only the NUL
20674
+ * record terminator plus first-newline field split parses it losslessly.
20675
+ * A valueless key (git's boolean-true shorthand) emits no newline at all.
20676
+ */
20677
+ static configList = configList;
20678
+ /**
20679
+ * `git config [-f <file>] --get-all -z <key>` — every value of a
20680
+ * (possibly multi-valued) key, NUL-terminated. An unset key exits 1 with
20681
+ * silent stderr.
20682
+ */
20683
+ static configGetAll = configGetAll;
20684
+ /**
20685
+ * Mutating: `git config [-f <file>] (--unset | --unset-all) <key>` —
20686
+ * removes a key (or, with `all`, every value of a multi-valued key).
20687
+ *
20688
+ * @remarks
20689
+ * git exits 5, silently, when the key was not set — a loud failure by
20690
+ * this package's classification, deliberately: an unset that silently did
20691
+ * nothing is indistinguishable from one that worked.
20692
+ */
20693
+ static configUnset = configUnset;
20694
+ /**
20695
+ * Mutating: `git rm [--cached] [-r] [--force] -- <paths...>` — removes
20696
+ * paths from the index (and, without `cached`, the working tree). The
20697
+ * literal `--` separator makes the pathspec injection-safe by
20698
+ * construction.
20699
+ */
20700
+ static rm = rm;
20701
+ /**
20702
+ * Mutating: `git mv [--force] -- <source> <destination>` — moves or
20703
+ * renames a tracked path. The literal `--` separator makes both positionals
20704
+ * injection-safe by construction.
20705
+ */
20706
+ static mv = mv;
20707
+ /**
20708
+ * `git check-ignore -z --stdin` — which of the given paths git would
20709
+ * ignore, paths fed NUL-separated via stdin and answers returned
20710
+ * NUL-separated.
20711
+ *
20712
+ * @remarks
20713
+ * The `--stdin -z` form is the only fully robust one: `-z` without
20714
+ * `--stdin` is rejected by git outright, and the non-`-z` output C-quotes
20715
+ * special-character paths. Feeding paths via stdin also makes them
20716
+ * injection-safe by construction — nothing caller-controlled enters the
20717
+ * argv. When NO path is ignored, git exits 1 with silent stderr.
20718
+ */
20719
+ static checkIgnore = checkIgnore;
20720
+ /**
20721
+ * Mutating: `git worktree add [--force] [--detach] <path> [<ref>]` —
20722
+ * creates a linked working tree at `path`, checked out at `ref` (or the
20723
+ * branch named after `path`'s basename).
20724
+ */
20725
+ static worktreeAdd = worktreeAdd;
20726
+ /**
20727
+ * `git worktree list --porcelain -z` — every working tree as a block of
20728
+ * NUL-terminated attributes (`worktree <path>`, `HEAD <sha>`,
20729
+ * `branch <ref>` / `detached`, `bare`, `locked [<reason>]`,
20730
+ * `prunable [<reason>]`), blocks separated by an empty attribute.
20731
+ */
20732
+ static worktreeList = worktreeList;
20733
+ /** Mutating: `git worktree remove [--force] <path>` — removes a linked working tree. */
20734
+ static worktreeRemove = worktreeRemove;
20735
+ /**
20736
+ * `git ls-files --stage -z [-- <pathspec>...]` — every INDEX entry (mode,
20737
+ * oid, stage number, path), NUL-terminated, optionally scoped to
20738
+ * `pathspec`.
20739
+ *
20740
+ * @remarks
20741
+ * The index-side sibling of {@link GitCommand.lsTree}: `lsTree` reads a
20742
+ * COMMITTED tree at a ref, while this reads the staging area — the only
20743
+ * place a staged-but-uncommitted gitlink (`160000 <oid> 0 <path>`) is
20744
+ * visible. `-z` is load-bearing twice over: paths may contain newlines,
20745
+ * and the non-`-z` output C-quotes special-character paths.
20746
+ */
20747
+ static lsFiles = lsFiles;
19348
20748
  };
19349
20749
  //#endregion
19350
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
20750
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/internal/run.js
19351
20751
  /**
19352
20752
  * Spawns `command` and collects its stdout, stderr, and exit code as a single
19353
20753
  * triple.
@@ -19374,7 +20774,7 @@ const runCollected = (command) => effect.Effect.scoped(effect.Effect.gen(functio
19374
20774
  };
19375
20775
  }));
19376
20776
  //#endregion
19377
- //#region ../../node_modules/.pnpm/@effected+git@0.5.2_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
20777
+ //#region ../../node_modules/.pnpm/@effected+git@0.6.0_effect@4.0.0-beta.101/node_modules/@effected/git/Git.js
19378
20778
  /** git's own ceiling: a run that has not answered in 30s is not going to. */
19379
20779
  const GIT_TIMEOUT = effect.Duration.seconds(30);
19380
20780
  /**
@@ -19402,7 +20802,16 @@ var GitCommandError = class extends effect.Schema.TaggedErrorClass()("GitCommand
19402
20802
  * logic routes on this instead of matching `detail` prose.
19403
20803
  */
19404
20804
  kind: effect.Schema.Literals(["refused", "failed"]),
19405
- /** The argument vector, without the leading `git`. */
20805
+ /**
20806
+ * The REDACTED argument vector, without the leading `git`.
20807
+ *
20808
+ * Sensitive positionals — config values, a URL's embedded userinfo — are
20809
+ * already masked by the constructor's redaction mask before this error is
20810
+ * constructed (`configSet`'s value reads `<redacted>`; a
20811
+ * `https://user:token@host/...` remote keeps everything but its
20812
+ * `userinfo@`). The raw argv is never persisted in an error value, and
20813
+ * `message` renders this redacted vector.
20814
+ */
19406
20815
  args: effect.Schema.Array(effect.Schema.String),
19407
20816
  /** The working directory the command ran in. */
19408
20817
  cwd: effect.Schema.String,
@@ -19448,9 +20857,74 @@ var UnknownRefError = class extends effect.Schema.TaggedErrorClass()("UnknownRef
19448
20857
  }
19449
20858
  };
19450
20859
  /**
19451
- * One entry of a `git ls-tree` listing.
20860
+ * A `git push` was rejected because the remote ref has moved: the classic
20861
+ * non-fast-forward rejection (`fetch first` / `non-fast-forward`), or a
20862
+ * `--force-with-lease` lease failure (`stale info`).
19452
20863
  *
19453
- * @public
20864
+ * @remarks
20865
+ * The typed signal a fetch-then-retry (or rebase-then-retry) fallback
20866
+ * branches on — every other push failure stays a {@link GitCommandError}.
20867
+ * Only `Git.push` can fail with this error.
20868
+ *
20869
+ * @public
20870
+ */
20871
+ var NonFastForwardError = class extends effect.Schema.TaggedErrorClass()("NonFastForwardError", {
20872
+ /** The working directory the push ran in. */
20873
+ cwd: effect.Schema.String,
20874
+ /** The refspec that was rejected, when the caller passed one. */
20875
+ refspec: effect.Schema.optionalKey(effect.Schema.String)
20876
+ }) {
20877
+ /** Renders the rejected push into a one-line message. */
20878
+ get message() {
20879
+ 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}`;
20880
+ }
20881
+ };
20882
+ /**
20883
+ * A merge-shaped operation (`pull`, `stash pop`, `stash apply`) stopped with
20884
+ * conflict markers in the working tree.
20885
+ *
20886
+ * @remarks
20887
+ * The typed signal a resolve-or-abort recovery branches on. The conflicted
20888
+ * state is REAL: git has already written conflict markers, and (for `pull`)
20889
+ * `MERGE_HEAD` is set — the caller owns resolving or aborting. Detection
20890
+ * matches git's conflict report, which lands on STDOUT for a merge and on
20891
+ * stderr for a rebase-mode pull; both streams are inspected.
20892
+ *
20893
+ * @public
20894
+ */
20895
+ var MergeConflictError = class extends effect.Schema.TaggedErrorClass()("MergeConflictError", {
20896
+ /** The working directory the merge ran in. */
20897
+ cwd: effect.Schema.String }) {
20898
+ /** Renders the conflicted merge into a one-line message. */
20899
+ get message() {
20900
+ return `merge conflict in ${this.cwd}: fix conflicts (or abort) before continuing`;
20901
+ }
20902
+ };
20903
+ /**
20904
+ * A merge-shaped operation refused to start because local modifications would
20905
+ * be overwritten — git's refusal reads
20906
+ * `Your local changes ... would be overwritten by merge`.
20907
+ *
20908
+ * @remarks
20909
+ * The typed "commit or stash first" signal. Unlike {@link MergeConflictError}
20910
+ * the working tree is UNTOUCHED — git aborted before changing anything.
20911
+ * Only the merge-shaped methods (`pull`, `stashPop`, `stashApply`) can fail
20912
+ * with this error.
20913
+ *
20914
+ * @public
20915
+ */
20916
+ var DirtyWorktreeError = class extends effect.Schema.TaggedErrorClass()("DirtyWorktreeError", {
20917
+ /** The working directory whose local changes blocked the operation. */
20918
+ cwd: effect.Schema.String }) {
20919
+ /** Renders the blocked operation into a one-line message. */
20920
+ get message() {
20921
+ return `local changes would be overwritten in ${this.cwd}: commit or stash them first`;
20922
+ }
20923
+ };
20924
+ /**
20925
+ * One entry of a `git ls-tree` listing.
20926
+ *
20927
+ * @public
19454
20928
  */
19455
20929
  var LsTreeEntry = class extends effect.Schema.Class("LsTreeEntry")({
19456
20930
  /** The entry's file mode, e.g. `100644`. */
@@ -19508,11 +20982,26 @@ const UNKNOWN_REF_PATTERNS = [
19508
20982
  "couldn't find remote ref"
19509
20983
  ];
19510
20984
  const ABSENT_AT_REF_PATTERNS = ["does not exist in", "exists on disk, but not in"];
20985
+ const PUSH_REJECTED_PATTERNS = [
20986
+ "non-fast-forward",
20987
+ "fetch first",
20988
+ "stale info"
20989
+ ];
20990
+ const MERGE_CONFLICT_PATTERNS = [
20991
+ "CONFLICT (",
20992
+ "Automatic merge failed",
20993
+ "could not apply"
20994
+ ];
20995
+ const DIRTY_WORKTREE_PATTERN = "would be overwritten by";
19511
20996
  const matchesAny = (stderr, patterns) => patterns.some((pattern) => stderr.includes(pattern));
19512
20997
  /**
19513
20998
  * Classifies one completed run (or spawn-level `PlatformError`) against
19514
20999
  * git's stderr taxonomy. Written once — every `Git` method funnels through
19515
21000
  * this before deciding its own return value.
21001
+ *
21002
+ * `args` is the invocation's REDACTED argv: it is the only argv this
21003
+ * function may persist into a `GitCommandError`, per the #86 redaction
21004
+ * policy.
19516
21005
  */
19517
21006
  const classify = (cwd, args, outcome, kind) => {
19518
21007
  if (outcome instanceof effect.PlatformError.PlatformError) {
@@ -19535,6 +21024,11 @@ const classify = (cwd, args, outcome, kind) => {
19535
21024
  };
19536
21025
  if (stderr.includes(NOT_A_REPOSITORY)) return { _tag: "notARepository" };
19537
21026
  if (matchesAny(stderr, UNKNOWN_REF_PATTERNS)) return { _tag: "unknownRef" };
21027
+ if (kind === "push" && stderr.includes("[rejected]") && matchesAny(stderr, PUSH_REJECTED_PATTERNS)) return { _tag: "nonFastForward" };
21028
+ if (kind === "merge") {
21029
+ if (stderr.includes(DIRTY_WORKTREE_PATTERN)) return { _tag: "dirtyWorktree" };
21030
+ if (matchesAny(stdout, MERGE_CONFLICT_PATTERNS) || matchesAny(stderr, MERGE_CONFLICT_PATTERNS)) return { _tag: "mergeConflict" };
21031
+ }
19538
21032
  if (kind === "quiet" && exitCode === 1 && stderr === "") return { _tag: "absent" };
19539
21033
  if (kind === "noSuchRemote" && stderr.includes("No such remote")) return { _tag: "absent" };
19540
21034
  if (kind === "show" && matchesAny(stderr, ABSENT_AT_REF_PATTERNS)) return { _tag: "absent" };
@@ -19551,13 +21045,19 @@ const classify = (cwd, args, outcome, kind) => {
19551
21045
  };
19552
21046
  };
19553
21047
  /**
19554
- * Runs `command`, classifies the outcome, and never fails: a spawn-level
19555
- * `PlatformError` and a per-run timeout are both absorbed into the
19556
- * `"failure"` classification rather than escaping the effect's error
19557
- * channel.
21048
+ * Runs an invocation's command in `cwd`, classifies the outcome, and never
21049
+ * fails: a spawn-level `PlatformError` and a per-run timeout are both
21050
+ * absorbed into the `"failure"` classification rather than escaping the
21051
+ * effect's error channel.
21052
+ *
21053
+ * The argv handed to `classify` — and therefore persisted into any
21054
+ * `GitCommandError` — is the invocation's REDACTED argv, never the raw one:
21055
+ * the redaction mask the pure constructor carries is applied here, at the
21056
+ * single classification choke point (the #86 redaction policy).
19558
21057
  */
19559
- const runClassified = (command, cwd, kind) => {
19560
- const args = effect_unstable_process.ChildProcess.isStandardCommand(command) ? command.args : [];
21058
+ const runClassified = (invocation, cwd, kind) => {
21059
+ const args = invocation.redactedArgs;
21060
+ const command = effect_unstable_process.ChildProcess.setCwd(invocation.command, cwd);
19561
21061
  return runCollected(command).pipe(effect.Effect.map((collected) => classify(cwd, args, collected, kind)), effect.Effect.catch((platformError) => effect.Effect.succeed(classify(cwd, args, platformError, kind))), effect.Effect.timeoutOrElse({
19562
21062
  duration: GIT_TIMEOUT,
19563
21063
  orElse: () => effect.Effect.succeed({
@@ -19687,7 +21187,43 @@ var StatusEntry = class extends effect.Schema.Class("StatusEntry")({
19687
21187
  path: effect.Schema.String,
19688
21188
  /** The original path; present only on rename/copy entries. */
19689
21189
  origPath: effect.Schema.optionalKey(effect.Schema.String)
19690
- }) {};
21190
+ }) {
21191
+ /**
21192
+ * Renders this entry back to one porcelain-shaped line: `XY <path>`.
21193
+ *
21194
+ * @remarks
21195
+ * **The rename convention is decided here, once, for every consumer.** By
21196
+ * default a rename/copy entry renders its NEW path only — `path` IS the
21197
+ * entry's current path, the one a line-oriented downstream can actually
21198
+ * open — which is a deliberate divergence from git's own non-`-z`
21199
+ * rendering (`orig -> new`). The arrow form is ambiguous to naive
21200
+ * line/whitespace splitters (paths may contain spaces, or a literal
21201
+ * `" -> "`), so it is opt-in via `renames: "arrow"` for consumers that
21202
+ * want git parity.
21203
+ *
21204
+ * A second recorded divergence: git's non-`-z` porcelain C-quotes paths
21205
+ * containing special characters; this renderer emits paths raw. It exists
21206
+ * for whitespace-insensitive text consumers — a machine parser should
21207
+ * consume the decoded {@link StatusEntry} values (or `-z` output)
21208
+ * directly, never re-parse this rendering.
21209
+ */
21210
+ toLine(options) {
21211
+ const rendered = options?.renames === "arrow" && this.origPath !== void 0 ? `${this.origPath} -> ${this.path}` : this.path;
21212
+ return `${this.x}${this.y} ${rendered}`;
21213
+ }
21214
+ /**
21215
+ * Renders entries back to porcelain-shaped text: one {@link StatusEntry.toLine}
21216
+ * line per entry, newline-joined, no trailing newline.
21217
+ *
21218
+ * @remarks
21219
+ * The route back from `Git.status`'s parsed entries to line-oriented text,
21220
+ * so a consumer whose downstream contract is porcelain-shaped text does
21221
+ * not hand-roll its own renderer (and re-decide the rename convention —
21222
+ * see {@link StatusEntry.toLine} for that decision). An empty array
21223
+ * renders as the empty string.
21224
+ */
21225
+ static format = (entries, options) => entries.map((entry) => entry.toLine(options)).join("\n");
21226
+ };
19691
21227
  /**
19692
21228
  * Parses `git log -1 --format=%H%x00%G?%x00%B` output: exactly two NUL
19693
21229
  * separators, everything after the second is the raw message, untrimmed.
@@ -19741,6 +21277,360 @@ const parseStatus = (output) => {
19741
21277
  return entries;
19742
21278
  };
19743
21279
  /**
21280
+ * One line of a `git submodule status` listing.
21281
+ *
21282
+ * @remarks
21283
+ * The `state` decodes git's one-character prefix: `" "` → `"current"` (the
21284
+ * checked-out commit matches the index gitlink), `"-"` → `"uninitialized"`,
21285
+ * `"+"` → `"outOfSync"` (the checked-out commit differs from the gitlink),
21286
+ * `"U"` → `"conflict"` (merge conflicts). `describe` carries the
21287
+ * parenthesized `git describe` suffix git appends for initialized
21288
+ * submodules.
21289
+ *
21290
+ * @public
21291
+ */
21292
+ var SubmoduleStatusEntry = class extends effect.Schema.Class("SubmoduleStatusEntry")({
21293
+ /** The decoded state prefix. */
21294
+ state: effect.Schema.Literals([
21295
+ "current",
21296
+ "uninitialized",
21297
+ "outOfSync",
21298
+ "conflict"
21299
+ ]),
21300
+ /** The submodule's checked-out (or, uninitialized, gitlink) commit sha. */
21301
+ sha: effect.Schema.String,
21302
+ /** The submodule's path relative to the superproject root. */
21303
+ path: effect.Schema.String,
21304
+ /** The `git describe` suffix, present only for initialized submodules. */
21305
+ describe: effect.Schema.optionalKey(effect.Schema.String)
21306
+ }) {};
21307
+ /**
21308
+ * Parses `git submodule status` output. Line-based — the one parser in this
21309
+ * package without a `-z` mode to lean on, because git does not offer one for
21310
+ * `submodule status`; a submodule path containing a newline (or a literal
21311
+ * ` (` suffix mimicking the describe parenthesis) would corrupt the parse.
21312
+ * Accepted as a git-imposed limitation.
21313
+ */
21314
+ const parseSubmoduleStatus = (output) => {
21315
+ const entries = [];
21316
+ for (const line of output.split("\n")) {
21317
+ const trimmedEnd = line.endsWith("\r") ? line.slice(0, -1) : line;
21318
+ if (trimmedEnd === "") continue;
21319
+ const prefix = trimmedEnd.charAt(0);
21320
+ const state = prefix === "-" ? "uninitialized" : prefix === "+" ? "outOfSync" : prefix === "U" ? "conflict" : "current";
21321
+ const rest = prefix === " " || prefix === "-" || prefix === "+" || prefix === "U" ? trimmedEnd.slice(1) : trimmedEnd;
21322
+ const shaEnd = rest.indexOf(" ");
21323
+ const sha = shaEnd === -1 ? rest : rest.slice(0, shaEnd);
21324
+ const remainder = shaEnd === -1 ? "" : rest.slice(shaEnd + 1);
21325
+ const describeStart = remainder.endsWith(")") ? remainder.lastIndexOf(" (") : -1;
21326
+ if (describeStart === -1) entries.push(SubmoduleStatusEntry.make({
21327
+ state,
21328
+ sha,
21329
+ path: remainder
21330
+ }));
21331
+ else entries.push(SubmoduleStatusEntry.make({
21332
+ state,
21333
+ sha,
21334
+ path: remainder.slice(0, describeStart),
21335
+ describe: remainder.slice(describeStart + 2, -1)
21336
+ }));
21337
+ }
21338
+ return entries;
21339
+ };
21340
+ /**
21341
+ * One ref a remote advertises, from `git ls-remote`.
21342
+ *
21343
+ * @remarks
21344
+ * `ref` is the FULL refname as advertised (`refs/heads/main`,
21345
+ * `refs/tags/v1`), including the `^{}` suffix on an annotated tag's peeled
21346
+ * entry — an annotated tag appears twice, once as the tag object and once
21347
+ * peeled to its commit.
21348
+ *
21349
+ * @public
21350
+ */
21351
+ var LsRemoteEntry = class LsRemoteEntry extends effect.Schema.Class("LsRemoteEntry")({
21352
+ /** The sha the advertised ref points at. */
21353
+ sha: effect.Schema.String,
21354
+ /** The full advertised refname, `^{}` peel suffix included. */
21355
+ ref: effect.Schema.String
21356
+ }) {
21357
+ /**
21358
+ * The human-facing short name of an advertised refname: the
21359
+ * `refs/heads/` / `refs/tags/` / `refs/remotes/` prefix and any `^{}`
21360
+ * peel suffix stripped (`refs/tags/v1^{}` → `v1`).
21361
+ */
21362
+ static shortName = (ref) => {
21363
+ const base = ref.endsWith("^{}") ? ref.slice(0, -3) : ref;
21364
+ for (const prefix of [
21365
+ "refs/heads/",
21366
+ "refs/tags/",
21367
+ "refs/remotes/"
21368
+ ]) if (base.startsWith(prefix)) return base.slice(prefix.length);
21369
+ return base;
21370
+ };
21371
+ /**
21372
+ * The entries whose short name is a NEAR MISS for `ref`: not an exact
21373
+ * match, but ending in `ref` right behind a separator (`@`, `/`, `-`,
21374
+ * `_`) — the monorepo-prefixed-tag case, where a caller asks for
21375
+ * `4.0.0-beta.101` and the remote advertises `effect@4.0.0-beta.101`.
21376
+ *
21377
+ * @remarks
21378
+ * A pure, decode-side helper for validate-before-mutate flows: run
21379
+ * `lsRemote`, look for the wanted ref, and when it is absent hand the
21380
+ * listing to this to compute a suggestion. Deliberately a helper on the
21381
+ * ENTRY value rather than behavior baked into the service — the service
21382
+ * returns the full listing and the caller owns the matching policy. An
21383
+ * annotated tag's peeled `^{}` entry shares its base short name, so a
21384
+ * near miss on such a tag can surface both of its entries.
21385
+ */
21386
+ static nearMatches = (entries, ref) => {
21387
+ const separators = [
21388
+ "@",
21389
+ "/",
21390
+ "-",
21391
+ "_"
21392
+ ];
21393
+ return entries.filter((entry) => {
21394
+ const short = LsRemoteEntry.shortName(entry.ref);
21395
+ if (short === ref || !short.endsWith(ref)) return false;
21396
+ return separators.includes(short.charAt(short.length - ref.length - 1));
21397
+ });
21398
+ };
21399
+ };
21400
+ /**
21401
+ * Parses `git ls-remote` output: one `<sha>\t<refname>` line per advertised
21402
+ * ref. Line-based deliberately — refnames cannot contain a newline (or a
21403
+ * tab), so the split is safe without a `-z` mode (which `ls-remote` does not
21404
+ * offer).
21405
+ */
21406
+ const parseLsRemote = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21407
+ const tabIndex = line.indexOf(" ");
21408
+ return LsRemoteEntry.make({
21409
+ sha: line.slice(0, tabIndex),
21410
+ ref: line.slice(tabIndex + 1)
21411
+ });
21412
+ });
21413
+ /**
21414
+ * One stash entry, from `git stash list`.
21415
+ *
21416
+ * @public
21417
+ */
21418
+ var StashEntry = class extends effect.Schema.Class("StashEntry")({
21419
+ /** The reflog selector (`stash@{0}`) — the index other stash methods take. */
21420
+ ref: effect.Schema.String,
21421
+ /** The stash commit's sha. */
21422
+ sha: effect.Schema.String,
21423
+ /** The reflog subject: `WIP on <branch>: ...` or `On <branch>: <message>`. */
21424
+ message: effect.Schema.String
21425
+ }) {};
21426
+ /**
21427
+ * Parses `git stash list -z --format=%gd%x1f%H%x1f%gs` output: NUL-terminated
21428
+ * records of unit-separated (`\x1f`) fields. Reflog subjects are single-line
21429
+ * and cannot contain either separator byte.
21430
+ */
21431
+ const parseStashList = (output) => parseNulSeparated(output).map((record) => {
21432
+ const [ref = "", sha = "", ...rest] = record.split("");
21433
+ return StashEntry.make({
21434
+ ref,
21435
+ sha,
21436
+ message: rest.join("")
21437
+ });
21438
+ });
21439
+ /**
21440
+ * One local (or remote-tracking) branch, from `git branch --list`.
21441
+ *
21442
+ * @public
21443
+ */
21444
+ var BranchEntry = class extends effect.Schema.Class("BranchEntry")({
21445
+ /** The short branch name (`main`, or `origin/main` for a remote branch). */
21446
+ name: effect.Schema.String,
21447
+ /** The branch tip's sha. */
21448
+ sha: effect.Schema.String,
21449
+ /** Whether this branch is checked out in the current working tree. */
21450
+ current: effect.Schema.Boolean
21451
+ }) {};
21452
+ /**
21453
+ * Parses `git branch --list --format=%(HEAD)%00%(refname:short)%00%(objectname)`
21454
+ * output: newline-separated records (refnames cannot contain newlines) of
21455
+ * NUL-separated fields. The `%(HEAD)` marker is `*` for the checked-out
21456
+ * branch; anything else (` `, or `+` for a branch checked out in a linked
21457
+ * worktree) is not-current.
21458
+ */
21459
+ const parseBranchList = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21460
+ const [marker = "", name = "", sha = ""] = line.split("\0");
21461
+ return BranchEntry.make({
21462
+ name,
21463
+ sha,
21464
+ current: marker === "*"
21465
+ });
21466
+ });
21467
+ /**
21468
+ * One ref, from `git for-each-ref`.
21469
+ *
21470
+ * @public
21471
+ */
21472
+ var RefEntry = class extends effect.Schema.Class("RefEntry")({
21473
+ /** The full refname (`refs/tags/v1`). */
21474
+ ref: effect.Schema.String,
21475
+ /** The sha of the object the ref points at. */
21476
+ sha: effect.Schema.String,
21477
+ /**
21478
+ * The pointed-at object's type. An annotated tag is `tag` (the tag
21479
+ * object itself, not its target commit).
21480
+ */
21481
+ objectType: effect.Schema.Literals([
21482
+ "commit",
21483
+ "tag",
21484
+ "tree",
21485
+ "blob"
21486
+ ])
21487
+ }) {};
21488
+ /**
21489
+ * Parses `git for-each-ref --format=%(refname)%00%(objectname)%00%(objecttype)`
21490
+ * output: newline-separated records (refnames cannot contain newlines) of
21491
+ * NUL-separated fields.
21492
+ */
21493
+ const parseForEachRef = (output) => output.split("\n").filter((line) => line.length > 0).map((line) => {
21494
+ const [ref = "", sha = "", objectType = "commit"] = line.split("\0");
21495
+ return RefEntry.make({
21496
+ ref,
21497
+ sha,
21498
+ objectType
21499
+ });
21500
+ });
21501
+ /**
21502
+ * One configuration entry, from `git config --list`.
21503
+ *
21504
+ * @public
21505
+ */
21506
+ var ConfigListEntry = class extends effect.Schema.Class("ConfigListEntry")({
21507
+ /** The canonical dotted key (`section.subsection.key`). */
21508
+ key: effect.Schema.String,
21509
+ /**
21510
+ * The raw value. A valueless key (git's boolean-true shorthand,
21511
+ * `[section]` + bare `key`) surfaces as the empty string — distinguish it
21512
+ * with `configGetAll` if the difference matters.
21513
+ */
21514
+ value: effect.Schema.String
21515
+ }) {};
21516
+ /**
21517
+ * Parses `git config --list -z` output: NUL-terminated records, key separated
21518
+ * from value by the FIRST newline (a config value may itself contain
21519
+ * newlines — the reason `-z` is load-bearing). A record with no newline is a
21520
+ * valueless boolean-shorthand key.
21521
+ */
21522
+ const parseConfigList = (output) => parseNulSeparated(output).map((record) => {
21523
+ const newlineIndex = record.indexOf("\n");
21524
+ return newlineIndex === -1 ? ConfigListEntry.make({
21525
+ key: record,
21526
+ value: ""
21527
+ }) : ConfigListEntry.make({
21528
+ key: record.slice(0, newlineIndex),
21529
+ value: record.slice(newlineIndex + 1)
21530
+ });
21531
+ });
21532
+ /**
21533
+ * One working tree, from `git worktree list --porcelain`.
21534
+ *
21535
+ * @public
21536
+ */
21537
+ var WorktreeEntry = class extends effect.Schema.Class("WorktreeEntry")({
21538
+ /** The working tree's absolute path. */
21539
+ path: effect.Schema.String,
21540
+ /** The checked-out commit sha; absent for a bare repository entry. */
21541
+ head: effect.Schema.optionalKey(effect.Schema.String),
21542
+ /** The checked-out branch's full refname; absent when detached or bare. */
21543
+ branch: effect.Schema.optionalKey(effect.Schema.String),
21544
+ /** Whether the working tree is in detached-HEAD state. */
21545
+ detached: effect.Schema.Boolean,
21546
+ /** Whether the entry is the bare repository itself. */
21547
+ bare: effect.Schema.Boolean,
21548
+ /** Present when the worktree is locked; holds the lock reason (possibly empty). */
21549
+ locked: effect.Schema.optionalKey(effect.Schema.String),
21550
+ /** Present when the worktree is prunable; holds the reason (possibly empty). */
21551
+ prunable: effect.Schema.optionalKey(effect.Schema.String)
21552
+ }) {};
21553
+ /**
21554
+ * Parses `git worktree list --porcelain -z` output: NUL-terminated attribute
21555
+ * lines, one blank attribute terminating each entry. Attribute vocabulary:
21556
+ * `worktree <path>`, `HEAD <sha>`, `branch <ref>`, and the flag/annotation
21557
+ * attributes `detached`, `bare`, `locked [<reason>]`, `prunable [<reason>]`.
21558
+ */
21559
+ const parseWorktreeList = (output) => {
21560
+ const entries = [];
21561
+ let path;
21562
+ let head;
21563
+ let branch;
21564
+ let detached = false;
21565
+ let bare = false;
21566
+ let locked;
21567
+ let prunable;
21568
+ const flush = () => {
21569
+ if (path !== void 0) entries.push(WorktreeEntry.make({
21570
+ path,
21571
+ detached,
21572
+ bare,
21573
+ ...head !== void 0 ? { head } : {},
21574
+ ...branch !== void 0 ? { branch } : {},
21575
+ ...locked !== void 0 ? { locked } : {},
21576
+ ...prunable !== void 0 ? { prunable } : {}
21577
+ }));
21578
+ path = void 0;
21579
+ head = void 0;
21580
+ branch = void 0;
21581
+ detached = false;
21582
+ bare = false;
21583
+ locked = void 0;
21584
+ prunable = void 0;
21585
+ };
21586
+ for (const attribute of output.split("\0")) if (attribute === "") flush();
21587
+ else if (attribute.startsWith("worktree ")) path = attribute.slice(9);
21588
+ else if (attribute.startsWith("HEAD ")) head = attribute.slice(5);
21589
+ else if (attribute.startsWith("branch ")) branch = attribute.slice(7);
21590
+ else if (attribute === "detached") detached = true;
21591
+ else if (attribute === "bare") bare = true;
21592
+ else if (attribute === "locked" || attribute.startsWith("locked ")) locked = attribute === "locked" ? "" : attribute.slice(7);
21593
+ else if (attribute === "prunable" || attribute.startsWith("prunable ")) prunable = attribute === "prunable" ? "" : attribute.slice(9);
21594
+ flush();
21595
+ return entries;
21596
+ };
21597
+ /**
21598
+ * One index (staging area) entry, from `git ls-files --stage`.
21599
+ *
21600
+ * @remarks
21601
+ * The index-side sibling of {@link LsTreeEntry}: this is the ONLY place a
21602
+ * staged-but-uncommitted gitlink (`mode` `160000`) is visible — `lsTree`
21603
+ * reads the committed tree and misses exactly that window.
21604
+ *
21605
+ * @public
21606
+ */
21607
+ var LsFilesEntry = class extends effect.Schema.Class("LsFilesEntry")({
21608
+ /** The entry's file mode, e.g. `100644` — `160000` for a gitlink. */
21609
+ mode: effect.Schema.String,
21610
+ /** The staged object id. */
21611
+ oid: effect.Schema.String,
21612
+ /** The merge stage: `0` normally; `1`/`2`/`3` during an unresolved merge. */
21613
+ stage: effect.Schema.Number,
21614
+ /** The entry's path, relative to `cwd`. May contain spaces or newlines. */
21615
+ path: effect.Schema.String
21616
+ }) {};
21617
+ /**
21618
+ * Parses `git ls-files --stage -z` output: each NUL-terminated entry is
21619
+ * `<mode> <oid> <stage>\t<path>`. `path` is everything after the first tab,
21620
+ * so a path containing spaces or newlines is preserved intact — the same
21621
+ * split rule as `parseLsTree`.
21622
+ */
21623
+ const parseLsFiles = (output) => parseNulSeparated(output).map((entry) => {
21624
+ const tabIndex = entry.indexOf(" ");
21625
+ const header = entry.slice(0, tabIndex).split(" ");
21626
+ return LsFilesEntry.make({
21627
+ mode: header[0] ?? "",
21628
+ oid: header[1] ?? "",
21629
+ stage: Number(header[2] ?? "0"),
21630
+ path: entry.slice(tabIndex + 1)
21631
+ });
21632
+ });
21633
+ /**
19744
21634
  * Refuse a caller-supplied ref or range that git would parse as an option.
19745
21635
  *
19746
21636
  * Refs are caller-controlled and land in git's argv as positional entries; a
@@ -19750,20 +21640,49 @@ const parseStatus = (output) => {
19750
21640
  * refused outright, before any spawn, as a typed {@link GitCommandError}.
19751
21641
  * `show`'s `path` needs no guard: it is fused after the ref into one
19752
21642
  * `ref:path` token, which cannot begin with `-` unless the ref does.
21643
+ *
21644
+ * `sensitive` values get the same check but a REDACTED report: a refused
21645
+ * sensitive positional (a `configSet` value) must not leak into
21646
+ * `GitCommandError.args`/`detail` any more than a spawned one may — the #86
21647
+ * redaction policy applies to guard rejections too.
19753
21648
  */
19754
- const rejectOptionLikeRefs = (cwd, refs) => {
21649
+ const rejectOptionLikeRefs = (cwd, refs, sensitive = []) => {
19755
21650
  const offending = refs.find((ref) => ref.startsWith("-"));
19756
- return offending === void 0 ? effect.Effect.void : effect.Effect.fail(new GitCommandError({
21651
+ if (offending !== void 0) return effect.Effect.fail(new GitCommandError({
19757
21652
  kind: "refused",
19758
21653
  args: [offending],
19759
21654
  cwd,
19760
21655
  stderr: "",
19761
21656
  detail: `refused a ref argument git would parse as an option: ${JSON.stringify(offending)}`
19762
21657
  }));
21658
+ return sensitive.find((value) => value.startsWith("-")) === void 0 ? effect.Effect.void : effect.Effect.fail(new GitCommandError({
21659
+ kind: "refused",
21660
+ args: ["<redacted>"],
21661
+ cwd,
21662
+ stderr: "",
21663
+ detail: "refused a sensitive argument git would parse as an option (value redacted)"
21664
+ }));
19763
21665
  };
21666
+ /**
21667
+ * Refuse a caller-supplied numeric index/limit that is not a non-negative
21668
+ * integer.
21669
+ *
21670
+ * Every relational comparison against `NaN` is `false`, so a bare
21671
+ * `value < 0` guard admits `NaN` (and a fractional value truncates nothing —
21672
+ * it rides straight into the argv as `stash@{1.5}` / `--max-count=NaN`).
21673
+ * Integrality and range are therefore checked together, pre-spawn, as a
21674
+ * typed refusal.
21675
+ */
21676
+ const rejectNonNaturalNumber = (cwd, label, value) => value === void 0 || Number.isInteger(value) && value >= 0 ? effect.Effect.void : effect.Effect.fail(new GitCommandError({
21677
+ kind: "refused",
21678
+ args: [String(value)],
21679
+ cwd,
21680
+ stderr: "",
21681
+ detail: `refused ${label}: expected a non-negative integer, received ${value}`
21682
+ }));
19764
21683
  /** Builds the `Git.Service` shape over an already-resolved `ChildProcessSpawner`. */
19765
21684
  const make = (spawner) => {
19766
- const runFor = (command, cwd, kind) => runClassified(command, cwd, kind).pipe(effect.Effect.provideService(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, spawner));
21685
+ const runFor = (invocation, cwd, kind) => runClassified(invocation, cwd, kind).pipe(effect.Effect.provideService(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, spawner));
19767
21686
  const show = effect.Effect.fn("Git.show")(function* (cwd, ref, path) {
19768
21687
  yield* effect.Effect.annotateCurrentSpan({
19769
21688
  cwd,
@@ -19771,8 +21690,7 @@ const make = (spawner) => {
19771
21690
  path
19772
21691
  });
19773
21692
  yield* rejectOptionLikeRefs(cwd, [ref]);
19774
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.show(ref, path), cwd);
19775
- const classified = yield* runFor(command, cwd, "show");
21693
+ const classified = yield* runFor(GitCommand.show(ref, path), cwd, "show");
19776
21694
  switch (classified._tag) {
19777
21695
  case "success": return effect.Option.some(classified.output);
19778
21696
  case "absent": return effect.Option.none();
@@ -19791,8 +21709,7 @@ const make = (spawner) => {
19791
21709
  ref
19792
21710
  });
19793
21711
  yield* rejectOptionLikeRefs(cwd, [ref]);
19794
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.lsTree(ref, options?.pathspec ?? []), cwd);
19795
- const classified = yield* runFor(command, cwd, "generic");
21712
+ const classified = yield* runFor(GitCommand.lsTree(ref, options?.pathspec ?? []), cwd, "generic");
19796
21713
  switch (classified._tag) {
19797
21714
  case "success": return parseLsTree(classified.output);
19798
21715
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
@@ -19810,8 +21727,7 @@ const make = (spawner) => {
19810
21727
  ref
19811
21728
  });
19812
21729
  yield* rejectOptionLikeRefs(cwd, [ref]);
19813
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.refExists(ref), cwd);
19814
- const classified = yield* runFor(command, cwd, "refExists");
21730
+ const classified = yield* runFor(GitCommand.refExists(ref), cwd, "refExists");
19815
21731
  switch (classified._tag) {
19816
21732
  case "success": return true;
19817
21733
  case "refMissing": return false;
@@ -19828,8 +21744,7 @@ const make = (spawner) => {
19828
21744
  b
19829
21745
  });
19830
21746
  yield* rejectOptionLikeRefs(cwd, [a, b]);
19831
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.mergeBase(a, b), cwd);
19832
- const classified = yield* runFor(command, cwd, "generic");
21747
+ const classified = yield* runFor(GitCommand.mergeBase(a, b), cwd, "generic");
19833
21748
  switch (classified._tag) {
19834
21749
  case "success": return classified.output.trim();
19835
21750
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
@@ -19850,8 +21765,7 @@ const make = (spawner) => {
19850
21765
  relative
19851
21766
  });
19852
21767
  yield* rejectOptionLikeRefs(cwd, [options.base, options.head]);
19853
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.changedFiles(options.base, options.head, relative), cwd);
19854
- const classified = yield* runFor(command, cwd, "generic");
21768
+ const classified = yield* runFor(GitCommand.changedFiles(options.base, options.head, relative), cwd, "generic");
19855
21769
  switch (classified._tag) {
19856
21770
  case "success": return parseNulSeparated(classified.output);
19857
21771
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
@@ -19863,8 +21777,8 @@ const make = (spawner) => {
19863
21777
  default: return yield* effect.Effect.die(`Git.changedFiles: unexpected classification "${classified._tag}"`);
19864
21778
  }
19865
21779
  });
19866
- const collectPaths = (method, command, cwd) => effect.Effect.gen(function* () {
19867
- const classified = yield* runFor(command, cwd, "generic");
21780
+ const collectPaths = (method, invocation, cwd) => effect.Effect.gen(function* () {
21781
+ const classified = yield* runFor(invocation, cwd, "generic");
19868
21782
  switch (classified._tag) {
19869
21783
  case "success": return parseNulSeparated(classified.output);
19870
21784
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
@@ -19882,7 +21796,7 @@ const make = (spawner) => {
19882
21796
  cwd,
19883
21797
  relative
19884
21798
  });
19885
- return yield* collectPaths("Git.unstagedChanges", effect_unstable_process.ChildProcess.setCwd(GitCommand.unstagedChanges(relative), cwd), cwd);
21799
+ return yield* collectPaths("Git.unstagedChanges", GitCommand.unstagedChanges(relative), cwd);
19886
21800
  });
19887
21801
  const stagedChanges = effect.Effect.fn("Git.stagedChanges")(function* (cwd, options) {
19888
21802
  const relative = options?.relative ?? false;
@@ -19890,7 +21804,7 @@ const make = (spawner) => {
19890
21804
  cwd,
19891
21805
  relative
19892
21806
  });
19893
- return yield* collectPaths("Git.stagedChanges", effect_unstable_process.ChildProcess.setCwd(GitCommand.stagedChanges(relative), cwd), cwd);
21807
+ return yield* collectPaths("Git.stagedChanges", GitCommand.stagedChanges(relative), cwd);
19894
21808
  });
19895
21809
  const untrackedFiles = effect.Effect.fn("Git.untrackedFiles")(function* (cwd, options) {
19896
21810
  const relative = options?.relative ?? false;
@@ -19898,7 +21812,7 @@ const make = (spawner) => {
19898
21812
  cwd,
19899
21813
  relative
19900
21814
  });
19901
- return yield* collectPaths("Git.untrackedFiles", effect_unstable_process.ChildProcess.setCwd(GitCommand.untrackedFiles(relative), cwd), cwd);
21815
+ return yield* collectPaths("Git.untrackedFiles", GitCommand.untrackedFiles(relative), cwd);
19902
21816
  });
19903
21817
  const workingChanges = effect.Effect.fn("Git.workingChanges")(function* (cwd, options) {
19904
21818
  yield* effect.Effect.annotateCurrentSpan({
@@ -19923,80 +21837,669 @@ const make = (spawner) => {
19923
21837
  relative
19924
21838
  });
19925
21839
  yield* rejectOptionLikeRefs(cwd, options.head === void 0 ? [options.base] : [options.base, options.head]);
19926
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.nameStatus(options.base, options.head, relative), cwd);
19927
- const classified = yield* runFor(command, cwd, "generic");
21840
+ const classified = yield* runFor(GitCommand.nameStatus(options.base, options.head, relative), cwd, "generic");
21841
+ switch (classified._tag) {
21842
+ case "success": return parseNameStatus(classified.output);
21843
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21844
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21845
+ ref: options.head === void 0 ? options.base : `${options.base}...${options.head}`,
21846
+ cwd
21847
+ }));
21848
+ case "failure": return yield* effect.Effect.fail(classified.error);
21849
+ default: return yield* effect.Effect.die(`Git.nameStatus: unexpected classification "${classified._tag}"`);
21850
+ }
21851
+ });
21852
+ const revParse = effect.Effect.fn("Git.revParse")(function* (cwd, ref) {
21853
+ yield* effect.Effect.annotateCurrentSpan({
21854
+ cwd,
21855
+ ref
21856
+ });
21857
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21858
+ const classified = yield* runFor(GitCommand.revParse(ref), cwd, "generic");
21859
+ switch (classified._tag) {
21860
+ case "success": return classified.output.trim();
21861
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21862
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21863
+ ref,
21864
+ cwd
21865
+ }));
21866
+ case "failure": return yield* effect.Effect.fail(classified.error);
21867
+ default: return yield* effect.Effect.die(`Git.revParse: unexpected classification "${classified._tag}"`);
21868
+ }
21869
+ });
21870
+ const checkout = effect.Effect.fn("Git.checkout")(function* (cwd, ref, options) {
21871
+ const detach = options?.detach ?? false;
21872
+ yield* effect.Effect.annotateCurrentSpan({
21873
+ cwd,
21874
+ ref,
21875
+ detach
21876
+ });
21877
+ yield* rejectOptionLikeRefs(cwd, [ref]);
21878
+ const classified = yield* runFor(GitCommand.checkout(ref, detach), cwd, "generic");
21879
+ switch (classified._tag) {
21880
+ case "success": return;
21881
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21882
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21883
+ ref,
21884
+ cwd
21885
+ }));
21886
+ case "failure": return yield* effect.Effect.fail(classified.error);
21887
+ default: return yield* effect.Effect.die(`Git.checkout: unexpected classification "${classified._tag}"`);
21888
+ }
21889
+ });
21890
+ const reset = effect.Effect.fn("Git.reset")(function* (cwd, options) {
21891
+ const mode = options?.mode ?? "mixed";
21892
+ yield* effect.Effect.annotateCurrentSpan({
21893
+ cwd,
21894
+ mode,
21895
+ ref: options?.ref ?? "HEAD"
21896
+ });
21897
+ if (options?.ref !== void 0) yield* rejectOptionLikeRefs(cwd, [options.ref]);
21898
+ const classified = yield* runFor(GitCommand.reset(mode, options?.ref), cwd, "generic");
21899
+ switch (classified._tag) {
21900
+ case "success": return;
21901
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21902
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21903
+ ref: options?.ref ?? "HEAD",
21904
+ cwd
21905
+ }));
21906
+ case "failure": return yield* effect.Effect.fail(classified.error);
21907
+ default: return yield* effect.Effect.die(`Git.reset: unexpected classification "${classified._tag}"`);
21908
+ }
21909
+ });
21910
+ const clean = effect.Effect.fn("Git.clean")(function* (cwd, options) {
21911
+ const directories = options?.directories ?? false;
21912
+ const ignored = options?.ignored ?? false;
21913
+ yield* effect.Effect.annotateCurrentSpan({
21914
+ cwd,
21915
+ directories,
21916
+ ignored
21917
+ });
21918
+ const classified = yield* runFor(GitCommand.clean(directories, ignored, options?.paths ?? []), cwd, "generic");
21919
+ switch (classified._tag) {
21920
+ case "success": return;
21921
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21922
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21923
+ ref: "working tree",
21924
+ cwd
21925
+ }));
21926
+ case "failure": return yield* effect.Effect.fail(classified.error);
21927
+ default: return yield* effect.Effect.die(`Git.clean: unexpected classification "${classified._tag}"`);
21928
+ }
21929
+ });
21930
+ const restore = effect.Effect.fn("Git.restore")(function* (cwd, paths, options) {
21931
+ yield* effect.Effect.annotateCurrentSpan({
21932
+ cwd,
21933
+ count: paths.length,
21934
+ source: options?.source ?? "(index)"
21935
+ });
21936
+ if (options?.source !== void 0) yield* rejectOptionLikeRefs(cwd, [options.source]);
21937
+ const classified = yield* runFor(GitCommand.restore(paths, options?.source, options?.staged ?? false, options?.worktree ?? false), cwd, "generic");
21938
+ switch (classified._tag) {
21939
+ case "success": return;
21940
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21941
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21942
+ ref: options?.source ?? "working tree",
21943
+ cwd
21944
+ }));
21945
+ case "failure": return yield* effect.Effect.fail(classified.error);
21946
+ default: return yield* effect.Effect.die(`Git.restore: unexpected classification "${classified._tag}"`);
21947
+ }
21948
+ });
21949
+ const branchCreate = effect.Effect.fn("Git.branchCreate")(function* (cwd, name, options) {
21950
+ const checkoutBranch = options?.checkout ?? false;
21951
+ const force = options?.force ?? false;
21952
+ yield* effect.Effect.annotateCurrentSpan({
21953
+ cwd,
21954
+ name,
21955
+ startPoint: options?.startPoint ?? "HEAD",
21956
+ checkout: checkoutBranch,
21957
+ force
21958
+ });
21959
+ yield* rejectOptionLikeRefs(cwd, [name, ...options?.startPoint !== void 0 ? [options.startPoint] : []]);
21960
+ const classified = yield* runFor(GitCommand.branchCreate(name, options?.startPoint, checkoutBranch, force), cwd, "generic");
21961
+ switch (classified._tag) {
21962
+ case "success": return;
21963
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21964
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21965
+ ref: options?.startPoint ?? name,
21966
+ cwd
21967
+ }));
21968
+ case "failure": return yield* effect.Effect.fail(classified.error);
21969
+ default: return yield* effect.Effect.die(`Git.branchCreate: unexpected classification "${classified._tag}"`);
21970
+ }
21971
+ });
21972
+ const branchDelete = effect.Effect.fn("Git.branchDelete")(function* (cwd, name, options) {
21973
+ yield* effect.Effect.annotateCurrentSpan({
21974
+ cwd,
21975
+ name,
21976
+ force: options?.force ?? false
21977
+ });
21978
+ yield* rejectOptionLikeRefs(cwd, [name]);
21979
+ const classified = yield* runFor(GitCommand.branchDelete(name, options?.force ?? false), cwd, "generic");
21980
+ switch (classified._tag) {
21981
+ case "success": return;
21982
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21983
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21984
+ ref: name,
21985
+ cwd
21986
+ }));
21987
+ case "failure": return yield* effect.Effect.fail(classified.error);
21988
+ default: return yield* effect.Effect.die(`Git.branchDelete: unexpected classification "${classified._tag}"`);
21989
+ }
21990
+ });
21991
+ const isShallow = effect.Effect.fn("Git.isShallow")(function* (cwd) {
21992
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
21993
+ const classified = yield* runFor(GitCommand.isShallow(), cwd, "generic");
21994
+ switch (classified._tag) {
21995
+ case "success": return classified.output.trim() === "true";
21996
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
21997
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
21998
+ ref: "HEAD",
21999
+ cwd
22000
+ }));
22001
+ case "failure": return yield* effect.Effect.fail(classified.error);
22002
+ default: return yield* effect.Effect.die(`Git.isShallow: unexpected classification "${classified._tag}"`);
22003
+ }
22004
+ });
22005
+ const fetchUnshallow = effect.Effect.fn("Git.fetchUnshallow")(function* (cwd, options) {
22006
+ const remote = options?.remote ?? "origin";
22007
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22008
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22009
+ const classified = yield* runFor(GitCommand.fetchUnshallow(remote), cwd, "generic");
22010
+ switch (classified._tag) {
22011
+ case "success": return;
22012
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22013
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22014
+ ref: "--unshallow",
22015
+ cwd
22016
+ }));
22017
+ case "failure": return yield* effect.Effect.fail(classified.error);
22018
+ default: return yield* effect.Effect.die(`Git.fetchUnshallow: unexpected classification "${classified._tag}"`);
22019
+ }
22020
+ });
22021
+ const fetch = effect.Effect.fn("Git.fetch")(function* (cwd, options) {
22022
+ const remote = options.remote ?? "origin";
22023
+ const tag = options.tag ?? false;
22024
+ yield* effect.Effect.annotateCurrentSpan({
22025
+ cwd,
22026
+ ref: options.ref,
22027
+ tag
22028
+ });
22029
+ yield* rejectOptionLikeRefs(cwd, [remote, options.ref]);
22030
+ yield* rejectNonNaturalNumber(cwd, "a fetch depth", options.depth);
22031
+ const classified = yield* runFor(GitCommand.fetch(remote, options.ref, options.depth, tag), cwd, "generic");
22032
+ switch (classified._tag) {
22033
+ case "success": return;
22034
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22035
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22036
+ ref: options.ref,
22037
+ cwd
22038
+ }));
22039
+ case "failure": return yield* effect.Effect.fail(classified.error);
22040
+ default: return yield* effect.Effect.die(`Git.fetch: unexpected classification "${classified._tag}"`);
22041
+ }
22042
+ });
22043
+ const fetchAny = effect.Effect.fn("Git.fetchAny")(function* (cwd, options) {
22044
+ yield* effect.Effect.annotateCurrentSpan({
22045
+ cwd,
22046
+ ref: options.ref
22047
+ });
22048
+ return yield* fetch(cwd, {
22049
+ ...options,
22050
+ tag: true
22051
+ }).pipe(effect.Effect.catchTag(["UnknownRefError", "GitCommandError"], (error) => error._tag === "GitCommandError" && error.kind === "refused" ? effect.Effect.fail(error) : fetch(cwd, options)));
22052
+ });
22053
+ const submoduleUpdate = effect.Effect.fn("Git.submoduleUpdate")(function* (cwd, options) {
22054
+ const init = options?.init ?? false;
22055
+ yield* effect.Effect.annotateCurrentSpan({
22056
+ cwd,
22057
+ init
22058
+ });
22059
+ yield* rejectNonNaturalNumber(cwd, "a submodule update depth", options?.depth);
22060
+ const classified = yield* runFor(GitCommand.submoduleUpdate(init, options?.depth, options?.paths ?? []), cwd, "generic");
22061
+ switch (classified._tag) {
22062
+ case "success": return;
22063
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22064
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22065
+ ref: "submodule update",
22066
+ cwd
22067
+ }));
22068
+ case "failure": return yield* effect.Effect.fail(classified.error);
22069
+ default: return yield* effect.Effect.die(`Git.submoduleUpdate: unexpected classification "${classified._tag}"`);
22070
+ }
22071
+ });
22072
+ const submoduleAdd = effect.Effect.fn("Git.submoduleAdd")(function* (cwd, options) {
22073
+ yield* effect.Effect.annotateCurrentSpan({
22074
+ cwd,
22075
+ path: options.path
22076
+ });
22077
+ yield* rejectNonNaturalNumber(cwd, "a submodule add depth", options.depth);
22078
+ const classified = yield* runFor(GitCommand.submoduleAdd(options.url, options.path, options.depth), cwd, "generic");
22079
+ switch (classified._tag) {
22080
+ case "success": return;
22081
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22082
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22083
+ ref: options.path,
22084
+ cwd
22085
+ }));
22086
+ case "failure": return yield* effect.Effect.fail(classified.error);
22087
+ default: return yield* effect.Effect.die(`Git.submoduleAdd: unexpected classification "${classified._tag}"`);
22088
+ }
22089
+ });
22090
+ const sparseCheckoutSet = effect.Effect.fn("Git.sparseCheckoutSet")(function* (cwd, patterns, options) {
22091
+ yield* effect.Effect.annotateCurrentSpan({
22092
+ cwd,
22093
+ cone: options.cone
22094
+ });
22095
+ yield* rejectOptionLikeRefs(cwd, patterns);
22096
+ const classified = yield* runFor(GitCommand.sparseCheckoutSet(patterns, options.cone), cwd, "generic");
22097
+ switch (classified._tag) {
22098
+ case "success": return;
22099
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22100
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22101
+ ref: "sparse-checkout",
22102
+ cwd
22103
+ }));
22104
+ case "failure": return yield* effect.Effect.fail(classified.error);
22105
+ default: return yield* effect.Effect.die(`Git.sparseCheckoutSet: unexpected classification "${classified._tag}"`);
22106
+ }
22107
+ });
22108
+ const configSet = effect.Effect.fn("Git.configSet")(function* (cwd, key, value, options) {
22109
+ yield* effect.Effect.annotateCurrentSpan({
22110
+ cwd,
22111
+ key,
22112
+ file: options?.file ?? "(repository config)"
22113
+ });
22114
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []], [value]);
22115
+ const classified = yield* runFor(GitCommand.configSet(key, value, options?.file), cwd, "generic");
22116
+ switch (classified._tag) {
22117
+ case "success": return;
22118
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22119
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22120
+ ref: key,
22121
+ cwd
22122
+ }));
22123
+ case "failure": return yield* effect.Effect.fail(classified.error);
22124
+ default: return yield* effect.Effect.die(`Git.configSet: unexpected classification "${classified._tag}"`);
22125
+ }
22126
+ });
22127
+ const add = effect.Effect.fn("Git.add")(function* (cwd, paths) {
22128
+ yield* effect.Effect.annotateCurrentSpan({
22129
+ cwd,
22130
+ count: paths.length
22131
+ });
22132
+ const classified = yield* runFor(GitCommand.add(paths), cwd, "generic");
22133
+ switch (classified._tag) {
22134
+ case "success": return;
22135
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22136
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22137
+ ref: "working tree",
22138
+ cwd
22139
+ }));
22140
+ case "failure": return yield* effect.Effect.fail(classified.error);
22141
+ default: return yield* effect.Effect.die(`Git.add: unexpected classification "${classified._tag}"`);
22142
+ }
22143
+ });
22144
+ const defaultBranch = effect.Effect.fn("Git.defaultBranch")(function* (cwd, options) {
22145
+ const remote = options?.remote ?? "origin";
22146
+ yield* effect.Effect.annotateCurrentSpan({
22147
+ cwd,
22148
+ remote
22149
+ });
22150
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22151
+ const classified = yield* runFor(GitCommand.defaultBranch(remote), cwd, "quiet");
22152
+ switch (classified._tag) {
22153
+ case "success": {
22154
+ const short = classified.output.trim();
22155
+ const prefix = `${remote}/`;
22156
+ return effect.Option.some(short.startsWith(prefix) ? short.slice(prefix.length) : short);
22157
+ }
22158
+ case "absent": return effect.Option.none();
22159
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22160
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22161
+ ref: `refs/remotes/${remote}/HEAD`,
22162
+ cwd
22163
+ }));
22164
+ case "failure": return yield* effect.Effect.fail(classified.error);
22165
+ default: return yield* effect.Effect.die(`Git.defaultBranch: unexpected classification "${classified._tag}"`);
22166
+ }
22167
+ });
22168
+ const currentBranch = effect.Effect.fn("Git.currentBranch")(function* (cwd) {
22169
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22170
+ const classified = yield* runFor(GitCommand.currentBranch(), cwd, "generic");
22171
+ switch (classified._tag) {
22172
+ case "success": {
22173
+ const name = classified.output.trim();
22174
+ return name === "HEAD" ? effect.Option.none() : effect.Option.some(name);
22175
+ }
22176
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22177
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22178
+ ref: "HEAD",
22179
+ cwd
22180
+ }));
22181
+ case "failure": return yield* effect.Effect.fail(classified.error);
22182
+ default: return yield* effect.Effect.die(`Git.currentBranch: unexpected classification "${classified._tag}"`);
22183
+ }
22184
+ });
22185
+ const repoRoot = effect.Effect.fn("Git.repoRoot")(function* (cwd) {
22186
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22187
+ const classified = yield* runFor(GitCommand.repoRoot(), cwd, "generic");
22188
+ switch (classified._tag) {
22189
+ case "success": return classified.output.trim();
22190
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22191
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22192
+ ref: "working tree",
22193
+ cwd
22194
+ }));
22195
+ case "failure": return yield* effect.Effect.fail(classified.error);
22196
+ default: return yield* effect.Effect.die(`Git.repoRoot: unexpected classification "${classified._tag}"`);
22197
+ }
22198
+ });
22199
+ const configGet = effect.Effect.fn("Git.configGet")(function* (cwd, key) {
22200
+ yield* effect.Effect.annotateCurrentSpan({
22201
+ cwd,
22202
+ key
22203
+ });
22204
+ yield* rejectOptionLikeRefs(cwd, [key]);
22205
+ const classified = yield* runFor(GitCommand.configGet(key), cwd, "quiet");
22206
+ switch (classified._tag) {
22207
+ case "success": return effect.Option.some(classified.output.trim());
22208
+ case "absent": return effect.Option.none();
22209
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22210
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22211
+ ref: key,
22212
+ cwd
22213
+ }));
22214
+ case "failure": return yield* effect.Effect.fail(classified.error);
22215
+ default: return yield* effect.Effect.die(`Git.configGet: unexpected classification "${classified._tag}"`);
22216
+ }
22217
+ });
22218
+ const remoteUrl = effect.Effect.fn("Git.remoteUrl")(function* (cwd, options) {
22219
+ const remote = options?.remote ?? "origin";
22220
+ yield* effect.Effect.annotateCurrentSpan({
22221
+ cwd,
22222
+ remote
22223
+ });
22224
+ yield* rejectOptionLikeRefs(cwd, [remote]);
22225
+ const classified = yield* runFor(GitCommand.remoteUrl(remote), cwd, "noSuchRemote");
22226
+ switch (classified._tag) {
22227
+ case "success": return effect.Option.some(classified.output.trim());
22228
+ case "absent": return effect.Option.none();
22229
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22230
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22231
+ ref: remote,
22232
+ cwd
22233
+ }));
22234
+ case "failure": return yield* effect.Effect.fail(classified.error);
22235
+ default: return yield* effect.Effect.die(`Git.remoteUrl: unexpected classification "${classified._tag}"`);
22236
+ }
22237
+ });
22238
+ const commitInfo = effect.Effect.fn("Git.commitInfo")(function* (cwd, ref) {
22239
+ const target = ref ?? "HEAD";
22240
+ yield* effect.Effect.annotateCurrentSpan({
22241
+ cwd,
22242
+ ref: target
22243
+ });
22244
+ yield* rejectOptionLikeRefs(cwd, [target]);
22245
+ const classified = yield* runFor(GitCommand.commitInfo(target), cwd, "generic");
22246
+ switch (classified._tag) {
22247
+ case "success": return parseCommitInfo(classified.output);
22248
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22249
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22250
+ ref: target,
22251
+ cwd
22252
+ }));
22253
+ case "failure": return yield* effect.Effect.fail(classified.error);
22254
+ default: return yield* effect.Effect.die(`Git.commitInfo: unexpected classification "${classified._tag}"`);
22255
+ }
22256
+ });
22257
+ const status = effect.Effect.fn("Git.status")(function* (cwd) {
22258
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22259
+ const classified = yield* runFor(GitCommand.status(), cwd, "generic");
22260
+ switch (classified._tag) {
22261
+ case "success": return parseStatus(classified.output);
22262
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22263
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22264
+ ref: "working tree",
22265
+ cwd
22266
+ }));
22267
+ case "failure": return yield* effect.Effect.fail(classified.error);
22268
+ default: return yield* effect.Effect.die(`Git.status: unexpected classification "${classified._tag}"`);
22269
+ }
22270
+ });
22271
+ const submoduleStatus = effect.Effect.fn("Git.submoduleStatus")(function* (cwd, options) {
22272
+ yield* effect.Effect.annotateCurrentSpan({
22273
+ cwd,
22274
+ recursive: options?.recursive ?? false
22275
+ });
22276
+ const classified = yield* runFor(GitCommand.submoduleStatus(options?.paths ?? [], options?.recursive ?? false), cwd, "generic");
22277
+ switch (classified._tag) {
22278
+ case "success": return parseSubmoduleStatus(classified.output);
22279
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22280
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22281
+ ref: "submodule status",
22282
+ cwd
22283
+ }));
22284
+ case "failure": return yield* effect.Effect.fail(classified.error);
22285
+ default: return yield* effect.Effect.die(`Git.submoduleStatus: unexpected classification "${classified._tag}"`);
22286
+ }
22287
+ });
22288
+ const submoduleInit = effect.Effect.fn("Git.submoduleInit")(function* (cwd, options) {
22289
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22290
+ const classified = yield* runFor(GitCommand.submoduleInit(options?.paths ?? []), cwd, "generic");
22291
+ switch (classified._tag) {
22292
+ case "success": return;
22293
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22294
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22295
+ ref: "submodule init",
22296
+ cwd
22297
+ }));
22298
+ case "failure": return yield* effect.Effect.fail(classified.error);
22299
+ default: return yield* effect.Effect.die(`Git.submoduleInit: unexpected classification "${classified._tag}"`);
22300
+ }
22301
+ });
22302
+ const submoduleDeinit = effect.Effect.fn("Git.submoduleDeinit")(function* (cwd, options) {
22303
+ const paths = options.paths ?? [];
22304
+ const all = options.all ?? false;
22305
+ yield* effect.Effect.annotateCurrentSpan({
22306
+ cwd,
22307
+ all,
22308
+ count: paths.length
22309
+ });
22310
+ if (!all && paths.length === 0) return yield* effect.Effect.fail(new GitCommandError({
22311
+ kind: "refused",
22312
+ args: ["submodule", "deinit"],
22313
+ cwd,
22314
+ stderr: "",
22315
+ detail: "refused: submoduleDeinit needs either paths or all: true"
22316
+ }));
22317
+ const classified = yield* runFor(GitCommand.submoduleDeinit(paths, all, options.force ?? false), cwd, "generic");
22318
+ switch (classified._tag) {
22319
+ case "success": return;
22320
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22321
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22322
+ ref: "submodule deinit",
22323
+ cwd
22324
+ }));
22325
+ case "failure": return yield* effect.Effect.fail(classified.error);
22326
+ default: return yield* effect.Effect.die(`Git.submoduleDeinit: unexpected classification "${classified._tag}"`);
22327
+ }
22328
+ });
22329
+ const submoduleSync = effect.Effect.fn("Git.submoduleSync")(function* (cwd, options) {
22330
+ yield* effect.Effect.annotateCurrentSpan({
22331
+ cwd,
22332
+ recursive: options?.recursive ?? false
22333
+ });
22334
+ const classified = yield* runFor(GitCommand.submoduleSync(options?.paths ?? [], options?.recursive ?? false), cwd, "generic");
22335
+ switch (classified._tag) {
22336
+ case "success": return;
22337
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22338
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22339
+ ref: "submodule sync",
22340
+ cwd
22341
+ }));
22342
+ case "failure": return yield* effect.Effect.fail(classified.error);
22343
+ default: return yield* effect.Effect.die(`Git.submoduleSync: unexpected classification "${classified._tag}"`);
22344
+ }
22345
+ });
22346
+ const submoduleSetUrl = effect.Effect.fn("Git.submoduleSetUrl")(function* (cwd, path, url) {
22347
+ yield* effect.Effect.annotateCurrentSpan({
22348
+ cwd,
22349
+ path
22350
+ });
22351
+ const classified = yield* runFor(GitCommand.submoduleSetUrl(path, url), cwd, "generic");
22352
+ switch (classified._tag) {
22353
+ case "success": return;
22354
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22355
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22356
+ ref: path,
22357
+ cwd
22358
+ }));
22359
+ case "failure": return yield* effect.Effect.fail(classified.error);
22360
+ default: return yield* effect.Effect.die(`Git.submoduleSetUrl: unexpected classification "${classified._tag}"`);
22361
+ }
22362
+ });
22363
+ const submoduleSetBranch = effect.Effect.fn("Git.submoduleSetBranch")(function* (cwd, path, options) {
22364
+ const branch = options?.branch;
22365
+ yield* effect.Effect.annotateCurrentSpan({
22366
+ cwd,
22367
+ path,
22368
+ branch: branch ?? "(default)"
22369
+ });
22370
+ if (branch !== void 0) yield* rejectOptionLikeRefs(cwd, [branch]);
22371
+ const classified = yield* runFor(GitCommand.submoduleSetBranch(path, branch), cwd, "generic");
22372
+ switch (classified._tag) {
22373
+ case "success": return;
22374
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22375
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22376
+ ref: branch ?? path,
22377
+ cwd
22378
+ }));
22379
+ case "failure": return yield* effect.Effect.fail(classified.error);
22380
+ default: return yield* effect.Effect.die(`Git.submoduleSetBranch: unexpected classification "${classified._tag}"`);
22381
+ }
22382
+ });
22383
+ const submoduleAbsorbgitdirs = effect.Effect.fn("Git.submoduleAbsorbgitdirs")(function* (cwd, options) {
22384
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22385
+ const classified = yield* runFor(GitCommand.submoduleAbsorbgitdirs(options?.paths ?? []), cwd, "generic");
19928
22386
  switch (classified._tag) {
19929
- case "success": return parseNameStatus(classified.output);
22387
+ case "success": return;
19930
22388
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
19931
22389
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
19932
- ref: options.head === void 0 ? options.base : `${options.base}...${options.head}`,
22390
+ ref: "submodule absorbgitdirs",
19933
22391
  cwd
19934
22392
  }));
19935
22393
  case "failure": return yield* effect.Effect.fail(classified.error);
19936
- default: return yield* effect.Effect.die(`Git.nameStatus: unexpected classification "${classified._tag}"`);
22394
+ default: return yield* effect.Effect.die(`Git.submoduleAbsorbgitdirs: unexpected classification "${classified._tag}"`);
19937
22395
  }
19938
22396
  });
19939
- const revParse = effect.Effect.fn("Git.revParse")(function* (cwd, ref) {
22397
+ const submoduleForeach = effect.Effect.fn("Git.submoduleForeach")(function* (cwd, command, options) {
19940
22398
  yield* effect.Effect.annotateCurrentSpan({
19941
22399
  cwd,
19942
- ref
22400
+ recursive: options?.recursive ?? false
19943
22401
  });
19944
- yield* rejectOptionLikeRefs(cwd, [ref]);
19945
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.revParse(ref), cwd);
19946
- const classified = yield* runFor(command, cwd, "generic");
22402
+ yield* rejectOptionLikeRefs(cwd, [command]);
22403
+ const classified = yield* runFor(GitCommand.submoduleForeach(command, options?.recursive ?? false), cwd, "generic");
19947
22404
  switch (classified._tag) {
19948
- case "success": return classified.output.trim();
22405
+ case "success": return classified.output;
19949
22406
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
19950
22407
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
19951
- ref,
22408
+ ref: "submodule foreach",
19952
22409
  cwd
19953
22410
  }));
19954
22411
  case "failure": return yield* effect.Effect.fail(classified.error);
19955
- default: return yield* effect.Effect.die(`Git.revParse: unexpected classification "${classified._tag}"`);
22412
+ default: return yield* effect.Effect.die(`Git.submoduleForeach: unexpected classification "${classified._tag}"`);
19956
22413
  }
19957
22414
  });
19958
- const checkout = effect.Effect.fn("Git.checkout")(function* (cwd, ref, options) {
19959
- const detach = options?.detach ?? false;
19960
- yield* effect.Effect.annotateCurrentSpan({
19961
- cwd,
19962
- ref,
19963
- detach
19964
- });
19965
- yield* rejectOptionLikeRefs(cwd, [ref]);
19966
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.checkout(ref, detach), cwd);
19967
- const classified = yield* runFor(command, cwd, "generic");
22415
+ const runVoid = (method, invocation, cwd, refLabel) => effect.Effect.gen(function* () {
22416
+ const classified = yield* runFor(invocation, cwd, "generic");
19968
22417
  switch (classified._tag) {
19969
22418
  case "success": return;
19970
22419
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
19971
22420
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
19972
- ref,
22421
+ ref: refLabel,
19973
22422
  cwd
19974
22423
  }));
19975
22424
  case "failure": return yield* effect.Effect.fail(classified.error);
19976
- default: return yield* effect.Effect.die(`Git.checkout: unexpected classification "${classified._tag}"`);
22425
+ default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
19977
22426
  }
19978
22427
  });
19979
- const fetch = effect.Effect.fn("Git.fetch")(function* (cwd, options) {
19980
- const remote = options.remote ?? "origin";
19981
- const tag = options.tag ?? false;
22428
+ const runParsed = (method, invocation, cwd, refLabel, kind, parse, absent) => effect.Effect.gen(function* () {
22429
+ const classified = yield* runFor(invocation, cwd, kind);
22430
+ switch (classified._tag) {
22431
+ case "success": return parse(classified.output);
22432
+ case "absent":
22433
+ if (absent !== void 0) return absent();
22434
+ return yield* effect.Effect.die(`${method}: unexpected classification "absent"`);
22435
+ case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
22436
+ case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
22437
+ ref: refLabel,
22438
+ cwd
22439
+ }));
22440
+ case "failure": return yield* effect.Effect.fail(classified.error);
22441
+ default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
22442
+ }
22443
+ });
22444
+ const lsRemote = effect.Effect.fn("Git.lsRemote")(function* (cwd, remote, options) {
19982
22445
  yield* effect.Effect.annotateCurrentSpan({
19983
22446
  cwd,
19984
- remote,
19985
- ref: options.ref,
19986
- tag
22447
+ heads: options?.heads ?? false,
22448
+ tags: options?.tags ?? false,
22449
+ patterns: (options?.patterns ?? []).length
19987
22450
  });
19988
- yield* rejectOptionLikeRefs(cwd, [remote, options.ref]);
19989
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.fetch(remote, options.ref, options.depth, tag), cwd);
19990
- const classified = yield* runFor(command, cwd, "generic");
22451
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.patterns ?? []]);
22452
+ return yield* runParsed("Git.lsRemote", GitCommand.lsRemote(remote, options?.heads ?? false, options?.tags ?? false, options?.patterns ?? []), cwd, "ls-remote", "generic", parseLsRemote);
22453
+ });
22454
+ const remoteAdd = effect.Effect.fn("Git.remoteAdd")(function* (cwd, name, url) {
22455
+ yield* effect.Effect.annotateCurrentSpan({
22456
+ cwd,
22457
+ name
22458
+ });
22459
+ yield* rejectOptionLikeRefs(cwd, [name, url]);
22460
+ return yield* runVoid("Git.remoteAdd", GitCommand.remoteAdd(name, url), cwd, name);
22461
+ });
22462
+ const remoteRemove = effect.Effect.fn("Git.remoteRemove")(function* (cwd, name) {
22463
+ yield* effect.Effect.annotateCurrentSpan({
22464
+ cwd,
22465
+ name
22466
+ });
22467
+ yield* rejectOptionLikeRefs(cwd, [name]);
22468
+ return yield* runVoid("Git.remoteRemove", GitCommand.remoteRemove(name), cwd, name);
22469
+ });
22470
+ const remoteSetUrl = effect.Effect.fn("Git.remoteSetUrl")(function* (cwd, name, url) {
22471
+ yield* effect.Effect.annotateCurrentSpan({
22472
+ cwd,
22473
+ name
22474
+ });
22475
+ yield* rejectOptionLikeRefs(cwd, [name, url]);
22476
+ return yield* runVoid("Git.remoteSetUrl", GitCommand.remoteSetUrl(name, url), cwd, name);
22477
+ });
22478
+ const stashPush = effect.Effect.fn("Git.stashPush")(function* (cwd, options) {
22479
+ yield* effect.Effect.annotateCurrentSpan({
22480
+ cwd,
22481
+ includeUntracked: options?.includeUntracked ?? false
22482
+ });
22483
+ return yield* runVoid("Git.stashPush", GitCommand.stashPush(options?.message, options?.includeUntracked ?? false, options?.paths ?? []), cwd, "stash");
22484
+ });
22485
+ const stashRestore = (method, invocation) => effect.Effect.fn(method)(function* (cwd, options) {
22486
+ yield* effect.Effect.annotateCurrentSpan({
22487
+ cwd,
22488
+ index: options?.index ?? 0
22489
+ });
22490
+ yield* rejectNonNaturalNumber(cwd, "a stash index", options?.index);
22491
+ const classified = yield* runFor(invocation(options?.index), cwd, "merge");
19991
22492
  switch (classified._tag) {
19992
22493
  case "success": return;
22494
+ case "dirtyWorktree": return yield* effect.Effect.fail(new DirtyWorktreeError({ cwd }));
22495
+ case "mergeConflict": return yield* effect.Effect.fail(new MergeConflictError({ cwd }));
19993
22496
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
19994
22497
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
19995
- ref: options.ref,
22498
+ ref: "stash",
19996
22499
  cwd
19997
22500
  }));
19998
22501
  case "failure": return yield* effect.Effect.fail(classified.error);
19999
- default: return yield* effect.Effect.die(`Git.fetch: unexpected classification "${classified._tag}"`);
22502
+ default: return yield* effect.Effect.die(`${method}: unexpected classification "${classified._tag}"`);
20000
22503
  }
20001
22504
  });
20002
22505
  return {
@@ -20009,254 +22512,235 @@ const make = (spawner) => {
20009
22512
  revParse,
20010
22513
  checkout,
20011
22514
  fetch,
20012
- fetchAny: effect.Effect.fn("Git.fetchAny")(function* (cwd, options) {
20013
- const remote = options.remote ?? "origin";
22515
+ fetchAny,
22516
+ fetchUnshallow,
22517
+ isShallow,
22518
+ reset,
22519
+ clean,
22520
+ restore,
22521
+ branchCreate,
22522
+ branchDelete,
22523
+ submoduleUpdate,
22524
+ submoduleAdd,
22525
+ submoduleStatus,
22526
+ submoduleInit,
22527
+ submoduleDeinit,
22528
+ submoduleSync,
22529
+ submoduleSetUrl,
22530
+ submoduleSetBranch,
22531
+ submoduleAbsorbgitdirs,
22532
+ submoduleForeach,
22533
+ sparseCheckoutSet,
22534
+ configSet,
22535
+ add,
22536
+ nameStatus,
22537
+ unstagedChanges,
22538
+ stagedChanges,
22539
+ untrackedFiles,
22540
+ defaultBranch,
22541
+ currentBranch,
22542
+ repoRoot,
22543
+ configGet,
22544
+ remoteUrl,
22545
+ commitInfo,
22546
+ status,
22547
+ lsRemote,
22548
+ remoteAdd,
22549
+ remoteRemove,
22550
+ remoteSetUrl,
22551
+ stashPush,
22552
+ stashPop: stashRestore("Git.stashPop", GitCommand.stashPop),
22553
+ stashApply: stashRestore("Git.stashApply", GitCommand.stashApply),
22554
+ stashDrop: effect.Effect.fn("Git.stashDrop")(function* (cwd, options) {
20014
22555
  yield* effect.Effect.annotateCurrentSpan({
20015
22556
  cwd,
20016
- remote,
20017
- ref: options.ref
22557
+ index: options?.index ?? 0
20018
22558
  });
20019
- return yield* fetch(cwd, {
20020
- ...options,
20021
- tag: true
20022
- }).pipe(effect.Effect.catchTag(["UnknownRefError", "GitCommandError"], (error) => error._tag === "GitCommandError" && error.kind === "refused" ? effect.Effect.fail(error) : fetch(cwd, options)));
22559
+ yield* rejectNonNaturalNumber(cwd, "a stash index", options?.index);
22560
+ return yield* runVoid("Git.stashDrop", GitCommand.stashDrop(options?.index), cwd, "stash");
22561
+ }),
22562
+ stashList: effect.Effect.fn("Git.stashList")(function* (cwd) {
22563
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22564
+ return yield* runParsed("Git.stashList", GitCommand.stashList(), cwd, "stash", "generic", parseStashList);
20023
22565
  }),
20024
- submoduleUpdate: effect.Effect.fn("Git.submoduleUpdate")(function* (cwd, options) {
20025
- const init = options?.init ?? false;
22566
+ branchList: effect.Effect.fn("Git.branchList")(function* (cwd, options) {
20026
22567
  yield* effect.Effect.annotateCurrentSpan({
20027
22568
  cwd,
20028
- init
22569
+ remotes: options?.remotes ?? false,
22570
+ all: options?.all ?? false
20029
22571
  });
20030
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.submoduleUpdate(init, options?.depth, options?.paths ?? []), cwd);
20031
- const classified = yield* runFor(command, cwd, "generic");
20032
- switch (classified._tag) {
20033
- case "success": return;
20034
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20035
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20036
- ref: "submodule update",
20037
- cwd
20038
- }));
20039
- case "failure": return yield* effect.Effect.fail(classified.error);
20040
- default: return yield* effect.Effect.die(`Git.submoduleUpdate: unexpected classification "${classified._tag}"`);
20041
- }
22572
+ return yield* runParsed("Git.branchList", GitCommand.branchList(options?.remotes ?? false, options?.all ?? false), cwd, "branches", "generic", parseBranchList);
20042
22573
  }),
20043
- submoduleAdd: effect.Effect.fn("Git.submoduleAdd")(function* (cwd, options) {
22574
+ tagCreate: effect.Effect.fn("Git.tagCreate")(function* (cwd, name, options) {
20044
22575
  yield* effect.Effect.annotateCurrentSpan({
20045
22576
  cwd,
20046
- url: options.url,
20047
- path: options.path
22577
+ name,
22578
+ ref: options?.ref ?? "HEAD",
22579
+ force: options?.force ?? false
20048
22580
  });
20049
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.submoduleAdd(options.url, options.path, options.depth), cwd);
20050
- const classified = yield* runFor(command, cwd, "generic");
20051
- switch (classified._tag) {
20052
- case "success": return;
20053
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20054
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20055
- ref: options.url,
20056
- cwd
20057
- }));
20058
- case "failure": return yield* effect.Effect.fail(classified.error);
20059
- default: return yield* effect.Effect.die(`Git.submoduleAdd: unexpected classification "${classified._tag}"`);
20060
- }
22581
+ yield* rejectOptionLikeRefs(cwd, [name, ...options?.ref !== void 0 ? [options.ref] : []]);
22582
+ return yield* runVoid("Git.tagCreate", GitCommand.tagCreate(name, options?.ref, options?.message, options?.force ?? false), cwd, options?.ref ?? name);
20061
22583
  }),
20062
- sparseCheckoutSet: effect.Effect.fn("Git.sparseCheckoutSet")(function* (cwd, patterns, options) {
22584
+ tagDelete: effect.Effect.fn("Git.tagDelete")(function* (cwd, name) {
20063
22585
  yield* effect.Effect.annotateCurrentSpan({
20064
22586
  cwd,
20065
- cone: options.cone
22587
+ name
20066
22588
  });
20067
- yield* rejectOptionLikeRefs(cwd, patterns);
20068
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.sparseCheckoutSet(patterns, options.cone), cwd);
20069
- const classified = yield* runFor(command, cwd, "generic");
20070
- switch (classified._tag) {
20071
- case "success": return;
20072
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20073
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20074
- ref: "sparse-checkout",
20075
- cwd
20076
- }));
20077
- case "failure": return yield* effect.Effect.fail(classified.error);
20078
- default: return yield* effect.Effect.die(`Git.sparseCheckoutSet: unexpected classification "${classified._tag}"`);
20079
- }
22589
+ yield* rejectOptionLikeRefs(cwd, [name]);
22590
+ return yield* runVoid("Git.tagDelete", GitCommand.tagDelete(name), cwd, name);
22591
+ }),
22592
+ tagList: effect.Effect.fn("Git.tagList")(function* (cwd, options) {
22593
+ yield* effect.Effect.annotateCurrentSpan({ cwd });
22594
+ yield* rejectOptionLikeRefs(cwd, options?.pattern !== void 0 ? [options.pattern] : []);
22595
+ return yield* runParsed("Git.tagList", GitCommand.tagList(options?.pattern), cwd, "tags", "generic", (output) => output.split("\n").filter((line) => line.length > 0));
20080
22596
  }),
20081
- configSet: effect.Effect.fn("Git.configSet")(function* (cwd, key, value, options) {
22597
+ forEachRef: effect.Effect.fn("Git.forEachRef")(function* (cwd, options) {
20082
22598
  yield* effect.Effect.annotateCurrentSpan({
20083
22599
  cwd,
20084
- key,
20085
- file: options?.file ?? "(repository config)"
22600
+ patterns: (options?.patterns ?? []).length
20086
22601
  });
20087
- yield* rejectOptionLikeRefs(cwd, [
20088
- key,
20089
- value,
20090
- ...options?.file !== void 0 ? [options.file] : []
20091
- ]);
20092
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.configSet(key, value, options?.file), cwd);
20093
- const classified = yield* runFor(command, cwd, "generic");
20094
- switch (classified._tag) {
20095
- case "success": return;
20096
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20097
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20098
- ref: key,
20099
- cwd
20100
- }));
20101
- case "failure": return yield* effect.Effect.fail(classified.error);
20102
- default: return yield* effect.Effect.die(`Git.configSet: unexpected classification "${classified._tag}"`);
20103
- }
22602
+ yield* rejectOptionLikeRefs(cwd, options?.patterns ?? []);
22603
+ return yield* runParsed("Git.forEachRef", GitCommand.forEachRef(options?.patterns ?? []), cwd, "for-each-ref", "generic", parseForEachRef);
20104
22604
  }),
20105
- add: effect.Effect.fn("Git.add")(function* (cwd, paths) {
22605
+ revList: effect.Effect.fn("Git.revList")(function* (cwd, ref, options) {
20106
22606
  yield* effect.Effect.annotateCurrentSpan({
20107
22607
  cwd,
20108
- count: paths.length
22608
+ ref,
22609
+ firstParent: options?.firstParent ?? false
22610
+ });
22611
+ yield* rejectOptionLikeRefs(cwd, [ref]);
22612
+ yield* rejectNonNaturalNumber(cwd, "a rev-list limit", options?.limit);
22613
+ 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));
22614
+ }),
22615
+ commit: effect.Effect.fn("Git.commit")(function* (cwd, message, options) {
22616
+ yield* effect.Effect.annotateCurrentSpan({
22617
+ cwd,
22618
+ amend: options?.amend ?? false
22619
+ });
22620
+ return yield* runVoid("Git.commit", GitCommand.commit(message, options?.all ?? false, options?.allowEmpty ?? false, options?.amend ?? false, options?.author), cwd, "HEAD");
22621
+ }),
22622
+ push: effect.Effect.fn("Git.push")(function* (cwd, options) {
22623
+ const remote = options?.remote ?? "origin";
22624
+ yield* effect.Effect.annotateCurrentSpan({
22625
+ cwd,
22626
+ refspec: options?.refspec ?? "(current branch)",
22627
+ forceWithLease: options?.forceWithLease ?? false
20109
22628
  });
20110
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.add(paths), cwd);
20111
- const classified = yield* runFor(command, cwd, "generic");
22629
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.refspec !== void 0 ? [options.refspec] : []]);
22630
+ const classified = yield* runFor(GitCommand.push(remote, options?.refspec, options?.force ?? false, options?.forceWithLease ?? false, options?.tags ?? false, options?.setUpstream ?? false), cwd, "push");
20112
22631
  switch (classified._tag) {
20113
22632
  case "success": return;
22633
+ case "nonFastForward": return yield* effect.Effect.fail(new NonFastForwardError({
22634
+ cwd,
22635
+ ...options?.refspec !== void 0 ? { refspec: options.refspec } : {}
22636
+ }));
20114
22637
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20115
22638
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20116
- ref: "working tree",
22639
+ ref: options?.refspec ?? "HEAD",
20117
22640
  cwd
20118
22641
  }));
20119
22642
  case "failure": return yield* effect.Effect.fail(classified.error);
20120
- default: return yield* effect.Effect.die(`Git.add: unexpected classification "${classified._tag}"`);
22643
+ default: return yield* effect.Effect.die(`Git.push: unexpected classification "${classified._tag}"`);
20121
22644
  }
20122
22645
  }),
20123
- nameStatus,
20124
- unstagedChanges,
20125
- stagedChanges,
20126
- untrackedFiles,
20127
- defaultBranch: effect.Effect.fn("Git.defaultBranch")(function* (cwd, options) {
22646
+ pull: effect.Effect.fn("Git.pull")(function* (cwd, options) {
20128
22647
  const remote = options?.remote ?? "origin";
20129
22648
  yield* effect.Effect.annotateCurrentSpan({
20130
22649
  cwd,
20131
- remote
22650
+ ref: options?.ref ?? "(upstream)",
22651
+ rebase: options?.rebase ?? false
20132
22652
  });
20133
- yield* rejectOptionLikeRefs(cwd, [remote]);
20134
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.defaultBranch(remote), cwd);
20135
- const classified = yield* runFor(command, cwd, "quiet");
22653
+ yield* rejectOptionLikeRefs(cwd, [remote, ...options?.ref !== void 0 ? [options.ref] : []]);
22654
+ const classified = yield* runFor(GitCommand.pull(remote, options?.ref, options?.rebase ?? false, options?.ffOnly ?? false), cwd, "merge");
20136
22655
  switch (classified._tag) {
20137
- case "success": {
20138
- const short = classified.output.trim();
20139
- const prefix = `${remote}/`;
20140
- return effect.Option.some(short.startsWith(prefix) ? short.slice(prefix.length) : short);
20141
- }
20142
- case "absent": return effect.Option.none();
22656
+ case "success": return;
22657
+ case "dirtyWorktree": return yield* effect.Effect.fail(new DirtyWorktreeError({ cwd }));
22658
+ case "mergeConflict": return yield* effect.Effect.fail(new MergeConflictError({ cwd }));
20143
22659
  case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20144
22660
  case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20145
- ref: `refs/remotes/${remote}/HEAD`,
22661
+ ref: options?.ref ?? "(upstream)",
20146
22662
  cwd
20147
22663
  }));
20148
22664
  case "failure": return yield* effect.Effect.fail(classified.error);
20149
- default: return yield* effect.Effect.die(`Git.defaultBranch: unexpected classification "${classified._tag}"`);
22665
+ default: return yield* effect.Effect.die(`Git.pull: unexpected classification "${classified._tag}"`);
20150
22666
  }
20151
22667
  }),
20152
- currentBranch: effect.Effect.fn("Git.currentBranch")(function* (cwd) {
20153
- yield* effect.Effect.annotateCurrentSpan({ cwd });
20154
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.currentBranch(), cwd);
20155
- const classified = yield* runFor(command, cwd, "generic");
20156
- switch (classified._tag) {
20157
- case "success": {
20158
- const name = classified.output.trim();
20159
- return name === "HEAD" ? effect.Option.none() : effect.Option.some(name);
20160
- }
20161
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20162
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20163
- ref: "HEAD",
20164
- cwd
20165
- }));
20166
- case "failure": return yield* effect.Effect.fail(classified.error);
20167
- default: return yield* effect.Effect.die(`Git.currentBranch: unexpected classification "${classified._tag}"`);
20168
- }
22668
+ configList: effect.Effect.fn("Git.configList")(function* (cwd, options) {
22669
+ yield* effect.Effect.annotateCurrentSpan({
22670
+ cwd,
22671
+ file: options?.file ?? "(repository config)"
22672
+ });
22673
+ yield* rejectOptionLikeRefs(cwd, options?.file !== void 0 ? [options.file] : []);
22674
+ return yield* runParsed("Git.configList", GitCommand.configList(options?.file), cwd, "config", "generic", parseConfigList);
20169
22675
  }),
20170
- repoRoot: effect.Effect.fn("Git.repoRoot")(function* (cwd) {
20171
- yield* effect.Effect.annotateCurrentSpan({ cwd });
20172
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.repoRoot(), cwd);
20173
- const classified = yield* runFor(command, cwd, "generic");
20174
- switch (classified._tag) {
20175
- case "success": return classified.output.trim();
20176
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20177
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20178
- ref: "working tree",
20179
- cwd
20180
- }));
20181
- case "failure": return yield* effect.Effect.fail(classified.error);
20182
- default: return yield* effect.Effect.die(`Git.repoRoot: unexpected classification "${classified._tag}"`);
20183
- }
22676
+ configGetAll: effect.Effect.fn("Git.configGetAll")(function* (cwd, key, options) {
22677
+ yield* effect.Effect.annotateCurrentSpan({
22678
+ cwd,
22679
+ key,
22680
+ file: options?.file ?? "(repository config)"
22681
+ });
22682
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []]);
22683
+ return yield* runParsed("Git.configGetAll", GitCommand.configGetAll(key, options?.file), cwd, key, "quiet", parseNulSeparated, () => []);
20184
22684
  }),
20185
- configGet: effect.Effect.fn("Git.configGet")(function* (cwd, key) {
22685
+ configUnset: effect.Effect.fn("Git.configUnset")(function* (cwd, key, options) {
20186
22686
  yield* effect.Effect.annotateCurrentSpan({
20187
22687
  cwd,
20188
- key
22688
+ key,
22689
+ file: options?.file ?? "(repository config)"
20189
22690
  });
20190
- yield* rejectOptionLikeRefs(cwd, [key]);
20191
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.configGet(key), cwd);
20192
- const classified = yield* runFor(command, cwd, "quiet");
20193
- switch (classified._tag) {
20194
- case "success": return effect.Option.some(classified.output.trim());
20195
- case "absent": return effect.Option.none();
20196
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20197
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20198
- ref: key,
20199
- cwd
20200
- }));
20201
- case "failure": return yield* effect.Effect.fail(classified.error);
20202
- default: return yield* effect.Effect.die(`Git.configGet: unexpected classification "${classified._tag}"`);
20203
- }
22691
+ yield* rejectOptionLikeRefs(cwd, [key, ...options?.file !== void 0 ? [options.file] : []]);
22692
+ return yield* runVoid("Git.configUnset", GitCommand.configUnset(key, options?.file, options?.all ?? false), cwd, key);
20204
22693
  }),
20205
- remoteUrl: effect.Effect.fn("Git.remoteUrl")(function* (cwd, options) {
20206
- const remote = options?.remote ?? "origin";
22694
+ rm: effect.Effect.fn("Git.rm")(function* (cwd, paths, options) {
20207
22695
  yield* effect.Effect.annotateCurrentSpan({
20208
22696
  cwd,
20209
- remote
22697
+ count: paths.length,
22698
+ cached: options?.cached ?? false
20210
22699
  });
20211
- yield* rejectOptionLikeRefs(cwd, [remote]);
20212
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.remoteUrl(remote), cwd);
20213
- const classified = yield* runFor(command, cwd, "noSuchRemote");
20214
- switch (classified._tag) {
20215
- case "success": return effect.Option.some(classified.output.trim());
20216
- case "absent": return effect.Option.none();
20217
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20218
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20219
- ref: remote,
20220
- cwd
20221
- }));
20222
- case "failure": return yield* effect.Effect.fail(classified.error);
20223
- default: return yield* effect.Effect.die(`Git.remoteUrl: unexpected classification "${classified._tag}"`);
20224
- }
22700
+ return yield* runVoid("Git.rm", GitCommand.rm(paths, options?.cached ?? false, options?.recursive ?? false, options?.force ?? false), cwd, "working tree");
20225
22701
  }),
20226
- commitInfo: effect.Effect.fn("Git.commitInfo")(function* (cwd, ref) {
20227
- const target = ref ?? "HEAD";
22702
+ mv: effect.Effect.fn("Git.mv")(function* (cwd, source, destination, options) {
20228
22703
  yield* effect.Effect.annotateCurrentSpan({
20229
22704
  cwd,
20230
- ref: target
22705
+ source,
22706
+ destination
20231
22707
  });
20232
- yield* rejectOptionLikeRefs(cwd, [target]);
20233
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.commitInfo(target), cwd);
20234
- const classified = yield* runFor(command, cwd, "generic");
20235
- switch (classified._tag) {
20236
- case "success": return parseCommitInfo(classified.output);
20237
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20238
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20239
- ref: target,
20240
- cwd
20241
- }));
20242
- case "failure": return yield* effect.Effect.fail(classified.error);
20243
- default: return yield* effect.Effect.die(`Git.commitInfo: unexpected classification "${classified._tag}"`);
20244
- }
22708
+ return yield* runVoid("Git.mv", GitCommand.mv(source, destination, options?.force ?? false), cwd, "working tree");
22709
+ }),
22710
+ checkIgnore: effect.Effect.fn("Git.checkIgnore")(function* (cwd, paths) {
22711
+ yield* effect.Effect.annotateCurrentSpan({
22712
+ cwd,
22713
+ count: paths.length
22714
+ });
22715
+ return yield* runParsed("Git.checkIgnore", GitCommand.checkIgnore(paths), cwd, "check-ignore", "quiet", parseNulSeparated, () => []);
22716
+ }),
22717
+ worktreeAdd: effect.Effect.fn("Git.worktreeAdd")(function* (cwd, path, options) {
22718
+ yield* effect.Effect.annotateCurrentSpan({
22719
+ cwd,
22720
+ path,
22721
+ ref: options?.ref ?? "(default)"
22722
+ });
22723
+ yield* rejectOptionLikeRefs(cwd, [path, ...options?.ref !== void 0 ? [options.ref] : []]);
22724
+ return yield* runVoid("Git.worktreeAdd", GitCommand.worktreeAdd(path, options?.ref, options?.detach ?? false, options?.force ?? false), cwd, options?.ref ?? path);
20245
22725
  }),
20246
- status: effect.Effect.fn("Git.status")(function* (cwd) {
22726
+ worktreeList: effect.Effect.fn("Git.worktreeList")(function* (cwd) {
20247
22727
  yield* effect.Effect.annotateCurrentSpan({ cwd });
20248
- const command = effect_unstable_process.ChildProcess.setCwd(GitCommand.status(), cwd);
20249
- const classified = yield* runFor(command, cwd, "generic");
20250
- switch (classified._tag) {
20251
- case "success": return parseStatus(classified.output);
20252
- case "notARepository": return yield* effect.Effect.fail(new NotARepositoryError({ cwd }));
20253
- case "unknownRef": return yield* effect.Effect.fail(new UnknownRefError({
20254
- ref: "working tree",
20255
- cwd
20256
- }));
20257
- case "failure": return yield* effect.Effect.fail(classified.error);
20258
- default: return yield* effect.Effect.die(`Git.status: unexpected classification "${classified._tag}"`);
20259
- }
22728
+ return yield* runParsed("Git.worktreeList", GitCommand.worktreeList(), cwd, "worktrees", "generic", parseWorktreeList);
22729
+ }),
22730
+ worktreeRemove: effect.Effect.fn("Git.worktreeRemove")(function* (cwd, path, options) {
22731
+ yield* effect.Effect.annotateCurrentSpan({
22732
+ cwd,
22733
+ path
22734
+ });
22735
+ yield* rejectOptionLikeRefs(cwd, [path]);
22736
+ return yield* runVoid("Git.worktreeRemove", GitCommand.worktreeRemove(path, options?.force ?? false), cwd, path);
22737
+ }),
22738
+ lsFiles: effect.Effect.fn("Git.lsFiles")(function* (cwd, options) {
22739
+ yield* effect.Effect.annotateCurrentSpan({
22740
+ cwd,
22741
+ patterns: (options?.pathspec ?? []).length
22742
+ });
22743
+ return yield* runParsed("Git.lsFiles", GitCommand.lsFiles(options?.pathspec ?? []), cwd, "index", "generic", parseLsFiles);
20260
22744
  })
20261
22745
  };
20262
22746
  };
@@ -20268,17 +22752,23 @@ const make = (spawner) => {
20268
22752
  const notStubbed = (method) => () => effect.Effect.die(/* @__PURE__ */ new Error(`Git.makeTest: ${method}() was called but not stubbed — no honest default exists for a test double; pass a \`${method}\` override.`));
20269
22753
  /**
20270
22754
  * Typed git introspection over core's `ChildProcessSpawner`: read a
20271
- * repository's state at any ref without checking it out, plus the mutating
20272
- * tier (`checkout`, `fetch`, `fetchAny`, `submoduleUpdate`, `submoduleAdd`,
20273
- * `sparseCheckoutSet`, `configSet`, `add`) that changes it.
22755
+ * repository's state at any ref without checking it out (including the
22756
+ * network read `lsRemote` and the index read `lsFiles`), plus the mutating
22757
+ * tier checkout/fetch, the working-tree restore trio and stash, branches
22758
+ * and tags, remotes, worktrees, commit/push/pull, submodules,
22759
+ * sparse-checkout, config writes and staging — that changes it. Every
22760
+ * mutating method's TSDoc opens with the literal word `Mutating:`.
20274
22761
  *
20275
22762
  * @remarks
20276
22763
  * Every method takes `cwd` explicitly and classifies git's stderr/exit-code
20277
22764
  * taxonomy exactly once, in this module's private `classify` step — a
20278
22765
  * spawn-level `PlatformError` and `Cause.TimeoutError` never escape a `Git`
20279
22766
  * method; every failure surfaces as {@link GitCommandError},
20280
- * {@link NotARepositoryError}, or {@link UnknownRefError}, or degrades to
20281
- * the documented non-error (`Option.none`, `false`).
22767
+ * {@link NotARepositoryError}, {@link UnknownRefError}, or one of the three
22768
+ * consumer-branchable classifications ({@link NonFastForwardError} from
22769
+ * `push`; {@link MergeConflictError} and {@link DirtyWorktreeError} from the
22770
+ * merge-shaped `pull` / `stashPop` / `stashApply`), or degrades to the
22771
+ * documented non-error (`Option.none`, `false`, the empty array).
20282
22772
  *
20283
22773
  * Every method whose TSDoc opens "Mutating:" changes the working tree,
20284
22774
  * `HEAD`, the index, the repository config, the object database and
@@ -20287,6 +22777,12 @@ const notStubbed = (method) => () => effect.Effect.die(/* @__PURE__ */ new Error
20287
22777
  * that — a caller running two mutating calls (or a mutating call alongside a
20288
22778
  * read) against one `cwd` at once owns the race.
20289
22779
  *
22780
+ * **Redaction policy (documented, not just convention).** Error values
22781
+ * persist only the constructor's REDACTED argv (see `GitCommandError.args`),
22782
+ * and span annotations carry stable identifiers only — `cwd`, refs, keys,
22783
+ * paths, remote names — never config values and never URLs, which can embed
22784
+ * userinfo. A new method must follow both halves before it ships.
22785
+ *
20290
22786
  * @public
20291
22787
  */
20292
22788
  var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
@@ -20301,7 +22797,7 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
20301
22797
  *
20302
22798
  * @remarks
20303
22799
  * Unlike `WorkspaceDiscovery.makeTest`, **no method here has an honest
20304
- * default** — the shape is twenty-six unrelated git operations, and a
22800
+ * default** — the shape is unrelated git operations, and a
20305
22801
  * fabricated answer for any of them (an empty tree, a made-up sha, a silent
20306
22802
  * no-op `checkout`) would leak into consumer logic as fact. So every
20307
22803
  * unstubbed method fails loudly as a defect
@@ -20340,8 +22836,23 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
20340
22836
  checkout: notStubbed("checkout"),
20341
22837
  fetch: notStubbed("fetch"),
20342
22838
  fetchAny: notStubbed("fetchAny"),
22839
+ fetchUnshallow: notStubbed("fetchUnshallow"),
22840
+ isShallow: notStubbed("isShallow"),
22841
+ reset: notStubbed("reset"),
22842
+ clean: notStubbed("clean"),
22843
+ restore: notStubbed("restore"),
22844
+ branchCreate: notStubbed("branchCreate"),
22845
+ branchDelete: notStubbed("branchDelete"),
20343
22846
  submoduleUpdate: notStubbed("submoduleUpdate"),
20344
22847
  submoduleAdd: notStubbed("submoduleAdd"),
22848
+ submoduleStatus: notStubbed("submoduleStatus"),
22849
+ submoduleInit: notStubbed("submoduleInit"),
22850
+ submoduleDeinit: notStubbed("submoduleDeinit"),
22851
+ submoduleSync: notStubbed("submoduleSync"),
22852
+ submoduleSetUrl: notStubbed("submoduleSetUrl"),
22853
+ submoduleSetBranch: notStubbed("submoduleSetBranch"),
22854
+ submoduleAbsorbgitdirs: notStubbed("submoduleAbsorbgitdirs"),
22855
+ submoduleForeach: notStubbed("submoduleForeach"),
20345
22856
  sparseCheckoutSet: notStubbed("sparseCheckoutSet"),
20346
22857
  configSet: notStubbed("configSet"),
20347
22858
  add: notStubbed("add"),
@@ -20356,6 +22867,34 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
20356
22867
  remoteUrl: notStubbed("remoteUrl"),
20357
22868
  commitInfo: notStubbed("commitInfo"),
20358
22869
  status: notStubbed("status"),
22870
+ lsRemote: notStubbed("lsRemote"),
22871
+ remoteAdd: notStubbed("remoteAdd"),
22872
+ remoteRemove: notStubbed("remoteRemove"),
22873
+ remoteSetUrl: notStubbed("remoteSetUrl"),
22874
+ stashPush: notStubbed("stashPush"),
22875
+ stashPop: notStubbed("stashPop"),
22876
+ stashApply: notStubbed("stashApply"),
22877
+ stashDrop: notStubbed("stashDrop"),
22878
+ stashList: notStubbed("stashList"),
22879
+ branchList: notStubbed("branchList"),
22880
+ tagCreate: notStubbed("tagCreate"),
22881
+ tagDelete: notStubbed("tagDelete"),
22882
+ tagList: notStubbed("tagList"),
22883
+ forEachRef: notStubbed("forEachRef"),
22884
+ revList: notStubbed("revList"),
22885
+ commit: notStubbed("commit"),
22886
+ push: notStubbed("push"),
22887
+ pull: notStubbed("pull"),
22888
+ configList: notStubbed("configList"),
22889
+ configGetAll: notStubbed("configGetAll"),
22890
+ configUnset: notStubbed("configUnset"),
22891
+ rm: notStubbed("rm"),
22892
+ mv: notStubbed("mv"),
22893
+ checkIgnore: notStubbed("checkIgnore"),
22894
+ worktreeAdd: notStubbed("worktreeAdd"),
22895
+ worktreeList: notStubbed("worktreeList"),
22896
+ worktreeRemove: notStubbed("worktreeRemove"),
22897
+ lsFiles: notStubbed("lsFiles"),
20359
22898
  ...overrides
20360
22899
  });
20361
22900
  /**
@@ -20384,7 +22923,7 @@ var Git = class Git extends effect.Context.Service()("@effected/git/Git") {
20384
22923
  static layerTest = (overrides = {}) => effect.Layer.succeed(Git, Git.makeTest(overrides));
20385
22924
  };
20386
22925
  //#endregion
20387
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ChangeDetector.js
22926
+ //#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
20388
22927
  /**
20389
22928
  * Which git refs to compare, and whether to fold in the working tree.
20390
22929
  *
@@ -20640,7 +23179,7 @@ function resolveFromCatalog(catalogs, wantedDependency) {
20640
23179
  };
20641
23180
  }
20642
23181
  //#endregion
20643
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/catalogs.js
23182
+ //#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
20644
23183
  /** Project a pnpm-workspace manifest's `catalog` / `catalogs` fields into a `Catalogs` map. */
20645
23184
  const inlineCatalogs = (manifest) => {
20646
23185
  if (manifest.catalog === void 0 && manifest.catalogs === void 0) return {};
@@ -20704,7 +23243,7 @@ const rangeOf = (catalogs, dependency, specifier) => {
20704
23243
  });
20705
23244
  };
20706
23245
  //#endregion
20707
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/ConfigDependencyHooks.js
23246
+ //#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
20708
23247
  /** Whether `value` is a non-null, non-array object. */
20709
23248
  const isObject$2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
20710
23249
  /**
@@ -20797,6 +23336,141 @@ const updateConfigOf = (mod) => {
20797
23336
  }
20798
23337
  };
20799
23338
  /**
23339
+ * The subprocess replay program {@link ConfigDependencyHooks.layerSubprocess}
23340
+ * hands to `node --input-type=module -e`.
23341
+ *
23342
+ * @remarks
23343
+ * A **static** string constant, deliberately: a bundler compiles a *computed*
23344
+ * dynamic `import()` into a context module that cannot resolve a runtime path
23345
+ * (`Cannot find module 'file:///…'`), so the computed import has to run in a
23346
+ * child process whose program text carries **no interpolated runtime value** —
23347
+ * the workspace root, the seed and the dependency names all arrive via argv
23348
+ * (`process.argv.slice(1)` under `-e`), never spliced into the script.
23349
+ *
23350
+ * The script mirrors this module's in-process semantics exactly so the two
23351
+ * layers are drop-in interchangeable: `pnpmfile.mjs` before `pnpmfile.cjs`
23352
+ * (pnpm 11's loader order), the `ERR_MODULE_NOT_FOUND`-for-the-candidate-itself
23353
+ * skip discrimination (`err.url` equality), the same hook-locator shapes, the
23354
+ * same tolerant threading of returned data (`configOf` / `finiteNumberOr` /
23355
+ * `stringArrayOr` clones below), and the same synchronous hook call. Only the
23356
+ * *mechanism* failures are reported: the script prints one final line of JSON —
23357
+ * `{ ok: true, config }` on success, `{ ok: false, name, message, stack? }`
23358
+ * naming the offending dependency on a load/replay failure — and exits through
23359
+ * the write callback so the payload is flushed even if a hook left the event
23360
+ * loop occupied. The final-line framing tolerates a hook's own `console.log`
23361
+ * noise on stdout.
23362
+ */
23363
+ const REPLAY_SCRIPT = `
23364
+ const [root, seedJson, ...names] = process.argv.slice(1);
23365
+ const { pathToFileURL } = await import("node:url");
23366
+ const { join } = await import("node:path");
23367
+ const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
23368
+ const finiteNumberOr = (value, fallback) => (typeof value === "number" && Number.isFinite(value) ? value : fallback);
23369
+ const stringArrayOr = (value, fallback) =>
23370
+ Array.isArray(value) && value.every((entry) => typeof entry === "string") ? value : fallback;
23371
+ const configOf = (value, fallback) =>
23372
+ isObject(value)
23373
+ ? {
23374
+ catalog: isObject(value.catalog) ? value.catalog : fallback.catalog,
23375
+ catalogs: isObject(value.catalogs) ? value.catalogs : fallback.catalogs,
23376
+ minimumReleaseAge: finiteNumberOr(value.minimumReleaseAge, fallback.minimumReleaseAge),
23377
+ minimumReleaseAgeExclude: stringArrayOr(value.minimumReleaseAgeExclude, fallback.minimumReleaseAgeExclude),
23378
+ }
23379
+ : fallback;
23380
+ const failure = (name, cause) => ({
23381
+ ok: false,
23382
+ name,
23383
+ message: cause instanceof Error ? cause.message : String(cause),
23384
+ ...(cause instanceof Error && typeof cause.stack === "string" ? { stack: cause.stack } : {}),
23385
+ });
23386
+ const replay = async () => {
23387
+ let catalog = {};
23388
+ const catalogs = {};
23389
+ for (const [name, entries] of Object.entries(JSON.parse(seedJson))) {
23390
+ if (name === "default") catalog = { ...entries };
23391
+ else catalogs[name] = { ...entries };
23392
+ }
23393
+ let config = { catalog, catalogs, minimumReleaseAge: undefined, minimumReleaseAgeExclude: undefined };
23394
+ for (const name of names) {
23395
+ let loaded;
23396
+ let found = false;
23397
+ for (const filename of ["pnpmfile.mjs", "pnpmfile.cjs"]) {
23398
+ const candidate = pathToFileURL(join(root, "node_modules", ".pnpm-config", name, filename)).href;
23399
+ try {
23400
+ loaded = await import(candidate);
23401
+ found = true;
23402
+ break;
23403
+ } catch (cause) {
23404
+ const url =
23405
+ isObject(cause) && cause.code === "ERR_MODULE_NOT_FOUND" && typeof cause.url === "string"
23406
+ ? cause.url
23407
+ : undefined;
23408
+ if (url === candidate) continue;
23409
+ return failure(name, cause);
23410
+ }
23411
+ }
23412
+ if (!found) continue;
23413
+ let hook;
23414
+ for (const candidate of [loaded, isObject(loaded) ? loaded.default : undefined]) {
23415
+ if (!isObject(candidate)) continue;
23416
+ if (isObject(candidate.hooks) && typeof candidate.hooks.updateConfig === "function") {
23417
+ hook = candidate.hooks.updateConfig;
23418
+ break;
23419
+ }
23420
+ if (typeof candidate.updateConfig === "function") {
23421
+ hook = candidate.updateConfig;
23422
+ break;
23423
+ }
23424
+ }
23425
+ if (hook === undefined) continue;
23426
+ try {
23427
+ config = configOf(hook(config), config);
23428
+ } catch (cause) {
23429
+ return failure(name, cause);
23430
+ }
23431
+ }
23432
+ return { ok: true, config };
23433
+ };
23434
+ const payload = await replay();
23435
+ process.stdout.write("\\n" + JSON.stringify(payload) + "\\n", () => process.exit(0));
23436
+ `;
23437
+ /**
23438
+ * The ceiling on one subprocess replay. A config dependency's `updateConfig`
23439
+ * reads and rewrites a config object — no install work, no network — so thirty
23440
+ * seconds is generous. Without a ceiling a pnpmfile that loops or awaits a
23441
+ * promise that never settles hangs `inject`, and through it the one memoized
23442
+ * {@link WorkspaceCatalogs} assemble pass every catalog read blocks on. Expiry
23443
+ * kills the child (`Run` scopes it) and surfaces as a `CommandFailedError`
23444
+ * through the same typed transport-failure path as any other mechanism failure.
23445
+ */
23446
+ const REPLAY_TIMEOUT = effect.Duration.seconds(30);
23447
+ /**
23448
+ * The subprocess protocol payload — a single JSON line near the end of the
23449
+ * child's stdout, framed and parsed by `Run.jsonLine`, which scans lines from
23450
+ * the end for the first that decodes (so a hook logging after the payload —
23451
+ * e.g. from `process.on("exit", ...)` — cannot displace it). The `ok`
23452
+ * discriminant is what keeps an accidental log line from satisfying the
23453
+ * envelope. The envelope is strict (a payload without a usable
23454
+ * `ok` discriminant is a mechanism failure, typed); the `config` slice inside a
23455
+ * success stays `Unknown` because a hook's returned *data* is tolerantly
23456
+ * threaded (`configOf`), never fatal.
23457
+ */
23458
+ const ReplayPayload = effect.Schema.Union([effect.Schema.Struct({
23459
+ ok: effect.Schema.Literal(true),
23460
+ config: effect.Schema.Unknown
23461
+ }), effect.Schema.Struct({
23462
+ ok: effect.Schema.Literal(false),
23463
+ name: effect.Schema.optionalKey(effect.Schema.String),
23464
+ message: effect.Schema.optionalKey(effect.Schema.String),
23465
+ stack: effect.Schema.optionalKey(effect.Schema.String)
23466
+ })]);
23467
+ /** Rebuild the subprocess's serialized failure as an `Error`, preserving the child-side stack when it carried one. */
23468
+ const replayFailureCause = (payload) => {
23469
+ const error = new Error(payload.message ?? "config dependency hook replay failed");
23470
+ if (payload.stack !== void 0) error.stack = payload.stack;
23471
+ return error;
23472
+ };
23473
+ /**
20800
23474
  * Replays a workspace's `configDependencies` `updateConfig` hooks over the inline
20801
23475
  * catalogs — the opt-in seam that lets hook-injected catalogs participate in
20802
23476
  * assembly.
@@ -20889,9 +23563,98 @@ var ConfigDependencyHooks = class ConfigDependencyHooks extends effect.Context.S
20889
23563
  releaseAge: releaseAgeOf(config)
20890
23564
  };
20891
23565
  }) });
23566
+ /**
23567
+ * The subprocess layer: replays each config dependency's pnpmfile in a `node`
23568
+ * child process instead of an in-process dynamic `import()`, with identical
23569
+ * typed semantics to {@link ConfigDependencyHooks.layerLive} — the two are
23570
+ * drop-in interchangeable.
23571
+ *
23572
+ * @remarks
23573
+ * `layerLive` computes the `import()` path at runtime, and a bundler (rspack,
23574
+ * for one) compiles a *computed* dynamic import into a context module that
23575
+ * throws `Cannot find module 'file:///…'` at runtime — so in any bundled
23576
+ * consumer, a GitHub Action above all, the in-process replay is unreachable.
23577
+ * This layer keeps every computed load out of the bundle graph: the replay
23578
+ * program is a **static** string constant passed via argv
23579
+ * (`node --input-type=module -e <script> <root> <seed> <...names>`), and the
23580
+ * child process performs the computed imports where no bundler rewrote them.
23581
+ * A subprocess also keeps config-dependency code out of the consumer's own
23582
+ * process.
23583
+ *
23584
+ * The contract's semantics are unchanged, not the downstream fail-open shape:
23585
+ * an empty `configDependencies` returns the seed without spawning anything; a
23586
+ * `..` path segment in a dependency name fails typed **before** any spawn; a
23587
+ * missing pnpmfile (neither `.mjs` nor `.cjs`) is the one legitimate skip,
23588
+ * discriminated inside the child by `err.url` equality exactly as
23589
+ * `layerLive` discriminates in process; any other load failure — a syntax
23590
+ * error, a throwing top level, an `ERR_MODULE_NOT_FOUND` for a module the
23591
+ * pnpmfile itself imports — and a hook that throws when called are serialized
23592
+ * back per-name and surface typed as a `hooks`-source `CatalogAssemblyError`
23593
+ * naming that dependency. A hook's returned *data* stays tolerantly threaded
23594
+ * (last well-formed write wins), never fatal. Spawn and transport failures —
23595
+ * `node` absent, a non-zero exit without a result payload, unparseable
23596
+ * output — fail typed too, never a defect and never a silent skip.
23597
+ *
23598
+ * Two bounds this layer imposes that `layerLive` cannot: the replay is
23599
+ * given thirty seconds (a pnpmfile that loops or awaits forever fails typed
23600
+ * instead of hanging the memoized assemble pass — a subprocess is killable,
23601
+ * while `layerLive`'s in-process synchronous hook call is not interruptible
23602
+ * by any means, so the asymmetry is inherent, not a parity violation), and
23603
+ * the child's stdout is captured under `Run.jsonLine`'s 16 MiB default
23604
+ * ceiling (a hook that logs more than that fails typed as `tooLarge`, where
23605
+ * `layerLive` — which captures nothing — would succeed).
23606
+ *
23607
+ * Catalog folding and normalization stay in the **parent** (the same
23608
+ * `@pnpm/catalogs`-derived path `layerLive` uses); the child returns only the
23609
+ * raw threaded config slice, since the script cannot import kit code.
23610
+ *
23611
+ * Requires core's `ChildProcessSpawner`, resolved when the layer is built —
23612
+ * the consumer provides it once at the edge (`@effect/platform-node`'s
23613
+ * `NodeServices.layer`), the same discharge `@effected/git` uses. Wired by
23614
+ * `WorkspaceCatalogs.layerWithConfigDependenciesSubprocess` /
23615
+ * `Workspaces.layerWithConfigDependenciesSubprocess`.
23616
+ */
23617
+ static layerSubprocess = effect.Layer.effect(ConfigDependencyHooks, effect.Effect.gen(function* () {
23618
+ const spawner = yield* effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner;
23619
+ return { inject: (root, configDependencies, seed) => effect.Effect.gen(function* () {
23620
+ const names = Object.keys(configDependencies);
23621
+ if (names.length === 0) return {
23622
+ catalogs: seed,
23623
+ releaseAge: {}
23624
+ };
23625
+ for (const name of names) if (hasTraversalSegment(name)) return yield* effect.Effect.fail(new CatalogAssemblyError({
23626
+ source: "hooks",
23627
+ path: name,
23628
+ cause: /* @__PURE__ */ new Error(`config dependency name has a '..' path segment: ${name}`)
23629
+ }));
23630
+ const command = effect_unstable_process.ChildProcess.make("node", [
23631
+ "--input-type=module",
23632
+ "-e",
23633
+ REPLAY_SCRIPT,
23634
+ root,
23635
+ JSON.stringify(seed),
23636
+ ...names
23637
+ ]);
23638
+ const payload = yield* Run.jsonLine(command, ReplayPayload, { timeout: REPLAY_TIMEOUT }).pipe(effect.Effect.provideService(effect_unstable_process.ChildProcessSpawner.ChildProcessSpawner, spawner), effect.Effect.catch((cause) => effect.Effect.fail(new CatalogAssemblyError({
23639
+ source: "hooks",
23640
+ path: root,
23641
+ cause
23642
+ }))));
23643
+ if (payload.ok === false) return yield* effect.Effect.fail(new CatalogAssemblyError({
23644
+ source: "hooks",
23645
+ path: payload.name ?? root,
23646
+ cause: replayFailureCause(payload)
23647
+ }));
23648
+ const config = configOf(payload.config, seedToConfig(seed));
23649
+ return {
23650
+ catalogs: configToEntries(config),
23651
+ releaseAge: releaseAgeOf(config)
23652
+ };
23653
+ }) };
23654
+ }));
20892
23655
  };
20893
23656
  //#endregion
20894
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/PackageManagerName.js
23657
+ //#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
20895
23658
  /**
20896
23659
  * The four package managers this package understands.
20897
23660
  *
@@ -21219,7 +23982,7 @@ var PackageManagerDetector = class PackageManagerDetector extends effect.Context
21219
23982
  static layerTest = (overrides = {}) => effect.Layer.succeed(PackageManagerDetector, PackageManagerDetector.makeTest(overrides));
21220
23983
  };
21221
23984
  //#endregion
21222
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/LockfileReader.js
23985
+ //#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
21223
23986
  /**
21224
23987
  * Raised when the workspace's lockfile cannot be read off disk.
21225
23988
  *
@@ -21399,7 +24162,7 @@ var LockfileReader = class LockfileReader extends effect.Context.Service()("@eff
21399
24162
  static layerTest = (overrides = {}) => effect.Layer.succeed(LockfileReader, LockfileReader.makeTest(overrides));
21400
24163
  };
21401
24164
  //#endregion
21402
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Publishability.js
24165
+ //#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
21403
24166
  /** The public npm registry, used when `publishConfig.registry` says nothing. */
21404
24167
  const DEFAULT_REGISTRY = "https://registry.npmjs.org/";
21405
24168
  /**
@@ -21558,7 +24321,7 @@ var PublishabilityDetector = class extends effect.Context.Service()("@effected/w
21558
24321
  static layerNone = effect.Layer.succeed(this, this.none);
21559
24322
  };
21560
24323
  //#endregion
21561
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/internal/importerVersions.js
24324
+ //#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
21562
24325
  /**
21563
24326
  * Strip pnpm's peer-disambiguation suffix from a recorded importer version.
21564
24327
  *
@@ -21644,7 +24407,7 @@ const unanimousVersionOf = (index, dependency) => {
21644
24407
  return agreed;
21645
24408
  };
21646
24409
  //#endregion
21647
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceCatalogs.js
24410
+ //#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
21648
24411
  /**
21649
24412
  * An immutable, fully-normalized catalog collection — the one catalog
21650
24413
  * resolution semantic in the package.
@@ -22065,6 +24828,24 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
22065
24828
  */
22066
24829
  static layerWithConfigDependencies = (options) => effect.Layer.effect(WorkspaceCatalogs, WorkspaceCatalogs.make(options)).pipe(effect.Layer.provide(ConfigDependencyHooks.layerLive));
22067
24830
  /**
24831
+ * The opt-in layer that replays config-dependency `pnpmfile` hooks in a
24832
+ * `node` **child process**: it wires
24833
+ * {@link ConfigDependencyHooks.layerSubprocess} in place of the in-process
24834
+ * `layerLive`.
24835
+ *
24836
+ * @remarks
24837
+ * Same typed semantics as {@link WorkspaceCatalogs.layerWithConfigDependencies}
24838
+ * — the two hook layers are drop-in interchangeable — but the replay's
24839
+ * computed dynamic `import()` runs in the subprocess, so it survives bundling
24840
+ * (a bundler compiles a computed in-process `import()` into a context module
24841
+ * that cannot resolve at runtime — every bundled GitHub Action hits this).
24842
+ * The cost is one extra requirement: core's `ChildProcessSpawner`, provided
24843
+ * once at the edge (`@effect/platform-node`'s `NodeServices.layer`) — the
24844
+ * same sanctioned R-widening as `Workspaces.layerWithGit`. Parameterized, so
24845
+ * bind it to a `const` and reuse it.
24846
+ */
24847
+ static layerWithConfigDependenciesSubprocess = (options) => effect.Layer.effect(WorkspaceCatalogs, WorkspaceCatalogs.make(options)).pipe(effect.Layer.provide(ConfigDependencyHooks.layerSubprocess));
24848
+ /**
22068
24849
  * A test double satisfying the full {@link WorkspaceCatalogsShape} with no
22069
24850
  * filesystem, lockfile read, or hook replay.
22070
24851
  *
@@ -22153,7 +24934,7 @@ var WorkspaceCatalogs = class WorkspaceCatalogs extends effect.Context.Service()
22153
24934
  }));
22154
24935
  };
22155
24936
  //#endregion
22156
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceStateSnapshot.js
24937
+ //#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
22157
24938
  const EMPTY = Object.freeze(Object.create(null));
22158
24939
  const DependencyMap = effect.Schema.Record(effect.Schema.String, effect.Schema.String).pipe(effect.Schema.withDecodingDefaultKey(effect.Effect.succeed(EMPTY)), effect.Schema.withConstructorDefault(effect.Effect.succeed(EMPTY)));
22159
24940
  /**
@@ -22376,7 +25157,7 @@ var WorkspaceStateSnapshot = class extends effect.Schema.Class("WorkspaceStateSn
22376
25157
  }
22377
25158
  };
22378
25159
  //#endregion
22379
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/WorkspaceSnapshots.js
25160
+ //#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
22380
25161
  /** Whether `value` is a non-null, non-array object. */
22381
25162
  const isObject = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
22382
25163
  /** Whether every value in a record is a string — a usable dependency map. */
@@ -22653,7 +25434,7 @@ var WorkspaceSnapshots = class WorkspaceSnapshots extends effect.Context.Service
22653
25434
  static layerTest = (overrides = {}) => effect.Layer.succeed(WorkspaceSnapshots, WorkspaceSnapshots.makeTest(overrides));
22654
25435
  };
22655
25436
  //#endregion
22656
- //#region ../../node_modules/.pnpm/@effected+workspaces@0.9.5_@effected+jsonc@0.5.2_effect@4.0.0-beta.101__effect@4.0.0-beta.101/node_modules/@effected/workspaces/Workspaces.js
25437
+ //#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
22657
25438
  const compose = (options, catalogsFactory) => {
22658
25439
  const roots = WorkspaceRoot.layer;
22659
25440
  const detector = PackageManagerDetector.layer;
@@ -22670,6 +25451,7 @@ const layerWithGit = (options) => {
22670
25451
  };
22671
25452
  const resolvers = effect.Layer.mergeAll(WorkspaceCatalogs.catalogResolver, WorkspaceDiscovery.workspaceResolver);
22672
25453
  const layerWithConfigDependencies = (options) => compose(options, WorkspaceCatalogs.layerWithConfigDependencies);
25454
+ const layerWithConfigDependenciesSubprocess = (options) => compose(options, WorkspaceCatalogs.layerWithConfigDependenciesSubprocess);
22673
25455
  const resolverLayer = (options) => resolvers.pipe(effect.Layer.provide(layerWithConfigDependencies(options)));
22674
25456
  const resolveManifest = effect.Effect.fn("Workspaces.resolveManifest")(function* (manifest, options) {
22675
25457
  return yield* manifest.resolve().pipe(effect.Effect.provide(resolverLayer(options)));
@@ -22751,6 +25533,32 @@ var Workspaces = class {
22751
25533
  */
22752
25534
  static layerWithConfigDependencies = layerWithConfigDependencies;
22753
25535
  /**
25536
+ * The git-free composite with config-dependency hook replay in a `node`
25537
+ * **child process** —
25538
+ * {@link WorkspaceCatalogs.layerWithConfigDependenciesSubprocess} in place of
25539
+ * the in-process replay.
25540
+ *
25541
+ * @remarks
25542
+ * Same typed semantics as {@link Workspaces.layerWithConfigDependencies}; the
25543
+ * difference is mechanism, and it matters in exactly one environment class: a
25544
+ * **bundled** consumer. The in-process replay's computed dynamic `import()`
25545
+ * is compiled by bundlers (rspack among them) into a context module that
25546
+ * throws `Cannot find module 'file:///…'` at runtime, which makes
25547
+ * `WorkspaceCatalogs.releaseAgeGate()` unreachable from any bundled GitHub
25548
+ * Action. Here the computed import runs inside a `node` child process whose
25549
+ * program text is a static string handed over argv, so nothing computed
25550
+ * enters the bundle graph.
25551
+ *
25552
+ * The extra requirement is core's `ChildProcessSpawner`, provided once at
25553
+ * the edge (`@effect/platform-node`'s `NodeServices.layer`) — the same
25554
+ * sanctioned R-widening as {@link Workspaces.layerWithGit}, and the reason
25555
+ * this is a separate composite rather than a flag: a consumer that keeps the
25556
+ * in-process replay should not have to be able to spawn a subprocess.
25557
+ *
25558
+ * **Bind the result to a `const`.**
25559
+ */
25560
+ static layerWithConfigDependenciesSubprocess = layerWithConfigDependenciesSubprocess;
25561
+ /**
22754
25562
  * The git-free composite plus {@link ChangeDetector} and
22755
25563
  * {@link WorkspaceSnapshots}, over `@effected/git`'s `Git` service.
22756
25564
  *
@@ -22760,7 +25568,8 @@ var Workspaces = class {
22760
25568
  * never detects changes or reads at a ref should not have to be able to
22761
25569
  * spawn a subprocess. The consumer provides `ChildProcessSpawner` once at
22762
25570
  * the edge (`@effect/platform-node`'s `NodeServices.layer`); a test
22763
- * provides `Layer.succeed(Git, …)` and needs no repository on disk.
25571
+ * provides `Git.layerTest({ })` git's own shipped double, whose
25572
+ * unstubbed members die named — and needs no repository on disk.
22764
25573
  */
22765
25574
  static layerWithGit = layerWithGit;
22766
25575
  /**
@@ -22809,9 +25618,14 @@ var Workspaces = class {
22809
25618
  * import { Workspaces } from "@effected/workspaces";
22810
25619
  * import { Layer } from "effect";
22811
25620
  *
25621
+ * // Bound to consts per the warning above: each factory call mints a
25622
+ * // fresh layer reference, and layers memoize by reference.
25623
+ * const LocalExecLayer = Workspaces.localExecLayer();
25624
+ * const WorkspacesLayer = Workspaces.layer();
25625
+ *
22812
25626
  * const AppLayer = ToolDiscovery.layer.pipe(
22813
- * Layer.provide(Workspaces.localExecLayer()),
22814
- * Layer.provide(Workspaces.layer()),
25627
+ * Layer.provide(LocalExecLayer),
25628
+ * Layer.provide(WorkspacesLayer),
22815
25629
  * Layer.provide(NodeServices.layer),
22816
25630
  * );
22817
25631
  * ```