@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.
Files changed (90) hide show
  1. package/README.md +46 -19
  2. package/dist/agent-probe.d.ts +21 -2
  3. package/dist/agent-probe.d.ts.map +1 -1
  4. package/dist/agent-probe.js +76 -22
  5. package/dist/agent-probe.js.map +1 -1
  6. package/dist/agent-runner.d.ts +90 -2
  7. package/dist/agent-runner.d.ts.map +1 -1
  8. package/dist/agent-runner.js +382 -24
  9. package/dist/agent-runner.js.map +1 -1
  10. package/dist/agent-summary.d.ts +15 -0
  11. package/dist/agent-summary.d.ts.map +1 -1
  12. package/dist/agent-summary.js +32 -2
  13. package/dist/agent-summary.js.map +1 -1
  14. package/dist/as-built.d.ts +6 -0
  15. package/dist/as-built.d.ts.map +1 -1
  16. package/dist/as-built.js +7 -0
  17. package/dist/as-built.js.map +1 -1
  18. package/dist/author.d.ts +9 -0
  19. package/dist/author.d.ts.map +1 -1
  20. package/dist/author.js +161 -24
  21. package/dist/author.js.map +1 -1
  22. package/dist/ci-init.d.ts.map +1 -1
  23. package/dist/ci-init.js +17 -12
  24. package/dist/ci-init.js.map +1 -1
  25. package/dist/cli.js +144 -11
  26. package/dist/cli.js.map +1 -1
  27. package/dist/config.d.ts +11 -0
  28. package/dist/config.d.ts.map +1 -1
  29. package/dist/config.js +13 -0
  30. package/dist/config.js.map +1 -1
  31. package/dist/crash-report.d.ts +58 -0
  32. package/dist/crash-report.d.ts.map +1 -0
  33. package/dist/crash-report.js +115 -0
  34. package/dist/crash-report.js.map +1 -0
  35. package/dist/decide.js +1 -1
  36. package/dist/decide.js.map +1 -1
  37. package/dist/decider-review.d.ts +33 -5
  38. package/dist/decider-review.d.ts.map +1 -1
  39. package/dist/decider-review.js +55 -9
  40. package/dist/decider-review.js.map +1 -1
  41. package/dist/decision-ledger.d.ts +54 -1
  42. package/dist/decision-ledger.d.ts.map +1 -1
  43. package/dist/decision-ledger.js +53 -1
  44. package/dist/decision-ledger.js.map +1 -1
  45. package/dist/decision-view.d.ts +10 -1
  46. package/dist/decision-view.d.ts.map +1 -1
  47. package/dist/decision-view.js +41 -0
  48. package/dist/decision-view.js.map +1 -1
  49. package/dist/exit-codes.d.ts +16 -2
  50. package/dist/exit-codes.d.ts.map +1 -1
  51. package/dist/exit-codes.js +17 -2
  52. package/dist/exit-codes.js.map +1 -1
  53. package/dist/index.d.ts +1 -0
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +1 -0
  56. package/dist/index.js.map +1 -1
  57. package/dist/manifest.d.ts +68 -14
  58. package/dist/manifest.d.ts.map +1 -1
  59. package/dist/manifest.js +301 -22
  60. package/dist/manifest.js.map +1 -1
  61. package/dist/permits.d.ts +135 -0
  62. package/dist/permits.d.ts.map +1 -0
  63. package/dist/permits.js +397 -0
  64. package/dist/permits.js.map +1 -0
  65. package/dist/preflight.d.ts +73 -0
  66. package/dist/preflight.d.ts.map +1 -0
  67. package/dist/preflight.js +225 -0
  68. package/dist/preflight.js.map +1 -0
  69. package/dist/publish.d.ts +71 -0
  70. package/dist/publish.d.ts.map +1 -1
  71. package/dist/publish.js +319 -1
  72. package/dist/publish.js.map +1 -1
  73. package/dist/run-program.d.ts +70 -2
  74. package/dist/run-program.d.ts.map +1 -1
  75. package/dist/run-program.js +677 -60
  76. package/dist/run-program.js.map +1 -1
  77. package/dist/skill-roots.d.ts +11 -3
  78. package/dist/skill-roots.d.ts.map +1 -1
  79. package/dist/skill-roots.js +59 -12
  80. package/dist/skill-roots.js.map +1 -1
  81. package/dist/whole-program-review.d.ts +4 -0
  82. package/dist/whole-program-review.d.ts.map +1 -1
  83. package/dist/whole-program-review.js +9 -1
  84. package/dist/whole-program-review.js.map +1 -1
  85. package/package.json +2 -2
  86. package/skills/plan-program/SKILL.md +125 -5
  87. package/dist/verify-allowlist.d.ts +0 -23
  88. package/dist/verify-allowlist.d.ts.map +0 -1
  89. package/dist/verify-allowlist.js +0 -46
  90. 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;
@@ -1 +1 @@
1
- {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"publish.d.ts","sourceRoot":"","sources":["../src/publish.ts"],"names":[],"mappings":"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"}