@popoverai/dotrequirements 0.34.2 → 0.36.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/dist/commands/solution/approval.d.ts +9 -0
- package/dist/commands/solution/approval.js +19 -0
- package/dist/commands/solution/ask.d.ts +10 -5
- package/dist/commands/solution/ask.js +23 -8
- package/dist/commands/solution/brief.d.ts +2 -0
- package/dist/commands/solution/contract.d.ts +1 -1
- package/dist/commands/solution/contract.js +14 -2
- package/dist/commands/solution/index.js +65 -16
- package/dist/commands/solution/pull-request.d.ts +43 -2
- package/dist/commands/solution/pull-request.js +92 -3
- package/dist/commands/solution/review.d.ts +5 -4
- package/dist/commands/solution/review.js +13 -13
- package/dist/commands/solution/status.js +8 -3
- package/dist/commands/solution/things.js +2 -2
- package/dist/commands/solution/thread.js +1 -1
- package/dist/convex.d.ts +4 -0
- package/dist/convex.js +5 -0
- package/dist/rehearsal/types.d.ts +7 -8
- package/package.json +1 -1
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { type WhereOptions } from "./run-file.js";
|
|
2
|
+
/**
|
|
3
|
+
* `dotreq solution approval complete <decision>`: the agent takes the
|
|
4
|
+
* action on the option the owner chose, exactly as the option carried it,
|
|
5
|
+
* once, and prints what came of it (DECIDE-4.1). Refused, saying why, when
|
|
6
|
+
* she hasn't chosen it, it was taken already, or another agent asked.
|
|
7
|
+
*/
|
|
8
|
+
export declare function approvalCompleteCommand(decisionId: string, options: WhereOptions): Promise<void>;
|
|
9
|
+
//# sourceMappingURL=approval.d.ts.map
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
import { api } from "../../convex.js";
|
|
2
|
+
import { solutionClient } from "./client.js";
|
|
3
|
+
import { requireWhere } from "./run-file.js";
|
|
4
|
+
/**
|
|
5
|
+
* `dotreq solution approval complete <decision>`: the agent takes the
|
|
6
|
+
* action on the option the owner chose, exactly as the option carried it,
|
|
7
|
+
* once, and prints what came of it (DECIDE-4.1). Refused, saying why, when
|
|
8
|
+
* she hasn't chosen it, it was taken already, or another agent asked.
|
|
9
|
+
*/
|
|
10
|
+
export async function approvalCompleteCommand(decisionId, options) {
|
|
11
|
+
const { solutionId, agent } = requireWhere(options);
|
|
12
|
+
const result = (await solutionClient().mutation(api.solutions.mutations.completeApproval, { solutionId, agent, decisionId }));
|
|
13
|
+
// DECIDE-4.7: refused because the work moved on, kept so the brief stops
|
|
14
|
+
// offering it, and said as any refusal is.
|
|
15
|
+
if ("refused" in result)
|
|
16
|
+
throw new Error(result.refused);
|
|
17
|
+
console.log(result.said);
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=approval.js.map
|
|
@@ -1,9 +1,14 @@
|
|
|
1
1
|
import { type WhereOptions } from "./run-file.js";
|
|
2
|
+
export type AskOptions = WhereOptions & {
|
|
3
|
+
/** One action as JSON, `{"tool": ..., "args": ...}`, to ask only whether it may be taken (DECIDE-3.4). */
|
|
4
|
+
approvalRequest?: string;
|
|
5
|
+
};
|
|
2
6
|
/**
|
|
3
|
-
* `dotreq solution ask <request-file>`: the drafter
|
|
4
|
-
* owner, on the outcome it is
|
|
5
|
-
* reviewer
|
|
6
|
-
*
|
|
7
|
+
* `dotreq solution ask <request-file>`: the drafter or a reviewer puts a
|
|
8
|
+
* decision to the owner, on the outcome it is at or the one `--outcome`
|
|
9
|
+
* names (VERB-3.0). A reviewer gives its result once she has answered (3.1).
|
|
10
|
+
* `--approval-request '<action>'`, with no file, asks only whether it may
|
|
11
|
+
* take that one action (DECIDE-3.4).
|
|
7
12
|
*/
|
|
8
|
-
export declare function askCommand(file: string, options:
|
|
13
|
+
export declare function askCommand(file: string | undefined, options: AskOptions): Promise<void>;
|
|
9
14
|
//# sourceMappingURL=ask.d.ts.map
|
|
@@ -4,24 +4,39 @@ import { pushBeforeRecord } from "./pushing.js";
|
|
|
4
4
|
import { readRequest } from "./request.js";
|
|
5
5
|
import { onOutcome, requireWhere } from "./run-file.js";
|
|
6
6
|
/**
|
|
7
|
-
* `dotreq solution ask <request-file>`: the drafter
|
|
8
|
-
* owner, on the outcome it is
|
|
9
|
-
* reviewer
|
|
10
|
-
*
|
|
7
|
+
* `dotreq solution ask <request-file>`: the drafter or a reviewer puts a
|
|
8
|
+
* decision to the owner, on the outcome it is at or the one `--outcome`
|
|
9
|
+
* names (VERB-3.0). A reviewer gives its result once she has answered (3.1).
|
|
10
|
+
* `--approval-request '<action>'`, with no file, asks only whether it may
|
|
11
|
+
* take that one action (DECIDE-3.4).
|
|
11
12
|
*/
|
|
12
13
|
export async function askCommand(file, options) {
|
|
13
|
-
|
|
14
|
+
if ((file === undefined) === (options.approvalRequest === undefined)) {
|
|
15
|
+
throw new Error("Ask with a request file, or with --approval-request '<action>' alone: one of them.");
|
|
16
|
+
}
|
|
17
|
+
const asking = file !== undefined
|
|
18
|
+
? { request: readRequest(file) }
|
|
19
|
+
: { approvalRequest: actionFrom(options.approvalRequest ?? "") };
|
|
14
20
|
const where = requireWhere(options);
|
|
15
21
|
const { solutionId, agent } = where;
|
|
16
22
|
const client = solutionClient();
|
|
17
23
|
// SOLBRANCH-3.0: the drafter's commits reach the branch before Quinn is asked.
|
|
18
24
|
await pushBeforeRecord(client, where);
|
|
19
|
-
await client.mutation(api.solutions.mutations.ask, {
|
|
25
|
+
const decision = await client.mutation(api.solutions.mutations.ask, {
|
|
20
26
|
solutionId,
|
|
21
27
|
agent,
|
|
22
28
|
...(where.outcome ? { outcome: where.outcome } : {}),
|
|
23
|
-
|
|
29
|
+
...asking,
|
|
24
30
|
});
|
|
25
|
-
console.log(`Asked${onOutcome(where.outcome)}. It waits on the owner's decision.`);
|
|
31
|
+
console.log(`Asked${onOutcome(where.outcome)}. It waits on the owner's decision${decision ? ` (${decision})` : ""}.`);
|
|
32
|
+
}
|
|
33
|
+
/** The action `--approval-request` names, as JSON. The backend checks it. */
|
|
34
|
+
function actionFrom(text) {
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(text);
|
|
37
|
+
}
|
|
38
|
+
catch (error) {
|
|
39
|
+
throw new Error(`--approval-request takes the action as JSON, {"tool": ..., "args": ...}: ${error instanceof Error ? error.message : String(error)}`);
|
|
40
|
+
}
|
|
26
41
|
}
|
|
27
42
|
//# sourceMappingURL=ask.js.map
|
|
@@ -54,6 +54,8 @@ 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[];
|
|
57
59
|
};
|
|
58
60
|
/** A checkpoint on the plan panel, as far as the CLI reads it. */
|
|
59
61
|
export type PanelCheckpoint = {
|
|
@@ -5,5 +5,5 @@
|
|
|
5
5
|
* request is validated against; the CLI can't import the backend, so this
|
|
6
6
|
* is that text, and a test keeps the two the same.
|
|
7
7
|
*/
|
|
8
|
-
export declare const REQUEST_CONTRACT = "Ask the person to decide something about the outcome you are drafting. A choice presents options with a recommendation. One decision per request: if two things need deciding, ask twice.\n\nA request is JSON with a \"kind\" and the fields of that kind:\n\nchoice:\n question (text, up to 200 characters): The question, phrased as a question in the words the person will read it, not as a topic.\n options (list, at least 2): The live alternatives. More than four makes deciding harder; give more only when each is a genuine choice. Leave out anything you have already ruled out.\n name (text, up to 200 characters): The option as you would say it to the person: a noun phrase they can repeat back, not a label.\n benefits (list of text, each up to 200 characters): What is better if this option is taken. One line each, in your own words.\n costs (list of text, each up to 200 characters): What is worse if this option is taken: what it would take to build, and what the person lives with afterwards. Effort is a cost like any other.\n note (text, up to 600 characters, optional): Anything you learned or checked about this option that is not a benefit or a cost. Leave it out when there is nothing to add.\n recommendation (object): Which option you would take, and the one reason why.\n option (text, up to 200 characters): The name of the option you recommend, exactly as it appears in options.\n because (text, up to 200 characters): The one reason that carries it, in one line. The full reasoning belongs in background.\n background (text, up to 4000 characters): What the person needs to know to decide well that the options do not already say. Include only context that would substantially change the quality of the decision. The person reads this after the options, so do not reiterate them.";
|
|
8
|
+
export declare const REQUEST_CONTRACT = "Ask the person to decide something about the outcome you are drafting or reviewing. A choice presents options with a recommendation. One decision per request: if two things need deciding, ask twice.\n\nA request is JSON with a \"kind\" and the fields of that kind:\n\nchoice:\n question (text, up to 200 characters): The question, phrased as a question in the words the person will read it, not as a topic.\n options (list, at least 2): The live alternatives. More than four makes deciding harder; give more only when each is a genuine choice. Leave out anything you have already ruled out.\n name (text, up to 200 characters): The option as you would say it to the person: a noun phrase they can repeat back, not a label.\n benefits (list of text, each up to 200 characters): What is better if this option is taken. One line each, in your own words.\n costs (list of text, each up to 200 characters): What is worse if this option is taken: what it would take to build, and what the person lives with afterwards. Effort is a cost like any other.\n note (text, up to 600 characters, optional): Anything you learned or checked about this option that is not a benefit or a cost. Leave it out when there is nothing to add.\n action (object, optional): An action you may take only with the person's permission, which choosing this option gives. Once they choose it, take it with `dotreq solution approval complete <decision>`. Leave it out for anything you may do yourself.\n tool (text, up to 200 characters): The action, by name. The one that needs the person's permission is \"fix\", starting a fix.\n args (object): The action's arguments, as it takes them: a fix's are below.\n recommendation (object): Which option you would take, and the one reason why.\n option (text, up to 200 characters): The name of the option you recommend, exactly as it appears in options.\n because (text, up to 200 characters): The one reason that carries it, in one line. The full reasoning belongs in background.\n background (text, up to 4000 characters): What the person needs to know to decide well that the options do not already say. Include only context that would substantially change the quality of the decision. The person reads this after the options, so do not reiterate them.\n\nThe args of a \"fix\" action:\n name (text, up to 120 characters): A short name for the fix, from what it puts right, as \"dice below the controls\".\n words (text, up to 2000 characters): What you found, in your own words.\n plan (text, up to 2000 characters): The fix as you would put it to the person, in a sentence or two.\n redo (list, at least 1): The outcomes the fix redoes, and what would change in each.\n outcome (text, up to 200 characters): An outcome to redo, by its name.\n change (text, up to 2000 characters): What would change in it.\n rerun (list of text, each up to 200 characters): The outcomes that await the ones redone and should run again from them. Empty when none should.";
|
|
9
9
|
//# sourceMappingURL=contract.d.ts.map
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
* request is validated against; the CLI can't import the backend, so this
|
|
6
6
|
* is that text, and a test keeps the two the same.
|
|
7
7
|
*/
|
|
8
|
-
export const REQUEST_CONTRACT = `Ask the person to decide something about the outcome you are drafting. A choice presents options with a recommendation. One decision per request: if two things need deciding, ask twice.
|
|
8
|
+
export const REQUEST_CONTRACT = `Ask the person to decide something about the outcome you are drafting or reviewing. A choice presents options with a recommendation. One decision per request: if two things need deciding, ask twice.
|
|
9
9
|
|
|
10
10
|
A request is JSON with a "kind" and the fields of that kind:
|
|
11
11
|
|
|
@@ -16,8 +16,20 @@ choice:
|
|
|
16
16
|
benefits (list of text, each up to 200 characters): What is better if this option is taken. One line each, in your own words.
|
|
17
17
|
costs (list of text, each up to 200 characters): What is worse if this option is taken: what it would take to build, and what the person lives with afterwards. Effort is a cost like any other.
|
|
18
18
|
note (text, up to 600 characters, optional): Anything you learned or checked about this option that is not a benefit or a cost. Leave it out when there is nothing to add.
|
|
19
|
+
action (object, optional): An action you may take only with the person's permission, which choosing this option gives. Once they choose it, take it with \`dotreq solution approval complete <decision>\`. Leave it out for anything you may do yourself.
|
|
20
|
+
tool (text, up to 200 characters): The action, by name. The one that needs the person's permission is "fix", starting a fix.
|
|
21
|
+
args (object): The action's arguments, as it takes them: a fix's are below.
|
|
19
22
|
recommendation (object): Which option you would take, and the one reason why.
|
|
20
23
|
option (text, up to 200 characters): The name of the option you recommend, exactly as it appears in options.
|
|
21
24
|
because (text, up to 200 characters): The one reason that carries it, in one line. The full reasoning belongs in background.
|
|
22
|
-
background (text, up to 4000 characters): What the person needs to know to decide well that the options do not already say. Include only context that would substantially change the quality of the decision. The person reads this after the options, so do not reiterate them
|
|
25
|
+
background (text, up to 4000 characters): What the person needs to know to decide well that the options do not already say. Include only context that would substantially change the quality of the decision. The person reads this after the options, so do not reiterate them.
|
|
26
|
+
|
|
27
|
+
The args of a "fix" action:
|
|
28
|
+
name (text, up to 120 characters): A short name for the fix, from what it puts right, as "dice below the controls".
|
|
29
|
+
words (text, up to 2000 characters): What you found, in your own words.
|
|
30
|
+
plan (text, up to 2000 characters): The fix as you would put it to the person, in a sentence or two.
|
|
31
|
+
redo (list, at least 1): The outcomes the fix redoes, and what would change in each.
|
|
32
|
+
outcome (text, up to 200 characters): An outcome to redo, by its name.
|
|
33
|
+
change (text, up to 2000 characters): What would change in it.
|
|
34
|
+
rerun (list of text, each up to 200 characters): The outcomes that await the ones redone and should run again from them. Empty when none should.`;
|
|
23
35
|
//# sourceMappingURL=contract.js.map
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { Option } from "commander";
|
|
2
|
+
import { approvalCompleteCommand } from "./approval.js";
|
|
2
3
|
import { askCommand } from "./ask.js";
|
|
3
4
|
import { authorCommand } from "./author.js";
|
|
4
5
|
import { checkoutCommand, pushCommand } from "./checkout.js";
|
|
@@ -6,7 +7,7 @@ import { REQUEST_CONTRACT } from "./contract.js";
|
|
|
6
7
|
import { createCommand } from "./create.js";
|
|
7
8
|
import { thingsCommand } from "./look-up.js";
|
|
8
9
|
import { nextCommand } from "./next.js";
|
|
9
|
-
import { pullRequestCommand } from "./pull-request.js";
|
|
10
|
+
import { prStatusCommand, prWaitCommand, pullRequestCommand, } from "./pull-request.js";
|
|
10
11
|
import { rehearseCommand } from "./rehearse.js";
|
|
11
12
|
import { reviewCommand } from "./review.js";
|
|
12
13
|
import { doneCommand } from "./share.js";
|
|
@@ -41,7 +42,7 @@ Where what you made is, one or more:
|
|
|
41
42
|
mockup:<id> a mockup in dotrequirements
|
|
42
43
|
scores:<id> scores in dotrequirements, made with dotreq scores create
|
|
43
44
|
pr:<number> the solution's pull request, opened or found with
|
|
44
|
-
dotreq solution
|
|
45
|
+
dotreq solution pr open. An outcome kept on a pull
|
|
45
46
|
request is submitted with it, with the rest of its work
|
|
46
47
|
image:<path> an image, such as a screenshot: a PNG, JPEG, GIF, WebP or
|
|
47
48
|
AVIF. The app keeps a copy; don't commit it
|
|
@@ -91,11 +92,27 @@ Examples:
|
|
|
91
92
|
dotreq solution author file:src/checkout.ts@guest pr:12 image:checkout.png --comment "Guest path, behind the flag."
|
|
92
93
|
dotreq solution author "preview:8080/design/roll-count pnpm dev" file:src/RollCount.tsx --title "Roll count after three dice" --title "Roll count component" --comment "The roll count, as a dev-only page."
|
|
93
94
|
`;
|
|
94
|
-
/** What `
|
|
95
|
+
/** What `pr status` says, on its `--help` (PULL-4). */
|
|
96
|
+
const PR_STATUS_HELP = `
|
|
97
|
+
Reads the pull request of the outcome you are at, or of the outcome it awaits that
|
|
98
|
+
is kept on one, as GitHub reports it. The merge state is GitHub's word for whether
|
|
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; checks still running are named.
|
|
101
|
+
Reading it changes nothing.
|
|
102
|
+
`;
|
|
103
|
+
/** What `pr wait` does, on its `--help` (PULL-5, PULL-6). */
|
|
104
|
+
const PR_WAIT_HELP = `
|
|
105
|
+
For a reviewer, when the pull request has to change before you can give a result,
|
|
106
|
+
as while its checks run. Records where it stands now; then end your session
|
|
107
|
+
without a result. You are started again, in this session, when GitHub reports it
|
|
108
|
+
changed and nothing on it is still running, or once it is merged or closed. A new
|
|
109
|
+
submission ends the wait too, and you review that as you would any other.
|
|
110
|
+
`;
|
|
111
|
+
/** What `pr open` does, on its `--help`, where `author --help` sends the agent (PULL-2). */
|
|
95
112
|
const PULL_REQUEST_HELP = `
|
|
96
113
|
Pushes your commits to the solution's branch, then opens a pull request from it
|
|
97
|
-
into the branch it was made from,
|
|
98
|
-
Prints its reference and its address:
|
|
114
|
+
into the branch it was made from, as a draft, or finds the one already open. The
|
|
115
|
+
plan says when it becomes ready for review. Prints its reference and its address:
|
|
99
116
|
|
|
100
117
|
The solution's pull request is pr:12: https://github.com/<owner>/<repository>/pull/12
|
|
101
118
|
|
|
@@ -123,8 +140,15 @@ The outcome waits until that is fixed and you are started again.
|
|
|
123
140
|
const ASK_EXAMPLES = `
|
|
124
141
|
Examples:
|
|
125
142
|
dotreq solution ask question.json
|
|
143
|
+
dotreq solution ask --approval-request '{"tool": "fix", "args": {"name": "Receipt email required", "words": "...", "plan": "...", "redo": [{"outcome": "Code", "change": "..."}], "rerun": []}}'
|
|
144
|
+
|
|
145
|
+
A reviewer asks the same way, then gives its result once the owner has answered: it is
|
|
146
|
+
sent for again then.
|
|
126
147
|
|
|
127
|
-
|
|
148
|
+
An option may carry an action you may take only with the owner's permission: starting a
|
|
149
|
+
fix, as "fix". Choosing that option gives it; nothing is done until you take it, with
|
|
150
|
+
dotreq solution approval complete <decision>. --approval-request asks only whether you may
|
|
151
|
+
take one action.
|
|
128
152
|
`;
|
|
129
153
|
/**
|
|
130
154
|
* What each result does, on `review --help` (STEP-REVIEW-1, 2), and the
|
|
@@ -135,8 +159,10 @@ const REVIEW_RESULTS = `
|
|
|
135
159
|
Results:
|
|
136
160
|
approved The work moves on.
|
|
137
161
|
approved-with-revisions What remains is small: the drafter fixes it once, and it moves on without another review.
|
|
138
|
-
needs-revision The drafter revises and you read it again.
|
|
139
|
-
|
|
162
|
+
needs-revision The drafter revises and you read it again. From the twelfth round, give it only once the owner has chosen it.
|
|
163
|
+
|
|
164
|
+
When whether to approve turns on the owner's own judgement, put a decision to them first
|
|
165
|
+
with dotreq solution ask, and give your result once they have answered.
|
|
140
166
|
|
|
141
167
|
When you approve, write an executive summary for the owner with --executive-summary (or
|
|
142
168
|
--summary), describing the work as it will stand once any fixes you asked for are made. If
|
|
@@ -157,7 +183,6 @@ needs-revision, with no video. Only a plain approval carries a video.
|
|
|
157
183
|
|
|
158
184
|
Examples:
|
|
159
185
|
dotreq solution review approved --comment "Checked the pitch against the board; the customer is named." --executive-summary "A pitch for guest checkout, for first-time buyers. Look at the appetite: two weeks."
|
|
160
|
-
dotreq solution review escalate --comment "Whether to name a segment is your call: the drafter and I disagree."
|
|
161
186
|
dotreq solution review needs-revision --comment "The risk score gives no reason."
|
|
162
187
|
dotreq solution review approved "video:demo/final.mp4 .dotreq/demo-scripts/steps.json" --comment "Recorded it; step 3 now waits for the receipt." --executive-summary "A two-minute demo of guest checkout. Look at step 4: the receipt."
|
|
163
188
|
`;
|
|
@@ -216,15 +241,29 @@ export function registerSolution(program) {
|
|
|
216
241
|
.option("--title <text>", "A reference's name on the outcome's tab, for the owner: one per reference, in the order the references are given, or none", (value, previous = []) => [...previous, value])
|
|
217
242
|
.addHelpText("after", REFERENCE_FORMS)
|
|
218
243
|
.action(wrap(authorCommand));
|
|
219
|
-
|
|
220
|
-
.command("
|
|
244
|
+
const pr = solution
|
|
245
|
+
.command("pr", HIDDEN)
|
|
246
|
+
.description("The solution's pull request: open it, read it, wait on it");
|
|
247
|
+
whereOptions(pr
|
|
248
|
+
.command("open")
|
|
221
249
|
.description("Push the solution's branch and open its pull request, or find the one open; prints its reference, pr:<number>, to submit"))
|
|
222
250
|
.addHelpText("after", PULL_REQUEST_HELP)
|
|
223
251
|
.action(wrap(pullRequestCommand));
|
|
252
|
+
whereOptions(pr
|
|
253
|
+
.command("status")
|
|
254
|
+
.description("Where the pull request of the outcome you are at stands, in GitHub's words: its merge state, conflicts, review decision and checks"))
|
|
255
|
+
.option("--json", "Print as JSON")
|
|
256
|
+
.addHelpText("after", PR_STATUS_HELP)
|
|
257
|
+
.action(wrap(prStatusCommand));
|
|
258
|
+
whereOptions(pr
|
|
259
|
+
.command("wait")
|
|
260
|
+
.description("Wait on the pull request with your session ended: you start again when it changes and nothing on it is still running"))
|
|
261
|
+
.addHelpText("after", PR_WAIT_HELP)
|
|
262
|
+
.action(wrap(prWaitCommand));
|
|
224
263
|
whereOptions(solution
|
|
225
264
|
.command("review <result> [video...]", HIDDEN)
|
|
226
|
-
.description("Record the review's result: approved, approved-with-revisions
|
|
227
|
-
.option("--comment <text>", "What should change, what you checked
|
|
265
|
+
.description("Record the review's result: approved, approved-with-revisions or needs-revision"))
|
|
266
|
+
.option("--comment <text>", "What should change, or what you checked: required for every result")
|
|
228
267
|
.option("--executive-summary <text>", "For the owner, with every approval (required there)")
|
|
229
268
|
.option("--summary <text>", "Short for --executive-summary")
|
|
230
269
|
.addHelpText("after", REVIEW_RESULTS)
|
|
@@ -235,14 +274,24 @@ export function registerSolution(program) {
|
|
|
235
274
|
.option("--keep", "Leave the scenario's earlier runs in place, to review the new run beside them")
|
|
236
275
|
.action(wrap(rehearseCommand));
|
|
237
276
|
whereOptions(solution
|
|
238
|
-
.command("ask
|
|
239
|
-
.description("Put a decision to the owner, as JSON in the named file
|
|
277
|
+
.command("ask [request-file]", HIDDEN)
|
|
278
|
+
.description("Put a decision to the owner, as JSON in the named file, drafting or reviewing"))
|
|
279
|
+
.option("--approval-request <action>", 'Ask only whether you may take one action, given as JSON: {"tool": "fix", "args": {...}}. No request file then')
|
|
240
280
|
.addHelpText("after", `\n${REQUEST_CONTRACT}\n${ASK_EXAMPLES}`)
|
|
241
281
|
.action(wrap(askCommand));
|
|
282
|
+
const approval = solution
|
|
283
|
+
.command("approval", HIDDEN)
|
|
284
|
+
.description("An action the owner allowed by choosing the option that carries it");
|
|
285
|
+
approval
|
|
286
|
+
.command("complete <decision>")
|
|
287
|
+
.description("Take the action on the option the owner chose, exactly as offered, once, and print what came of it")
|
|
288
|
+
.option("--solution <id>", "Which solution, when the run does not say (inside a runner it does)")
|
|
289
|
+
.option("--agent <name>", "Which agent you are, when the run does not say (inside a runner it does)")
|
|
290
|
+
.action(wrap(approvalCompleteCommand));
|
|
242
291
|
whereOptions(solution
|
|
243
292
|
.command("thread", HIDDEN)
|
|
244
293
|
.description("The outcome's thread, oldest first: every submission, review, decision, stall and restart on it"))
|
|
245
|
-
.option("--latest [n]", "Only the newest n submission notes, review results
|
|
294
|
+
.option("--latest [n]", "Only the newest n submission notes, review results and decisions, still oldest first; alone, the newest one. Stalls, restarts and redrafts are left out")
|
|
246
295
|
.action(wrap(threadCommand));
|
|
247
296
|
whereOptions(solution
|
|
248
297
|
.command("things <name>", HIDDEN)
|
|
@@ -5,9 +5,50 @@ export type PullRequest = {
|
|
|
5
5
|
number: number;
|
|
6
6
|
};
|
|
7
7
|
/** The command that opens the solution's pull request and prints its reference. */
|
|
8
|
-
export declare const OPEN_IT = "dotreq solution
|
|
8
|
+
export declare const OPEN_IT = "dotreq solution pr open";
|
|
9
|
+
/** Where a pull request stands, in GitHub's words (web: lib/runner/github.ts). */
|
|
10
|
+
export type PullRequestState = {
|
|
11
|
+
number: number;
|
|
12
|
+
url: string;
|
|
13
|
+
mergeState: string;
|
|
14
|
+
mergeable: string;
|
|
15
|
+
reviewDecision: string | null;
|
|
16
|
+
checks: string | null;
|
|
17
|
+
failed: Array<{
|
|
18
|
+
name: string;
|
|
19
|
+
result: string;
|
|
20
|
+
link: string | null;
|
|
21
|
+
}>;
|
|
22
|
+
running: Array<{
|
|
23
|
+
name: string;
|
|
24
|
+
link: string | null;
|
|
25
|
+
}>;
|
|
26
|
+
head: string;
|
|
27
|
+
};
|
|
28
|
+
/**
|
|
29
|
+
* Where the pull request stood, as a wait records it (PULL-6.4): what a
|
|
30
|
+
* reviewer judges by, so a later read that differs is a change.
|
|
31
|
+
*/
|
|
32
|
+
export declare function seenOf(state: PullRequestState): string;
|
|
33
|
+
/** Where the pull request stands, as a reviewer reads it (PULL-4). */
|
|
34
|
+
export declare function describeState(state: PullRequestState): string;
|
|
35
|
+
/**
|
|
36
|
+
* `dotreq solution pr status`: where the pull request of the outcome the
|
|
37
|
+
* agent is at stands, in GitHub's words (PULL-4). Changes nothing (4.6).
|
|
38
|
+
*/
|
|
39
|
+
export declare function prStatusCommand(options: WhereOptions & {
|
|
40
|
+
json?: boolean;
|
|
41
|
+
}): Promise<void>;
|
|
42
|
+
/**
|
|
43
|
+
* `dotreq solution pr wait`: the reviewer waits on the pull request with
|
|
44
|
+
* no session running (PULL-5): it records where the pull request stands,
|
|
45
|
+
* and its session can end without a result. It starts again, in the same
|
|
46
|
+
* session, when the pull request changes and nothing on it is still running
|
|
47
|
+
* (PULL-6).
|
|
48
|
+
*/
|
|
49
|
+
export declare function prWaitCommand(options: WhereOptions): Promise<void>;
|
|
9
50
|
/**
|
|
10
|
-
* `dotreq solution
|
|
51
|
+
* `dotreq solution pr open`: the solution's pull request, opened or
|
|
11
52
|
* found (PULL-2). Inside a runner the branch is pushed first, as a submission
|
|
12
53
|
* pushes it (2.0, SOLBRANCH-3); then the app opens a pull request from it
|
|
13
54
|
* into the branch it was made from, or finds the one already open (2.3,
|
|
@@ -1,13 +1,101 @@
|
|
|
1
1
|
import { webApiUrl } from "../../cloud.js";
|
|
2
|
+
import { api } from "../../convex.js";
|
|
2
3
|
import { getProjectCredentials } from "../../utils/project-settings.js";
|
|
3
4
|
import { solutionClient } from "./client.js";
|
|
4
5
|
import { pushWork } from "./pushing.js";
|
|
5
6
|
import { requireWhere } from "./run-file.js";
|
|
6
7
|
import { outcomeFor } from "./status.js";
|
|
7
8
|
/** The command that opens the solution's pull request and prints its reference. */
|
|
8
|
-
export const OPEN_IT = "dotreq solution
|
|
9
|
+
export const OPEN_IT = "dotreq solution pr open";
|
|
9
10
|
/**
|
|
10
|
-
*
|
|
11
|
+
* Where the pull request stood, as a wait records it (PULL-6.4): what a
|
|
12
|
+
* reviewer judges by, so a later read that differs is a change.
|
|
13
|
+
*/
|
|
14
|
+
export function seenOf(state) {
|
|
15
|
+
return [
|
|
16
|
+
state.head,
|
|
17
|
+
state.mergeState,
|
|
18
|
+
state.mergeable,
|
|
19
|
+
state.reviewDecision ?? "",
|
|
20
|
+
state.checks ?? "",
|
|
21
|
+
].join(" ");
|
|
22
|
+
}
|
|
23
|
+
/** The pull request the outcome the agent is at reads, as the app finds it (PULL-4.0, 4.0.0). */
|
|
24
|
+
async function stateFor(where) {
|
|
25
|
+
const said = await ask({
|
|
26
|
+
solutionId: where.solutionId,
|
|
27
|
+
agent: where.agent,
|
|
28
|
+
...(where.outcome ? { outcome: where.outcome } : {}),
|
|
29
|
+
op: "status",
|
|
30
|
+
});
|
|
31
|
+
if (said.noRepository) {
|
|
32
|
+
// PULL-4.5.
|
|
33
|
+
throw new Error("There's no pull request: a pull request needs a repository, and this project has none connected.");
|
|
34
|
+
}
|
|
35
|
+
if (said.noBranch || said.none) {
|
|
36
|
+
// PULL-4.4.
|
|
37
|
+
throw new Error(`There's no pull request open for it. Its drafter opens one with \`${OPEN_IT}\`.`);
|
|
38
|
+
}
|
|
39
|
+
if (said.refused) {
|
|
40
|
+
throw new Error(`Couldn't read the pull request from the repository: ${said.refused}`);
|
|
41
|
+
}
|
|
42
|
+
if (!said.state)
|
|
43
|
+
throw new Error("The app gave no pull request.");
|
|
44
|
+
return said.state;
|
|
45
|
+
}
|
|
46
|
+
/** Where the pull request stands, as a reviewer reads it (PULL-4). */
|
|
47
|
+
export function describeState(state) {
|
|
48
|
+
const lines = [
|
|
49
|
+
`pr:${state.number} (${state.url}), at ${state.head.slice(0, 7)}`,
|
|
50
|
+
`Merge state: ${state.mergeState}`,
|
|
51
|
+
`Conflicts with the branch it merges into: ${state.mergeable === "conflicting" ? "yes" : state.mergeable === "mergeable" ? "no" : "not worked out yet"}`,
|
|
52
|
+
`Review decision: ${state.reviewDecision ?? "none required"}`,
|
|
53
|
+
`Checks: ${state.checks ?? "none"}`,
|
|
54
|
+
];
|
|
55
|
+
for (const check of state.failed) {
|
|
56
|
+
lines.push(` failed: ${check.name} (${check.result})${check.link ? ` ${check.link}` : ""}`);
|
|
57
|
+
}
|
|
58
|
+
for (const check of state.running) {
|
|
59
|
+
lines.push(` still running: ${check.name}${check.link ? ` ${check.link}` : ""}`);
|
|
60
|
+
}
|
|
61
|
+
if (state.mergeable === "unknown") {
|
|
62
|
+
// PULL-4.3.
|
|
63
|
+
lines.push("GitHub hasn't yet worked out whether it can merge: read it again shortly, or wait on it.");
|
|
64
|
+
}
|
|
65
|
+
return lines.join("\n");
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* `dotreq solution pr status`: where the pull request of the outcome the
|
|
69
|
+
* agent is at stands, in GitHub's words (PULL-4). Changes nothing (4.6).
|
|
70
|
+
*/
|
|
71
|
+
export async function prStatusCommand(options) {
|
|
72
|
+
const state = await stateFor(requireWhere(options));
|
|
73
|
+
console.log(options.json ? JSON.stringify(state) : describeState(state));
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* `dotreq solution pr wait`: the reviewer waits on the pull request with
|
|
77
|
+
* no session running (PULL-5): it records where the pull request stands,
|
|
78
|
+
* and its session can end without a result. It starts again, in the same
|
|
79
|
+
* session, when the pull request changes and nothing on it is still running
|
|
80
|
+
* (PULL-6).
|
|
81
|
+
*/
|
|
82
|
+
export async function prWaitCommand(options) {
|
|
83
|
+
const where = requireWhere(options);
|
|
84
|
+
const state = await stateFor(where);
|
|
85
|
+
await solutionClient().mutation(api.solutions.waits.waitOnPullRequest, {
|
|
86
|
+
solutionId: where.solutionId,
|
|
87
|
+
agent: where.agent,
|
|
88
|
+
...(where.outcome ? { outcome: where.outcome } : {}),
|
|
89
|
+
seen: seenOf(state),
|
|
90
|
+
});
|
|
91
|
+
console.log([
|
|
92
|
+
describeState(state),
|
|
93
|
+
"",
|
|
94
|
+
"Waiting on it. End your session now: you'll be started again, here, when it changes and nothing on it is still running.",
|
|
95
|
+
].join("\n"));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* `dotreq solution pr open`: the solution's pull request, opened or
|
|
11
99
|
* found (PULL-2). Inside a runner the branch is pushed first, as a submission
|
|
12
100
|
* pushes it (2.0, SOLBRANCH-3); then the app opens a pull request from it
|
|
13
101
|
* into the branch it was made from, or finds the one already open (2.3,
|
|
@@ -98,7 +186,8 @@ function pullRequestIn(said) {
|
|
|
98
186
|
/**
|
|
99
187
|
* Ask the app's pull-request route, on the project's credentials: with the
|
|
100
188
|
* outcome, to open the pull request it is kept on; with a number, to check
|
|
101
|
-
* that one is the solution's open pull request, which needs no outcome
|
|
189
|
+
* that one is the solution's open pull request, which needs no outcome;
|
|
190
|
+
* with `op: "status"`, for where the open one stands.
|
|
102
191
|
*/
|
|
103
192
|
async function ask(body) {
|
|
104
193
|
const { projectId, projectSecret } = getProjectCredentials();
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { type WhereOptions } from "./run-file.js";
|
|
2
2
|
import { type SummaryOptions } from "./summary.js";
|
|
3
3
|
export type ReviewOptions = WhereOptions & SummaryOptions & {
|
|
4
|
-
/** What should change, what was checked
|
|
4
|
+
/** What should change, or what was checked: required for every result (VERB-2.0, 2.1). */
|
|
5
5
|
comment?: string;
|
|
6
6
|
/**
|
|
7
7
|
* With an approval of a demo's script: the video recorded from it and
|
|
@@ -14,9 +14,10 @@ export type ReviewOptions = WhereOptions & SummaryOptions & {
|
|
|
14
14
|
* `dotreq solution review <result> --comment "..."`: the reviewer's
|
|
15
15
|
* result on the outcome it is reviewing, or on the one `--outcome` names.
|
|
16
16
|
* The comment is what the next reader of the thread sees first — the
|
|
17
|
-
* drafter works from it
|
|
18
|
-
*
|
|
19
|
-
*
|
|
17
|
+
* drafter works from it — so every result is refused without one before
|
|
18
|
+
* anything is recorded (VERB-2.0, 2.1). When the reviewer needs the
|
|
19
|
+
* owner's judgement it asks first (`dotreq solution ask`), and gives its
|
|
20
|
+
* result once she has answered; escalate is refused, saying so (2.4). An approval also carries an executive
|
|
20
21
|
* summary, `--executive-summary "..."`, which is what the owner reads with
|
|
21
22
|
* the work (VERB-2.5); the outcome's own rules decide what follows. An
|
|
22
23
|
* approval of a demo's script carries the video the reviewer recorded from
|
|
@@ -10,15 +10,17 @@ const RESULTS = {
|
|
|
10
10
|
approved: "approved",
|
|
11
11
|
"approved-with-revisions": "approved with revisions",
|
|
12
12
|
"needs-revision": "needs revision",
|
|
13
|
-
escalate: "escalate",
|
|
14
13
|
};
|
|
14
|
+
/** What a reviewer is told when it gives escalate, which is no longer a result (VERB-2.4): in the backend's words. */
|
|
15
|
+
const NO_ESCALATING = "Nothing was recorded: escalate is no longer a result. When you need the owner's judgement, put a decision to them with `dotreq solution ask` (`dotreq solution ask --help` shows the form), and give your result once they have answered.";
|
|
15
16
|
/**
|
|
16
17
|
* `dotreq solution review <result> --comment "..."`: the reviewer's
|
|
17
18
|
* result on the outcome it is reviewing, or on the one `--outcome` names.
|
|
18
19
|
* The comment is what the next reader of the thread sees first — the
|
|
19
|
-
* drafter works from it
|
|
20
|
-
*
|
|
21
|
-
*
|
|
20
|
+
* drafter works from it — so every result is refused without one before
|
|
21
|
+
* anything is recorded (VERB-2.0, 2.1). When the reviewer needs the
|
|
22
|
+
* owner's judgement it asks first (`dotreq solution ask`), and gives its
|
|
23
|
+
* result once she has answered; escalate is refused, saying so (2.4). An approval also carries an executive
|
|
22
24
|
* summary, `--executive-summary "..."`, which is what the owner reads with
|
|
23
25
|
* the work (VERB-2.5); the outcome's own rules decide what follows. An
|
|
24
26
|
* approval of a demo's script carries the video the reviewer recorded from
|
|
@@ -26,17 +28,17 @@ const RESULTS = {
|
|
|
26
28
|
* (SIGHT-13.2); no other result carries one (13.4.0).
|
|
27
29
|
*/
|
|
28
30
|
export async function reviewCommand(result, options) {
|
|
31
|
+
if (result === "escalate")
|
|
32
|
+
throw new Error(NO_ESCALATING);
|
|
29
33
|
const outcome = RESULTS[result];
|
|
30
34
|
if (!outcome) {
|
|
31
|
-
throw new Error(`A review result is approved, approved-with-revisions
|
|
35
|
+
throw new Error(`A review result is approved, approved-with-revisions or needs-revision, not "${result}".`);
|
|
32
36
|
}
|
|
33
37
|
const comment = options.comment?.trim();
|
|
34
38
|
if (!comment) {
|
|
35
39
|
throw new Error(outcome === "approved"
|
|
36
40
|
? "Say what you checked: your comment is what the next reader sees first."
|
|
37
|
-
:
|
|
38
|
-
? "Say what the owner is to decide: your comment is the note they read with the work."
|
|
39
|
-
: "Say what should change: the drafter works from your comment.");
|
|
41
|
+
: "Say what should change: the drafter works from your comment.");
|
|
40
42
|
}
|
|
41
43
|
// VERB-2.5, 2.5.0: an approval carries an executive summary for the
|
|
42
44
|
// owner, and nothing else does; refused before anything is recorded, in
|
|
@@ -47,7 +49,7 @@ export async function reviewCommand(result, options) {
|
|
|
47
49
|
throw new Error("Write an executive summary for the owner with --executive-summary: it's what they read first. Say what this is and what most needs their eye, as the work will stand once any fixes you asked for are made.");
|
|
48
50
|
}
|
|
49
51
|
if (!approving && summary) {
|
|
50
|
-
throw new Error(
|
|
52
|
+
throw new Error("Only an approval carries an executive summary, so nothing was recorded. Leave --executive-summary off: the drafter works from your comment.");
|
|
51
53
|
}
|
|
52
54
|
// SIGHT-13.2, 13.4.0: a video goes only with a plain approval, and is
|
|
53
55
|
// read before anything is pushed, uploaded or recorded.
|
|
@@ -55,7 +57,7 @@ export async function reviewCommand(result, options) {
|
|
|
55
57
|
if (recordings.length > 0 && outcome !== "approved") {
|
|
56
58
|
throw new Error(outcome === "approved with revisions"
|
|
57
59
|
? "Nothing was recorded: a demo's script isn't approved with revisions, because its drafter can't change the script without the video going out of step. Fix anything small yourself, record the video, and approve with it, saying in your comment what you changed; or give needs-revision."
|
|
58
|
-
:
|
|
60
|
+
: "Nothing was recorded: only an approval carries a video. Give your result without it: the drafter works from your comment, and no video is kept.");
|
|
59
61
|
}
|
|
60
62
|
const where = requireWhere(options);
|
|
61
63
|
const { solutionId, agent } = where;
|
|
@@ -83,9 +85,7 @@ export async function reviewCommand(result, options) {
|
|
|
83
85
|
// again once the reviewer has looked.
|
|
84
86
|
if (said?.refused)
|
|
85
87
|
throw new Error(said.refused);
|
|
86
|
-
console.log(outcome
|
|
87
|
-
? `Escalated${onOutcome(where.outcome)}. It waits on the owner's decision.`
|
|
88
|
-
: `Recorded your review${onOutcome(where.outcome)}: ${outcome}.`);
|
|
88
|
+
console.log(`Recorded your review${onOutcome(where.outcome)}: ${outcome}.`);
|
|
89
89
|
}
|
|
90
90
|
/**
|
|
91
91
|
* The videos a review carries (SIGHT-13.2): each recorded from a demo's
|
|
@@ -104,10 +104,11 @@ async function reviewerOwes(client, solutionId, outcome, agent) {
|
|
|
104
104
|
if (entry.kind === "submission")
|
|
105
105
|
since = at + 1;
|
|
106
106
|
});
|
|
107
|
+
// Only a review is a result: a question it put to the owner, or an
|
|
108
|
+
// escalation withdrawn when escalating went, leaves it still owing one.
|
|
107
109
|
return !thread
|
|
108
110
|
.slice(since)
|
|
109
|
-
.some((entry) => entry.agent === agent &&
|
|
110
|
-
(entry.kind === "review" || entry.kind === "escalation"));
|
|
111
|
+
.some((entry) => entry.agent === agent && entry.kind === "review");
|
|
111
112
|
}
|
|
112
113
|
/**
|
|
113
114
|
* `dotreq solution status`: where the outcome the agent is at stands, as
|
|
@@ -139,10 +140,14 @@ export async function statusCommand(options) {
|
|
|
139
140
|
// other reviewer stalled. Asking, stalling and recording all take the
|
|
140
141
|
// agent off it.
|
|
141
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;
|
|
142
146
|
const owes = part === "draft"
|
|
143
147
|
? !setAside &&
|
|
144
148
|
(atIt || outcome.status === "drafting" || outcome.status === "ready")
|
|
145
|
-
:
|
|
149
|
+
: !waiting &&
|
|
150
|
+
(atIt || outcome.status === "reviewing") &&
|
|
146
151
|
(await reviewerOwes(client, where.solutionId, outcome.name, where.agent));
|
|
147
152
|
if (options.json) {
|
|
148
153
|
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`);
|
|
@@ -22,10 +22,10 @@ export function parseThing(reference) {
|
|
|
22
22
|
return { kind, scoresId: rest };
|
|
23
23
|
case "pr": {
|
|
24
24
|
// PULL-3: the solution's pull request, by the reference
|
|
25
|
-
// `dotreq solution
|
|
25
|
+
// `dotreq solution pr open` printed.
|
|
26
26
|
const number = Number(rest.replace(/^#/, ""));
|
|
27
27
|
if (!Number.isInteger(number) || number <= 0) {
|
|
28
|
-
throw new Error(`"${reference}" isn't a pull request's reference. It is pr: and the pull request's number, as \`dotreq solution
|
|
28
|
+
throw new Error(`"${reference}" isn't a pull request's reference. It is pr: and the pull request's number, as \`dotreq solution pr open\` prints it, e.g. pr:42.`);
|
|
29
29
|
}
|
|
30
30
|
return { kind: "pull request", number };
|
|
31
31
|
}
|
|
@@ -4,7 +4,7 @@ import { requireWhere } from "./run-file.js";
|
|
|
4
4
|
import { outcomeFor } from "./status.js";
|
|
5
5
|
/**
|
|
6
6
|
* What `--latest` counts: what someone wrote — a submission note, a review
|
|
7
|
-
* result,
|
|
7
|
+
* result, a decision put to the person or their answer. A stall, a restart and a redraft
|
|
8
8
|
* because the outcome it is on was redrafted are on the thread but not
|
|
9
9
|
* counted, so a drafter revising after a restart reads the review it is
|
|
10
10
|
* answering, not the restart (VERB-6.4, 6.5).
|
package/dist/convex.d.ts
CHANGED
|
@@ -99,6 +99,7 @@ export declare const api: {
|
|
|
99
99
|
next: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
100
100
|
complete: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
101
101
|
ask: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
102
|
+
completeApproval: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
102
103
|
stall: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
103
104
|
answer: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
104
105
|
approveCheckpoint: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
@@ -121,6 +122,9 @@ export declare const api: {
|
|
|
121
122
|
recordPush: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
122
123
|
removal: import("convex/server").FunctionReference<"query", "public", any, any, string | undefined>;
|
|
123
124
|
};
|
|
125
|
+
waits: {
|
|
126
|
+
waitOnPullRequest: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
127
|
+
};
|
|
124
128
|
};
|
|
125
129
|
lib: {
|
|
126
130
|
authActions: {
|
package/dist/convex.js
CHANGED
|
@@ -112,6 +112,8 @@ export const api = {
|
|
|
112
112
|
next: mutation("solutions/mutations:next"),
|
|
113
113
|
complete: mutation("solutions/mutations:complete"),
|
|
114
114
|
ask: mutation("solutions/mutations:ask"),
|
|
115
|
+
// DECIDE-4: the action on the option the owner chose, taken once.
|
|
116
|
+
completeApproval: mutation("solutions/mutations:completeApproval"),
|
|
115
117
|
stall: mutation("solutions/mutations:stall"),
|
|
116
118
|
answer: mutation("solutions/mutations:answer"),
|
|
117
119
|
// A rehearsal's scripted approval of a checkpoint (CHECKPOINT-1.1).
|
|
@@ -141,6 +143,9 @@ export const api = {
|
|
|
141
143
|
recordPush: mutation("solutions/branches:recordPush"),
|
|
142
144
|
removal: query("solutions/branches:removal"),
|
|
143
145
|
},
|
|
146
|
+
waits: {
|
|
147
|
+
waitOnPullRequest: mutation("solutions/waits:waitOnPullRequest"),
|
|
148
|
+
},
|
|
144
149
|
},
|
|
145
150
|
lib: {
|
|
146
151
|
authActions: {
|
|
@@ -142,16 +142,15 @@ export type Script = {
|
|
|
142
142
|
/**
|
|
143
143
|
* Give this review result (reviewing), with the comment every result
|
|
144
144
|
* carries. An approval, with or without revisions, carries an executive
|
|
145
|
-
* summary (VERB-2.5), and needs revision
|
|
146
|
-
*
|
|
147
|
-
* (REHEARSE-1.1).
|
|
145
|
+
* summary (VERB-2.5), and needs revision carries none; a script that
|
|
146
|
+
* breaks either is refused, as the agent would be (REHEARSE-1.1).
|
|
148
147
|
*/
|
|
149
148
|
review?: {
|
|
150
|
-
outcome: "approved" | "approved with revisions" | "needs revision"
|
|
149
|
+
outcome: "approved" | "approved with revisions" | "needs revision";
|
|
151
150
|
comment: string;
|
|
152
151
|
summary?: string;
|
|
153
152
|
};
|
|
154
|
-
/** Put a decision to the person instead
|
|
153
|
+
/** Put a decision to the person instead, drafting or reviewing; a reviewer gives its result once she answers. */
|
|
155
154
|
ask?: unknown;
|
|
156
155
|
/** Stall instead. */
|
|
157
156
|
stall?: string;
|
|
@@ -160,7 +159,7 @@ export type Script = {
|
|
|
160
159
|
export type Party = "real" | Script | Script[];
|
|
161
160
|
/**
|
|
162
161
|
* What the person answers, in order asked: by an outcome's name, her answer
|
|
163
|
-
* to a
|
|
162
|
+
* to a decision its drafter or a reviewer put to her; by a checkpoint's name, her
|
|
164
163
|
* decision there, which a rehearsal gives only as an approval.
|
|
165
164
|
*/
|
|
166
165
|
export type PersonScript = Record<string, Array<{
|
|
@@ -296,7 +295,7 @@ export type RehearsalClient = {
|
|
|
296
295
|
/** With `made`: the drafter's executive summary (VERB-1.6). */
|
|
297
296
|
summary?: string;
|
|
298
297
|
review?: {
|
|
299
|
-
outcome: "approved" | "approved with revisions" | "needs revision"
|
|
298
|
+
outcome: "approved" | "approved with revisions" | "needs revision";
|
|
300
299
|
comment: string;
|
|
301
300
|
/** With an approval: the executive summary (VERB-2.5). */
|
|
302
301
|
summary?: string;
|
|
@@ -314,7 +313,7 @@ export type RehearsalClient = {
|
|
|
314
313
|
outcome: string;
|
|
315
314
|
reason: string;
|
|
316
315
|
}): Promise<void>;
|
|
317
|
-
/** The decision open on an outcome
|
|
316
|
+
/** The decision open on an outcome, its drafter's or a reviewer's, or null. Absent when the client can't answer for the person. */
|
|
318
317
|
openDecision?(solutionId: string, outcome: string): Promise<{
|
|
319
318
|
id: string;
|
|
320
319
|
} | null>;
|
package/package.json
CHANGED