@pmelab/gtd 8.3.0 → 8.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +17 -12
- package/dist/gtd.bundle.mjs +162 -19
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -117,18 +117,23 @@ steering-file entries are chosen by which file you create:
|
|
|
117
117
|
Both flows converge on the same tail: an agent hands you a `.gtd/REVIEW.md`
|
|
118
118
|
checkbox review of the diff — the prompt never inlines the diff itself; it names
|
|
119
119
|
the commit the changes are based at and the agent runs `git diff` to read the
|
|
120
|
-
range before writing the review.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
120
|
+
range before writing the review. While the cycle rests at that gate, gtd opens a
|
|
121
|
+
**review checkout window**: HEAD is rewound to the review base with the working
|
|
122
|
+
tree untouched, so the whole reviewable change shows up as ordinary uncommitted
|
|
123
|
+
changes in your editor's normal git integration (and files added during the
|
|
124
|
+
cycle show up as ordinary untracked files, so discarding one deletes it). The
|
|
125
|
+
window closes on the next gtd invocation. Tick a box as you review each hunk
|
|
126
|
+
(ticking just records "I read this"), and leave a **comment** to request
|
|
127
|
+
changes: a note on a line, an inline `// TODO`-style comment in the code, or a
|
|
128
|
+
direct code edit. Any comment sends a build + re-review round — an agent first
|
|
129
|
+
turns your comments into an explicit instruction list, then a build turn
|
|
130
|
+
implements it (a re-review then covers only the follow-through, and a hand-edit
|
|
131
|
+
is treated as your own fix the agent completes without reverting your lines; a
|
|
132
|
+
comment can't be silently dropped — a build turn that addresses nothing is
|
|
133
|
+
refused). Ticking every box with no comment is the sign-off, which collapses the
|
|
134
|
+
whole cycle into one commit (a **squash finale** whose message an agent drafts).
|
|
135
|
+
Stepping with a box still unticked and no comment is refused (finish reviewing
|
|
136
|
+
first), as is deleting `.gtd/REVIEW.md`.
|
|
132
137
|
|
|
133
138
|
The same review tail also has a direct entry point — `gtd review <commitish>`
|
|
134
139
|
starts a brand new process reviewing `<commitish>..HEAD` with no cycle of its
|
package/dist/gtd.bundle.mjs
CHANGED
|
@@ -6541,6 +6541,14 @@ const Equivalence$3 = (self, that) => matchWith(self, that, {
|
|
|
6541
6541
|
* @since 2.0.0
|
|
6542
6542
|
* @category math
|
|
6543
6543
|
*/
|
|
6544
|
+
const times = /*#__PURE__*/ dual(2, (self, times) => match$6(self, {
|
|
6545
|
+
onMillis: (millis) => make$40(millis * times),
|
|
6546
|
+
onNanos: (nanos) => make$40(nanos * BigInt(times))
|
|
6547
|
+
}));
|
|
6548
|
+
/**
|
|
6549
|
+
* @since 2.0.0
|
|
6550
|
+
* @category math
|
|
6551
|
+
*/
|
|
6544
6552
|
const sum = /*#__PURE__*/ dual(2, (self, that) => matchWith(self, that, {
|
|
6545
6553
|
onMillis: (self, that) => make$40(self + that),
|
|
6546
6554
|
onNanos: (self, that) => make$40(self + that)
|
|
@@ -9804,6 +9812,10 @@ const defaultServicesWith = (f) => withFiberRuntime$1((fiber) => f(fiber.current
|
|
|
9804
9812
|
const clockWith = (f) => defaultServicesWith((services) => f(services.unsafeMap.get(clockTag.key)));
|
|
9805
9813
|
/** @internal */
|
|
9806
9814
|
const currentTimeMillis$1 = /*#__PURE__*/ clockWith((clock) => clock.currentTimeMillis);
|
|
9815
|
+
/** @internal */
|
|
9816
|
+
const randomWith = (f) => defaultServicesWith((services) => f(services.unsafeMap.get(randomTag.key)));
|
|
9817
|
+
/** @internal */
|
|
9818
|
+
const next$1 = /*#__PURE__*/ randomWith((random) => random.next);
|
|
9807
9819
|
//#endregion
|
|
9808
9820
|
//#region node_modules/effect/dist/esm/Boolean.js
|
|
9809
9821
|
/**
|
|
@@ -11786,7 +11798,7 @@ const fromIterable = (iterable) => {
|
|
|
11786
11798
|
return new MetricBoundariesImpl(pipe(iterable, appendAll$2(of$1(Number.POSITIVE_INFINITY)), dedupe));
|
|
11787
11799
|
};
|
|
11788
11800
|
/** @internal */
|
|
11789
|
-
const exponential = (options) => pipe(makeBy(options.count - 1, (i) => options.start * Math.pow(options.factor, i)), unsafeFromArray, fromIterable);
|
|
11801
|
+
const exponential$2 = (options) => pipe(makeBy(options.count - 1, (i) => options.start * Math.pow(options.factor, i)), unsafeFromArray, fromIterable);
|
|
11790
11802
|
/** @internal */
|
|
11791
11803
|
const MetricKeyTypeTypeId = /*#__PURE__*/ Symbol.for("effect/MetricKeyType");
|
|
11792
11804
|
/** @internal */
|
|
@@ -12860,7 +12872,7 @@ const fiberSuccesses = /*#__PURE__*/ counter("effect_fiber_successes", { increme
|
|
|
12860
12872
|
/** @internal */
|
|
12861
12873
|
const fiberFailures = /*#__PURE__*/ counter("effect_fiber_failures", { incremental: true });
|
|
12862
12874
|
/** @internal */
|
|
12863
|
-
const fiberLifetimes = /*#__PURE__*/ tagged$1(/*#__PURE__*/ histogram("effect_fiber_lifetimes", /*#__PURE__*/ exponential({
|
|
12875
|
+
const fiberLifetimes = /*#__PURE__*/ tagged$1(/*#__PURE__*/ histogram("effect_fiber_lifetimes", /*#__PURE__*/ exponential$2({
|
|
12864
12876
|
start: .5,
|
|
12865
12877
|
factor: 2,
|
|
12866
12878
|
count: 35
|
|
@@ -14303,7 +14315,7 @@ const isEmpty$3 = (self) => {
|
|
|
14303
14315
|
return self.startMillis >= self.endMillis;
|
|
14304
14316
|
};
|
|
14305
14317
|
/** @internal */
|
|
14306
|
-
const intersect$
|
|
14318
|
+
const intersect$5 = /*#__PURE__*/ dual(2, (self, that) => {
|
|
14307
14319
|
const start = Math.max(self.startMillis, that.startMillis);
|
|
14308
14320
|
const end = Math.min(self.endMillis, that.endMillis);
|
|
14309
14321
|
return make$22(start, end);
|
|
@@ -14356,7 +14368,7 @@ const isEmpty$2 = isEmpty$3;
|
|
|
14356
14368
|
* @since 2.0.0
|
|
14357
14369
|
* @category ordering
|
|
14358
14370
|
*/
|
|
14359
|
-
const intersect$
|
|
14371
|
+
const intersect$4 = intersect$5;
|
|
14360
14372
|
/**
|
|
14361
14373
|
* Calculates the size of the `Interval` as the `Duration` from the start of the
|
|
14362
14374
|
* interval to the end of the interval.
|
|
@@ -14383,14 +14395,14 @@ const make$20 = (intervals) => {
|
|
|
14383
14395
|
};
|
|
14384
14396
|
};
|
|
14385
14397
|
/** @internal */
|
|
14386
|
-
const intersect$
|
|
14398
|
+
const intersect$3 = /*#__PURE__*/ dual(2, (self, that) => intersectLoop(self.intervals, that.intervals, empty$24()));
|
|
14387
14399
|
/** @internal */
|
|
14388
14400
|
const intersectLoop = (_left, _right, _acc) => {
|
|
14389
14401
|
let left = _left;
|
|
14390
14402
|
let right = _right;
|
|
14391
14403
|
let acc = _acc;
|
|
14392
14404
|
while (isNonEmpty$4(left) && isNonEmpty$4(right)) {
|
|
14393
|
-
const interval = pipe(headNonEmpty(left), intersect$
|
|
14405
|
+
const interval = pipe(headNonEmpty(left), intersect$4(headNonEmpty(right)));
|
|
14394
14406
|
const intervals = isEmpty$2(interval) ? acc : pipe(acc, prepend$1(interval));
|
|
14395
14407
|
if (pipe(headNonEmpty(left), lessThan$3(headNonEmpty(right)))) left = tailNonEmpty(left);
|
|
14396
14408
|
else right = tailNonEmpty(right);
|
|
@@ -14427,7 +14439,7 @@ const make$19 = make$20;
|
|
|
14427
14439
|
* @since 2.0.0
|
|
14428
14440
|
* @category utils
|
|
14429
14441
|
*/
|
|
14430
|
-
const intersect$
|
|
14442
|
+
const intersect$2 = intersect$3;
|
|
14431
14443
|
/**
|
|
14432
14444
|
* The start of the earliest interval in the specified `Intervals`.
|
|
14433
14445
|
*
|
|
@@ -15740,6 +15752,15 @@ const uncapitalize = (self) => {
|
|
|
15740
15752
|
* @since 2.0.0
|
|
15741
15753
|
*/
|
|
15742
15754
|
const isNonEmpty$1 = (self) => self.length > 0;
|
|
15755
|
+
//#endregion
|
|
15756
|
+
//#region node_modules/effect/dist/esm/Random.js
|
|
15757
|
+
/**
|
|
15758
|
+
* Returns the next numeric value from the pseudo-random number generator.
|
|
15759
|
+
*
|
|
15760
|
+
* @since 2.0.0
|
|
15761
|
+
* @category constructors
|
|
15762
|
+
*/
|
|
15763
|
+
const next = next$1;
|
|
15743
15764
|
/** @internal */
|
|
15744
15765
|
const ScheduleTypeId = /*#__PURE__*/ Symbol.for("effect/Schedule");
|
|
15745
15766
|
/** @internal */
|
|
@@ -15866,9 +15887,18 @@ const checkEffect = /*#__PURE__*/ dual(2, (self, test) => makeWithState(self.ini
|
|
|
15866
15887
|
]);
|
|
15867
15888
|
})));
|
|
15868
15889
|
/** @internal */
|
|
15890
|
+
const delayedEffect = /*#__PURE__*/ dual(2, (self, f) => modifyDelayEffect(self, (_, delay) => f(delay)));
|
|
15891
|
+
/** @internal */
|
|
15892
|
+
const delayedSchedule = (schedule) => addDelay(schedule, (x) => x);
|
|
15893
|
+
/** @internal */
|
|
15869
15894
|
const driver = (self) => pipe(make$29([none$4(), self.initial]), map$8((ref) => new ScheduleDriverImpl(self, ref)));
|
|
15870
15895
|
/** @internal */
|
|
15871
|
-
const
|
|
15896
|
+
const exponential$1 = (baseInput, factor = 2) => {
|
|
15897
|
+
const base = decode(baseInput);
|
|
15898
|
+
return delayedSchedule(map$5(forever, (i) => times(base, Math.pow(factor, i))));
|
|
15899
|
+
};
|
|
15900
|
+
/** @internal */
|
|
15901
|
+
const intersect$1 = /*#__PURE__*/ dual(2, (self, that) => intersectWith(self, that, intersect$2));
|
|
15872
15902
|
/** @internal */
|
|
15873
15903
|
const intersectWith = /*#__PURE__*/ dual(3, (self, that, f) => makeWithState([self.initial, that.initial], (now, input, state) => pipe(zipWith$2(self.step(now, input, state[0]), that.step(now, input, state[1]), (a, b) => [a, b]), flatMap$6(([[lState, out, lDecision], [rState, out2, rDecision]]) => {
|
|
15874
15904
|
if (isContinue(lDecision) && isContinue(rDecision)) return intersectWithLoop(self, that, input, lState, out, lDecision.intervals, rState, out2, rDecision.intervals, f);
|
|
@@ -15904,6 +15934,23 @@ const intersectWithLoop = (self, that, input, lState, out, lInterval, rState, ou
|
|
|
15904
15934
|
});
|
|
15905
15935
|
};
|
|
15906
15936
|
/** @internal */
|
|
15937
|
+
const jittered$1 = (self) => jitteredWith(self, {
|
|
15938
|
+
min: .8,
|
|
15939
|
+
max: 1.2
|
|
15940
|
+
});
|
|
15941
|
+
/** @internal */
|
|
15942
|
+
const jitteredWith = /*#__PURE__*/ dual(2, (self, options) => {
|
|
15943
|
+
const { max, min } = Object.assign({
|
|
15944
|
+
min: .8,
|
|
15945
|
+
max: 1.2
|
|
15946
|
+
}, options);
|
|
15947
|
+
return delayedEffect(self, (duration) => map$8(next, (random) => {
|
|
15948
|
+
const d = toMillis(duration);
|
|
15949
|
+
const jittered = d * min * (1 - random) + d * max * random;
|
|
15950
|
+
return millis(jittered);
|
|
15951
|
+
}));
|
|
15952
|
+
});
|
|
15953
|
+
/** @internal */
|
|
15907
15954
|
const map$5 = /*#__PURE__*/ dual(2, (self, f) => mapEffect(self, (out) => sync$2(() => f(out))));
|
|
15908
15955
|
/** @internal */
|
|
15909
15956
|
const mapEffect = /*#__PURE__*/ dual(2, (self, f) => makeWithState(self.initial, (now, input, state) => flatMap$6(self.step(now, input, state), ([state, out, decision]) => map$8(f(out), (out2) => [
|
|
@@ -15941,7 +15988,7 @@ const passthrough = (self) => makeWithState(self.initial, (now, input, state) =>
|
|
|
15941
15988
|
decision
|
|
15942
15989
|
])));
|
|
15943
15990
|
/** @internal */
|
|
15944
|
-
const recurs = (n) => whileOutput(forever, (out) => out < n);
|
|
15991
|
+
const recurs$1 = (n) => whileOutput(forever, (out) => out < n);
|
|
15945
15992
|
/** @internal */
|
|
15946
15993
|
const spaced$1 = (duration) => addDelay(forever, () => duration);
|
|
15947
15994
|
/** @internal */
|
|
@@ -15990,7 +16037,7 @@ const repeat_combined = /*#__PURE__*/ dual(2, (self, options) => {
|
|
|
15990
16037
|
if (typeof applied === "boolean") return succeed$8(applied);
|
|
15991
16038
|
return scheduleDefectWrap(applied);
|
|
15992
16039
|
}) : withWhile;
|
|
15993
|
-
const withTimes = options.times ? intersect(withUntil, recurs(options.times)).pipe(map$5((intersectionPair) => intersectionPair[0])) : withUntil;
|
|
16040
|
+
const withTimes = options.times ? intersect$1(withUntil, recurs$1(options.times)).pipe(map$5((intersectionPair) => intersectionPair[0])) : withUntil;
|
|
15994
16041
|
return scheduleDefectRefail(repeat_Effect(self, withTimes));
|
|
15995
16042
|
});
|
|
15996
16043
|
/** @internal */
|
|
@@ -16026,7 +16073,7 @@ const fromRetryOptions = (options) => {
|
|
|
16026
16073
|
if (typeof applied === "boolean") return succeed$8(applied);
|
|
16027
16074
|
return scheduleDefectWrap(applied);
|
|
16028
16075
|
}) : withWhile;
|
|
16029
|
-
return options.times !== void 0 ? intersect(withUntil, recurs(options.times)) : withUntil;
|
|
16076
|
+
return options.times !== void 0 ? intersect$1(withUntil, recurs$1(options.times)) : withUntil;
|
|
16030
16077
|
};
|
|
16031
16078
|
/** @internal */
|
|
16032
16079
|
const retryOrElse_Effect = /*#__PURE__*/ dual(3, (self, policy, orElse) => flatMap$6(driver(policy), (driver) => retryOrElse_EffectLoop(provideServiceEffect(self, CurrentIterationMetadata, get$4(driver.iterationMeta)), driver, (e, out) => provideServiceEffect(orElse(e, out), CurrentIterationMetadata, get$4(driver.iterationMeta)))));
|
|
@@ -20184,6 +20231,79 @@ const provideMerge = provideMerge$1;
|
|
|
20184
20231
|
//#endregion
|
|
20185
20232
|
//#region node_modules/effect/dist/esm/Schedule.js
|
|
20186
20233
|
/**
|
|
20234
|
+
* Creates a schedule that recurs indefinitely with exponentially increasing
|
|
20235
|
+
* delays.
|
|
20236
|
+
*
|
|
20237
|
+
* **Details**
|
|
20238
|
+
*
|
|
20239
|
+
* This schedule starts with an initial delay of `base` and increases the delay
|
|
20240
|
+
* exponentially on each repetition using the formula `base * factor^n`, where
|
|
20241
|
+
* `n` is the number of times the schedule has executed so far. If no `factor`
|
|
20242
|
+
* is provided, it defaults to `2`, causing the delay to double after each
|
|
20243
|
+
* execution.
|
|
20244
|
+
*
|
|
20245
|
+
* @since 2.0.0
|
|
20246
|
+
* @category Constructors
|
|
20247
|
+
*/
|
|
20248
|
+
const exponential = exponential$1;
|
|
20249
|
+
/**
|
|
20250
|
+
* Combines two schedules, continuing only if both schedules want to continue,
|
|
20251
|
+
* using the longer delay.
|
|
20252
|
+
*
|
|
20253
|
+
* **Details**
|
|
20254
|
+
*
|
|
20255
|
+
* This function takes two schedules and creates a new schedule that only
|
|
20256
|
+
* continues execution if both schedules allow it. The interval between
|
|
20257
|
+
* recurrences is determined by the longer delay between the two schedules.
|
|
20258
|
+
*
|
|
20259
|
+
* The output of the resulting schedule is a tuple containing the outputs of
|
|
20260
|
+
* both schedules. The input type is the intersection of both schedules' input
|
|
20261
|
+
* types.
|
|
20262
|
+
*
|
|
20263
|
+
* This is useful when coordinating multiple scheduling conditions where
|
|
20264
|
+
* execution should proceed only when both schedules permit it.
|
|
20265
|
+
*
|
|
20266
|
+
* @see {@link intersectWith} If you need to use a custom merge function.
|
|
20267
|
+
*
|
|
20268
|
+
* @since 2.0.0
|
|
20269
|
+
* @category Composition
|
|
20270
|
+
*/
|
|
20271
|
+
const intersect = intersect$1;
|
|
20272
|
+
/**
|
|
20273
|
+
* Returns a new schedule that randomly adjusts the interval size within a
|
|
20274
|
+
* range.
|
|
20275
|
+
*
|
|
20276
|
+
* **Details**
|
|
20277
|
+
*
|
|
20278
|
+
* This function modifies a schedule so that its delay between executions is
|
|
20279
|
+
* randomly varied within a range. By default, the delay is adjusted between
|
|
20280
|
+
* `80%` (`0.8 * interval`) and `120%` (`1.2 * interval`) of the original
|
|
20281
|
+
* interval size.
|
|
20282
|
+
*
|
|
20283
|
+
* This is useful for adding randomness to repeated executions, reducing
|
|
20284
|
+
* contention in distributed systems, and avoiding synchronized execution
|
|
20285
|
+
* patterns that can cause bottlenecks.
|
|
20286
|
+
*
|
|
20287
|
+
* @see {@link jitteredWith} If you need to specify custom min/max values.
|
|
20288
|
+
*
|
|
20289
|
+
* @since 2.0.0
|
|
20290
|
+
* @category Timing & Delay
|
|
20291
|
+
*/
|
|
20292
|
+
const jittered = jittered$1;
|
|
20293
|
+
/**
|
|
20294
|
+
* A schedule that recurs a fixed number of times before terminating.
|
|
20295
|
+
*
|
|
20296
|
+
* **Details**
|
|
20297
|
+
*
|
|
20298
|
+
* This schedule will continue executing until it has been stepped `n` times,
|
|
20299
|
+
* after which it will stop. The output of the schedule is the current count of
|
|
20300
|
+
* recurrences.
|
|
20301
|
+
*
|
|
20302
|
+
* @category Constructors
|
|
20303
|
+
* @since 2.0.0
|
|
20304
|
+
*/
|
|
20305
|
+
const recurs = recurs$1;
|
|
20306
|
+
/**
|
|
20187
20307
|
* Returns a schedule that recurs continuously, with each repetition
|
|
20188
20308
|
* spaced by the specified `duration` from the last run.
|
|
20189
20309
|
*
|
|
@@ -191264,15 +191384,40 @@ const parseNameStatus = (out) => {
|
|
|
191264
191384
|
return result;
|
|
191265
191385
|
};
|
|
191266
191386
|
/**
|
|
191387
|
+
* True when `error` is git's `index.lock` contention failure — another process
|
|
191388
|
+
* held the index lock when git tried to take it. gtd shares one worktree index
|
|
191389
|
+
* with every git-aware tool the reviewer runs (editor SCM, `gtd lsp`,
|
|
191390
|
+
* git-aware shell prompts): each refreshes its stat cache by WRITING the index
|
|
191391
|
+
* whenever a `git reset --mixed` in the review window wakes it, so gtd's own
|
|
191392
|
+
* index writes lose the `index.lock` race often on a large repo (where each
|
|
191393
|
+
* write takes long enough for the windows to overlap). The lock failure is a
|
|
191394
|
+
* pure "couldn't start" — git did nothing — so the losing command is safe to
|
|
191395
|
+
* retry verbatim (see `withIndexLockRetry`).
|
|
191396
|
+
*/
|
|
191397
|
+
const isIndexLockError = (error) => /index\.lock[\s\S]*File exists|Another git process seems to be running/i.test(error.message);
|
|
191398
|
+
/**
|
|
191399
|
+
* Retry an index-writing git command through transient `index.lock` contention
|
|
191400
|
+
* with jittered exponential backoff (~10ms → ~640ms, capped at 6 retries), and
|
|
191401
|
+
* ONLY on that error — any other failure propagates on the first attempt. This
|
|
191402
|
+
* is the general defense for the concurrent reality `isIndexLockError`
|
|
191403
|
+
* describes; it covers every index writer (`git add -A`, `reset`, `restore`),
|
|
191404
|
+
* not just the review window's own steps.
|
|
191405
|
+
*/
|
|
191406
|
+
const withIndexLockRetry = (eff) => retry(eff, {
|
|
191407
|
+
schedule: intersect(recurs(6), exponential(millis(10), 2)).pipe(jittered),
|
|
191408
|
+
while: (error) => isIndexLockError(error)
|
|
191409
|
+
});
|
|
191410
|
+
/**
|
|
191267
191411
|
* Run a command and return its stdout — FAILING on a non-zero exit code with
|
|
191268
191412
|
* the command line and stderr in the error message. `Command.string` alone
|
|
191269
191413
|
* only collects stdout and silently ignores exit codes, which used to make
|
|
191270
191414
|
* gtd report success on rejected commits (hooks, gpg), resolve Idle outside a
|
|
191271
191415
|
* repository, and lose files whose quoted paths broke a swallowed `git add`.
|
|
191272
191416
|
* Callers that expect a probe to fail (missing refs, empty repos) handle it
|
|
191273
|
-
* with an explicit `catchAll`.
|
|
191417
|
+
* with an explicit `catchAll`. `index.lock` contention is retried transparently
|
|
191418
|
+
* (`withIndexLockRetry`) before any caller's `catchAll` sees it.
|
|
191274
191419
|
*/
|
|
191275
|
-
const run = (root, ...args) => scoped$3(gen(function* () {
|
|
191420
|
+
const run = (root, ...args) => withIndexLockRetry(scoped$3(gen(function* () {
|
|
191276
191421
|
const process = yield* (yield* CommandExecutor).start(make$1(...args).pipe(workingDirectory(root), stdout("pipe"), stderr("pipe")));
|
|
191277
191422
|
const collect = (stream) => stream.pipe(decodeText(), mkString);
|
|
191278
191423
|
const [stdout$2, stderr$2, exitCode] = yield* all([
|
|
@@ -191282,7 +191427,7 @@ const run = (root, ...args) => scoped$3(gen(function* () {
|
|
|
191282
191427
|
], { concurrency: "unbounded" });
|
|
191283
191428
|
if (exitCode !== 0) return yield* fail$2(/* @__PURE__ */ new Error(`${args.join(" ")} failed (exit ${exitCode}): ${stderr$2.trim()}`));
|
|
191284
191429
|
return stdout$2;
|
|
191285
|
-
})).pipe(mapError$1((e) => e instanceof Error ? e : new Error(String(e))));
|
|
191430
|
+
})).pipe(mapError$1((e) => e instanceof Error ? e : new Error(String(e)))));
|
|
191286
191431
|
const makeGitImpl = (executor, root) => {
|
|
191287
191432
|
const exec = (...args) => run(root, ...args).pipe(provide$1(succeed$2(CommandExecutor, executor)));
|
|
191288
191433
|
return {
|
|
@@ -191348,8 +191493,7 @@ const makeGitImpl = (executor, root) => {
|
|
|
191348
191493
|
deleteRef: (ref) => exec("git", "update-ref", "-d", ref).pipe(asVoid),
|
|
191349
191494
|
mixedResetTo: (ref) => exec("git", "reset", "--mixed", ref).pipe(asVoid),
|
|
191350
191495
|
hardResetTo: (ref) => exec("git", "reset", "--hard", ref).pipe(asVoid),
|
|
191351
|
-
restoreStagedFrom: (source, paths) => paths.length === 0 ? _void : exec("git", "restore", "--staged", `--source=${source}`, "--", ...paths).pipe(catchAll(() => _void))
|
|
191352
|
-
addIntentToAdd: () => exec("git", "add", "--intent-to-add", ".").pipe(asVoid)
|
|
191496
|
+
restoreStagedFrom: (source, paths) => paths.length === 0 ? _void : exec("git", "restore", "--staged", `--source=${source}`, "--", ...paths).pipe(catchAll(() => _void))
|
|
191353
191497
|
};
|
|
191354
191498
|
};
|
|
191355
191499
|
const makeLiveEffect = gen(function* () {
|
|
@@ -192525,8 +192669,8 @@ const closeReviewWindow = gen(function* () {
|
|
|
192525
192669
|
* is nothing to surface and the window stays closed.
|
|
192526
192670
|
*
|
|
192527
192671
|
* Ordering is crash-safe: base ref → head ref → mixed reset → `.gtd/` index
|
|
192528
|
-
* pin
|
|
192529
|
-
*
|
|
192672
|
+
* pin. A crash before the head-ref write leaves only a stale base ref
|
|
192673
|
+
* (overwritten on the next open); a crash after it leaves HEAD ==
|
|
192530
192674
|
* review-head, which the next invocation's close restores as a no-op.
|
|
192531
192675
|
*/
|
|
192532
192676
|
const openReviewWindow = gen(function* () {
|
|
@@ -192542,7 +192686,6 @@ const openReviewWindow = gen(function* () {
|
|
|
192542
192686
|
yield* git.updateRef(REVIEW_HEAD_REF, headHash);
|
|
192543
192687
|
yield* git.mixedResetTo(base);
|
|
192544
192688
|
yield* git.restoreStagedFrom(REVIEW_HEAD_REF, [".gtd"]);
|
|
192545
|
-
yield* git.addIntentToAdd();
|
|
192546
192689
|
return { opened: true };
|
|
192547
192690
|
});
|
|
192548
192691
|
//#endregion
|