@wildorder/nightshift 0.12.0 → 0.14.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +46 -19
- package/dist/agent-probe.d.ts +21 -2
- package/dist/agent-probe.d.ts.map +1 -1
- package/dist/agent-probe.js +76 -22
- package/dist/agent-probe.js.map +1 -1
- package/dist/agent-runner.d.ts +90 -2
- package/dist/agent-runner.d.ts.map +1 -1
- package/dist/agent-runner.js +382 -24
- package/dist/agent-runner.js.map +1 -1
- package/dist/agent-summary.d.ts +15 -0
- package/dist/agent-summary.d.ts.map +1 -1
- package/dist/agent-summary.js +32 -2
- package/dist/agent-summary.js.map +1 -1
- package/dist/as-built.d.ts +6 -0
- package/dist/as-built.d.ts.map +1 -1
- package/dist/as-built.js +7 -0
- package/dist/as-built.js.map +1 -1
- package/dist/author.d.ts +9 -0
- package/dist/author.d.ts.map +1 -1
- package/dist/author.js +161 -24
- package/dist/author.js.map +1 -1
- package/dist/ci-init.d.ts.map +1 -1
- package/dist/ci-init.js +17 -12
- package/dist/ci-init.js.map +1 -1
- package/dist/cli.js +144 -11
- package/dist/cli.js.map +1 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +13 -0
- package/dist/config.js.map +1 -1
- package/dist/crash-report.d.ts +58 -0
- package/dist/crash-report.d.ts.map +1 -0
- package/dist/crash-report.js +115 -0
- package/dist/crash-report.js.map +1 -0
- package/dist/decide.js +1 -1
- package/dist/decide.js.map +1 -1
- package/dist/decider-review.d.ts +33 -5
- package/dist/decider-review.d.ts.map +1 -1
- package/dist/decider-review.js +55 -9
- package/dist/decider-review.js.map +1 -1
- package/dist/decision-ledger.d.ts +54 -1
- package/dist/decision-ledger.d.ts.map +1 -1
- package/dist/decision-ledger.js +53 -1
- package/dist/decision-ledger.js.map +1 -1
- package/dist/decision-view.d.ts +10 -1
- package/dist/decision-view.d.ts.map +1 -1
- package/dist/decision-view.js +41 -0
- package/dist/decision-view.js.map +1 -1
- package/dist/exit-codes.d.ts +16 -2
- package/dist/exit-codes.d.ts.map +1 -1
- package/dist/exit-codes.js +17 -2
- package/dist/exit-codes.js.map +1 -1
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +1 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +68 -14
- package/dist/manifest.d.ts.map +1 -1
- package/dist/manifest.js +301 -22
- package/dist/manifest.js.map +1 -1
- package/dist/permits.d.ts +135 -0
- package/dist/permits.d.ts.map +1 -0
- package/dist/permits.js +397 -0
- package/dist/permits.js.map +1 -0
- package/dist/preflight.d.ts +73 -0
- package/dist/preflight.d.ts.map +1 -0
- package/dist/preflight.js +225 -0
- package/dist/preflight.js.map +1 -0
- package/dist/publish.d.ts +71 -0
- package/dist/publish.d.ts.map +1 -1
- package/dist/publish.js +319 -1
- package/dist/publish.js.map +1 -1
- package/dist/run-program.d.ts +70 -2
- package/dist/run-program.d.ts.map +1 -1
- package/dist/run-program.js +677 -60
- package/dist/run-program.js.map +1 -1
- package/dist/skill-roots.d.ts +11 -3
- package/dist/skill-roots.d.ts.map +1 -1
- package/dist/skill-roots.js +59 -12
- package/dist/skill-roots.js.map +1 -1
- package/dist/whole-program-review.d.ts +4 -0
- package/dist/whole-program-review.d.ts.map +1 -1
- package/dist/whole-program-review.js +9 -1
- package/dist/whole-program-review.js.map +1 -1
- package/package.json +2 -2
- package/skills/plan-program/SKILL.md +125 -5
- package/dist/verify-allowlist.d.ts +0 -23
- package/dist/verify-allowlist.d.ts.map +0 -1
- package/dist/verify-allowlist.js +0 -46
- package/dist/verify-allowlist.js.map +0 -1
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
import { spawn } from "node:child_process";
|
|
2
|
+
import { tail } from "./agent-runner.js";
|
|
3
|
+
/**
|
|
4
|
+
* The preflight stage: at run start, before baseline verification and any
|
|
5
|
+
* agent spawn, executes every *pending* prerequisite's `verifyCommand` as a
|
|
6
|
+
* deterministic, bounded subprocess. Exit zero flips it to `satisfied` (in
|
|
7
|
+
* memory — the caller decides when to persist); anything else — nonzero
|
|
8
|
+
* exit, spawn failure, timeout — uniformly means unmet, with a captured
|
|
9
|
+
* reason, and never throws out of this module. See
|
|
10
|
+
* `tasks/human-prerequisites/ws-02-*.md` for the full design.
|
|
11
|
+
*/
|
|
12
|
+
/** The wall-clock ceiling on a single prerequisite check. A deterministic
|
|
13
|
+
* check that has not answered in this long is treated as unmet, and the
|
|
14
|
+
* process tree is killed so it can never outlive the run. A constant, never
|
|
15
|
+
* a config key — the charter keeps tuning knobs off the config surface. */
|
|
16
|
+
export const PREREQUISITE_TIMEOUT_MS = 60_000;
|
|
17
|
+
// In-memory output is kept to a bounded tail, mirroring agent-runner.ts's
|
|
18
|
+
// own OUTPUT_TAIL_LIMIT — this module intentionally does not import that
|
|
19
|
+
// private constant.
|
|
20
|
+
const OUTPUT_TAIL_LIMIT = 200_000;
|
|
21
|
+
/** How long a timed-out check waits, past its own ceiling, for the kill
|
|
22
|
+
* request to take effect before giving up on `close` and settling anyway.
|
|
23
|
+
* A kill (`taskkill`, a signalled process group) has no completion callback
|
|
24
|
+
* to await, so without this bound a slow or failed kill would turn a
|
|
25
|
+
* *bounded* check into an unbounded one — this is the backstop that keeps
|
|
26
|
+
* the promise settling promptly regardless. */
|
|
27
|
+
const KILL_GRACE_MS = 3_000;
|
|
28
|
+
/**
|
|
29
|
+
* Kills a spawned shell line's whole process tree, not just the shell
|
|
30
|
+
* process `spawn` returned — a `verifyCommand` may fork descendants (node,
|
|
31
|
+
* curl, a helper script), and `child.kill()` alone would orphan them: on
|
|
32
|
+
* Windows in particular, killing only the returned `cmd.exe` process leaves
|
|
33
|
+
* its own child (say, `node`) running and still holding the inherited stdio
|
|
34
|
+
* pipe handles, so `close` never fires until that orphan exits on its own —
|
|
35
|
+
* confirmed empirically (see the git history of this function's tests): a
|
|
36
|
+
* `child.kill()` issued *before* `taskkill /T` gets a chance to walk the
|
|
37
|
+
* still-live tree kills the wrapper first, orphans the descendant, and
|
|
38
|
+
* taskkill then reports "not found" for a pid that is already gone —
|
|
39
|
+
* reproducing exactly the unbounded-wait failure this function exists to
|
|
40
|
+
* prevent. So the whole tree is killed as a single unit, by pid, while the
|
|
41
|
+
* tree is still intact — never a separate signal to the immediate child
|
|
42
|
+
* first.
|
|
43
|
+
*
|
|
44
|
+
* POSIX: the child was spawned `detached: true`, making it its own
|
|
45
|
+
* process-group leader; signalling the negative pid signals the whole group
|
|
46
|
+
* atomically. `ESRCH` (the group already exited) is swallowed — best effort.
|
|
47
|
+
*
|
|
48
|
+
* Windows: there is no process-group signal, so `taskkill /T /F` is used,
|
|
49
|
+
* which walks the live process tree from `pid` and terminates it forcibly in
|
|
50
|
+
* one call. Fire-and-forget as far as this function is concerned — its
|
|
51
|
+
* caller (the grace timer in {@link makePrerequisiteRunner}) is what bounds
|
|
52
|
+
* the wait, since an external kill request has no completion callback of its
|
|
53
|
+
* own to await; a spawn failure for `taskkill` itself (e.g. an unusual PATH)
|
|
54
|
+
* is swallowed the same way.
|
|
55
|
+
*/
|
|
56
|
+
function killProcessTree(pid) {
|
|
57
|
+
if (process.platform === "win32") {
|
|
58
|
+
const killer = spawn("taskkill", ["/pid", String(pid), "/T", "/F"], {
|
|
59
|
+
windowsHide: true,
|
|
60
|
+
stdio: "ignore",
|
|
61
|
+
});
|
|
62
|
+
killer.on("error", () => {
|
|
63
|
+
// taskkill itself failed to spawn — the grace timer still bounds the
|
|
64
|
+
// wait regardless.
|
|
65
|
+
});
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
try {
|
|
69
|
+
process.kill(-pid, "SIGKILL");
|
|
70
|
+
}
|
|
71
|
+
catch {
|
|
72
|
+
// Already exited, or never became a group leader — best effort.
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Builds a bounded, process-tree-killing `PrerequisiteRunner`. Fixing the
|
|
77
|
+
* timeout inside a `(command, cwd)` runner would leave a timeout test no
|
|
78
|
+
* choice but to wait out the real production ceiling; this factory keeps the
|
|
79
|
+
* ceiling a test seam while {@link defaultPrerequisiteRunner} wires the
|
|
80
|
+
* production constant once.
|
|
81
|
+
*/
|
|
82
|
+
export function makePrerequisiteRunner(timeoutMs = PREREQUISITE_TIMEOUT_MS) {
|
|
83
|
+
return (command, cwd) => new Promise((resolvePromise, rejectPromise) => {
|
|
84
|
+
// shell: true, exactly like defaultVerifyRunner — a verifyCommand is a
|
|
85
|
+
// whole shell line the human/planner authored, run under cmd /c or
|
|
86
|
+
// /bin/sh -c. detached: true on POSIX makes the child a process-group
|
|
87
|
+
// leader so killProcessTree can signal the whole tree; Windows has no
|
|
88
|
+
// such option and uses taskkill /T instead.
|
|
89
|
+
const child = spawn(command, [], {
|
|
90
|
+
cwd,
|
|
91
|
+
shell: true,
|
|
92
|
+
windowsHide: true,
|
|
93
|
+
stdio: ["pipe", "pipe", "pipe"],
|
|
94
|
+
...(process.platform === "win32" ? {} : { detached: true }),
|
|
95
|
+
});
|
|
96
|
+
let buffered = "";
|
|
97
|
+
const push = (chunk) => {
|
|
98
|
+
buffered = (buffered + chunk).slice(-OUTPUT_TAIL_LIMIT);
|
|
99
|
+
};
|
|
100
|
+
child.stdout?.setEncoding("utf8");
|
|
101
|
+
child.stderr?.setEncoding("utf8");
|
|
102
|
+
child.stdout?.on("data", push);
|
|
103
|
+
child.stderr?.on("data", push);
|
|
104
|
+
// Never reads stdin, and ends it immediately — the same headless
|
|
105
|
+
// posture as defaultVerifyRunner (agent-runner.ts).
|
|
106
|
+
child.stdin?.end();
|
|
107
|
+
let settled = false;
|
|
108
|
+
let timedOut = false;
|
|
109
|
+
let graceTimer;
|
|
110
|
+
const settle = (result) => {
|
|
111
|
+
if (settled)
|
|
112
|
+
return;
|
|
113
|
+
settled = true;
|
|
114
|
+
clearTimeout(timer);
|
|
115
|
+
clearTimeout(graceTimer);
|
|
116
|
+
resolvePromise(result);
|
|
117
|
+
};
|
|
118
|
+
const timer = setTimeout(() => {
|
|
119
|
+
timedOut = true;
|
|
120
|
+
if (child.pid !== undefined)
|
|
121
|
+
killProcessTree(child.pid);
|
|
122
|
+
// The kill above is a request, not a confirmation — `taskkill` and a
|
|
123
|
+
// signalled process group have no completion callback this runner
|
|
124
|
+
// can await, and a slow or failed kill must never turn a *bounded*
|
|
125
|
+
// check into an unbounded one (SC-03/SC-11: the run always
|
|
126
|
+
// terminates). `close` still wins the race in the overwhelmingly
|
|
127
|
+
// common case where the kill lands promptly; this grace window is
|
|
128
|
+
// strictly a backstop for the rest.
|
|
129
|
+
graceTimer = setTimeout(() => {
|
|
130
|
+
settle({ exitCode: 1, output: buffered, timedOut: true });
|
|
131
|
+
}, KILL_GRACE_MS);
|
|
132
|
+
graceTimer.unref();
|
|
133
|
+
}, timeoutMs);
|
|
134
|
+
timer.unref();
|
|
135
|
+
child.on("error", (error) => {
|
|
136
|
+
if (settled)
|
|
137
|
+
return;
|
|
138
|
+
settled = true;
|
|
139
|
+
clearTimeout(timer);
|
|
140
|
+
clearTimeout(graceTimer);
|
|
141
|
+
rejectPromise(error);
|
|
142
|
+
});
|
|
143
|
+
child.on("close", (code) => {
|
|
144
|
+
settle({ exitCode: code ?? 1, output: buffered, timedOut });
|
|
145
|
+
});
|
|
146
|
+
});
|
|
147
|
+
}
|
|
148
|
+
/** The production runner: the 60 s ceiling, wired once. */
|
|
149
|
+
export const defaultPrerequisiteRunner = makePrerequisiteRunner();
|
|
150
|
+
/**
|
|
151
|
+
* Runs every pending prerequisite's `verifyCommand` once. Mutates
|
|
152
|
+
* `manifest.prerequisites` in place on a met check (pending → satisfied);
|
|
153
|
+
* the caller decides when (and whether) to persist that mutation to disk. An
|
|
154
|
+
* already-`satisfied` prerequisite is never re-run — settled facts stay
|
|
155
|
+
* settled (SC-06). No `verifyCommand` outcome can throw out of this
|
|
156
|
+
* function or halt the run (SC-03): a thrown spawn failure is caught here.
|
|
157
|
+
*/
|
|
158
|
+
export async function runPreflight(args) {
|
|
159
|
+
const { manifest, cwd, runner, now, runId, runStartCommit, log } = args;
|
|
160
|
+
const checks = [];
|
|
161
|
+
const events = [];
|
|
162
|
+
for (const prerequisite of manifest.prerequisites) {
|
|
163
|
+
if (prerequisite.status === "satisfied") {
|
|
164
|
+
checks.push({ id: prerequisite.id, met: true, newlySatisfied: false });
|
|
165
|
+
continue;
|
|
166
|
+
}
|
|
167
|
+
let run;
|
|
168
|
+
try {
|
|
169
|
+
run = await runner(prerequisite.verifyCommand, cwd);
|
|
170
|
+
}
|
|
171
|
+
catch (error) {
|
|
172
|
+
const message = error?.message?.trim();
|
|
173
|
+
const reason = message && message !== ""
|
|
174
|
+
? message
|
|
175
|
+
: "the verify command could not be started";
|
|
176
|
+
checks.push({
|
|
177
|
+
id: prerequisite.id,
|
|
178
|
+
met: false,
|
|
179
|
+
reason,
|
|
180
|
+
newlySatisfied: false,
|
|
181
|
+
});
|
|
182
|
+
log(`preflight: ${prerequisite.id} unmet — ${reason}`);
|
|
183
|
+
continue;
|
|
184
|
+
}
|
|
185
|
+
if (run.timedOut) {
|
|
186
|
+
const reason = `the verify command did not finish within ` +
|
|
187
|
+
`${PREREQUISITE_TIMEOUT_MS}ms and was terminated`;
|
|
188
|
+
checks.push({
|
|
189
|
+
id: prerequisite.id,
|
|
190
|
+
met: false,
|
|
191
|
+
reason,
|
|
192
|
+
newlySatisfied: false,
|
|
193
|
+
});
|
|
194
|
+
log(`preflight: ${prerequisite.id} unmet — ${reason}`);
|
|
195
|
+
continue;
|
|
196
|
+
}
|
|
197
|
+
if (run.exitCode !== 0) {
|
|
198
|
+
const tailed = tail(run.output, 1500).trim();
|
|
199
|
+
const reason = tailed !== ""
|
|
200
|
+
? tailed
|
|
201
|
+
: `the verify command exited ${run.exitCode} with no output`;
|
|
202
|
+
checks.push({
|
|
203
|
+
id: prerequisite.id,
|
|
204
|
+
met: false,
|
|
205
|
+
reason,
|
|
206
|
+
newlySatisfied: false,
|
|
207
|
+
});
|
|
208
|
+
log(`preflight: ${prerequisite.id} unmet — ${reason}`);
|
|
209
|
+
continue;
|
|
210
|
+
}
|
|
211
|
+
prerequisite.status = "satisfied";
|
|
212
|
+
checks.push({ id: prerequisite.id, met: true, newlySatisfied: true });
|
|
213
|
+
events.push({
|
|
214
|
+
kind: "prerequisite-verified",
|
|
215
|
+
at: now().toISOString(),
|
|
216
|
+
id: prerequisite.id,
|
|
217
|
+
verifyCommand: prerequisite.verifyCommand,
|
|
218
|
+
runId,
|
|
219
|
+
...(runStartCommit === undefined ? {} : { commit: runStartCommit }),
|
|
220
|
+
});
|
|
221
|
+
log(`preflight: ${prerequisite.id} satisfied`);
|
|
222
|
+
}
|
|
223
|
+
return { checks, events };
|
|
224
|
+
}
|
|
225
|
+
//# sourceMappingURL=preflight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"preflight.js","sourceRoot":"","sources":["../src/preflight.ts"],"names":[],"mappings":"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"}
|
package/dist/publish.d.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { type AgentRunner } from "./agent-runner.js";
|
|
2
|
+
import { type NightshiftConfig } from "./config.js";
|
|
1
3
|
/**
|
|
2
4
|
* The handover from a finished run to a reviewable pull request: pushes the
|
|
3
5
|
* program branch, opens or updates exactly one draft PR through `gh`,
|
|
@@ -53,6 +55,17 @@ export interface GhClient {
|
|
|
53
55
|
updateComment(cwd: string, commentId: string, body: string): Promise<void>;
|
|
54
56
|
/** Removes a now-stale nightshift-authored comment. */
|
|
55
57
|
deleteComment(cwd: string, commentId: string): Promise<void>;
|
|
58
|
+
/**
|
|
59
|
+
* GitHub's mergeability computation for a PR, as raw gh strings. `mergeable`
|
|
60
|
+
* is one of MERGEABLE | CONFLICTING | UNKNOWN; `mergeStateStatus` is the
|
|
61
|
+
* fuller state (CLEAN | DIRTY | BLOCKED | BEHIND | DRAFT | UNSTABLE |
|
|
62
|
+
* HAS_HOOKS | UNKNOWN). Normalization and the UNKNOWN retry live in
|
|
63
|
+
* `publish`, not here, so the boundary stays thin and the retry is testable.
|
|
64
|
+
*/
|
|
65
|
+
viewMergeability(cwd: string, prNumber: number): Promise<{
|
|
66
|
+
mergeable: string;
|
|
67
|
+
mergeStateStatus: string;
|
|
68
|
+
}>;
|
|
56
69
|
}
|
|
57
70
|
/**
|
|
58
71
|
* Git operations `publish` needs beyond `program-branch.ts`'s derivation —
|
|
@@ -65,6 +78,32 @@ export interface PublishGit {
|
|
|
65
78
|
/** Is the branch ahead of base? `git rev-list --count <base>..<branch>`. */
|
|
66
79
|
commitsAhead(cwd: string, base: string, branch: string): Promise<number>;
|
|
67
80
|
push(cwd: string, remote: string, branch: string): Promise<void>;
|
|
81
|
+
/**
|
|
82
|
+
* Fetches `branch` from `remote` so a subsequent merge sees its current
|
|
83
|
+
* tip, not whatever this checkout last saw at clone/checkout time.
|
|
84
|
+
*/
|
|
85
|
+
fetchBranch(cwd: string, remote: string, branch: string): Promise<void>;
|
|
86
|
+
/**
|
|
87
|
+
* Merges `ref` into the checked-out branch without committing
|
|
88
|
+
* (`git merge --no-commit --no-ff`). `"up-to-date"` means `ref` was
|
|
89
|
+
* already an ancestor of HEAD and nothing happened; `"merged"` means it
|
|
90
|
+
* merged cleanly and is staged, waiting for `commitMerge`; `"conflict"`
|
|
91
|
+
* means it left unmerged paths and the merge is still in progress.
|
|
92
|
+
*/
|
|
93
|
+
mergeNoCommit(cwd: string, ref: string): Promise<{
|
|
94
|
+
status: "up-to-date";
|
|
95
|
+
} | {
|
|
96
|
+
status: "merged";
|
|
97
|
+
} | {
|
|
98
|
+
status: "conflict";
|
|
99
|
+
paths: string[];
|
|
100
|
+
}>;
|
|
101
|
+
/** Aborts an in-progress merge, restoring the pre-merge working tree. */
|
|
102
|
+
abortMerge(cwd: string): Promise<void>;
|
|
103
|
+
/** Resolves one unmerged path to the checked-out branch's own side, and stages it. */
|
|
104
|
+
checkoutOurs(cwd: string, path: string): Promise<void>;
|
|
105
|
+
/** Commits a merge staged by `mergeNoCommit`/`checkoutOurs`. */
|
|
106
|
+
commitMerge(cwd: string, message: string): Promise<void>;
|
|
68
107
|
}
|
|
69
108
|
export declare const defaultPublishGit: PublishGit;
|
|
70
109
|
export declare const defaultGhClient: GhClient;
|
|
@@ -75,8 +114,32 @@ export interface PublishOptions {
|
|
|
75
114
|
gh?: GhClient;
|
|
76
115
|
/** Injected git boundary; default execFile-backed. */
|
|
77
116
|
git?: PublishGit;
|
|
117
|
+
/**
|
|
118
|
+
* Loaded internally via `loadConfig` when omitted, exactly like `run` and
|
|
119
|
+
* `author` load it in `cli.ts` — publish has no dedicated action of its
|
|
120
|
+
* own to load it first. Test seam only; production never needs to pass it.
|
|
121
|
+
*/
|
|
122
|
+
config?: NightshiftConfig;
|
|
123
|
+
/** Passed straight through to the pre-publish as-built refresh; default reviewer runner. */
|
|
124
|
+
agentRunner?: AgentRunner;
|
|
78
125
|
log?: (line: string) => void;
|
|
126
|
+
/** Injected for tests so the UNKNOWN retry does not actually wait. */
|
|
127
|
+
sleep?: (ms: number) => Promise<void>;
|
|
79
128
|
}
|
|
129
|
+
/** GitHub's answer to "does this PR merge cleanly into its base?" */
|
|
130
|
+
export type MergeableState = "mergeable" | "conflicting" | "unknown";
|
|
131
|
+
/** What the pre-publish base sync did. */
|
|
132
|
+
export type BaseSyncOutcome = {
|
|
133
|
+
status: "up-to-date";
|
|
134
|
+
} | {
|
|
135
|
+
status: "merged";
|
|
136
|
+
} | {
|
|
137
|
+
status: "conflict";
|
|
138
|
+
paths: string[];
|
|
139
|
+
} | {
|
|
140
|
+
status: "skipped";
|
|
141
|
+
reason: string;
|
|
142
|
+
};
|
|
80
143
|
export interface PublishResult {
|
|
81
144
|
prNumber: number;
|
|
82
145
|
prUrl: string;
|
|
@@ -85,7 +148,15 @@ export interface PublishResult {
|
|
|
85
148
|
escalationComments: number;
|
|
86
149
|
/** Report-continuation comments upserted this publish (0 when the report fits). */
|
|
87
150
|
continuationComments: number;
|
|
151
|
+
/** GitHub's mergeable state for the upserted PR (SC-07). */
|
|
152
|
+
mergeable: MergeableState;
|
|
153
|
+
/** What the pre-publish base sync did (SC-08). */
|
|
154
|
+
baseSync: BaseSyncOutcome;
|
|
88
155
|
}
|
|
156
|
+
/** The named `nightshift publish` / `nightshift run --publish` mergeability line (SC-07). */
|
|
157
|
+
export declare function mergeabilityLine(mergeable: MergeableState): string;
|
|
158
|
+
/** The named `nightshift publish` / `nightshift run --publish` base-sync line (SC-08). */
|
|
159
|
+
export declare function baseSyncLine(baseSync: BaseSyncOutcome): string;
|
|
89
160
|
interface ReportChunk {
|
|
90
161
|
/** A verbatim, contiguous slice of the report — never rewritten or decorated. */
|
|
91
162
|
payload: string;
|
package/dist/publish.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|