@popoverai/dotrequirements 0.36.1 → 0.37.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/commands/solution/brief.d.ts +0 -2
- package/dist/commands/solution/index.js +7 -23
- package/dist/commands/solution/pull-request.d.ts +3 -13
- package/dist/commands/solution/pull-request.js +17 -72
- package/dist/commands/solution/status.js +1 -5
- package/dist/convex.d.ts +0 -3
- package/dist/convex.js +0 -3
- package/package.json +1 -1
|
@@ -54,8 +54,6 @@ export type PanelOutcome = {
|
|
|
54
54
|
agent: string;
|
|
55
55
|
part: "draft" | "review";
|
|
56
56
|
}>;
|
|
57
|
-
/** The reviewers waiting on its pull request, their sessions ended (PULL-5). */
|
|
58
|
-
waiting?: string[];
|
|
59
57
|
};
|
|
60
58
|
/** A checkpoint on the plan panel, as far as the CLI reads it. */
|
|
61
59
|
export type PanelCheckpoint = {
|
|
@@ -7,7 +7,7 @@ import { REQUEST_CONTRACT } from "./contract.js";
|
|
|
7
7
|
import { createCommand } from "./create.js";
|
|
8
8
|
import { thingsCommand } from "./look-up.js";
|
|
9
9
|
import { nextCommand } from "./next.js";
|
|
10
|
-
import { prStatusCommand,
|
|
10
|
+
import { prStatusCommand, pullRequestCommand } from "./pull-request.js";
|
|
11
11
|
import { rehearseCommand } from "./rehearse.js";
|
|
12
12
|
import { reviewCommand } from "./review.js";
|
|
13
13
|
import { doneCommand } from "./share.js";
|
|
@@ -97,22 +97,11 @@ const PR_STATUS_HELP = `
|
|
|
97
97
|
Reads the pull request of the outcome you are at, or of the outcome it awaits that
|
|
98
98
|
is kept on one, as GitHub reports it. The merge state is GitHub's word for whether
|
|
99
99
|
it can merge: clean means it can, with every required check passing and no
|
|
100
|
-
conflict. Failed checks come with a link to them
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
For a reviewer, while the pull request's checks run or GitHub works out whether it
|
|
106
|
-
can merge. Records where it stands now; then end your session without a result.
|
|
107
|
-
You are started again, in this session, once GitHub reports it clean, once it is
|
|
108
|
-
merged or closed, or when the wait is up: ten minutes unless you say, up to an
|
|
109
|
-
hour. A conflict, a failed check or a branch behind doesn't change by waiting:
|
|
110
|
-
judge it now. A new submission ends the wait too, and you review that as you
|
|
111
|
-
would any other.
|
|
112
|
-
|
|
113
|
-
Examples:
|
|
114
|
-
dotreq solution pr wait
|
|
115
|
-
dotreq solution pr wait 30m
|
|
100
|
+
conflict. Failed checks come with a link to them and what they reported, as GitHub
|
|
101
|
+
gives it: their output and annotations, or the end of their job's log. Checks still
|
|
102
|
+
running are named. Each review follows, with its verdict and its comments, from the
|
|
103
|
+
repository's owners, members and collaborators and the apps installed on it; those
|
|
104
|
+
by anyone else are left out and counted. Reading it changes nothing.
|
|
116
105
|
`;
|
|
117
106
|
/** What `pr open` does, on its `--help`, where `author --help` sends the agent (PULL-2). */
|
|
118
107
|
const PULL_REQUEST_HELP = `
|
|
@@ -249,7 +238,7 @@ export function registerSolution(program) {
|
|
|
249
238
|
.action(wrap(authorCommand));
|
|
250
239
|
const pr = solution
|
|
251
240
|
.command("pr", HIDDEN)
|
|
252
|
-
.description("The solution's pull request: open it, read it
|
|
241
|
+
.description("The solution's pull request: open it, read it");
|
|
253
242
|
whereOptions(pr
|
|
254
243
|
.command("open")
|
|
255
244
|
.description("Push the solution's branch and open its pull request, or find the one open; prints its reference, pr:<number>, to submit"))
|
|
@@ -261,11 +250,6 @@ export function registerSolution(program) {
|
|
|
261
250
|
.option("--json", "Print as JSON")
|
|
262
251
|
.addHelpText("after", PR_STATUS_HELP)
|
|
263
252
|
.action(wrap(prStatusCommand));
|
|
264
|
-
whereOptions(pr
|
|
265
|
-
.command("wait [duration]")
|
|
266
|
-
.description("Wait on the pull request with your session ended, for ten minutes unless you say (as 5m or 1h, up to an hour): you start again once it is clean, merged or closed, or when the time is up"))
|
|
267
|
-
.addHelpText("after", PR_WAIT_HELP)
|
|
268
|
-
.action(wrap(prWaitCommand));
|
|
269
253
|
whereOptions(solution
|
|
270
254
|
.command("review <result> [video...]", HIDDEN)
|
|
271
255
|
.description("Record the review's result: approved, approved-with-revisions or needs-revision"))
|
|
@@ -18,15 +18,16 @@ export type PullRequestState = {
|
|
|
18
18
|
name: string;
|
|
19
19
|
result: string;
|
|
20
20
|
link: string | null;
|
|
21
|
+
/** What the check reported, as GitHub gave it, or why it couldn't (PULL-4.7). */
|
|
22
|
+
reported?: unknown;
|
|
21
23
|
}>;
|
|
22
24
|
running: Array<{
|
|
23
25
|
name: string;
|
|
24
26
|
link: string | null;
|
|
25
27
|
}>;
|
|
26
28
|
head: string;
|
|
29
|
+
reviews?: unknown;
|
|
27
30
|
};
|
|
28
|
-
/** Where the pull request stood, in words, as a wait records it beside what the line shows (PULL-5.1.0). */
|
|
29
|
-
export declare function seenOf(state: PullRequestState): string;
|
|
30
31
|
/** Where the pull request stands, as a reviewer reads it (PULL-4). */
|
|
31
32
|
export declare function describeState(state: PullRequestState): string;
|
|
32
33
|
/**
|
|
@@ -36,17 +37,6 @@ export declare function describeState(state: PullRequestState): string;
|
|
|
36
37
|
export declare function prStatusCommand(options: WhereOptions & {
|
|
37
38
|
json?: boolean;
|
|
38
39
|
}): Promise<void>;
|
|
39
|
-
/** A wait's length as an agent types it, `90s`, `5m` or `1h`, in milliseconds; refused past an hour or at none (PULL-5.8 to 5.10). */
|
|
40
|
-
export declare function waitFor(duration: string | undefined): number;
|
|
41
|
-
/**
|
|
42
|
-
* `dotreq solution pr wait [duration]`: the reviewer waits on the pull
|
|
43
|
-
* request with no session running (PULL-5), ten minutes unless it says, up
|
|
44
|
-
* to an hour: it records what it saw, and its session can end without a
|
|
45
|
-
* result. It starts again, in the same session, once the pull request is
|
|
46
|
-
* `clean`, once it is merged or closed, or when the wait is up (PULL-6). A
|
|
47
|
-
* pull request already `clean` needs no wait (5.11).
|
|
48
|
-
*/
|
|
49
|
-
export declare function prWaitCommand(duration: string | undefined, options: WhereOptions): Promise<void>;
|
|
50
40
|
/**
|
|
51
41
|
* `dotreq solution pr open`: the solution's pull request, opened or
|
|
52
42
|
* found (PULL-2). Inside a runner the branch is pushed first, as a submission
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import { webApiUrl } from "../../cloud.js";
|
|
2
|
-
import { api } from "../../convex.js";
|
|
3
2
|
import { getProjectCredentials } from "../../utils/project-settings.js";
|
|
4
3
|
import { solutionClient } from "./client.js";
|
|
5
4
|
import { pushWork } from "./pushing.js";
|
|
@@ -7,16 +6,6 @@ import { requireWhere } from "./run-file.js";
|
|
|
7
6
|
import { outcomeFor } from "./status.js";
|
|
8
7
|
/** The command that opens the solution's pull request and prints its reference. */
|
|
9
8
|
export const OPEN_IT = "dotreq solution pr open";
|
|
10
|
-
/** Where the pull request stood, in words, as a wait records it beside what the line shows (PULL-5.1.0). */
|
|
11
|
-
export function seenOf(state) {
|
|
12
|
-
return [
|
|
13
|
-
state.head,
|
|
14
|
-
state.mergeState,
|
|
15
|
-
state.mergeable,
|
|
16
|
-
state.reviewDecision ?? "",
|
|
17
|
-
state.checks ?? "",
|
|
18
|
-
].join(" ");
|
|
19
|
-
}
|
|
20
9
|
/** The pull request the outcome the agent is at reads, as the app finds it (PULL-4.0, 4.0.0). */
|
|
21
10
|
async function stateFor(where) {
|
|
22
11
|
const said = await ask({
|
|
@@ -38,7 +27,14 @@ async function stateFor(where) {
|
|
|
38
27
|
}
|
|
39
28
|
if (!said.state)
|
|
40
29
|
throw new Error("The app gave no pull request.");
|
|
41
|
-
return said.
|
|
30
|
+
return said.reviews === undefined
|
|
31
|
+
? said.state
|
|
32
|
+
: { ...said.state, reviews: said.reviews };
|
|
33
|
+
}
|
|
34
|
+
/** What GitHub reported, as it gave it, indented under the line it belongs to. */
|
|
35
|
+
function asGiven(reported, indent) {
|
|
36
|
+
const text = typeof reported === "string" ? reported : JSON.stringify(reported, null, 2);
|
|
37
|
+
return text.split("\n").map((line) => `${indent}${line}`);
|
|
42
38
|
}
|
|
43
39
|
/** Where the pull request stands, as a reviewer reads it (PULL-4). */
|
|
44
40
|
export function describeState(state) {
|
|
@@ -51,13 +47,21 @@ export function describeState(state) {
|
|
|
51
47
|
];
|
|
52
48
|
for (const check of state.failed) {
|
|
53
49
|
lines.push(` failed: ${check.name} (${check.result})${check.link ? ` ${check.link}` : ""}`);
|
|
50
|
+
// PULL-4.7: what it reported, as GitHub gave it.
|
|
51
|
+
if (check.reported !== undefined) {
|
|
52
|
+
lines.push(" It reported:", ...asGiven(check.reported, " "));
|
|
53
|
+
}
|
|
54
54
|
}
|
|
55
55
|
for (const check of state.running) {
|
|
56
56
|
lines.push(` still running: ${check.name}${check.link ? ` ${check.link}` : ""}`);
|
|
57
57
|
}
|
|
58
58
|
if (state.mergeable === "unknown") {
|
|
59
59
|
// PULL-4.3.
|
|
60
|
-
lines.push("GitHub hasn't yet worked out whether it can merge: read it again shortly
|
|
60
|
+
lines.push("GitHub hasn't yet worked out whether it can merge: read it again shortly.");
|
|
61
|
+
}
|
|
62
|
+
// PULL-4.8: each review, with its verdict and its comments.
|
|
63
|
+
if (state.reviews !== undefined) {
|
|
64
|
+
lines.push("Reviews and their comments, as GitHub gave them:", ...asGiven(state.reviews, " "));
|
|
61
65
|
}
|
|
62
66
|
return lines.join("\n");
|
|
63
67
|
}
|
|
@@ -69,65 +73,6 @@ export async function prStatusCommand(options) {
|
|
|
69
73
|
const state = await stateFor(requireWhere(options));
|
|
70
74
|
console.log(options.json ? JSON.stringify(state) : describeState(state));
|
|
71
75
|
}
|
|
72
|
-
/** What a reviewer is told when it asks for a wait it can't have (PULL-5.10), in the backend's words. */
|
|
73
|
-
const WAIT_REFUSED = "Nothing is waiting: a wait is up to an hour, ten minutes unless you say, as `dotreq solution pr wait 5m` or `pr wait 1h`.";
|
|
74
|
-
/** A wait's length as an agent types it, `90s`, `5m` or `1h`, in milliseconds; refused past an hour or at none (PULL-5.8 to 5.10). */
|
|
75
|
-
export function waitFor(duration) {
|
|
76
|
-
if (duration === undefined)
|
|
77
|
-
return 10 * 60 * 1000;
|
|
78
|
-
const found = /^(\d+)(s|m|h)$/.exec(duration.trim());
|
|
79
|
-
const unit = { s: 1000, m: 60 * 1000, h: 60 * 60 * 1000 };
|
|
80
|
-
const ms = found ? Number(found[1]) * unit[found[2]] : 0;
|
|
81
|
-
if (!(ms > 0 && ms <= 60 * 60 * 1000))
|
|
82
|
-
throw new Error(WAIT_REFUSED);
|
|
83
|
-
return ms;
|
|
84
|
-
}
|
|
85
|
-
/** In words, how long a wait is. */
|
|
86
|
-
function forHowLong(ms) {
|
|
87
|
-
if (ms === 3_600_000)
|
|
88
|
-
return "an hour";
|
|
89
|
-
if (ms % 60_000 !== 0) {
|
|
90
|
-
const seconds = Math.round(ms / 1000);
|
|
91
|
-
return `${seconds} second${seconds === 1 ? "" : "s"}`;
|
|
92
|
-
}
|
|
93
|
-
const minutes = ms / 60_000;
|
|
94
|
-
return `${minutes} minute${minutes === 1 ? "" : "s"}`;
|
|
95
|
-
}
|
|
96
|
-
/**
|
|
97
|
-
* `dotreq solution pr wait [duration]`: the reviewer waits on the pull
|
|
98
|
-
* request with no session running (PULL-5), ten minutes unless it says, up
|
|
99
|
-
* to an hour: it records what it saw, and its session can end without a
|
|
100
|
-
* result. It starts again, in the same session, once the pull request is
|
|
101
|
-
* `clean`, once it is merged or closed, or when the wait is up (PULL-6). A
|
|
102
|
-
* pull request already `clean` needs no wait (5.11).
|
|
103
|
-
*/
|
|
104
|
-
export async function prWaitCommand(duration, options) {
|
|
105
|
-
const forMs = waitFor(duration);
|
|
106
|
-
const where = requireWhere(options);
|
|
107
|
-
const state = await stateFor(where);
|
|
108
|
-
if (state.mergeState === "clean") {
|
|
109
|
-
throw new Error(`Nothing is waiting: the pull request is already \`clean\`.\n\n${describeState(state)}`);
|
|
110
|
-
}
|
|
111
|
-
await solutionClient().mutation(api.solutions.waits.waitOnPullRequest, {
|
|
112
|
-
solutionId: where.solutionId,
|
|
113
|
-
agent: where.agent,
|
|
114
|
-
...(where.outcome ? { outcome: where.outcome } : {}),
|
|
115
|
-
seen: seenOf(state),
|
|
116
|
-
saw: {
|
|
117
|
-
number: state.number,
|
|
118
|
-
url: state.url,
|
|
119
|
-
conflicting: state.mergeable === "conflicting",
|
|
120
|
-
failed: state.failed.length,
|
|
121
|
-
running: state.running.length,
|
|
122
|
-
},
|
|
123
|
-
forMs,
|
|
124
|
-
});
|
|
125
|
-
console.log([
|
|
126
|
-
describeState(state),
|
|
127
|
-
"",
|
|
128
|
-
`Waiting on it. End your session now: you'll be started again, here, once it is \`clean\`, once it is merged or closed, or in ${forHowLong(forMs)}, whichever comes first.`,
|
|
129
|
-
].join("\n"));
|
|
130
|
-
}
|
|
131
76
|
/**
|
|
132
77
|
* `dotreq solution pr open`: the solution's pull request, opened or
|
|
133
78
|
* found (PULL-2). Inside a runner the branch is pushed first, as a submission
|
|
@@ -140,14 +140,10 @@ export async function statusCommand(options) {
|
|
|
140
140
|
// other reviewer stalled. Asking, stalling and recording all take the
|
|
141
141
|
// agent off it.
|
|
142
142
|
const atIt = outcome.atWork?.some((each) => each.agent === where.agent && each.part === part) === true;
|
|
143
|
-
// PULL-5.2: a reviewer waiting on the pull request owes nothing until it
|
|
144
|
-
// starts again.
|
|
145
|
-
const waiting = part === "review" && outcome.waiting?.includes(where.agent) === true;
|
|
146
143
|
const owes = part === "draft"
|
|
147
144
|
? !setAside &&
|
|
148
145
|
(atIt || outcome.status === "drafting" || outcome.status === "ready")
|
|
149
|
-
:
|
|
150
|
-
(atIt || outcome.status === "reviewing") &&
|
|
146
|
+
: (atIt || outcome.status === "reviewing") &&
|
|
151
147
|
(await reviewerOwes(client, where.solutionId, outcome.name, where.agent));
|
|
152
148
|
if (options.json) {
|
|
153
149
|
process.stdout.write(`${JSON.stringify({ agent: where.agent, outcome: outcome.name, part, status: outcome.status, reason: outcome.reason ?? null, reviews: part === "review", ...(setAside ? { setAside } : {}), owes })}\n`);
|
package/dist/convex.d.ts
CHANGED
|
@@ -122,9 +122,6 @@ export declare const api: {
|
|
|
122
122
|
recordPush: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
123
123
|
removal: import("convex/server").FunctionReference<"query", "public", any, any, string | undefined>;
|
|
124
124
|
};
|
|
125
|
-
waits: {
|
|
126
|
-
waitOnPullRequest: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
127
|
-
};
|
|
128
125
|
};
|
|
129
126
|
lib: {
|
|
130
127
|
authActions: {
|
package/dist/convex.js
CHANGED
|
@@ -143,9 +143,6 @@ export const api = {
|
|
|
143
143
|
recordPush: mutation("solutions/branches:recordPush"),
|
|
144
144
|
removal: query("solutions/branches:removal"),
|
|
145
145
|
},
|
|
146
|
-
waits: {
|
|
147
|
-
waitOnPullRequest: mutation("solutions/waits:waitOnPullRequest"),
|
|
148
|
-
},
|
|
149
146
|
},
|
|
150
147
|
lib: {
|
|
151
148
|
authActions: {
|
package/package.json
CHANGED