@bridge4dev/runner 0.11.0 → 0.22.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/dist/adapters/claude.d.ts +15 -7
- package/dist/adapters/claude.js +1024 -70
- package/dist/adapters/codex.d.ts +18 -3
- package/dist/adapters/codex.js +224 -65
- package/dist/adapters/questions.d.ts +42 -0
- package/dist/adapters/questions.js +86 -0
- package/dist/adapters/types.d.ts +200 -4
- package/dist/attachments.d.ts +8 -1
- package/dist/attachments.js +22 -4
- package/dist/auto-resume.d.ts +18 -0
- package/dist/auto-resume.js +104 -0
- package/dist/commit-message.d.ts +51 -0
- package/dist/commit-message.js +224 -0
- package/dist/config.d.ts +29 -6
- package/dist/config.js +15 -0
- package/dist/crash-note.d.ts +54 -0
- package/dist/crash-note.js +105 -0
- package/dist/git.d.ts +71 -0
- package/dist/git.js +207 -10
- package/dist/gitops.d.ts +489 -12
- package/dist/gitops.js +1717 -96
- package/dist/index.js +435 -32
- package/dist/paths.d.ts +26 -0
- package/dist/paths.js +34 -0
- package/dist/policy.d.ts +63 -0
- package/dist/policy.js +412 -10
- package/dist/protocol.d.ts +382 -60
- package/dist/protocol.js +104 -1
- package/dist/recipe-schema.d.ts +310 -0
- package/dist/recipe-schema.js +103 -0
- package/dist/recipe.d.ts +94 -0
- package/dist/recipe.js +238 -0
- package/dist/self-update.d.ts +7 -0
- package/dist/self-update.js +171 -23
- package/dist/service-unit.d.ts +79 -0
- package/dist/service-unit.js +211 -0
- package/dist/supervisor.d.ts +108 -1
- package/dist/supervisor.js +1010 -56
- package/dist/verify-queue.d.ts +17 -0
- package/dist/verify-queue.js +100 -0
- package/dist/verify.d.ts +203 -0
- package/dist/verify.js +788 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/package.json +2 -2
package/dist/gitops.d.ts
CHANGED
|
@@ -7,6 +7,30 @@ export interface GitFileEntry {
|
|
|
7
7
|
/** Present in the working tree but not committed yet. */
|
|
8
8
|
uncommitted: boolean;
|
|
9
9
|
}
|
|
10
|
+
/**
|
|
11
|
+
* One line of `git status --porcelain`, kept as the two columns git wrote.
|
|
12
|
+
*
|
|
13
|
+
* Both letters travel, not a flattened verdict, because the pair is the whole
|
|
14
|
+
* meaning: `MM` is a file that is staged AND edited again since, and it belongs
|
|
15
|
+
* in two groups of the panel at once. Any collapsing we did here would have to
|
|
16
|
+
* be undone in the browser.
|
|
17
|
+
*/
|
|
18
|
+
export interface GitWorkingEntry {
|
|
19
|
+
/** Repo-root-relative — exactly the string every write command takes back. */
|
|
20
|
+
path: string;
|
|
21
|
+
/** Index column (X). `?` for untracked, ' ' when nothing is staged. */
|
|
22
|
+
index: string;
|
|
23
|
+
/** Worktree column (Y). ' ' when the file is fully staged. */
|
|
24
|
+
worktree: string;
|
|
25
|
+
/** Where a rename came from, when git reported one. */
|
|
26
|
+
origPath?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function isConflictedEntry(entry: {
|
|
29
|
+
index: string;
|
|
30
|
+
worktree: string;
|
|
31
|
+
}): boolean;
|
|
32
|
+
export declare function isStagedEntry(entry: GitWorkingEntry): boolean;
|
|
33
|
+
export declare function isUnstagedEntry(entry: GitWorkingEntry): boolean;
|
|
10
34
|
export interface GitStatusResult {
|
|
11
35
|
branch: string;
|
|
12
36
|
baseBranch: string;
|
|
@@ -16,30 +40,312 @@ export interface GitStatusResult {
|
|
|
16
40
|
/** Commits the agent made on the session branch (base..HEAD). */
|
|
17
41
|
agentCommits: number;
|
|
18
42
|
uncommittedFiles: number;
|
|
43
|
+
/** Tip of the session branch — what an apply would swallow. */
|
|
44
|
+
branchSha: string | null;
|
|
45
|
+
/** Tip of the base branch right now. */
|
|
46
|
+
baseSha: string | null;
|
|
47
|
+
/** Where the two last agreed. */
|
|
48
|
+
forkSha: string | null;
|
|
49
|
+
/** Commits the branch has that the base does not. */
|
|
50
|
+
ahead: number | null;
|
|
51
|
+
/** Commits the base has that the branch does not — «main moved on». */
|
|
52
|
+
behind: number | null;
|
|
53
|
+
/**
|
|
54
|
+
* Commits made since the last «Apply» swallowed the branch, excluding
|
|
55
|
+
* anything the base contributed. This — not `ahead` — is the honest «N
|
|
56
|
+
* commits not in main»: a squash merge never makes the branch an ancestor,
|
|
57
|
+
* so `ahead` keeps counting work that already landed.
|
|
58
|
+
*
|
|
59
|
+
* `null` means «we cannot know»: no apply has been recorded with a branch
|
|
60
|
+
* tip. The caller must NOT substitute `ahead` — that is the number this
|
|
61
|
+
* field exists to replace.
|
|
62
|
+
*/
|
|
63
|
+
newCommits: number | null;
|
|
64
|
+
/** Commits made since the last successful «Push». */
|
|
65
|
+
aheadOfPushed: number | null;
|
|
66
|
+
/** The branch the PROJECT FOLDER is checked out on right now. */
|
|
67
|
+
worktreeBranch: string | null;
|
|
68
|
+
/** The folder moved off the branch this session forked from. */
|
|
69
|
+
drifted: boolean;
|
|
70
|
+
/** The branch this session forked from is gone from the repository. */
|
|
71
|
+
baseMissing: boolean;
|
|
72
|
+
/**
|
|
73
|
+
* Uncommitted changes in the PROJECT FOLDER — not in the session worktree.
|
|
74
|
+
*
|
|
75
|
+
* `applySession` has refused to merge into a dirty checkout since session 4,
|
|
76
|
+
* and until now nothing told the panel, so «Apply» was offered, pressed, and
|
|
77
|
+
* refused with an instruction to go and fix it by hand on a server the person
|
|
78
|
+
* pressing may not even have a shell on. Same predicate as the guard —
|
|
79
|
+
* `status --porcelain` in `workspacePath` — so the panel and the runner
|
|
80
|
+
* cannot disagree about it.
|
|
81
|
+
*
|
|
82
|
+
* `null` is «could not read it», and it is deliberately NOT `true`. Session
|
|
83
|
+
* 14 rounds an unknown tree to «dirty», and that is right there: it WITHHOLDS
|
|
84
|
+
* a claim. Here the same rounding would BLOCK the button — turning a failed
|
|
85
|
+
* `git status` into a dead end of our own making, which is the exact thing
|
|
86
|
+
* this field exists to remove. Unknown keeps the old behaviour: offer Apply,
|
|
87
|
+
* and let the guard on the other side have the last word.
|
|
88
|
+
*/
|
|
89
|
+
workspaceDirty: boolean | null;
|
|
90
|
+
/** The paths, so the panel can name what is in the way. Capped. */
|
|
91
|
+
workspaceDirtyFiles: string[];
|
|
92
|
+
workspaceDirtyCount: number;
|
|
93
|
+
/**
|
|
94
|
+
* A merge stopped in the PROJECT FOLDER and is waiting for a human.
|
|
95
|
+
*
|
|
96
|
+
* Kept apart from `mergeInProgress` above, which is about this session's own
|
|
97
|
+
* tree. The two are the same folder only for a DIRECT session, and the
|
|
98
|
+
* difference decides what a BRANCH session is told: a conflicted tree cannot
|
|
99
|
+
* be committed, so «commit it and press Apply again» would be advice nobody
|
|
100
|
+
* can follow (QA-110 m7).
|
|
101
|
+
*/
|
|
102
|
+
workspaceMergeInProgress: boolean;
|
|
103
|
+
/**
|
|
104
|
+
* Every path `git status` has something to say about, with both of its
|
|
105
|
+
* columns. This is what the Source Control panel groups into «Staged
|
|
106
|
+
* Changes», «Changes» and «Merge Changes» — the same three groups VS Code
|
|
107
|
+
* draws, from the same one command.
|
|
108
|
+
*
|
|
109
|
+
* `files` above answers a different question («what would an Apply bring
|
|
110
|
+
* to main») and cannot answer this one: it is a diff against the base, so it
|
|
111
|
+
* knows nothing about the index and calls a staged file and an unstaged file
|
|
112
|
+
* by the same name.
|
|
113
|
+
*/
|
|
114
|
+
working: GitWorkingEntry[];
|
|
115
|
+
/** True total — `working` is capped, this never is. */
|
|
116
|
+
workingCount: number;
|
|
117
|
+
workingTruncated: boolean;
|
|
118
|
+
stagedCount: number;
|
|
119
|
+
unstagedCount: number;
|
|
120
|
+
conflictedCount: number;
|
|
121
|
+
/** `MERGE_HEAD` exists: a merge stopped here and is waiting for a human. */
|
|
122
|
+
mergeInProgress: boolean;
|
|
123
|
+
/** The remote-tracking branch this branch follows, `origin/main`-style. */
|
|
124
|
+
upstream: string | null;
|
|
125
|
+
/** Commits this branch has that its upstream does not — what Push sends. */
|
|
126
|
+
aheadUpstream: number | null;
|
|
127
|
+
/** Commits the upstream has that this branch does not — what Pull brings. */
|
|
128
|
+
behindUpstream: number | null;
|
|
129
|
+
/** Remotes configured at all: no remote means no Push and no Pull. */
|
|
130
|
+
remotes: string[];
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* `git status --porcelain=v1 -z`, parsed.
|
|
134
|
+
*
|
|
135
|
+
* NUL-separated and not line-separated on purpose: a file name may legally
|
|
136
|
+
* contain a newline, and with `core.quotePath=false` — which we set globally so
|
|
137
|
+
* Cyrillic paths stay readable — git no longer escapes it. Splitting that output
|
|
138
|
+
* on `\n` invents two entries out of one file, and the second one is a path that
|
|
139
|
+
* exists nowhere. `-z` is the only format that cannot be misread.
|
|
140
|
+
*
|
|
141
|
+
* A rename or a copy carries its ORIGINAL path as its own NUL-terminated token
|
|
142
|
+
* right after the entry, so the loop consumes two tokens for those.
|
|
143
|
+
*/
|
|
144
|
+
export declare function parsePorcelainZ(raw: string): GitWorkingEntry[];
|
|
145
|
+
export interface ResolvedBase {
|
|
146
|
+
baseBranch: string;
|
|
147
|
+
baseRef: string;
|
|
148
|
+
/** The API pinned this base at session creation and it still exists. */
|
|
149
|
+
pinned: boolean;
|
|
150
|
+
/** The pinned base was asked for and is not in this repository any more. */
|
|
151
|
+
baseMissing: boolean;
|
|
19
152
|
}
|
|
20
|
-
export
|
|
153
|
+
export interface GitStatusInput {
|
|
154
|
+
worktreePath: string;
|
|
155
|
+
workspacePath: string;
|
|
156
|
+
sessionBranch: string;
|
|
157
|
+
/** The base pinned at session creation; absent for pre-session-13 rows. */
|
|
158
|
+
baseBranch?: string;
|
|
159
|
+
/** Branch tip the last «Apply» swallowed — makes `newCommits` truthful. */
|
|
160
|
+
appliedBranchSha?: string;
|
|
161
|
+
/** Branch tip the last «Push» sent — makes `aheadOfPushed` truthful. */
|
|
162
|
+
pushedSha?: string;
|
|
163
|
+
/**
|
|
164
|
+
* Session 16 — the session works in the project folder itself, on the branch
|
|
165
|
+
* the folder is already on.
|
|
166
|
+
*
|
|
167
|
+
* There is no base to be «ahead of» then: the branch IS the base, and every
|
|
168
|
+
* number derived from the pair — ahead, behind, newCommits, drift — would be
|
|
169
|
+
* a comparison of a thing with itself. So the whole block is skipped and
|
|
170
|
+
* reported as unknown, and `files` becomes what an uncommitted-work list
|
|
171
|
+
* should be: the diff against HEAD.
|
|
172
|
+
*/
|
|
173
|
+
direct?: boolean;
|
|
174
|
+
}
|
|
175
|
+
export declare function gitStatus(input: GitStatusInput): Promise<GitStatusResult>;
|
|
21
176
|
export interface GitDiffResult {
|
|
22
177
|
diff: string;
|
|
23
178
|
truncated: boolean;
|
|
24
179
|
}
|
|
25
180
|
/** Exposed for tests: the header check is the control worth pinning directly. */
|
|
26
181
|
export declare function capDiffForTest(diff: string): GitDiffResult;
|
|
27
|
-
|
|
182
|
+
/**
|
|
183
|
+
* Which comparison a diff request means (session 16).
|
|
184
|
+
*
|
|
185
|
+
* `base` is the historical one and stays the default: the whole change of this
|
|
186
|
+
* branch against the branch it forked from, which is what «Apply» would bring.
|
|
187
|
+
* The Source Control panel asks the two questions an editor asks instead —
|
|
188
|
+
* `staged` is HEAD↔index, `worktree` is index↔disk — because a file that is
|
|
189
|
+
* both staged and edited again has two different diffs and showing one of them
|
|
190
|
+
* twice is how a person loses an edit they thought they had saved.
|
|
191
|
+
*/
|
|
192
|
+
export type GitDiffMode = 'base' | 'staged' | 'worktree';
|
|
193
|
+
export declare function gitDiff(worktreePath: string, workspacePath: string, sessionBranch: string, filePath: string, baseBranch?: string, mode?: GitDiffMode): Promise<GitDiffResult>;
|
|
194
|
+
/**
|
|
195
|
+
* The whole diff of the branch against its base — masked, never header-checked.
|
|
196
|
+
*
|
|
197
|
+
* Deliberately separate from `gitDiff`: that one REFUSES a diff containing a
|
|
198
|
+
* protected file, which is right for a panel showing one file at a time and
|
|
199
|
+
* wrong here, where the answer would be «no commit message at all, because the
|
|
200
|
+
* branch happens to touch `.env.example`». The caller strips protected files
|
|
201
|
+
* instead of losing the diff, and says how many it dropped.
|
|
202
|
+
*/
|
|
203
|
+
export declare function gitBranchDiff(input: {
|
|
204
|
+
worktreePath: string;
|
|
205
|
+
workspacePath: string;
|
|
206
|
+
sessionBranch: string;
|
|
207
|
+
baseBranch?: string;
|
|
208
|
+
maxBytes?: number;
|
|
209
|
+
}): Promise<{
|
|
210
|
+
diff: string;
|
|
211
|
+
truncated: boolean;
|
|
212
|
+
}>;
|
|
28
213
|
export interface GitCommitResult {
|
|
29
214
|
committed: boolean;
|
|
30
215
|
sha?: string;
|
|
31
216
|
reason?: string;
|
|
32
217
|
}
|
|
33
|
-
export
|
|
218
|
+
export interface GitStageResult {
|
|
219
|
+
/** How many paths were handed to git — not how many changed. */
|
|
220
|
+
paths: number;
|
|
221
|
+
staged: number;
|
|
222
|
+
unstaged: number;
|
|
223
|
+
}
|
|
224
|
+
export interface GitDiscardResult {
|
|
225
|
+
/** Tracked files put back to what the index holds. */
|
|
226
|
+
restored: number;
|
|
227
|
+
/** Untracked files removed from disk. */
|
|
228
|
+
deleted: number;
|
|
229
|
+
/** Conflicted paths, which git refuses to restore — named, not swallowed. */
|
|
230
|
+
skipped: string[];
|
|
231
|
+
}
|
|
232
|
+
export interface GitPullResult {
|
|
233
|
+
pulled: boolean;
|
|
234
|
+
alreadyUpToDate?: boolean;
|
|
235
|
+
/** The branch moved without a merge commit — the ordinary, happy case. */
|
|
236
|
+
fastForward?: boolean;
|
|
237
|
+
commitSha?: string;
|
|
238
|
+
upstream?: string;
|
|
239
|
+
remote?: string;
|
|
240
|
+
conflict?: boolean;
|
|
241
|
+
conflictPaths?: string[];
|
|
242
|
+
behind?: number;
|
|
243
|
+
ahead?: number;
|
|
244
|
+
error?: string;
|
|
245
|
+
}
|
|
246
|
+
export interface GitMergeAbortResult {
|
|
247
|
+
aborted: boolean;
|
|
248
|
+
reason?: string;
|
|
249
|
+
}
|
|
34
250
|
export interface ApplyResult {
|
|
35
251
|
applied: boolean;
|
|
36
252
|
commitSha?: string;
|
|
37
253
|
conflict?: boolean;
|
|
38
254
|
/** On conflict: the branch the agent must merge into its session branch. */
|
|
39
255
|
baseBranch?: string;
|
|
256
|
+
/**
|
|
257
|
+
* Everything already in the base — nothing new to merge. A normal outcome,
|
|
258
|
+
* not a failure: it used to surface as a raw «Commit failed: nothing to
|
|
259
|
+
* commit» from git.
|
|
260
|
+
*/
|
|
261
|
+
noChanges?: boolean;
|
|
262
|
+
/** The project folder is not on the branch this session forked from. */
|
|
263
|
+
drifted?: boolean;
|
|
264
|
+
/** What the folder IS on, so the message can name it. */
|
|
265
|
+
workspaceBranch?: string;
|
|
266
|
+
/** Tip of the session branch this apply swallowed — the next one starts here. */
|
|
267
|
+
branchSha?: string;
|
|
268
|
+
/** Tip of the base before the merge, for the journal. */
|
|
269
|
+
baseShaBefore?: string;
|
|
270
|
+
/**
|
|
271
|
+
* Refused because the PROJECT FOLDER has uncommitted changes (session 15).
|
|
272
|
+
*
|
|
273
|
+
* A flag rather than only the sentence: the API used to see nothing but a
|
|
274
|
+
* free-text `error`, so this refusal reached the user as a raw string with no
|
|
275
|
+
* state behind it and no way forward. `error` stays alongside it so an API
|
|
276
|
+
* older than session 15 keeps behaving exactly as it did.
|
|
277
|
+
*/
|
|
278
|
+
workspaceDirty?: boolean;
|
|
279
|
+
workspaceDirtyFiles?: string[];
|
|
280
|
+
workspaceDirtyCount?: number;
|
|
281
|
+
/** …and whether that dirt is a stopped merge, which cannot be committed. */
|
|
282
|
+
workspaceMergeInProgress?: boolean;
|
|
283
|
+
error?: string;
|
|
284
|
+
}
|
|
285
|
+
export interface ApplySessionInput {
|
|
286
|
+
workspacePath: string;
|
|
287
|
+
worktreePath: string;
|
|
288
|
+
sessionBranch: string;
|
|
289
|
+
message: string;
|
|
290
|
+
/**
|
|
291
|
+
* The base pinned at session creation. When given, the apply refuses to run
|
|
292
|
+
* while the project folder sits on any other branch: merging into whatever
|
|
293
|
+
* happens to be checked out is how work silently landed in the wrong place.
|
|
294
|
+
*/
|
|
295
|
+
expectedBase?: string;
|
|
296
|
+
/**
|
|
297
|
+
* Branch tip the previous apply already merged. Only work after it counts —
|
|
298
|
+
* this is what turns «Apply» from a one-shot door into a repeatable action.
|
|
299
|
+
*/
|
|
300
|
+
sinceSha?: string;
|
|
301
|
+
}
|
|
302
|
+
export interface UpdateFromBaseResult {
|
|
303
|
+
updated: boolean;
|
|
304
|
+
commitSha?: string;
|
|
305
|
+
/** The branch already contained everything the base has. */
|
|
306
|
+
alreadyUpToDate?: boolean;
|
|
307
|
+
conflict?: boolean;
|
|
308
|
+
/** Paths git could not merge — captured BEFORE the abort wipes them. */
|
|
309
|
+
conflictPaths?: string[];
|
|
310
|
+
baseBranch?: string;
|
|
311
|
+
error?: string;
|
|
312
|
+
}
|
|
313
|
+
export interface GitBranchEntry {
|
|
314
|
+
name: string;
|
|
315
|
+
sha: string;
|
|
316
|
+
subject: string;
|
|
317
|
+
date: string;
|
|
318
|
+
/** Absolute path of the worktree holding it — git refuses a second checkout. */
|
|
319
|
+
checkedOutIn: string | null;
|
|
320
|
+
/** Reachable from the current base: the work is already in. */
|
|
321
|
+
merged: boolean;
|
|
322
|
+
}
|
|
323
|
+
export interface GitBranchesResult {
|
|
324
|
+
branches: GitBranchEntry[];
|
|
325
|
+
/** What the project folder is on right now. */
|
|
326
|
+
currentBranch: string | null;
|
|
327
|
+
currentSha: string | null;
|
|
328
|
+
remotes: string[];
|
|
329
|
+
truncated: boolean;
|
|
330
|
+
}
|
|
331
|
+
/**
|
|
332
|
+
* Every local branch, with the one fact the user cannot see anywhere else:
|
|
333
|
+
* whether it is already checked out in another worktree. Git refuses to check
|
|
334
|
+
* one branch out twice, so «continue this branch» has to know before it starts,
|
|
335
|
+
* not after the worktree command fails.
|
|
336
|
+
*/
|
|
337
|
+
export declare function gitBranches(workspacePath: string): Promise<GitBranchesResult>;
|
|
338
|
+
export interface GitPushResult {
|
|
339
|
+
pushed: boolean;
|
|
340
|
+
remote?: string;
|
|
341
|
+
branch?: string;
|
|
342
|
+
/** The sha that is now on the remote. */
|
|
343
|
+
commitSha?: string;
|
|
344
|
+
alreadyUpToDate?: boolean;
|
|
345
|
+
/** This push also gave the branch an upstream (session 16). */
|
|
346
|
+
upstreamSet?: boolean;
|
|
40
347
|
error?: string;
|
|
41
348
|
}
|
|
42
|
-
export declare function applySession(workspacePath: string, worktreePath: string, sessionBranch: string, message: string): Promise<ApplyResult>;
|
|
43
349
|
/**
|
|
44
350
|
* Reading history is the one git surface where the *repository*, not the
|
|
45
351
|
* session worktree, is the right place to stand: a finished session may have
|
|
@@ -53,6 +359,21 @@ export declare function applySession(workspacePath: string, worktreePath: string
|
|
|
53
359
|
* `assertRefArgument` / `sanitizeBranch` and by the same denylist the Changes
|
|
54
360
|
* panel uses.
|
|
55
361
|
*/
|
|
362
|
+
/**
|
|
363
|
+
* A ref pointing at a commit, with its KIND (session 14).
|
|
364
|
+
*
|
|
365
|
+
* Until now these were bare strings, so a local branch, a remote-tracking
|
|
366
|
+
* branch and a tag were drawn identically and `tag: v1.2` leaked its prefix
|
|
367
|
+
* into the badge. The graph needs to tell them apart to look like a repository
|
|
368
|
+
* viewer rather than a list.
|
|
369
|
+
*/
|
|
370
|
+
export interface GitRef {
|
|
371
|
+
/** Short name: `main`, `origin/main`, `v1.2.0`. */
|
|
372
|
+
name: string;
|
|
373
|
+
type: 'head' | 'remote' | 'tag';
|
|
374
|
+
/** `HEAD -> ` pointed here: this is what the folder is checked out on. */
|
|
375
|
+
isHead: boolean;
|
|
376
|
+
}
|
|
56
377
|
export interface GitLogCommit {
|
|
57
378
|
sha: string;
|
|
58
379
|
/** Empty for a root commit, more than one for a merge. */
|
|
@@ -60,12 +381,28 @@ export interface GitLogCommit {
|
|
|
60
381
|
author: string;
|
|
61
382
|
/** Author date, ISO-8601 with offset. */
|
|
62
383
|
date: string;
|
|
384
|
+
/** Who committed it — differs from the author after a rebase or a cherry-pick. */
|
|
385
|
+
committer: string;
|
|
386
|
+
committerDate: string;
|
|
63
387
|
subject: string;
|
|
64
|
-
|
|
65
|
-
refs: string[];
|
|
388
|
+
refs: GitRef[];
|
|
66
389
|
}
|
|
67
390
|
/** Which slice of history to show. */
|
|
68
391
|
export type GitLogScope = 'session' | 'branch' | 'all';
|
|
392
|
+
/**
|
|
393
|
+
* Which refs a log (and therefore a commit read) may reach (session 14).
|
|
394
|
+
*
|
|
395
|
+
* `refs` names them explicitly; `includeRemotes`/`includeTags`/`all` widen the
|
|
396
|
+
* set to whole namespaces. `all` deliberately expands to
|
|
397
|
+
* `--branches --remotes --tags` rather than the bare `--all`, which would also
|
|
398
|
+
* drag in `refs/stash` and `refs/notes` — neither is history anybody asked for.
|
|
399
|
+
*/
|
|
400
|
+
export interface GitRefSelector {
|
|
401
|
+
refs?: string[];
|
|
402
|
+
includeRemotes?: boolean;
|
|
403
|
+
includeTags?: boolean;
|
|
404
|
+
all?: boolean;
|
|
405
|
+
}
|
|
69
406
|
export interface GitLogResult {
|
|
70
407
|
branch: string;
|
|
71
408
|
baseBranch: string;
|
|
@@ -73,6 +410,12 @@ export interface GitLogResult {
|
|
|
73
410
|
mergeBase: string | null;
|
|
74
411
|
commits: GitLogCommit[];
|
|
75
412
|
hasMore: boolean;
|
|
413
|
+
/** The refs this page was actually allowed to walk — echoed for the caller. */
|
|
414
|
+
scopeRefs: string[];
|
|
415
|
+
/**
|
|
416
|
+
* Where the next page starts. Plain offset — see the note on `GitLogInput`.
|
|
417
|
+
*/
|
|
418
|
+
nextSkip: number;
|
|
76
419
|
}
|
|
77
420
|
export interface GitCommitFileEntry {
|
|
78
421
|
path: string;
|
|
@@ -89,9 +432,13 @@ export interface GitCommitDetail {
|
|
|
89
432
|
author: string;
|
|
90
433
|
authorEmail: string;
|
|
91
434
|
date: string;
|
|
435
|
+
/** Session 14: the committer is a different person after a rebase. */
|
|
436
|
+
committer: string;
|
|
437
|
+
committerEmail: string;
|
|
438
|
+
committerDate: string;
|
|
92
439
|
subject: string;
|
|
93
440
|
body: string;
|
|
94
|
-
refs:
|
|
441
|
+
refs: GitRef[];
|
|
95
442
|
files: GitCommitFileEntry[];
|
|
96
443
|
/** The file list hit the cap — the commit touched more than we return. */
|
|
97
444
|
truncated: boolean;
|
|
@@ -103,19 +450,109 @@ export interface GitCommitFileDiff {
|
|
|
103
450
|
}
|
|
104
451
|
/** A full or abbreviated commit hash — never a ref name, never an option. */
|
|
105
452
|
export declare function isCommitSha(value: string): boolean;
|
|
453
|
+
/**
|
|
454
|
+
* Everything a ref name must satisfy before it becomes a git argument.
|
|
455
|
+
*
|
|
456
|
+
* The same class of check branch names go through (`sanitizeBranch`), because
|
|
457
|
+
* that is exactly what these are: `main`, `origin/main`, `v1.2.0`. A leading
|
|
458
|
+
* dash would be an option, `..` a range, and neither belongs in an argv slot
|
|
459
|
+
* built from a query string.
|
|
460
|
+
*
|
|
461
|
+
* Plus the pseudo-refs above, which are the hole this check exists to close.
|
|
462
|
+
*/
|
|
463
|
+
export declare function sanitizeRefName(value: unknown): string | null;
|
|
106
464
|
/**
|
|
107
465
|
* `--numstat` names a rename as `old => new` (or `dir/{old => new}/file`),
|
|
108
466
|
* while `--name-status` gives the plain new path. Keying the two maps by
|
|
109
467
|
* different strings is why every renamed file showed `null` additions.
|
|
110
468
|
*/
|
|
111
469
|
export declare function normalizeNumstatPath(raw: string): string;
|
|
112
|
-
export
|
|
470
|
+
export interface GitLogInput extends GitRefSelector {
|
|
113
471
|
workspacePath: string;
|
|
114
|
-
|
|
472
|
+
/**
|
|
473
|
+
* The session branch. Optional since session 14: the repository graph is
|
|
474
|
+
* reached from the workspace, where there is no session and therefore no
|
|
475
|
+
* branch that has to be in the picture.
|
|
476
|
+
*/
|
|
477
|
+
branch?: string;
|
|
115
478
|
scope?: GitLogScope;
|
|
116
479
|
limit?: number;
|
|
480
|
+
/**
|
|
481
|
+
* Where this page starts. An OFFSET, and deliberately so.
|
|
482
|
+
*
|
|
483
|
+
* Session 14 first paged by a `--before=<committer date>` cursor, to avoid
|
|
484
|
+
* the prefix re-walk `--skip` pays. That is unsound, and QA-108 proved it on
|
|
485
|
+
* real git with no clock skew at all: `--topo-order` holds a parent back
|
|
486
|
+
* until every child is emitted, so the emitted dates are NOT monotonically
|
|
487
|
+
* decreasing. One ordinary feature branch — started in January, merged in
|
|
488
|
+
* July — emits merge, the whole January side, then the June main-line, so a
|
|
489
|
+
* page boundary inside the January side leaves the remaining June commits
|
|
490
|
+
* NEWER than the page's date. `--before` then excludes them from every later
|
|
491
|
+
* page, `hasMore` goes false, and a truncated history is presented as
|
|
492
|
+
* complete. Taking the minimum date instead of the last made it strictly
|
|
493
|
+
* worse: a smaller boundary excludes more.
|
|
494
|
+
*
|
|
495
|
+
* There is no repair for that combination — a date filter and a topological
|
|
496
|
+
* order answer different questions. `--skip` re-walks the prefix, which is
|
|
497
|
+
* O(n) per page and invisible at the depths a human scrolls; every real git
|
|
498
|
+
* UI (GitHub, GitLab, VS Code's Git Graph) pages the same way.
|
|
499
|
+
*/
|
|
117
500
|
skip?: number;
|
|
118
|
-
|
|
501
|
+
/** The base pinned at session creation (session 13). */
|
|
502
|
+
baseBranch?: string;
|
|
503
|
+
}
|
|
504
|
+
export declare function gitLog(input: GitLogInput): Promise<GitLogResult>;
|
|
505
|
+
export interface GitRefEntry extends GitRef {
|
|
506
|
+
sha: string;
|
|
507
|
+
subject: string;
|
|
508
|
+
/** Committer date, ISO-8601 — the list is sorted newest first by it. */
|
|
509
|
+
date: string;
|
|
510
|
+
/** For a local branch: the remote-tracking ref it follows, if any. */
|
|
511
|
+
upstream: string | null;
|
|
512
|
+
/** Absolute path of the worktree holding it — git refuses a second checkout. */
|
|
513
|
+
checkedOutIn: string | null;
|
|
514
|
+
}
|
|
515
|
+
export interface GitRefsResult {
|
|
516
|
+
refs: GitRefEntry[];
|
|
517
|
+
/** What the project folder is on right now (null on a detached HEAD). */
|
|
518
|
+
currentBranch: string | null;
|
|
519
|
+
currentSha: string | null;
|
|
520
|
+
remotes: string[];
|
|
521
|
+
truncated: boolean;
|
|
522
|
+
}
|
|
523
|
+
/**
|
|
524
|
+
* Every ref worth drawing, with the two facts a picker cannot get anywhere
|
|
525
|
+
* else: which worktree holds a branch, and what it tracks.
|
|
526
|
+
*
|
|
527
|
+
* One `for-each-ref` over the three namespaces rather than three calls — the
|
|
528
|
+
* type comes from the ref path, which is more reliable than guessing from the
|
|
529
|
+
* short name.
|
|
530
|
+
*/
|
|
531
|
+
export declare function gitRefs(workspacePath: string): Promise<GitRefsResult>;
|
|
532
|
+
export interface WorkspaceStateResult {
|
|
533
|
+
/** The branch the project folder is on; null when HEAD is detached. */
|
|
534
|
+
branch: string | null;
|
|
535
|
+
sha: string | null;
|
|
536
|
+
subject: string;
|
|
537
|
+
/** Committer date of that commit, ISO-8601. */
|
|
538
|
+
date: string;
|
|
539
|
+
/** Uncommitted changes in the project folder itself. */
|
|
540
|
+
dirty: boolean;
|
|
541
|
+
dirtyFiles: number;
|
|
542
|
+
/** The remote-tracking branch it follows, and how far apart they are. */
|
|
543
|
+
upstream: string | null;
|
|
544
|
+
ahead: number | null;
|
|
545
|
+
behind: number | null;
|
|
546
|
+
remotes: string[];
|
|
547
|
+
}
|
|
548
|
+
/**
|
|
549
|
+
* The truth about the checkout everything is actually built from.
|
|
550
|
+
*
|
|
551
|
+
* The product used to collect exactly this during path validation and throw it
|
|
552
|
+
* away, which is why it could never answer «is the running build yours» — the
|
|
553
|
+
* question behind «how do I know docker was not rebuilt». Read-only.
|
|
554
|
+
*/
|
|
555
|
+
export declare function workspaceState(workspacePath: string): Promise<WorkspaceStateResult>;
|
|
119
556
|
/**
|
|
120
557
|
* One commit: its metadata and the files it touched, or — when `filePath` is
|
|
121
558
|
* given — the diff of that one file.
|
|
@@ -125,12 +562,52 @@ export declare function gitLog(input: {
|
|
|
125
562
|
* parents, and the answer to "what did this merge bring onto my branch" comes
|
|
126
563
|
* out empty. For an ordinary commit the flag changes nothing.
|
|
127
564
|
*/
|
|
128
|
-
export declare function gitShow(workspacePath: string, sha: string, filePath?: string, branch?: string): Promise<GitCommitDetail | GitCommitFileDiff>;
|
|
565
|
+
export declare function gitShow(workspacePath: string, sha: string, filePath?: string, branch?: string, baseBranch?: string, selector?: GitRefSelector): Promise<GitCommitDetail | GitCommitFileDiff>;
|
|
129
566
|
export interface RevertResult {
|
|
130
567
|
reverted: boolean;
|
|
131
568
|
revertSha?: string;
|
|
132
569
|
conflict?: boolean;
|
|
570
|
+
/** Same refusal as «Apply», same reason — see `ApplyResult` (session 15). */
|
|
571
|
+
workspaceDirty?: boolean;
|
|
572
|
+
workspaceDirtyFiles?: string[];
|
|
573
|
+
workspaceDirtyCount?: number;
|
|
574
|
+
/** …and whether that dirt is a stopped merge, which cannot be committed. */
|
|
575
|
+
workspaceMergeInProgress?: boolean;
|
|
133
576
|
error?: string;
|
|
134
577
|
}
|
|
135
|
-
export declare
|
|
578
|
+
export declare const gitCommit: (worktreePath: string, message: string, options?: {
|
|
579
|
+
all?: boolean;
|
|
580
|
+
} | undefined) => Promise<GitCommitResult>;
|
|
581
|
+
export declare const gitStage: (input: {
|
|
582
|
+
worktreePath: string;
|
|
583
|
+
paths?: readonly string[];
|
|
584
|
+
all?: boolean;
|
|
585
|
+
}) => Promise<GitStageResult>;
|
|
586
|
+
export declare const gitUnstage: (input: {
|
|
587
|
+
worktreePath: string;
|
|
588
|
+
paths?: readonly string[];
|
|
589
|
+
all?: boolean;
|
|
590
|
+
}) => Promise<GitStageResult>;
|
|
591
|
+
export declare const gitDiscard: (input: {
|
|
592
|
+
worktreePath: string;
|
|
593
|
+
paths?: readonly string[];
|
|
594
|
+
all?: boolean;
|
|
595
|
+
}) => Promise<GitDiscardResult>;
|
|
596
|
+
export declare const gitPull: (input: {
|
|
597
|
+
worktreePath: string;
|
|
598
|
+
}) => Promise<GitPullResult>;
|
|
599
|
+
export declare const gitMergeAbort: (worktreePath: string) => Promise<GitMergeAbortResult>;
|
|
600
|
+
export declare const applySession: (input: ApplySessionInput) => Promise<ApplyResult>;
|
|
601
|
+
export declare const revertApply: (workspacePath: string, commitSha: string, expectedBase?: string | undefined) => Promise<RevertResult>;
|
|
602
|
+
export declare const updateFromBase: (input: {
|
|
603
|
+
workspacePath: string;
|
|
604
|
+
worktreePath: string;
|
|
605
|
+
sessionBranch: string;
|
|
606
|
+
baseBranch?: string;
|
|
607
|
+
}) => Promise<UpdateFromBaseResult>;
|
|
608
|
+
export declare const gitPush: (input: {
|
|
609
|
+
workspacePath: string;
|
|
610
|
+
branch: string;
|
|
611
|
+
remote: string;
|
|
612
|
+
}) => Promise<GitPushResult>;
|
|
136
613
|
//# sourceMappingURL=gitops.d.ts.map
|