@wildorder/nightshift 0.5.0 → 0.7.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/LICENSE +21 -21
- package/dist/author.d.ts +13 -0
- package/dist/author.d.ts.map +1 -1
- package/dist/author.js +46 -13
- package/dist/author.js.map +1 -1
- package/dist/ci-init.d.ts +51 -0
- package/dist/ci-init.d.ts.map +1 -0
- package/dist/ci-init.js +274 -0
- package/dist/ci-init.js.map +1 -0
- package/dist/cli.js +99 -11
- package/dist/cli.js.map +1 -1
- package/dist/decide.d.ts +13 -5
- package/dist/decide.d.ts.map +1 -1
- package/dist/decide.js +50 -35
- package/dist/decide.js.map +1 -1
- package/dist/decider-review.d.ts +68 -1
- package/dist/decider-review.d.ts.map +1 -1
- package/dist/decider-review.js +211 -3
- package/dist/decider-review.js.map +1 -1
- package/dist/decision-ledger.d.ts +79 -1
- package/dist/decision-ledger.d.ts.map +1 -1
- package/dist/decision-ledger.js +118 -11
- package/dist/decision-ledger.js.map +1 -1
- package/dist/decision-view.d.ts +41 -0
- package/dist/decision-view.d.ts.map +1 -0
- package/dist/decision-view.js +264 -0
- package/dist/decision-view.js.map +1 -0
- package/dist/exit-codes.d.ts +44 -0
- package/dist/exit-codes.d.ts.map +1 -0
- package/dist/exit-codes.js +49 -0
- package/dist/exit-codes.js.map +1 -0
- package/dist/findings.d.ts +3 -0
- package/dist/findings.d.ts.map +1 -1
- package/dist/findings.js.map +1 -1
- package/dist/index.d.ts +7 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/manifest.d.ts +2 -2
- package/dist/program-branch.d.ts +65 -0
- package/dist/program-branch.d.ts.map +1 -0
- package/dist/program-branch.js +123 -0
- package/dist/program-branch.js.map +1 -0
- package/dist/programs-dir.d.ts +27 -0
- package/dist/programs-dir.d.ts.map +1 -0
- package/dist/programs-dir.js +52 -0
- package/dist/programs-dir.js.map +1 -0
- package/dist/publish.d.ts +105 -0
- package/dist/publish.d.ts.map +1 -0
- package/dist/publish.js +528 -0
- package/dist/publish.js.map +1 -0
- package/dist/report-path.d.ts +7 -0
- package/dist/report-path.d.ts.map +1 -0
- package/dist/report-path.js +10 -0
- package/dist/report-path.js.map +1 -0
- package/dist/review-pass.d.ts +33 -1
- package/dist/review-pass.d.ts.map +1 -1
- package/dist/review-pass.js +94 -42
- package/dist/review-pass.js.map +1 -1
- package/dist/run-program.d.ts +29 -3
- package/dist/run-program.d.ts.map +1 -1
- package/dist/run-program.js +431 -47
- package/dist/run-program.js.map +1 -1
- package/dist/run-publish.d.ts +41 -0
- package/dist/run-publish.d.ts.map +1 -0
- package/dist/run-publish.js +33 -0
- package/dist/run-publish.js.map +1 -0
- package/package.json +5 -4
- package/skills/plan-program/SKILL.md +14 -0
- package/templates/AGENTS.md +29 -29
- package/templates/CLAUDE.md +7 -7
- package/templates/vision.md +46 -46
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
import { execFile } from "node:child_process";
|
|
2
|
+
import { promisify } from "node:util";
|
|
3
|
+
const execFileAsync = promisify(execFile);
|
|
4
|
+
/**
|
|
5
|
+
* The fixed prefix for every program branch. Not a config key — the charter
|
|
6
|
+
* keeps tuning knobs off the config surface, and a second source of truth
|
|
7
|
+
* next to this function is exactly what this module exists to prevent.
|
|
8
|
+
*/
|
|
9
|
+
export const PROGRAM_BRANCH_PREFIX = "program/";
|
|
10
|
+
/**
|
|
11
|
+
* The one place a program ID becomes a branch name. The runner's
|
|
12
|
+
* preconditions and the branch command both call this; nothing else derives
|
|
13
|
+
* a branch name anywhere in the codebase.
|
|
14
|
+
*/
|
|
15
|
+
export function programBranchName(programId) {
|
|
16
|
+
return `${PROGRAM_BRANCH_PREFIX}${programId}`;
|
|
17
|
+
}
|
|
18
|
+
export const defaultProgramBranchGit = {
|
|
19
|
+
async isRepository(cwd) {
|
|
20
|
+
try {
|
|
21
|
+
await execFileAsync("git", ["rev-parse", "--is-inside-work-tree"], { cwd });
|
|
22
|
+
return true;
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
async currentBranch(cwd) {
|
|
29
|
+
try {
|
|
30
|
+
const { stdout } = await execFileAsync("git", ["symbolic-ref", "--quiet", "--short", "HEAD"], { cwd });
|
|
31
|
+
return stdout.trim();
|
|
32
|
+
}
|
|
33
|
+
catch {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
},
|
|
37
|
+
async localBranchExists(cwd, branch) {
|
|
38
|
+
try {
|
|
39
|
+
await execFileAsync("git", ["rev-parse", "--verify", "--quiet", `refs/heads/${branch}`], { cwd });
|
|
40
|
+
return true;
|
|
41
|
+
}
|
|
42
|
+
catch {
|
|
43
|
+
return false;
|
|
44
|
+
}
|
|
45
|
+
},
|
|
46
|
+
async originHeadBranch(cwd) {
|
|
47
|
+
try {
|
|
48
|
+
const { stdout } = await execFileAsync("git", ["symbolic-ref", "--quiet", "--short", "refs/remotes/origin/HEAD"], { cwd });
|
|
49
|
+
const ref = stdout.trim();
|
|
50
|
+
return ref.startsWith("origin/") ? ref.slice("origin/".length) : ref;
|
|
51
|
+
}
|
|
52
|
+
catch {
|
|
53
|
+
return undefined;
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
async configDefaultBranch(cwd) {
|
|
57
|
+
try {
|
|
58
|
+
const { stdout } = await execFileAsync("git", ["config", "--get", "init.defaultBranch"], { cwd });
|
|
59
|
+
const value = stdout.trim();
|
|
60
|
+
return value === "" ? undefined : value;
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
},
|
|
66
|
+
async switchTo(cwd, branch) {
|
|
67
|
+
await execFileAsync("git", ["switch", branch], { cwd });
|
|
68
|
+
},
|
|
69
|
+
async createAndSwitch(cwd, branch) {
|
|
70
|
+
await execFileAsync("git", ["switch", "-c", branch], { cwd });
|
|
71
|
+
},
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Creates a program's branch and switches to it, or switches to it when a
|
|
75
|
+
* prior run already made it, and reports which. Never discards uncommitted
|
|
76
|
+
* work: creating carries the working tree onto the new branch, and switching
|
|
77
|
+
* to an existing branch with conflicting local changes surfaces git's own
|
|
78
|
+
* refusal rather than overriding it.
|
|
79
|
+
*/
|
|
80
|
+
export async function createOrSwitchProgramBranch(programId, options) {
|
|
81
|
+
const cwd = options?.cwd ?? process.cwd();
|
|
82
|
+
const git = options?.git ?? defaultProgramBranchGit;
|
|
83
|
+
const branch = programBranchName(programId);
|
|
84
|
+
if (!(await git.isRepository(cwd))) {
|
|
85
|
+
throw new Error(`${cwd} is not a git repository; run \`git init\` or plan from inside your repository.`);
|
|
86
|
+
}
|
|
87
|
+
const current = await git.currentBranch(cwd);
|
|
88
|
+
if (current === undefined) {
|
|
89
|
+
throw new Error("HEAD is detached; check out your default branch, then re-run.");
|
|
90
|
+
}
|
|
91
|
+
if (await git.localBranchExists(cwd, branch)) {
|
|
92
|
+
await git.switchTo(cwd, branch);
|
|
93
|
+
return { action: "switched", branch };
|
|
94
|
+
}
|
|
95
|
+
await git.createAndSwitch(cwd, branch);
|
|
96
|
+
return { action: "created", branch };
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* Resolves the repository's default branch name, in order: `origin/HEAD`,
|
|
100
|
+
* then the first of `main`/`master` that exists locally, then
|
|
101
|
+
* `init.defaultBranch`, then `"main"`.
|
|
102
|
+
*
|
|
103
|
+
* This is a heuristic, not a guarantee. It is authoritative when
|
|
104
|
+
* `origin/HEAD` is set and correct for the common `main`/`master` local
|
|
105
|
+
* repositories, but it cannot identify a custom default (say `trunk`) with
|
|
106
|
+
* neither `origin/HEAD` nor a matching `init.defaultBranch` — it will return
|
|
107
|
+
* `main` in that case. This does not create a safety hole: the run
|
|
108
|
+
* preconditions in `run-program.ts` never rely on this alone. If this
|
|
109
|
+
* function misnames the default, the wrong-branch precondition still refuses
|
|
110
|
+
* a run on any branch that is not the one derived from the program ID; only
|
|
111
|
+
* the specificity of the refusal message degrades.
|
|
112
|
+
*/
|
|
113
|
+
export async function detectDefaultBranch(cwd, git = defaultProgramBranchGit) {
|
|
114
|
+
const originHead = await git.originHeadBranch(cwd);
|
|
115
|
+
if (originHead !== undefined)
|
|
116
|
+
return originHead;
|
|
117
|
+
for (const candidate of ["main", "master"]) {
|
|
118
|
+
if (await git.localBranchExists(cwd, candidate))
|
|
119
|
+
return candidate;
|
|
120
|
+
}
|
|
121
|
+
return (await git.configDefaultBranch(cwd)) ?? "main";
|
|
122
|
+
}
|
|
123
|
+
//# sourceMappingURL=program-branch.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"program-branch.js","sourceRoot":"","sources":["../src/program-branch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `docs/programs` — the runner's own bookkeeping: the manifest, the append-only
|
|
3
|
+
* decision ledger, and the run report. Nothing an agent is asked to build ever
|
|
4
|
+
* lives here, which is why `diffSince` excludes it from every diff a reviewer
|
|
5
|
+
* or decider sees.
|
|
6
|
+
*
|
|
7
|
+
* It is also the one directory a `git reset --hard` must never take with it.
|
|
8
|
+
* Both rollback seams — `decide`'s replay and the runner's failed-fix reset —
|
|
9
|
+
* roll *code* back to an anchor commit while the journal explaining why must
|
|
10
|
+
* survive: the ledger is append-only by contract, and a rollback that
|
|
11
|
+
* truncated it would erase the very record the human is meant to rule on.
|
|
12
|
+
* Snapshot before the reset, restore after.
|
|
13
|
+
*/
|
|
14
|
+
export declare const PROGRAMS_DIR: string;
|
|
15
|
+
export interface FileSnapshot {
|
|
16
|
+
relPath: string;
|
|
17
|
+
content: Buffer;
|
|
18
|
+
}
|
|
19
|
+
/** Every file under `docs/programs`, in memory. A missing directory is an empty snapshot. */
|
|
20
|
+
export declare function snapshotProgramsDir(root: string): Promise<FileSnapshot[]>;
|
|
21
|
+
/**
|
|
22
|
+
* Write a snapshot back. Purely additive: a file the reset removed is
|
|
23
|
+
* restored, a file written after the snapshot is left alone — nothing under
|
|
24
|
+
* `docs/programs` is ever deleted here.
|
|
25
|
+
*/
|
|
26
|
+
export declare function restoreProgramsDir(root: string, snapshot: FileSnapshot[]): Promise<void>;
|
|
27
|
+
//# sourceMappingURL=programs-dir.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"programs-dir.d.ts","sourceRoot":"","sources":["../src/programs-dir.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;GAYG;AAEH,eAAO,MAAM,YAAY,QAA2B,CAAC;AAErD,MAAM,WAAW,YAAY;IAC3B,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,6FAA6F;AAC7F,wBAAsB,mBAAmB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,EAAE,CAAC,CAmB/E;AAED;;;;GAIG;AACH,wBAAsB,kBAAkB,CACtC,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,YAAY,EAAE,GACvB,OAAO,CAAC,IAAI,CAAC,CAMf"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import { mkdir, readFile, readdir, stat, writeFile } from "node:fs/promises";
|
|
2
|
+
import { dirname, join, relative } from "node:path";
|
|
3
|
+
/**
|
|
4
|
+
* `docs/programs` — the runner's own bookkeeping: the manifest, the append-only
|
|
5
|
+
* decision ledger, and the run report. Nothing an agent is asked to build ever
|
|
6
|
+
* lives here, which is why `diffSince` excludes it from every diff a reviewer
|
|
7
|
+
* or decider sees.
|
|
8
|
+
*
|
|
9
|
+
* It is also the one directory a `git reset --hard` must never take with it.
|
|
10
|
+
* Both rollback seams — `decide`'s replay and the runner's failed-fix reset —
|
|
11
|
+
* roll *code* back to an anchor commit while the journal explaining why must
|
|
12
|
+
* survive: the ledger is append-only by contract, and a rollback that
|
|
13
|
+
* truncated it would erase the very record the human is meant to rule on.
|
|
14
|
+
* Snapshot before the reset, restore after.
|
|
15
|
+
*/
|
|
16
|
+
export const PROGRAMS_DIR = join("docs", "programs");
|
|
17
|
+
/** Every file under `docs/programs`, in memory. A missing directory is an empty snapshot. */
|
|
18
|
+
export async function snapshotProgramsDir(root) {
|
|
19
|
+
const dir = join(root, PROGRAMS_DIR);
|
|
20
|
+
let entries;
|
|
21
|
+
try {
|
|
22
|
+
entries = await readdir(dir, { recursive: true });
|
|
23
|
+
}
|
|
24
|
+
catch {
|
|
25
|
+
return [];
|
|
26
|
+
}
|
|
27
|
+
const snapshots = [];
|
|
28
|
+
for (const entry of entries) {
|
|
29
|
+
const full = join(dir, entry);
|
|
30
|
+
const info = await stat(full);
|
|
31
|
+
if (!info.isFile())
|
|
32
|
+
continue;
|
|
33
|
+
snapshots.push({
|
|
34
|
+
relPath: relative(root, full),
|
|
35
|
+
content: await readFile(full),
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
return snapshots;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Write a snapshot back. Purely additive: a file the reset removed is
|
|
42
|
+
* restored, a file written after the snapshot is left alone — nothing under
|
|
43
|
+
* `docs/programs` is ever deleted here.
|
|
44
|
+
*/
|
|
45
|
+
export async function restoreProgramsDir(root, snapshot) {
|
|
46
|
+
for (const file of snapshot) {
|
|
47
|
+
const full = join(root, file.relPath);
|
|
48
|
+
await mkdir(dirname(full), { recursive: true });
|
|
49
|
+
await writeFile(full, file.content);
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=programs-dir.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"programs-dir.js","sourceRoot":"","sources":["../src/programs-dir.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,OAAO,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAC7E,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAEpD;;;;;;;;;;;;GAYG;AAEH,MAAM,CAAC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;AAOrD,6FAA6F;AAC7F,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,IAAY;IACpD,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACrC,IAAI,OAAiB,CAAC;IACtB,IAAI,CAAC;QACH,OAAO,GAAG,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;IACD,MAAM,SAAS,GAAmB,EAAE,CAAC;IACrC,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;QAC9B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE;YAAE,SAAS;QAC7B,SAAS,CAAC,IAAI,CAAC;YACb,OAAO,EAAE,QAAQ,CAAC,IAAI,EAAE,IAAI,CAAC;YAC7B,OAAO,EAAE,MAAM,QAAQ,CAAC,IAAI,CAAC;SAC9B,CAAC,CAAC;IACL,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,IAAY,EACZ,QAAwB;IAExB,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;QACtC,MAAM,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAChD,MAAM,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACtC,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The handover from a finished run to a reviewable pull request: pushes the
|
|
3
|
+
* program branch, opens or updates exactly one draft PR through `gh`,
|
|
4
|
+
* renders the run report as its body (continuing oversized reports into
|
|
5
|
+
* comments), and upserts one comment per escalated decision. Idempotent —
|
|
6
|
+
* re-publishing edits the existing PR and its comments rather than
|
|
7
|
+
* duplicating them.
|
|
8
|
+
*
|
|
9
|
+
* `publish` is deliberately separate from `runProgram`: the runner owns
|
|
10
|
+
* commits and knows nothing about forges, and this command owns the forge
|
|
11
|
+
* and knows nothing about building. Authentication is entirely `gh`'s job —
|
|
12
|
+
* nightshift never reads, stores, or passes a token.
|
|
13
|
+
*/
|
|
14
|
+
export declare const GITHUB_PR_BODY_LIMIT = 65536;
|
|
15
|
+
export interface GhComment {
|
|
16
|
+
/** The forge's own comment id, opaque; used to edit or delete it. */
|
|
17
|
+
id: string;
|
|
18
|
+
body: string;
|
|
19
|
+
}
|
|
20
|
+
export interface GhPullRequest {
|
|
21
|
+
number: number;
|
|
22
|
+
url: string;
|
|
23
|
+
/** open | closed | merged — so publish can tell a live handover from history. */
|
|
24
|
+
state: "open" | "closed" | "merged";
|
|
25
|
+
/** Whether the PR is still a draft; asserted by the SC-06 test. */
|
|
26
|
+
isDraft: boolean;
|
|
27
|
+
}
|
|
28
|
+
export interface GhClient {
|
|
29
|
+
/**
|
|
30
|
+
* Preflight: succeeds when `gh` is installed and authenticated, and throws
|
|
31
|
+
* the actionable "not installed" / "not authenticated" errors otherwise.
|
|
32
|
+
* Called once at the very start of publish, before any push or PR work.
|
|
33
|
+
*/
|
|
34
|
+
checkAuth(cwd: string): Promise<void>;
|
|
35
|
+
/**
|
|
36
|
+
* The open PR whose head is this branch, or undefined. Returns only an
|
|
37
|
+
* OPEN PR — a closed or merged PR for the branch is history, not the live
|
|
38
|
+
* handover. Never returns two: GitHub permits at most one open PR per
|
|
39
|
+
* head->base pair.
|
|
40
|
+
*/
|
|
41
|
+
findOpenPullRequest(cwd: string, headBranch: string): Promise<GhPullRequest | undefined>;
|
|
42
|
+
/** Opens a draft PR; returns its number, url, state, and draft flag. */
|
|
43
|
+
createDraftPullRequest(cwd: string, input: {
|
|
44
|
+
headBranch: string;
|
|
45
|
+
baseBranch: string;
|
|
46
|
+
title: string;
|
|
47
|
+
body: string;
|
|
48
|
+
}): Promise<GhPullRequest>;
|
|
49
|
+
/** Rewrites the body of an existing PR; does not change its draft/ready state. */
|
|
50
|
+
updatePullRequestBody(cwd: string, number: number, body: string): Promise<void>;
|
|
51
|
+
listComments(cwd: string, number: number): Promise<GhComment[]>;
|
|
52
|
+
createComment(cwd: string, number: number, body: string): Promise<void>;
|
|
53
|
+
updateComment(cwd: string, commentId: string, body: string): Promise<void>;
|
|
54
|
+
/** Removes a now-stale nightshift-authored comment. */
|
|
55
|
+
deleteComment(cwd: string, commentId: string): Promise<void>;
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Git operations `publish` needs beyond `program-branch.ts`'s derivation —
|
|
59
|
+
* kept local to this module, mirroring `ProgramBranchGit`, so the runner's
|
|
60
|
+
* `GitOps` stays about building, not remotes.
|
|
61
|
+
*/
|
|
62
|
+
export interface PublishGit {
|
|
63
|
+
/** The branch HEAD points at, for the provenance check; `git rev-parse --abbrev-ref HEAD`. */
|
|
64
|
+
currentBranch(cwd: string): Promise<string>;
|
|
65
|
+
/** Is the branch ahead of base? `git rev-list --count <base>..<branch>`. */
|
|
66
|
+
commitsAhead(cwd: string, base: string, branch: string): Promise<number>;
|
|
67
|
+
push(cwd: string, remote: string, branch: string): Promise<void>;
|
|
68
|
+
}
|
|
69
|
+
export declare const defaultPublishGit: PublishGit;
|
|
70
|
+
export declare const defaultGhClient: GhClient;
|
|
71
|
+
export interface PublishOptions {
|
|
72
|
+
cwd: string;
|
|
73
|
+
programId: string;
|
|
74
|
+
/** Injected GitHub boundary; default spawns `gh`. */
|
|
75
|
+
gh?: GhClient;
|
|
76
|
+
/** Injected git boundary; default execFile-backed. */
|
|
77
|
+
git?: PublishGit;
|
|
78
|
+
log?: (line: string) => void;
|
|
79
|
+
}
|
|
80
|
+
export interface PublishResult {
|
|
81
|
+
prNumber: number;
|
|
82
|
+
prUrl: string;
|
|
83
|
+
action: "created" | "updated";
|
|
84
|
+
/** Escalation comments upserted this publish. */
|
|
85
|
+
escalationComments: number;
|
|
86
|
+
/** Report-continuation comments upserted this publish (0 when the report fits). */
|
|
87
|
+
continuationComments: number;
|
|
88
|
+
}
|
|
89
|
+
interface ReportChunk {
|
|
90
|
+
/** A verbatim, contiguous slice of the report — never rewritten or decorated. */
|
|
91
|
+
payload: string;
|
|
92
|
+
/** True when this chunk's payload ends mid-section (the degenerate fallback). */
|
|
93
|
+
cutMidSection: boolean;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Splits the run report into chunks whose payloads are verbatim, contiguous
|
|
97
|
+
* slices of the report — concatenating every payload in order reproduces the
|
|
98
|
+
* report byte-for-byte. A report that fits under the limit is a single
|
|
99
|
+
* chunk; an oversized report is packed on section boundaries, falling back
|
|
100
|
+
* to paragraph/character boundaries only for a section too large on its own.
|
|
101
|
+
*/
|
|
102
|
+
export declare function splitReportIntoChunks(report: string): ReportChunk[];
|
|
103
|
+
export declare function publish(options: PublishOptions): Promise<PublishResult>;
|
|
104
|
+
export {};
|
|
105
|
+
//# sourceMappingURL=publish.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
|