@webpieces/repo-workflow-core 0.0.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/package.json +31 -0
- package/src/agent-worktree-lock.d.ts +21 -0
- package/src/agent-worktree-lock.js +77 -0
- package/src/agent-worktree-lock.js.map +1 -0
- package/src/branch-archiver.d.ts +70 -0
- package/src/branch-archiver.js +157 -0
- package/src/branch-archiver.js.map +1 -0
- package/src/branch-identity.d.ts +6 -0
- package/src/branch-identity.js +59 -0
- package/src/branch-identity.js.map +1 -0
- package/src/branch-mutation-log.d.ts +77 -0
- package/src/branch-mutation-log.js +221 -0
- package/src/branch-mutation-log.js.map +1 -0
- package/src/branch-reaper.d.ts +122 -0
- package/src/branch-reaper.js +261 -0
- package/src/branch-reaper.js.map +1 -0
- package/src/harness-agent-activity.d.ts +154 -0
- package/src/harness-agent-activity.js +346 -0
- package/src/harness-agent-activity.js.map +1 -0
- package/src/index.d.ts +14 -0
- package/src/index.js +18 -0
- package/src/index.js.map +1 -0
- package/src/main-sync-file.d.ts +121 -0
- package/src/main-sync-file.js +281 -0
- package/src/main-sync-file.js.map +1 -0
- package/src/main-sync-status.d.ts +197 -0
- package/src/main-sync-status.js +555 -0
- package/src/main-sync-status.js.map +1 -0
- package/src/merged-branch-verdicts.d.ts +189 -0
- package/src/merged-branch-verdicts.js +251 -0
- package/src/merged-branch-verdicts.js.map +1 -0
- package/src/merged-branches.d.ts +140 -0
- package/src/merged-branches.js +521 -0
- package/src/merged-branches.js.map +1 -0
- package/src/review-identity-stamp.d.ts +82 -0
- package/src/review-identity-stamp.js +172 -0
- package/src/review-identity-stamp.js.map +1 -0
- package/src/worktree-lock-verdicts.d.ts +149 -0
- package/src/worktree-lock-verdicts.js +225 -0
- package/src/worktree-lock-verdicts.js.map +1 -0
- package/src/worktree-reaper.d.ts +116 -0
- package/src/worktree-reaper.js +318 -0
- package/src/worktree-reaper.js.map +1 -0
- package/src/worktrees.d.ts +113 -0
- package/src/worktrees.js +260 -0
- package/src/worktrees.js.map +1 -0
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import { AtomicFile } from '@webpieces/tooling-common';
|
|
2
|
+
import { DotWebpieces } from '@webpieces/tooling-common';
|
|
3
|
+
import { WorktreeService } from './worktrees';
|
|
4
|
+
import { WorktreeLockVerdicts } from './worktree-lock-verdicts';
|
|
5
|
+
import { CacheFreshness, MergedBranchesCache } from './merged-branch-verdicts';
|
|
6
|
+
export { MergedBranch, DeletableBranch, DeletableWorktree, MergedBranchesCache, CacheFreshness, CACHE_STALE_AFTER_MS, CLASSIFICATION_MERGED_PR, CLASSIFICATION_BACKUP_OF_MERGED, CLASSIFICATION_BACKUP_OF_LIVE, CLASSIFICATION_NO_COMMITS, CLASSIFICATION_SUPERSEDED, CLASSIFICATION_CONTENT_IN_MAIN, CLASSIFICATION_NEVER_PROPOSED, CLASSIFICATION_IN_USE, CLASSIFICATION_PRUNABLE, CLASSIFICATION_LOCKED, CLASSIFICATION_CURRENT, CLASSIFICATION_DETACHED, ADJUDICATED_CLASSIFICATIONS, } from './merged-branch-verdicts';
|
|
7
|
+
export declare class MergedBranchesService {
|
|
8
|
+
private readonly worktrees;
|
|
9
|
+
private readonly dotDir;
|
|
10
|
+
private readonly atomicFile;
|
|
11
|
+
private readonly locks;
|
|
12
|
+
constructor(worktrees?: WorktreeService, dotDir?: DotWebpieces, atomicFile?: AtomicFile, locks?: WorktreeLockVerdicts);
|
|
13
|
+
/**
|
|
14
|
+
* SHARED scope — one per repo, in the primary clone, NOT one per worktree. This file's contents
|
|
15
|
+
* describe every branch AND every worktree in the repo, so a per-worktree copy was a repo-wide fact
|
|
16
|
+
* stored N times and therefore N times wrong: branch-creation-guard reported "8 parked local
|
|
17
|
+
* branches" against an actual 1, reading a copy that predated deletions made from another worktree.
|
|
18
|
+
*/
|
|
19
|
+
mergedBranchesPath(repoRoot: string): string;
|
|
20
|
+
readMergedBranches(repoRoot: string): MergedBranchesCache | null;
|
|
21
|
+
/**
|
|
22
|
+
* How old is this cache, and may its numbers be quoted as fact?
|
|
23
|
+
*
|
|
24
|
+
* `now` is a parameter purely so the specs can pin it; every caller passes nothing.
|
|
25
|
+
*/
|
|
26
|
+
freshness(cache: MergedBranchesCache, now?: number): CacheFreshness;
|
|
27
|
+
/**
|
|
28
|
+
* Drop every cached verdict whose subject no longer exists, using only LOCAL, instant git reads.
|
|
29
|
+
*
|
|
30
|
+
* The verdicts themselves are NOT re-derived here — that is the detached refresher's job and it
|
|
31
|
+
* needs the network. This answers a different and much cheaper question: does this branch / this
|
|
32
|
+
* worktree still exist at all? A cache written before a `git branch -D` or a `git worktree remove`
|
|
33
|
+
* keeps naming things that are gone, and a reader that counts those entries reports a repo that
|
|
34
|
+
* does not exist (observed: 8 parked branches asserted against an actual 1) and then blocks on it.
|
|
35
|
+
*
|
|
36
|
+
* Fails toward the cache: if git cannot answer (empty branch list), the cache is returned untouched
|
|
37
|
+
* rather than emptied, since "git failed" must never read as "everything was deleted".
|
|
38
|
+
*/
|
|
39
|
+
reconcile(repoRoot: string, cache: MergedBranchesCache): MergedBranchesCache;
|
|
40
|
+
/**
|
|
41
|
+
* ATOMIC write. Now that this file is shared by every worktree it has N concurrent writers (one
|
|
42
|
+
* detached refresher per agent), and its readers are the guards' BLOCKING path. A plain
|
|
43
|
+
* `writeFileSync` truncates before it writes, so a reader landing in that window gets a torn
|
|
44
|
+
* document — the reader-side retry added in PR #526 cannot rescue a syntactically valid PREFIX.
|
|
45
|
+
* Fixed where it belongs: temp file + `rename()`, which POSIX makes atomic. See AtomicFile.
|
|
46
|
+
*
|
|
47
|
+
* This buys ATOMIC READS, not lost-update protection: two read-modify-write cycles still end
|
|
48
|
+
* last-writer-wins. That is acceptable and deliberate — this is a DERIVED cache, recomputed from
|
|
49
|
+
* `gh` + git by the refresher, and wp-cleanup recomputes rather than trusting it before deleting
|
|
50
|
+
* anything. Nothing here is transactional and no caller may assume it is.
|
|
51
|
+
*/
|
|
52
|
+
writeMergedBranches(repoRoot: string, cache: MergedBranchesCache): void;
|
|
53
|
+
/**
|
|
54
|
+
* Every local branch except `main`. Uses `git for-each-ref`, NOT `git branch` — the latter is a
|
|
55
|
+
* porcelain command whose output the branch-creation-guard's own regex mistakes for a branch
|
|
56
|
+
* CREATION, so the guard would block the cleanup it just demanded.
|
|
57
|
+
*/
|
|
58
|
+
localBranches(repoRoot: string): string[];
|
|
59
|
+
/**
|
|
60
|
+
* The SLOW path, run only inside the detached refresher. ONE bulk `gh` call, then a purely local
|
|
61
|
+
* classification. Never run on the hook's blocking path.
|
|
62
|
+
*/
|
|
63
|
+
computeMergedBranches(repoRoot: string, ignoreStaleAgentLocks: boolean): MergedBranchesCache;
|
|
64
|
+
/**
|
|
65
|
+
* Verdicts for the worktree budget. The main worktree is excluded outright — it is the primary
|
|
66
|
+
* clone and is not a thing you can remove.
|
|
67
|
+
*
|
|
68
|
+
* A worktree is deletable when its directory is already gone (`prunable`), or when its branch is
|
|
69
|
+
* dead by the very same proof the branch cap uses — a MERGED PR, its own or that of the branch it
|
|
70
|
+
* snapshots. Nothing else. It is spared when its LOCK still stands (see WorktreeLockVerdicts for
|
|
71
|
+
* what makes one stand), when it is the worktree we are standing in right now (removing your own
|
|
72
|
+
* cwd is not a thing to suggest to an agent), or when its branch is anything short of provably
|
|
73
|
+
* merged — INCLUDING a branch with no commits yet, which is what every worktree looks like while
|
|
74
|
+
* an agent is working in it. `deletable` means PROVABLY dead and nothing weaker; wp-cleanup reaps
|
|
75
|
+
* the zero-commit ones on top of that, but only after checking on disk whether anybody is holding
|
|
76
|
+
* them (see CLASSIFICATION_NO_COMMITS), which is a question these verdicts do not answer.
|
|
77
|
+
*
|
|
78
|
+
* THE BRANCH VERDICT IS COMPUTED BEFORE THE LOCK IS RULED ON, which is new and is the point: one
|
|
79
|
+
* of the four things that can override an agent lock is the branch already being provably dead,
|
|
80
|
+
* and that cannot be weighed until it is known. Two extra local git calls per locked worktree, on
|
|
81
|
+
* a path that only ever runs in the detached refresher and in wp-cleanup itself.
|
|
82
|
+
*/
|
|
83
|
+
private classifyWorktrees;
|
|
84
|
+
private lockDecision;
|
|
85
|
+
/**
|
|
86
|
+
* Verdict for one branch: its own merged PR, else the base it was backed up from, else empty.
|
|
87
|
+
*
|
|
88
|
+
* The verdict itself is unchanged. What is new is that EVERY entry now carries its tip SHA, its
|
|
89
|
+
* unique-commit count and its PR state, so a `keep` can be shown to a human as a delete candidate
|
|
90
|
+
* rather than just counted. This runs only in the detached refresher, so the two extra local git
|
|
91
|
+
* calls per branch cost the blocking hook path nothing.
|
|
92
|
+
*/
|
|
93
|
+
private classify;
|
|
94
|
+
/**
|
|
95
|
+
* The three genuinely different reasons a branch survives the deletable proofs, ordered by how
|
|
96
|
+
* confidently a human can say yes to deleting it.
|
|
97
|
+
*
|
|
98
|
+
* The safety posture is UNCHANGED: all three are still SPARED, never auto-deleted. The only thing
|
|
99
|
+
* that changed is that wp-cleanup can now ask a question whose answer is knowable.
|
|
100
|
+
*/
|
|
101
|
+
private classifySpared;
|
|
102
|
+
/**
|
|
103
|
+
* True when EVERY commit on the branch has a patch-equivalent already in origin/main.
|
|
104
|
+
*
|
|
105
|
+
* `git cherry origin/main <branch>` prints one line per commit: `+ <sha>` = not upstream,
|
|
106
|
+
* `- <sha>` = an equivalent change IS upstream. All-minus means the content landed (typically by
|
|
107
|
+
* cherry-pick or rebase-merge) even though the SHAs differ. Any failure returns false — "cannot
|
|
108
|
+
* prove the content is in main" must never read as "safe".
|
|
109
|
+
*/
|
|
110
|
+
private contentAlreadyInMain;
|
|
111
|
+
/**
|
|
112
|
+
* Does this local branch exist? Used to prove a snapshot is not the last copy of its work — the
|
|
113
|
+
* base branch being present is that proof. Verifies it is a BRANCH (`refs/heads/`), not just any
|
|
114
|
+
* resolvable rev, so a tag or a stray SHA sharing the name cannot stand in for the base.
|
|
115
|
+
*/
|
|
116
|
+
private branchExists;
|
|
117
|
+
private tipSha;
|
|
118
|
+
/**
|
|
119
|
+
* Commits on `branch` that are not on origin/main. Returns -1 ("assume it has work") whenever the
|
|
120
|
+
* count cannot be established — an unresolvable origin/main must never read as "empty branch".
|
|
121
|
+
*/
|
|
122
|
+
private commitsAheadOfMain;
|
|
123
|
+
/**
|
|
124
|
+
* The ONE bulk network call. Every merged PR's head branch in a single round trip — no per-branch
|
|
125
|
+
* lookups. Fails SOFT: if `gh` is missing, unauthenticated, or offline we return [], which makes
|
|
126
|
+
* every branch a `keep`. The guard then deletes nothing rather than guessing.
|
|
127
|
+
*/
|
|
128
|
+
private fetchMergedPrs;
|
|
129
|
+
/**
|
|
130
|
+
* The DISPLAY-only second lookup: every PR (any state) keyed by head branch, so a spared branch can
|
|
131
|
+
* be shown to a human as "PR #12 CLOSED (not merged)" or "no PR" instead of an opaque name. Kept
|
|
132
|
+
* SEPARATE from fetchMergedPrs on purpose — folding both into one `--state all` call would let a
|
|
133
|
+
* flood of open/closed PRs push older MERGED ones out of the limit and silently stop reaping real
|
|
134
|
+
* dead branches. Fails soft to an empty map: the verdicts do not depend on it.
|
|
135
|
+
*/
|
|
136
|
+
private fetchPrStates;
|
|
137
|
+
private reviveList;
|
|
138
|
+
private reviveWorktrees;
|
|
139
|
+
private capture;
|
|
140
|
+
}
|