@popoverai/dotrequirements 0.38.4 → 0.39.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/author.js +14 -2
- package/dist/commands/solution/brief.d.ts +2 -1
- package/dist/commands/solution/change.d.ts +12 -0
- package/dist/commands/solution/change.js +29 -0
- package/dist/commands/solution/index.js +7 -1
- package/dist/commands/solution/own-changes.d.ts +22 -0
- package/dist/commands/solution/own-changes.js +78 -0
- package/dist/commands/solution/pull-request.d.ts +5 -1
- package/dist/commands/solution/pull-request.js +7 -3
- package/dist/convex.d.ts +1 -0
- package/dist/convex.js +2 -0
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { api } from "../../convex.js";
|
|
|
4
4
|
import { currentBranch, headCommit, repositoryRoot } from "./branch.js";
|
|
5
5
|
import { solutionClient } from "./client.js";
|
|
6
6
|
import { readImage, uploadImage } from "./image.js";
|
|
7
|
+
import { ownChangesOf } from "./own-changes.js";
|
|
7
8
|
import { screenshotPreview } from "./preview-screenshot.js";
|
|
8
9
|
import { checkPullRequest } from "./pull-request.js";
|
|
9
10
|
import { pushBeforeRecord, refuseUncommitted } from "./pushing.js";
|
|
@@ -76,6 +77,12 @@ export async function authorCommand(references, options) {
|
|
|
76
77
|
// SOLDOC-12.2.0: a file from the checkout's own branch keeps the commit
|
|
77
78
|
// it was submitted at, so the page can tell when it changes after.
|
|
78
79
|
const commit = checkout ? headCommit(cwd) : null;
|
|
80
|
+
// CHECKPOINT-12.4 to 12.6: what the pull request would merge, taken after
|
|
81
|
+
// the push, so the checkpoint can tell a branch brought up to date from
|
|
82
|
+
// changed code. Without one, as when the fetch fails, the work is
|
|
83
|
+
// recorded all the same and reads as changed.
|
|
84
|
+
const merging = [...pullRequests.values()].find((made) => made.base);
|
|
85
|
+
const ownChanges = checkout && merging?.base ? ownChangesOf(cwd, merging.base) : null;
|
|
79
86
|
/** A reference as it is submitted: where the thing is, as the backend keeps it. */
|
|
80
87
|
const submissionOf = async (thing) => {
|
|
81
88
|
const recording = videos.get(thing);
|
|
@@ -99,8 +106,12 @@ export async function authorCommand(references, options) {
|
|
|
99
106
|
return { kind: "image", storageId, name: image.name };
|
|
100
107
|
}
|
|
101
108
|
const pullRequest = pullRequests.get(thing);
|
|
102
|
-
if (pullRequest)
|
|
103
|
-
|
|
109
|
+
if (pullRequest) {
|
|
110
|
+
// The branch it merges into is the CLI's, for `ownChanges`; the
|
|
111
|
+
// backend keeps the pull request by its number and address.
|
|
112
|
+
const { base: _base, ...kept } = pullRequest;
|
|
113
|
+
return { kind: "pull request", ...kept };
|
|
114
|
+
}
|
|
104
115
|
if (thing.kind === "preview") {
|
|
105
116
|
// SIGHT-12.0, 12.2: a screenshot of the page it opens on, kept as an
|
|
106
117
|
// image is; without one, it is submitted all the same.
|
|
@@ -141,6 +152,7 @@ export async function authorCommand(references, options) {
|
|
|
141
152
|
comment,
|
|
142
153
|
...(summary ? { summary } : {}),
|
|
143
154
|
...(files.length ? { files } : {}),
|
|
155
|
+
...(ownChanges ? { ownChanges } : {}),
|
|
144
156
|
};
|
|
145
157
|
const result = await client.mutation(api.solutions.mutations.complete, args);
|
|
146
158
|
const saved = result?.saved ?? [];
|
|
@@ -12,7 +12,8 @@
|
|
|
12
12
|
* images and demo scripts `next` saves in the checkout (SIGHT-9.3, 13.1).
|
|
13
13
|
*/
|
|
14
14
|
export type Brief = {
|
|
15
|
-
|
|
15
|
+
/** `request`: what the solution's agent asked it, which it answers (CONVO-11). */
|
|
16
|
+
kind: "step" | "review" | "request";
|
|
16
17
|
/** The outcome the agent took; `label` is its name too. */
|
|
17
18
|
step: {
|
|
18
19
|
label: string;
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { type WhereOptions } from "./run-file.js";
|
|
2
|
+
/**
|
|
3
|
+
* `dotreq solution change --comment "<what changed and why>"`: a made
|
|
4
|
+
* outcome's drafter, asked by the solution's agent to change it, records
|
|
5
|
+
* the change in place (VERB-8). Its commits are pushed first, as before any
|
|
6
|
+
* record (VERB-8.1, SOLBRANCH-3); the outcome stays made, and its history
|
|
7
|
+
* says what changed and why, at the solution's agent's request.
|
|
8
|
+
*/
|
|
9
|
+
export declare function changeCommand(options: WhereOptions & {
|
|
10
|
+
comment?: string;
|
|
11
|
+
}): Promise<void>;
|
|
12
|
+
//# sourceMappingURL=change.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
import { api } from "../../convex.js";
|
|
2
|
+
import { solutionClient } from "./client.js";
|
|
3
|
+
import { pushBeforeRecord } from "./pushing.js";
|
|
4
|
+
import { requireWhere } from "./run-file.js";
|
|
5
|
+
/**
|
|
6
|
+
* `dotreq solution change --comment "<what changed and why>"`: a made
|
|
7
|
+
* outcome's drafter, asked by the solution's agent to change it, records
|
|
8
|
+
* the change in place (VERB-8). Its commits are pushed first, as before any
|
|
9
|
+
* record (VERB-8.1, SOLBRANCH-3); the outcome stays made, and its history
|
|
10
|
+
* says what changed and why, at the solution's agent's request.
|
|
11
|
+
*/
|
|
12
|
+
export async function changeCommand(options) {
|
|
13
|
+
const comment = options.comment?.trim();
|
|
14
|
+
// VERB-8.3: what it says is all the history shows of the change.
|
|
15
|
+
if (!comment) {
|
|
16
|
+
throw new Error("Say what changed and why with --comment: what you say is what the outcome's history shows of the change.");
|
|
17
|
+
}
|
|
18
|
+
const where = requireWhere(options);
|
|
19
|
+
const client = solutionClient();
|
|
20
|
+
await pushBeforeRecord(client, where);
|
|
21
|
+
const { done } = await client.mutation(api.solutions.mutations.changeInPlace, {
|
|
22
|
+
solutionId: where.solutionId,
|
|
23
|
+
agent: where.agent,
|
|
24
|
+
...(where.outcome ? { outcome: where.outcome } : {}),
|
|
25
|
+
comment,
|
|
26
|
+
});
|
|
27
|
+
console.log(done);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=change.js.map
|
|
@@ -2,6 +2,7 @@ import { Option } from "commander";
|
|
|
2
2
|
import { approvalCompleteCommand } from "./approval.js";
|
|
3
3
|
import { askCommand } from "./ask.js";
|
|
4
4
|
import { authorCommand } from "./author.js";
|
|
5
|
+
import { changeCommand } from "./change.js";
|
|
5
6
|
import { checkoutCommand, pushCommand } from "./checkout.js";
|
|
6
7
|
import { REQUEST_CONTRACT } from "./contract.js";
|
|
7
8
|
import { createCommand } from "./create.js";
|
|
@@ -219,7 +220,7 @@ export function registerSolution(program) {
|
|
|
219
220
|
whereOptions(solution
|
|
220
221
|
.command("author <reference...>", HIDDEN)
|
|
221
222
|
.description("Record what you made, and what changed and why"))
|
|
222
|
-
.option("--comment <text>", "What changed and why: the next reader sees it first (required)")
|
|
223
|
+
.option("--comment <text>", "What changed and why: the next reader sees it first, so open on a sentence that stands on its own and says what changed (required)")
|
|
223
224
|
.option("--executive-summary <text>", "For the owner, when your work moves on before anyone reviews it (required there)")
|
|
224
225
|
.option("--summary <text>", "Short for --executive-summary")
|
|
225
226
|
.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])
|
|
@@ -269,6 +270,11 @@ export function registerSolution(program) {
|
|
|
269
270
|
whereOptions(solution
|
|
270
271
|
.command("things <name>", HIDDEN)
|
|
271
272
|
.description("What an outcome or an input holds now, or the outcomes a checkpoint presents: one reference a line")).action(wrap(thingsCommand));
|
|
273
|
+
whereOptions(solution
|
|
274
|
+
.command("change", HIDDEN)
|
|
275
|
+
.description("Record a change you made in place to a made outcome, as the solution's agent asked: what changed and why. The outcome stays made"))
|
|
276
|
+
.option("--comment <text>", "What changed and why: what the outcome's history shows of the change (required)")
|
|
277
|
+
.action(wrap(changeCommand));
|
|
272
278
|
whereOptions(solution
|
|
273
279
|
.command("stall <reason>", HIDDEN)
|
|
274
280
|
.description("Your work cannot go on, and no decision would fix that: what has to change before it can be started again"))
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pull request's own changes, fingerprinted from the checkout: what it
|
|
3
|
+
* would merge into `base`, as `git patch-id` sees it (CHECKPOINT-12.4 to
|
|
4
|
+
* 12.6). Merging a newer `base` in, or rebasing onto it, leaves the
|
|
5
|
+
* fingerprint as it was; resolving a conflict, a whitespace change or a new
|
|
6
|
+
* commit of the branch's own gives a new one.
|
|
7
|
+
*
|
|
8
|
+
* `--verbatim` keeps whitespace, and `-U0` drops the context lines and
|
|
9
|
+
* leaves line numbers only in the hunk headers, which `patch-id` ignores, so
|
|
10
|
+
* what moved under the change doesn't count as changing it. The cost, an
|
|
11
|
+
* accepted limit (12.4.0): a fix that only moves the branch's own lines
|
|
12
|
+
* elsewhere in the same file keeps the fingerprint too.
|
|
13
|
+
*
|
|
14
|
+
* Null when any step fails, the fetch included: the work is then recorded
|
|
15
|
+
* without one, and the checkpoint counts the pull request as changed
|
|
16
|
+
* (12.6). Never throws.
|
|
17
|
+
*/
|
|
18
|
+
export declare function ownChangesOf(cwd: string, base: string): {
|
|
19
|
+
commit: string;
|
|
20
|
+
patchId: string;
|
|
21
|
+
} | null;
|
|
22
|
+
//# sourceMappingURL=own-changes.d.ts.map
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
/**
|
|
3
|
+
* The pull request's own changes, fingerprinted from the checkout: what it
|
|
4
|
+
* would merge into `base`, as `git patch-id` sees it (CHECKPOINT-12.4 to
|
|
5
|
+
* 12.6). Merging a newer `base` in, or rebasing onto it, leaves the
|
|
6
|
+
* fingerprint as it was; resolving a conflict, a whitespace change or a new
|
|
7
|
+
* commit of the branch's own gives a new one.
|
|
8
|
+
*
|
|
9
|
+
* `--verbatim` keeps whitespace, and `-U0` drops the context lines and
|
|
10
|
+
* leaves line numbers only in the hunk headers, which `patch-id` ignores, so
|
|
11
|
+
* what moved under the change doesn't count as changing it. The cost, an
|
|
12
|
+
* accepted limit (12.4.0): a fix that only moves the branch's own lines
|
|
13
|
+
* elsewhere in the same file keeps the fingerprint too.
|
|
14
|
+
*
|
|
15
|
+
* Null when any step fails, the fetch included: the work is then recorded
|
|
16
|
+
* without one, and the checkpoint counts the pull request as changed
|
|
17
|
+
* (12.6). Never throws.
|
|
18
|
+
*/
|
|
19
|
+
export function ownChangesOf(cwd, base) {
|
|
20
|
+
try {
|
|
21
|
+
// The base as the repository has it now: an older one would put its
|
|
22
|
+
// newer commits, merged into the branch, among the branch's own.
|
|
23
|
+
const fetched = run(cwd, [
|
|
24
|
+
"fetch",
|
|
25
|
+
"--quiet",
|
|
26
|
+
"origin",
|
|
27
|
+
`+refs/heads/${base}:refs/remotes/origin/${base}`,
|
|
28
|
+
]);
|
|
29
|
+
if (!fetched)
|
|
30
|
+
return null;
|
|
31
|
+
const commit = text(run(cwd, ["rev-parse", "--verify", "--quiet", "HEAD"]));
|
|
32
|
+
if (!commit)
|
|
33
|
+
return null;
|
|
34
|
+
const mergeBase = text(run(cwd, ["merge-base", "HEAD", `refs/remotes/origin/${base}`]));
|
|
35
|
+
if (!mergeBase)
|
|
36
|
+
return null;
|
|
37
|
+
const diff = run(cwd, [
|
|
38
|
+
"diff",
|
|
39
|
+
"--no-ext-diff",
|
|
40
|
+
"--no-textconv",
|
|
41
|
+
"--no-color",
|
|
42
|
+
"--binary",
|
|
43
|
+
"-U0",
|
|
44
|
+
mergeBase,
|
|
45
|
+
commit,
|
|
46
|
+
]);
|
|
47
|
+
if (!diff)
|
|
48
|
+
return null;
|
|
49
|
+
// `patch-id` prints nothing for an empty diff.
|
|
50
|
+
if (diff.length === 0)
|
|
51
|
+
return { commit, patchId: "empty" };
|
|
52
|
+
const id = run(cwd, ["patch-id", "--verbatim"], diff);
|
|
53
|
+
if (!id)
|
|
54
|
+
return null;
|
|
55
|
+
// A diff it gives no id for, as one only changing a file's mode, can't
|
|
56
|
+
// be told from another: no fingerprint.
|
|
57
|
+
const patchId = text(id)?.split(/\s+/)[0];
|
|
58
|
+
return patchId ? { commit, patchId } : null;
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
return null;
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
/** Git's stdout, as bytes, or null when it failed. */
|
|
65
|
+
function run(cwd, args, input) {
|
|
66
|
+
const ran = spawnSync("git", args, {
|
|
67
|
+
cwd,
|
|
68
|
+
input,
|
|
69
|
+
maxBuffer: 1024 * 1024 * 1024,
|
|
70
|
+
// A fetch that wants a password fails rather than waiting for one.
|
|
71
|
+
env: { ...process.env, GIT_TERMINAL_PROMPT: "0" },
|
|
72
|
+
});
|
|
73
|
+
return ran.status === 0 && !ran.error ? ran.stdout : null;
|
|
74
|
+
}
|
|
75
|
+
function text(out) {
|
|
76
|
+
return out?.toString("utf8").trim() || null;
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=own-changes.js.map
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
import { type Where, type WhereOptions } from "./run-file.js";
|
|
2
|
-
/**
|
|
2
|
+
/**
|
|
3
|
+
* The solution's pull request: its number and where it opens, and, when
|
|
4
|
+
* checked by its number, the branch it merges into (CHECKPOINT-12.4).
|
|
5
|
+
*/
|
|
3
6
|
export type PullRequest = {
|
|
4
7
|
url: string;
|
|
5
8
|
number: number;
|
|
9
|
+
base?: string;
|
|
6
10
|
};
|
|
7
11
|
/** The command that opens the solution's pull request and prints its reference. */
|
|
8
12
|
export declare const OPEN_IT = "dotreq solution pr open";
|
|
@@ -91,9 +91,13 @@ export async function checkPullRequest(where, number) {
|
|
|
91
91
|
return pullRequest;
|
|
92
92
|
}
|
|
93
93
|
function pullRequestIn(said) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
94
|
+
if (!said.url || typeof said.number !== "number")
|
|
95
|
+
return null;
|
|
96
|
+
return {
|
|
97
|
+
url: said.url,
|
|
98
|
+
number: said.number,
|
|
99
|
+
...(typeof said.base === "string" && said.base ? { base: said.base } : {}),
|
|
100
|
+
};
|
|
97
101
|
}
|
|
98
102
|
/**
|
|
99
103
|
* Ask the app's pull-request route, on the project's credentials: with the
|
package/dist/convex.d.ts
CHANGED
|
@@ -101,6 +101,7 @@ export declare const api: {
|
|
|
101
101
|
ask: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
102
102
|
completeApproval: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
103
103
|
stall: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
104
|
+
changeInPlace: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
104
105
|
answer: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
105
106
|
approveCheckpoint: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
|
106
107
|
removeRehearsal: import("convex/server").FunctionReference<"mutation", "public", any, any, string | undefined>;
|
package/dist/convex.js
CHANGED
|
@@ -115,6 +115,8 @@ export const api = {
|
|
|
115
115
|
// DECIDE-4: the action on the option the owner chose, taken once.
|
|
116
116
|
completeApproval: mutation("solutions/mutations:completeApproval"),
|
|
117
117
|
stall: mutation("solutions/mutations:stall"),
|
|
118
|
+
// VERB-8: a made outcome's drafter's change in place.
|
|
119
|
+
changeInPlace: mutation("solutions/mutations:changeInPlace"),
|
|
118
120
|
answer: mutation("solutions/mutations:answer"),
|
|
119
121
|
// A rehearsal's scripted approval of a checkpoint (CHECKPOINT-1.1).
|
|
120
122
|
approveCheckpoint: mutation("solutions/mutations:approveCheckpoint"),
|
package/package.json
CHANGED