mergestorm 0.3.15 → 0.3.17
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 +4 -4
- package/dist/api.d.ts +44 -4
- package/dist/api.js +55 -12
- package/dist/automation-catalog.d.ts +37 -0
- package/dist/automation-catalog.js +13 -0
- package/dist/client/index.d.ts +4 -2
- package/dist/client/index.js +4 -2
- package/dist/commands/browse.d.ts +2 -2
- package/dist/commands/browse.js +7 -11
- package/dist/commands/credits.js +1 -0
- package/dist/commands/pr.d.ts +4 -0
- package/dist/commands/pr.js +32 -5
- package/dist/commands/registry.js +7 -4
- package/dist/commands/review-client.d.ts +10 -3
- package/dist/commands/review-client.js +75 -24
- package/dist/commands/review.js +17 -14
- package/dist/commands/settings.d.ts +2 -2
- package/dist/commands/settings.js +2 -9
- package/dist/commands/stack.d.ts +55 -2
- package/dist/commands/stack.js +274 -37
- package/dist/commands/status.js +4 -2
- package/dist/commands/whoami.js +9 -9
- package/dist/git.js +1 -1
- package/dist/repo-identity.d.ts +1 -1
- package/dist/repo-identity.js +13 -2
- package/dist/stack-dto.d.ts +55 -2
- package/dist/stack-dto.js +0 -6
- package/dist/stack-meta.d.ts +12 -0
- package/dist/stack-meta.js +32 -3
- package/dist/ui/banner.js +6 -0
- package/dist/ui/human-summary.d.ts +2 -0
- package/dist/ui/human-summary.js +153 -0
- package/dist/ui/usage.d.ts +1 -2
- package/dist/ui/usage.js +3 -4
- package/package.json +1 -1
- package/skill/SKILL.md +3 -3
- package/skill/mergestorm-pr-loop/SKILL.md +36 -21
package/README.md
CHANGED
|
@@ -45,12 +45,12 @@ On a TTY, bare `mergestorm` (or `mergestorm shell`) opens a branded REPL: a comp
|
|
|
45
45
|
|
|
46
46
|
```
|
|
47
47
|
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
48
|
-
│ ▟██▛ mergestorm v0.3.
|
|
48
|
+
│ ▟██▛ mergestorm v0.3.17 │
|
|
49
49
|
│ ▜▙ ● msk_live_… · maelstrom │
|
|
50
50
|
│ [████████░░░░░░░░░░░░░░░░░░░░░░] 25% used · Resets Sep 5, 10:53am (UTC)│
|
|
51
51
|
│ │
|
|
52
52
|
│ review a diff · usage for tabs · /help for all commands │
|
|
53
|
-
│ New in v0.3.
|
|
53
|
+
│ New in v0.3.17: nginx 413 names the upload limit instead of Failed: {} │
|
|
54
54
|
╰──────────────────────────────────────────────────────────────────────────────╯
|
|
55
55
|
mergestorm
|
|
56
56
|
╭──────────────────────────────────────────────────────────────────────────────╮
|
|
@@ -99,7 +99,7 @@ mergestorm stack reset --force Clear local authoring state (not branches/PRs)
|
|
|
99
99
|
|
|
100
100
|
`mg` is a short alias for `mergestorm` (same binary), e.g. `mg stack create`. Happy path: **create → commit → submit → restack → land**. On review-unit stacks, `stack land` **promotes** the tip into the unit (same gates as the dashboard); otherwise it lands the bottom open PR. `stack adopt` is for importing a chain that already exists on GitHub (legacy / Graphite). Restack/land use the same login key (`/api/v1/stacks`). Unattended landing is `mg queue add`.
|
|
101
101
|
|
|
102
|
-
`stack create` checks out a new branch from the current tip (or `--onto <branch>`), discovers trunk (`main` / `master` / `origin/HEAD`, overridable with `--trunk`), and records `{ branch, parentBranch }` in CLI-managed state under **`~/.mergestorm/stacks/<repo-id>/stack.json`**. The CLI updates this automatically; never edit it.
|
|
102
|
+
`stack create` checks out a new branch from the current tip (or `--onto <branch>`), discovers trunk (`main` / `master` / `origin/HEAD`, overridable with `--trunk`), and records `{ branch, parentBranch }` in CLI-managed state under **`~/.mergestorm/stacks/<repo-id>/stack.json`**. The CLI updates this automatically; never edit it. Each worktree has its own authoring state; independent clones stay isolated too. Creating onto trunk with a non-empty active stack starts a new one. `--trunk` only sets trunk metadata — it does **not** change the parent; use `--onto main` (etc.) for a fresh stack from trunk.
|
|
103
103
|
|
|
104
104
|
If the parent branch is already a layer of a **registered** (submitted) stack, `create` and `submit` refuse unless you pass **`--extend`**. That blocks accidentally gluing an unrelated PR onto an open unit. Growing a registered stack on purpose: `mg stack create --onto <tip> --extend` → commit → `mg stack submit --extend`.
|
|
105
105
|
|
|
@@ -119,7 +119,7 @@ Removes `~/.mergestorm/config.json` so the stored key is no longer used.
|
|
|
119
119
|
|
|
120
120
|
### `review [base] [head]`
|
|
121
121
|
|
|
122
|
-
Collects `git diff base...head` (default: discovered trunk — `origin/HEAD`, `main`, or `master`), attaches the changed file contents (up to 40 files, skipping files > 400 KB), submits the job, and polls until it finishes (~8 min max — Core plus a Max fleet can exceed 3 minutes). The thread slug defaults to the current branch (`local/<branch>`); pass `--thread` to override so follow-ups chain on a chosen slug. The CLI does not scan
|
|
122
|
+
Collects `git diff base...head` (default: discovered trunk — `origin/HEAD`, `main`, or `master`), attaches the changed file contents (up to 40 files, skipping files > 400 KB), submits the job, and polls until it finishes (~8 min max — Core plus a Max fleet can exceed 3 minutes). The thread slug defaults to the current branch (`local/<branch>`); pass `--thread` to override so follow-ups chain on a chosen slug. The CLI still does not scan a repo folder for review context. GitHub Vortex will read house-rule files in a later PR (`AGENTS.md`, `CLAUDE.md`, alwaysApply Cursor rules). That ingest is not shipping yet.
|
|
123
123
|
|
|
124
124
|
```bash
|
|
125
125
|
mergestorm review # discovered trunk (origin/HEAD, main, or master)...HEAD
|
package/dist/api.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { type Config } from "./config.js";
|
|
2
|
+
import { BEARER_SETTINGS_KEYS as SETTINGS_WRITABLE_KEYS, type BearerSettingsKey as SettingsWritableKey } from "./automation-catalog.js";
|
|
2
3
|
import type { MergeQueueEntryDto, StackDto } from "./stack-dto.js";
|
|
3
4
|
export type { MergeQueueBounceDetail, MergeQueueBounceKind, MergeQueueEnqueuedBy, MergeQueueEnqueuedVia, MergeQueueEntryDto, MergeQueueEntryState, StackBranchState, StackCiStatus, StackDto, StackLayerChecks, StackLayerDto, StackReviewStatus, StackTempestStatus, StackUnitDto, StackUnitMemberDto, } from "./stack-dto.js";
|
|
4
5
|
/** Default per-request timeout so a hung API cannot stall the shell/CI forever. */
|
|
@@ -45,6 +46,10 @@ export type MeResponse = {
|
|
|
45
46
|
limit: number | null;
|
|
46
47
|
remaining: number | null;
|
|
47
48
|
};
|
|
49
|
+
/** Non-expiring credits spent after the monthly standard pool. */
|
|
50
|
+
bonus?: {
|
|
51
|
+
remaining: number;
|
|
52
|
+
};
|
|
48
53
|
};
|
|
49
54
|
};
|
|
50
55
|
export type JobListItem = {
|
|
@@ -121,6 +126,8 @@ export type PrVortexReview = {
|
|
|
121
126
|
verdict: string | null;
|
|
122
127
|
summary?: string | null;
|
|
123
128
|
head_sha: string | null;
|
|
129
|
+
/** Attempt number on this head (#2027). Absent only from servers older than the pass column. */
|
|
130
|
+
pass?: number;
|
|
124
131
|
review_count: number;
|
|
125
132
|
skip_reason: string | null;
|
|
126
133
|
reviewed_at: string | null;
|
|
@@ -128,12 +135,25 @@ export type PrVortexReview = {
|
|
|
128
135
|
findings: PrReviewFindings | null;
|
|
129
136
|
patch_policy: unknown | null;
|
|
130
137
|
};
|
|
138
|
+
/**
|
|
139
|
+
* Pass selection on the DB-only PR review read (#2027). `pass` names one row;
|
|
140
|
+
* `afterPass` asks for a later pass (`pass > afterPass`) on the SHA filter.
|
|
141
|
+
*/
|
|
142
|
+
export type PrReviewPassSelector = {
|
|
143
|
+
pass?: number;
|
|
144
|
+
afterPass?: number;
|
|
145
|
+
};
|
|
146
|
+
export declare function isPositiveInteger(value: unknown): value is number;
|
|
147
|
+
/** Append pass selection and SHA filter to a PR review query. */
|
|
148
|
+
export declare function applyPrReviewQuery(query: URLSearchParams, opts: PrReviewPassSelector & {
|
|
149
|
+
afterSha?: string;
|
|
150
|
+
}): void;
|
|
131
151
|
/**
|
|
132
152
|
* Bearer-writable settings keys, mirroring the `/api/v1/settings` allowlist.
|
|
133
153
|
* The connected flags are read-only there and deliberately absent here.
|
|
134
154
|
*/
|
|
135
|
-
export
|
|
136
|
-
export type SettingsWritableKey
|
|
155
|
+
export { SETTINGS_WRITABLE_KEYS };
|
|
156
|
+
export type { SettingsWritableKey };
|
|
137
157
|
export type SettingsPatch = Partial<Record<SettingsWritableKey, boolean>>;
|
|
138
158
|
/** GET and PATCH `/api/v1/settings` both answer with this shape. */
|
|
139
159
|
export type SettingsResponse = Record<SettingsWritableKey, boolean> & {
|
|
@@ -171,7 +191,8 @@ export declare function getReview(jobId: string, cfg?: Config, opts?: {
|
|
|
171
191
|
export declare function getPrVortexReview(owner: string, repo: string, prNumber: number, cfg?: Config, opts?: {
|
|
172
192
|
signal?: AbortSignal;
|
|
173
193
|
timeoutMs?: number;
|
|
174
|
-
|
|
194
|
+
afterSha?: string;
|
|
195
|
+
} & PrReviewPassSelector): Promise<PrVortexReview>;
|
|
175
196
|
/** List stacks (Bearer GET /api/v1/stacks). */
|
|
176
197
|
export declare function listStacks(cfg?: Config, opts?: {
|
|
177
198
|
timeoutMs?: number;
|
|
@@ -180,13 +201,32 @@ export declare function listStacks(cfg?: Config, opts?: {
|
|
|
180
201
|
export declare function getEnrichedStack(stackId: string, cfg?: Config, opts?: {
|
|
181
202
|
timeoutMs?: number;
|
|
182
203
|
}): Promise<StackDto | null>;
|
|
204
|
+
/**
|
|
205
|
+
* Per-stack automation policy. Auto land is a boolean; the review / patch
|
|
206
|
+
* overrides are tri-state (`null` clears back to the account flag). Absent
|
|
207
|
+
* keys are left untouched.
|
|
208
|
+
*/
|
|
209
|
+
export type StackPolicyPatch = {
|
|
210
|
+
autoEnqueueWhenReady?: boolean;
|
|
211
|
+
autoReviewOverride?: boolean | null;
|
|
212
|
+
autoPatchOverride?: boolean | null;
|
|
213
|
+
};
|
|
214
|
+
/** Drop undefined keys so the wire body only carries what was requested. */
|
|
215
|
+
export declare function stackPolicyBody(policy: StackPolicyPatch | undefined): StackPolicyPatch;
|
|
183
216
|
/** Adopt an open PR chain (Bearer POST /api/v1/stacks/adopt). */
|
|
184
|
-
export declare function adoptStack(owner: string, repo: string, prNumber: number, cfg?: Config): Promise<unknown>;
|
|
217
|
+
export declare function adoptStack(owner: string, repo: string, prNumber: number, cfg?: Config, policy?: StackPolicyPatch): Promise<unknown>;
|
|
185
218
|
/** Mint or reuse the PR3+ park freeze (Bearer POST /api/v1/stacks/:id/ensure-upper-park). */
|
|
186
219
|
export declare function ensureUpperPark(stackId: string, cfg?: Config): Promise<{
|
|
187
220
|
freezeBranch: string;
|
|
188
221
|
created: boolean;
|
|
189
222
|
}>;
|
|
223
|
+
/** Arm or disarm Auto land on one owned stack. */
|
|
224
|
+
export declare function setStackAutoLand(stackId: string, enabled: boolean, cfg?: Config): Promise<unknown>;
|
|
225
|
+
/**
|
|
226
|
+
* Patch any subset of one owned stack's automation policy
|
|
227
|
+
* (Bearer PATCH /api/v1/stacks/:id). `null` clears an override.
|
|
228
|
+
*/
|
|
229
|
+
export declare function setStackPolicy(stackId: string, policy: StackPolicyPatch, cfg?: Config): Promise<unknown>;
|
|
190
230
|
/** Restack descendants (Bearer POST /api/v1/stacks/:id/restack). */
|
|
191
231
|
export declare function restackStack(stackId: string, cfg?: Config): Promise<unknown>;
|
|
192
232
|
/** Land the bottom open layer (Bearer POST /api/v1/stacks/:id/land-next). */
|
package/dist/api.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { apiBase, loadConfig, resolveApiKey } from "./config.js";
|
|
2
|
+
import { BEARER_SETTINGS_KEYS as SETTINGS_WRITABLE_KEYS, } from "./automation-catalog.js";
|
|
2
3
|
import { CommandError, REVIEW_EXIT, rateLimitedMessage } from "./errors.js";
|
|
3
4
|
/** Default per-request timeout so a hung API cannot stall the shell/CI forever. */
|
|
4
5
|
export const DEFAULT_API_TIMEOUT_MS = 30_000;
|
|
@@ -154,19 +155,23 @@ export async function devicePost(base, route, json, opts = {}) {
|
|
|
154
155
|
}
|
|
155
156
|
return { status: res.status, body: parsed };
|
|
156
157
|
}
|
|
158
|
+
export function isPositiveInteger(value) {
|
|
159
|
+
return typeof value === "number" && Number.isInteger(value) && value >= 1;
|
|
160
|
+
}
|
|
161
|
+
/** Append pass selection and SHA filter to a PR review query. */
|
|
162
|
+
export function applyPrReviewQuery(query, opts) {
|
|
163
|
+
if (opts.afterSha)
|
|
164
|
+
query.set("after_sha", opts.afterSha);
|
|
165
|
+
if (opts.pass !== undefined)
|
|
166
|
+
query.set("pass", String(opts.pass));
|
|
167
|
+
if (opts.afterPass !== undefined)
|
|
168
|
+
query.set("after_pass", String(opts.afterPass));
|
|
169
|
+
}
|
|
157
170
|
/**
|
|
158
171
|
* Bearer-writable settings keys, mirroring the `/api/v1/settings` allowlist.
|
|
159
172
|
* The connected flags are read-only there and deliberately absent here.
|
|
160
173
|
*/
|
|
161
|
-
export
|
|
162
|
-
"auto_review_enabled",
|
|
163
|
-
"auto_patch_enabled",
|
|
164
|
-
"vortex_show_thinking_traces",
|
|
165
|
-
"repo_overview_enabled",
|
|
166
|
-
"review_unit_land_prs_enabled",
|
|
167
|
-
"cyclone_review_unit_land_prs_enabled",
|
|
168
|
-
"vortex_seam_specialist_enabled",
|
|
169
|
-
];
|
|
174
|
+
export { SETTINGS_WRITABLE_KEYS };
|
|
170
175
|
/**
|
|
171
176
|
* Fetch Bearer /api/v1/settings; null on 404/network/timeouts so panels can
|
|
172
177
|
* degrade (same contract as {@link getMe}), while 401 still surfaces.
|
|
@@ -290,6 +295,7 @@ export async function getPrVortexReview(owner, repo, prNumber, cfg, opts) {
|
|
|
290
295
|
repo: cleanRepo,
|
|
291
296
|
pr_number: String(prNumber),
|
|
292
297
|
});
|
|
298
|
+
applyPrReviewQuery(query, opts ?? {});
|
|
293
299
|
const { status, body, retryAfterSeconds } = await apiFetch(resolved, `/api/v1/stacks/pr-review?${query.toString()}`, { signal: opts?.signal, timeoutMs: opts?.timeoutMs });
|
|
294
300
|
if (status === 404) {
|
|
295
301
|
throw new CommandError(`Vortex review not found: ${cleanOwner}/${cleanRepo}#${prNumber}`, REVIEW_EXIT.failed, "not_found");
|
|
@@ -343,16 +349,38 @@ export async function getEnrichedStack(stackId, cfg, opts) {
|
|
|
343
349
|
}
|
|
344
350
|
return stacks.find((stack) => stack?.id === id) ?? null;
|
|
345
351
|
}
|
|
352
|
+
/** Drop undefined keys so the wire body only carries what was requested. */
|
|
353
|
+
export function stackPolicyBody(policy) {
|
|
354
|
+
const body = {};
|
|
355
|
+
if (typeof policy?.autoEnqueueWhenReady === "boolean") {
|
|
356
|
+
body.autoEnqueueWhenReady = policy.autoEnqueueWhenReady;
|
|
357
|
+
}
|
|
358
|
+
if (policy?.autoReviewOverride !== undefined) {
|
|
359
|
+
body.autoReviewOverride = policy.autoReviewOverride;
|
|
360
|
+
}
|
|
361
|
+
if (policy?.autoPatchOverride !== undefined) {
|
|
362
|
+
body.autoPatchOverride = policy.autoPatchOverride;
|
|
363
|
+
}
|
|
364
|
+
return body;
|
|
365
|
+
}
|
|
346
366
|
/** Adopt an open PR chain (Bearer POST /api/v1/stacks/adopt). */
|
|
347
|
-
export async function adoptStack(owner, repo, prNumber, cfg) {
|
|
367
|
+
export async function adoptStack(owner, repo, prNumber, cfg, policy) {
|
|
348
368
|
const resolved = cfg ?? (await loadConfig());
|
|
349
|
-
const { status, body } = await apiFetch(resolved, "/api/v1/stacks/adopt", {
|
|
369
|
+
const { status, body, retryAfterSeconds } = await apiFetch(resolved, "/api/v1/stacks/adopt", {
|
|
350
370
|
method: "POST",
|
|
351
|
-
json: {
|
|
371
|
+
json: {
|
|
372
|
+
owner,
|
|
373
|
+
repo,
|
|
374
|
+
prNumber,
|
|
375
|
+
...stackPolicyBody(policy),
|
|
376
|
+
},
|
|
352
377
|
});
|
|
353
378
|
if (status === 404) {
|
|
354
379
|
throw new CommandError("Stacks API is not available on this server yet. Deploy the API update or use the dashboard.");
|
|
355
380
|
}
|
|
381
|
+
if (status === 429) {
|
|
382
|
+
throw new CommandError(rateLimitedMessage(retryAfterSeconds), REVIEW_EXIT.rate_limited, "rate_limited", { retryAfterSeconds });
|
|
383
|
+
}
|
|
356
384
|
if (status !== 200) {
|
|
357
385
|
throw new CommandError(`Failed to import stack (HTTP ${status}): ${JSON.stringify(body)}`);
|
|
358
386
|
}
|
|
@@ -390,6 +418,21 @@ async function stackMutation(stackId, pathSuffix, method, json, failLabel, cfg)
|
|
|
390
418
|
}
|
|
391
419
|
return body;
|
|
392
420
|
}
|
|
421
|
+
/** Arm or disarm Auto land on one owned stack. */
|
|
422
|
+
export async function setStackAutoLand(stackId, enabled, cfg) {
|
|
423
|
+
return setStackPolicy(stackId, { autoEnqueueWhenReady: enabled }, cfg);
|
|
424
|
+
}
|
|
425
|
+
/**
|
|
426
|
+
* Patch any subset of one owned stack's automation policy
|
|
427
|
+
* (Bearer PATCH /api/v1/stacks/:id). `null` clears an override.
|
|
428
|
+
*/
|
|
429
|
+
export async function setStackPolicy(stackId, policy, cfg) {
|
|
430
|
+
const json = stackPolicyBody(policy);
|
|
431
|
+
if (Object.keys(json).length === 0) {
|
|
432
|
+
throw new CommandError("setStackPolicy needs at least one policy key");
|
|
433
|
+
}
|
|
434
|
+
return stackMutation(stackId, "", "PATCH", json, "Failed to set stack policy", cfg);
|
|
435
|
+
}
|
|
393
436
|
/** Restack descendants (Bearer POST /api/v1/stacks/:id/restack). */
|
|
394
437
|
export async function restackStack(stackId, cfg) {
|
|
395
438
|
return stackMutation(stackId, "/restack", "POST", {}, "Failed to restack", cfg);
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
export declare const BEARER_SETTINGS: readonly [{
|
|
2
|
+
readonly key: "auto_review_enabled";
|
|
3
|
+
readonly flag: "--auto-review";
|
|
4
|
+
readonly label: "Auto review";
|
|
5
|
+
}, {
|
|
6
|
+
readonly key: "auto_patch_enabled";
|
|
7
|
+
readonly flag: "--auto-patch";
|
|
8
|
+
readonly label: "Auto patch";
|
|
9
|
+
}, {
|
|
10
|
+
readonly key: "vortex_show_thinking_traces";
|
|
11
|
+
readonly flag: "--vortex-thinking";
|
|
12
|
+
readonly label: "Vortex thinking traces";
|
|
13
|
+
}, {
|
|
14
|
+
readonly key: "repo_overview_enabled";
|
|
15
|
+
readonly flag: "--repo-overview";
|
|
16
|
+
readonly label: "Repo overview";
|
|
17
|
+
}, {
|
|
18
|
+
readonly key: "review_unit_land_prs_enabled";
|
|
19
|
+
readonly flag: "--review-unit-land";
|
|
20
|
+
readonly label: "Review Unit land PRs";
|
|
21
|
+
}, {
|
|
22
|
+
readonly key: "cyclone_review_unit_land_prs_enabled";
|
|
23
|
+
readonly flag: "--cyclone-review-unit-land";
|
|
24
|
+
readonly label: "Cyclone Review Unit land PRs";
|
|
25
|
+
}, {
|
|
26
|
+
readonly key: "vortex_seam_specialist_enabled";
|
|
27
|
+
readonly flag: "--vortex-seam";
|
|
28
|
+
readonly label: "Vortex seam specialist";
|
|
29
|
+
}, {
|
|
30
|
+
readonly key: "auto_land_default";
|
|
31
|
+
readonly flag: "--auto-land";
|
|
32
|
+
readonly label: "Auto land (new stacks)";
|
|
33
|
+
}];
|
|
34
|
+
export type BearerSettingsKey = (typeof BEARER_SETTINGS)[number]["key"];
|
|
35
|
+
export declare const BEARER_SETTINGS_KEYS: readonly BearerSettingsKey[];
|
|
36
|
+
export declare const BEARER_SETTINGS_FLAGS: Record<string, BearerSettingsKey>;
|
|
37
|
+
export declare const BEARER_SETTINGS_LABELS: Record<BearerSettingsKey, string>;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
export const BEARER_SETTINGS = [
|
|
2
|
+
{ key: "auto_review_enabled", flag: "--auto-review", label: "Auto review" },
|
|
3
|
+
{ key: "auto_patch_enabled", flag: "--auto-patch", label: "Auto patch" },
|
|
4
|
+
{ key: "vortex_show_thinking_traces", flag: "--vortex-thinking", label: "Vortex thinking traces" },
|
|
5
|
+
{ key: "repo_overview_enabled", flag: "--repo-overview", label: "Repo overview" },
|
|
6
|
+
{ key: "review_unit_land_prs_enabled", flag: "--review-unit-land", label: "Review Unit land PRs" },
|
|
7
|
+
{ key: "cyclone_review_unit_land_prs_enabled", flag: "--cyclone-review-unit-land", label: "Cyclone Review Unit land PRs" },
|
|
8
|
+
{ key: "vortex_seam_specialist_enabled", flag: "--vortex-seam", label: "Vortex seam specialist" },
|
|
9
|
+
{ key: "auto_land_default", flag: "--auto-land", label: "Auto land (new stacks)" },
|
|
10
|
+
];
|
|
11
|
+
export const BEARER_SETTINGS_KEYS = BEARER_SETTINGS.map((r) => r.key);
|
|
12
|
+
export const BEARER_SETTINGS_FLAGS = Object.fromEntries(BEARER_SETTINGS.map((r) => [r.flag, r.key]));
|
|
13
|
+
export const BEARER_SETTINGS_LABELS = Object.fromEntries(BEARER_SETTINGS.map((r) => [r.key, r.label]));
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { DEFAULT_API, apiBase, clearConfig, configPath, keyDisplay, loadConfig, mergestormHome, resolveApiKey, saveConfig, type Config, } from "../config.js";
|
|
2
|
-
export {
|
|
2
|
+
export { BEARER_SETTINGS, BEARER_SETTINGS_FLAGS, BEARER_SETTINGS_KEYS, BEARER_SETTINGS_LABELS, type BearerSettingsKey, } from "../automation-catalog.js";
|
|
3
|
+
export { API_TIMEOUT_PREFIX, DEFAULT_API_TIMEOUT_MS, SETTINGS_WRITABLE_KEYS, adoptStack, apiFetch, cancelMergeQueueEntry, devicePost, enqueueStack, ensureUpperPark, getEnrichedStack, getMe, getPrVortexReview, getReview, getSettings, landNextStack, listJobs, listMergeQueueEntries, listStacks, listThreads, parseRetryAfterSeconds, patchSettings, restackStack, setStackAutoLand, setStackPolicy, stackPolicyBody, type ApiFetchInit, type ApiFetchResult, type JobListItem, type MeResponse, type MergeQueueBounceDetail, type MergeQueueBounceKind, type MergeQueueEnqueuedBy, type MergeQueueEnqueuedVia, type MergeQueueEntryDto, type MergeQueueEntryState, type PrReviewFinding, type PrReviewFindings, type PrVortexReview, type SettingsPatch, type SettingsResponse, type SettingsWritableKey, type StackDto, type StackPolicyPatch, type ThreadDetail, type ThreadListItem, } from "../api.js";
|
|
3
4
|
export { CommandError, DetachedError, RATE_LIMITED_HINT, REVIEW_EXIT, isCommandErrorCode, rateLimitedMessage, type CommandErrorCode, type CommandErrorExtras, } from "../errors.js";
|
|
4
|
-
export { REVIEW_POLL_BACKOFF_MS, REVIEW_POLL_DEFAULT_TIMEOUT_MS, REVIEW_POLL_INTERVAL_MS, REVIEW_POLL_MAX_INTERVAL_MS, REVIEW_POLL_MAX_TRANSIENT_RETRIES, REVIEW_POLL_STRETCH_AFTER_MS, REVIEW_POLL_STRETCH_SPAN_MS, REVIEW_THREAD_SLUG_RE, PrReviewPollTimeoutError, ReviewPollTimeoutError, collectReviewInput, isTransientReviewPollError, isTransientReviewPollStatus, loadReviewContext, pollPrVortexReview, pollReview, stretchedPollIntervalMs, submitReview, transientRetryWaitMs, type PollReviewOptions, type PollPrVortexReviewOptions, type ReviewInput, type SubmitReviewOptions, } from "../commands/review-client.js";
|
|
5
|
+
export { REVIEW_POLL_BACKOFF_MS, REVIEW_POLL_DEFAULT_TIMEOUT_MS, REVIEW_POLL_INTERVAL_MS, REVIEW_POLL_MAX_INTERVAL_MS, REVIEW_POLL_MAX_TRANSIENT_RETRIES, REVIEW_POLL_STRETCH_AFTER_MS, REVIEW_POLL_STRETCH_SPAN_MS, REVIEW_THREAD_SLUG_RE, PrReviewPollTimeoutError, ReviewPollTimeoutError, collectReviewInput, formatReviewSubmitError, isTransientReviewPollError, isTransientReviewPollStatus, loadReviewContext, pollPrVortexReview, pollReview, stretchedPollIntervalMs, submitReview, transientRetryWaitMs, type PollReviewOptions, type PollPrVortexReviewOptions, type ReviewInput, type SubmitReviewOptions, } from "../commands/review-client.js";
|
|
5
6
|
export { REVIEW_JOB_ENVELOPE_SCHEMA, toReviewJobEnvelope, type ReviewEnvelopeFallbacks, type ReviewJobEnvelope, type ReviewJobRow, } from "../ui/job-envelope.js";
|
|
7
|
+
export { discoverTrunk } from "../git-stack.js";
|
package/dist/client/index.js
CHANGED
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
export { DEFAULT_API, apiBase, clearConfig, configPath, keyDisplay, loadConfig, mergestormHome, resolveApiKey, saveConfig, } from "../config.js";
|
|
2
|
-
export {
|
|
2
|
+
export { BEARER_SETTINGS, BEARER_SETTINGS_FLAGS, BEARER_SETTINGS_KEYS, BEARER_SETTINGS_LABELS, } from "../automation-catalog.js";
|
|
3
|
+
export { API_TIMEOUT_PREFIX, DEFAULT_API_TIMEOUT_MS, SETTINGS_WRITABLE_KEYS, adoptStack, apiFetch, cancelMergeQueueEntry, devicePost, enqueueStack, ensureUpperPark, getEnrichedStack, getMe, getPrVortexReview, getReview, getSettings, landNextStack, listJobs, listMergeQueueEntries, listStacks, listThreads, parseRetryAfterSeconds, patchSettings, restackStack, setStackAutoLand, setStackPolicy, stackPolicyBody, } from "../api.js";
|
|
3
4
|
export { CommandError, DetachedError, RATE_LIMITED_HINT, REVIEW_EXIT, isCommandErrorCode, rateLimitedMessage, } from "../errors.js";
|
|
4
|
-
export { REVIEW_POLL_BACKOFF_MS, REVIEW_POLL_DEFAULT_TIMEOUT_MS, REVIEW_POLL_INTERVAL_MS, REVIEW_POLL_MAX_INTERVAL_MS, REVIEW_POLL_MAX_TRANSIENT_RETRIES, REVIEW_POLL_STRETCH_AFTER_MS, REVIEW_POLL_STRETCH_SPAN_MS, REVIEW_THREAD_SLUG_RE, PrReviewPollTimeoutError, ReviewPollTimeoutError, collectReviewInput, isTransientReviewPollError, isTransientReviewPollStatus, loadReviewContext, pollPrVortexReview, pollReview, stretchedPollIntervalMs, submitReview, transientRetryWaitMs, } from "../commands/review-client.js";
|
|
5
|
+
export { REVIEW_POLL_BACKOFF_MS, REVIEW_POLL_DEFAULT_TIMEOUT_MS, REVIEW_POLL_INTERVAL_MS, REVIEW_POLL_MAX_INTERVAL_MS, REVIEW_POLL_MAX_TRANSIENT_RETRIES, REVIEW_POLL_STRETCH_AFTER_MS, REVIEW_POLL_STRETCH_SPAN_MS, REVIEW_THREAD_SLUG_RE, PrReviewPollTimeoutError, ReviewPollTimeoutError, collectReviewInput, formatReviewSubmitError, isTransientReviewPollError, isTransientReviewPollStatus, loadReviewContext, pollPrVortexReview, pollReview, stretchedPollIntervalMs, submitReview, transientRetryWaitMs, } from "../commands/review-client.js";
|
|
5
6
|
export { REVIEW_JOB_ENVELOPE_SCHEMA, toReviewJobEnvelope, } from "../ui/job-envelope.js";
|
|
7
|
+
export { discoverTrunk } from "../git-stack.js";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type JobListItem, type SettingsResponse
|
|
1
|
+
import { type JobListItem, type SettingsResponse } from "../api.js";
|
|
2
2
|
import { type ReviewJobRow } from "../ui/job-envelope.js";
|
|
3
3
|
import { type TabId, type TabsConfigRow } from "../ui/tabs.js";
|
|
4
4
|
import { type UsagePanelJob } from "../ui/usage.js";
|
|
@@ -27,7 +27,7 @@ export declare function buildStatusTabLines(input: StatusTabInput): string[];
|
|
|
27
27
|
/** In-place job detail for the Jobs tab (same envelope as `status <id>`). */
|
|
28
28
|
export declare function formatJobDetailLines(row: ReviewJobRow): string[];
|
|
29
29
|
/** Human labels for the Config tab and the static `settings` printout. */
|
|
30
|
-
export declare const SETTINGS_LABELS: Record<
|
|
30
|
+
export declare const SETTINGS_LABELS: Record<"auto_review_enabled" | "auto_patch_enabled" | "vortex_show_thinking_traces" | "repo_overview_enabled" | "review_unit_land_prs_enabled" | "cyclone_review_unit_land_prs_enabled" | "vortex_seam_specialist_enabled" | "auto_land_default", string>;
|
|
31
31
|
/** Config rows in a stable order: writable toggles, then connected flags. */
|
|
32
32
|
export declare function buildConfigRows(settings: SettingsResponse): TabsConfigRow[];
|
|
33
33
|
/**
|
package/dist/commands/browse.js
CHANGED
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { getMe, getReview, getSettings, listJobs, patchSettings, SETTINGS_WRITABLE_KEYS, } from "../api.js";
|
|
2
|
+
import { BEARER_SETTINGS_LABELS } from "../automation-catalog.js";
|
|
2
3
|
import { apiBase, keyDisplay, loadConfig, resolveApiKey } from "../config.js";
|
|
3
4
|
import { CommandError } from "../errors.js";
|
|
4
5
|
import { ansi } from "../ui/ansi.js";
|
|
6
|
+
import { humanSummary } from "../ui/human-summary.js";
|
|
5
7
|
import { toReviewJobEnvelope, } from "../ui/job-envelope.js";
|
|
6
8
|
import { runTabsBrowser, } from "../ui/tabs.js";
|
|
7
9
|
import { formatDaysLeft, formatResetLabel } from "../ui/usage.js";
|
|
@@ -89,9 +91,10 @@ export function formatJobDetailLines(row) {
|
|
|
89
91
|
lines.push(` Credits ${e.credits.standard} standard`);
|
|
90
92
|
if (e.error)
|
|
91
93
|
lines.push(ansi.red(` Error ${e.error}`));
|
|
92
|
-
|
|
94
|
+
const summary = e.summary ? humanSummary(e.summary) : null;
|
|
95
|
+
if (summary) {
|
|
93
96
|
lines.push("");
|
|
94
|
-
for (const l of
|
|
97
|
+
for (const l of summary.split("\n"))
|
|
95
98
|
lines.push(` ${l}`);
|
|
96
99
|
}
|
|
97
100
|
const inline = e.findings?.inline ?? [];
|
|
@@ -117,15 +120,7 @@ export function formatJobDetailLines(row) {
|
|
|
117
120
|
return lines;
|
|
118
121
|
}
|
|
119
122
|
/** Human labels for the Config tab and the static `settings` printout. */
|
|
120
|
-
export const SETTINGS_LABELS =
|
|
121
|
-
auto_review_enabled: "Auto review",
|
|
122
|
-
auto_patch_enabled: "Auto patch",
|
|
123
|
-
vortex_show_thinking_traces: "Vortex thinking traces",
|
|
124
|
-
repo_overview_enabled: "Repo overview",
|
|
125
|
-
review_unit_land_prs_enabled: "Review Unit land PRs",
|
|
126
|
-
cyclone_review_unit_land_prs_enabled: "Cyclone Review Unit land PRs",
|
|
127
|
-
vortex_seam_specialist_enabled: "Vortex seam specialist",
|
|
128
|
-
};
|
|
123
|
+
export const SETTINGS_LABELS = BEARER_SETTINGS_LABELS;
|
|
129
124
|
/** Config rows in a stable order: writable toggles, then connected flags. */
|
|
130
125
|
export function buildConfigRows(settings) {
|
|
131
126
|
return [
|
|
@@ -225,6 +220,7 @@ export async function openTabsBrowser(initial) {
|
|
|
225
220
|
plan: me.plan_label_key ?? me.plan_key,
|
|
226
221
|
used: me.usage.standard.used,
|
|
227
222
|
limit: me.usage.standard.limit,
|
|
223
|
+
bonusRemaining: me.usage.bonus?.remaining,
|
|
228
224
|
resetsAt: me.resets_at,
|
|
229
225
|
jobs: jobs.slice(0, 5).map(toPanelJob),
|
|
230
226
|
jobsError: jobsError ?? undefined,
|
package/dist/commands/credits.js
CHANGED
package/dist/commands/pr.d.ts
CHANGED
|
@@ -6,6 +6,10 @@ export type ParsedPrArgs = {
|
|
|
6
6
|
format: "json" | "pretty";
|
|
7
7
|
wait: boolean;
|
|
8
8
|
afterSha?: string;
|
|
9
|
+
/** Exact pass on the head (#2027). */
|
|
10
|
+
pass?: number;
|
|
11
|
+
/** Only a pass later than this one on the head (#2027). */
|
|
12
|
+
afterPass?: number;
|
|
9
13
|
timeoutMs: number;
|
|
10
14
|
};
|
|
11
15
|
export type PrOptions = {
|
package/dist/commands/pr.js
CHANGED
|
@@ -3,9 +3,17 @@ import { loadConfig } from "../config.js";
|
|
|
3
3
|
import { CommandError, REVIEW_EXIT } from "../errors.js";
|
|
4
4
|
import { ansi } from "../ui/ansi.js";
|
|
5
5
|
import { renderFindings } from "../ui/findings.js";
|
|
6
|
+
import { humanSummary } from "../ui/human-summary.js";
|
|
6
7
|
import { PrReviewPollTimeoutError, REVIEW_POLL_DEFAULT_TIMEOUT_MS, pollPrVortexReview, } from "./review-client.js";
|
|
7
8
|
import { parseAdoptTarget } from "./stack.js";
|
|
8
|
-
const PR_USAGE = "usage: mergestorm pr <owner/repo>#<n> [--json] [--wait] [--after-sha <sha>] [--timeout <s>]";
|
|
9
|
+
const PR_USAGE = "usage: mergestorm pr <owner/repo>#<n> [--json] [--wait] [--after-sha <sha>] [--pass <n>] [--after-pass <n>] [--timeout <s>]";
|
|
10
|
+
function parsePassFlag(flag, value) {
|
|
11
|
+
const parsed = Number(value);
|
|
12
|
+
if (!value?.trim() || !/^[0-9]+$/.test(value.trim()) || !Number.isSafeInteger(parsed) || parsed < 1) {
|
|
13
|
+
throw usageError(`${flag} requires a positive integer`);
|
|
14
|
+
}
|
|
15
|
+
return parsed;
|
|
16
|
+
}
|
|
9
17
|
function usageError(message = PR_USAGE) {
|
|
10
18
|
return new CommandError(message, REVIEW_EXIT.usage, "usage");
|
|
11
19
|
}
|
|
@@ -14,6 +22,8 @@ export function parsePrArgs(args, defaults = { format: "json" }) {
|
|
|
14
22
|
let format = defaults.format;
|
|
15
23
|
let wait = false;
|
|
16
24
|
let afterSha;
|
|
25
|
+
let pass;
|
|
26
|
+
let afterPass;
|
|
17
27
|
let timeoutMs = REVIEW_POLL_DEFAULT_TIMEOUT_MS;
|
|
18
28
|
for (let i = 0; i < args.length; i += 1) {
|
|
19
29
|
const arg = args[i];
|
|
@@ -42,6 +52,14 @@ export function parsePrArgs(args, defaults = { format: "json" }) {
|
|
|
42
52
|
}
|
|
43
53
|
continue;
|
|
44
54
|
}
|
|
55
|
+
if (arg === "--pass" || arg.startsWith("--pass=")) {
|
|
56
|
+
pass = parsePassFlag("--pass", arg === "--pass" ? args[++i] : arg.slice("--pass=".length));
|
|
57
|
+
continue;
|
|
58
|
+
}
|
|
59
|
+
if (arg === "--after-pass" || arg.startsWith("--after-pass=")) {
|
|
60
|
+
afterPass = parsePassFlag("--after-pass", arg === "--after-pass" ? args[++i] : arg.slice("--after-pass=".length));
|
|
61
|
+
continue;
|
|
62
|
+
}
|
|
45
63
|
if (arg === "--timeout" || arg.startsWith("--timeout=")) {
|
|
46
64
|
const value = arg === "--timeout" ? args[++i] : arg.slice("--timeout=".length);
|
|
47
65
|
const seconds = Number(value);
|
|
@@ -58,6 +76,12 @@ export function parsePrArgs(args, defaults = { format: "json" }) {
|
|
|
58
76
|
}
|
|
59
77
|
if (afterSha && !wait)
|
|
60
78
|
throw usageError("--after-sha requires --wait");
|
|
79
|
+
if (pass !== undefined && afterPass !== undefined) {
|
|
80
|
+
throw usageError("--pass and --after-pass are exclusive");
|
|
81
|
+
}
|
|
82
|
+
if ((pass !== undefined || afterPass !== undefined) && (!wait || !afterSha)) {
|
|
83
|
+
throw usageError("--pass and --after-pass require --wait --after-sha");
|
|
84
|
+
}
|
|
61
85
|
if (target.length < 1 || target.length > 2)
|
|
62
86
|
throw usageError();
|
|
63
87
|
let parsed;
|
|
@@ -67,7 +91,7 @@ export function parsePrArgs(args, defaults = { format: "json" }) {
|
|
|
67
91
|
catch {
|
|
68
92
|
throw usageError();
|
|
69
93
|
}
|
|
70
|
-
return { ...parsed, format, wait, afterSha, timeoutMs };
|
|
94
|
+
return { ...parsed, format, wait, afterSha, pass, afterPass, timeoutMs };
|
|
71
95
|
}
|
|
72
96
|
function printPretty(envelope) {
|
|
73
97
|
console.log(`Status: ${envelope.status}`);
|
|
@@ -78,8 +102,9 @@ function printPretty(envelope) {
|
|
|
78
102
|
console.log(`Finding count: ${envelope.finding_count}`);
|
|
79
103
|
if (envelope.skip_reason)
|
|
80
104
|
console.log(`Skip reason: ${envelope.skip_reason}`);
|
|
81
|
-
|
|
82
|
-
|
|
105
|
+
const summary = envelope.summary ? humanSummary(envelope.summary) : null;
|
|
106
|
+
if (summary)
|
|
107
|
+
console.log(summary);
|
|
83
108
|
renderFindings(envelope.findings, {
|
|
84
109
|
emptyMessage: envelope.status === "completed",
|
|
85
110
|
});
|
|
@@ -96,6 +121,8 @@ export async function cmdPr(args, opts = {}) {
|
|
|
96
121
|
timeoutMs: parsed.timeoutMs,
|
|
97
122
|
intervalMs: opts.pollIntervalMs,
|
|
98
123
|
afterSha: parsed.afterSha,
|
|
124
|
+
pass: parsed.pass,
|
|
125
|
+
afterPass: parsed.afterPass,
|
|
99
126
|
signal: opts.signal,
|
|
100
127
|
...opts.poll,
|
|
101
128
|
onTick(kind) {
|
|
@@ -116,7 +143,7 @@ export async function cmdPr(args, opts = {}) {
|
|
|
116
143
|
console.log("");
|
|
117
144
|
}
|
|
118
145
|
else {
|
|
119
|
-
envelope = await getPrVortexReview(parsed.owner, parsed.repo, parsed.prNumber, cfg, { signal: opts.signal });
|
|
146
|
+
envelope = await getPrVortexReview(parsed.owner, parsed.repo, parsed.prNumber, cfg, { signal: opts.signal, pass: parsed.pass, afterPass: parsed.afterPass });
|
|
120
147
|
}
|
|
121
148
|
if (parsed.format === "json") {
|
|
122
149
|
console.log(JSON.stringify(envelope, null, opts.mode === "shell" ? 2 : undefined));
|
|
@@ -66,7 +66,8 @@ export const COMMAND_REGISTRY = [
|
|
|
66
66
|
summary: "Latest Vortex review for a GitHub PR",
|
|
67
67
|
usage: [
|
|
68
68
|
"mergestorm pr <owner/repo>#<n> Fetch the latest Vortex PR review",
|
|
69
|
-
" [--json] [--wait] [--after-sha <sha>] [--timeout <s>]",
|
|
69
|
+
" [--json] [--wait] [--after-sha <sha>] [--pass <n>] [--after-pass <n>] [--timeout <s>]",
|
|
70
|
+
" --pass reads one attempt on the head; --after-pass waits for a later one (#2027)",
|
|
70
71
|
" Also accepts: mergestorm pr <owner/repo> <n>",
|
|
71
72
|
],
|
|
72
73
|
async run(args, ctx) {
|
|
@@ -164,6 +165,7 @@ export const COMMAND_REGISTRY = [
|
|
|
164
165
|
" [--auto-review on|off] [--auto-patch on|off] [--vortex-thinking on|off]",
|
|
165
166
|
" [--repo-overview on|off] [--review-unit-land on|off]",
|
|
166
167
|
" [--cyclone-review-unit-land on|off] [--vortex-seam on|off]",
|
|
168
|
+
" [--auto-land on|off] Auto land default for stacks opened after this",
|
|
167
169
|
" With flags: PATCH those settings and print the stored result",
|
|
168
170
|
],
|
|
169
171
|
async run(args, ctx) {
|
|
@@ -210,11 +212,12 @@ export const COMMAND_REGISTRY = [
|
|
|
210
212
|
name: "stack",
|
|
211
213
|
summary: "Stacks: /stack how-to, list yours, create → submit",
|
|
212
214
|
usage: [
|
|
213
|
-
"mergestorm stack create [name] New local
|
|
214
|
-
"mergestorm stack submit Push active
|
|
215
|
+
"mergestorm stack create [name] New local layer ([--onto] [--trunk] [--extend] [--auto-land on|off] [--auto-review on|off] [--auto-patch on|off])",
|
|
216
|
+
"mergestorm stack submit Push/open active stack ([--extend] [--auto-land on|off] [--auto-review on|off] [--auto-patch on|off])",
|
|
215
217
|
"mergestorm stack reset --force Clear this repo's pre-submit authoring state",
|
|
216
218
|
"mergestorm stack list [--json] List registered stacks",
|
|
217
|
-
"mergestorm stack
|
|
219
|
+
"mergestorm stack set <stack-id> [--auto-land on|off] [--auto-review on|off|default] [--auto-patch on|off|default] [--json] Per-stack policy",
|
|
220
|
+
"mergestorm stack adopt <owner/repo>#<pr> [--auto-land on|off] [--auto-review on|off] [--auto-patch on|off] Import an open PR chain",
|
|
218
221
|
"mergestorm stack restack <stack-id> Restack stack descendants",
|
|
219
222
|
"mergestorm stack land <stack-id> Land bottom PR (or promote into unit)",
|
|
220
223
|
],
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type PrVortexReview } from "../api.js";
|
|
1
|
+
import { type PrReviewPassSelector, type PrVortexReview } from "../api.js";
|
|
2
2
|
import type { Config } from "../config.js";
|
|
3
3
|
import type { ReviewJobRow } from "../ui/job-envelope.js";
|
|
4
4
|
export declare const REVIEW_POLL_INTERVAL_MS = 2000;
|
|
@@ -10,6 +10,8 @@ export declare const REVIEW_POLL_STRETCH_AFTER_MS = 60000;
|
|
|
10
10
|
export declare const REVIEW_POLL_STRETCH_SPAN_MS = 60000;
|
|
11
11
|
/** Same thread slug contract as POST /api/v1/reviews. */
|
|
12
12
|
export declare const REVIEW_THREAD_SLUG_RE: RegExp;
|
|
13
|
+
/** Same product limit as `api/src/v1/reviews.ts` `MAX_DIFF_BYTES`. */
|
|
14
|
+
export declare const MAX_REVIEW_DIFF_BYTES = 1000000;
|
|
13
15
|
export declare const MAX_CONTEXT_TEXT_CHARS = 60000;
|
|
14
16
|
export declare const MAX_CONTEXT_FILES = 10;
|
|
15
17
|
export declare const MAX_CONTEXT_FILE_CHARS = 16000;
|
|
@@ -52,7 +54,7 @@ export type LoadReviewContextOptions = {
|
|
|
52
54
|
contextFiles: string[];
|
|
53
55
|
cwd?: string;
|
|
54
56
|
readStdin?: () => Promise<string>;
|
|
55
|
-
/**
|
|
57
|
+
/** Bound contextFiles to this directory; defaults to the canonical repo root. */
|
|
56
58
|
sandboxCwd?: string;
|
|
57
59
|
};
|
|
58
60
|
/** Load --context / --context-file and enforce the API caps client-side. */
|
|
@@ -62,6 +64,11 @@ export declare function submitReview(cfg: Config, input: ReviewInput, opts?: Sub
|
|
|
62
64
|
row: ReviewJobRow;
|
|
63
65
|
retryAfterSeconds?: number;
|
|
64
66
|
}>;
|
|
67
|
+
/**
|
|
68
|
+
* Human copy for a failed POST /api/v1/reviews.
|
|
69
|
+
* nginx 413 is HTML, so `submitReview` stores `{}` and used to print `Failed: {}`.
|
|
70
|
+
*/
|
|
71
|
+
export declare function formatReviewSubmitError(status: number, body: unknown): string;
|
|
65
72
|
/** Exponential backoff with jitter in `[0.5, 1.0]` of the base delay. */
|
|
66
73
|
export declare function transientRetryWaitMs(input: {
|
|
67
74
|
retryAfterSeconds?: number;
|
|
@@ -98,7 +105,7 @@ export type PollReviewOptions = {
|
|
|
98
105
|
/** Test seam for backoff jitter; production uses `Math.random`. */
|
|
99
106
|
random?: () => number;
|
|
100
107
|
};
|
|
101
|
-
export type PollPrVortexReviewOptions = PollReviewOptions & {
|
|
108
|
+
export type PollPrVortexReviewOptions = PollReviewOptions & PrReviewPassSelector & {
|
|
102
109
|
afterSha?: string;
|
|
103
110
|
};
|
|
104
111
|
/** Poll the DB-only PR review endpoint until the requested pass is resting. */
|