@cueloop/schema 0.1.0-alpha.45 → 0.1.0-alpha.47
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/package.json +1 -1
- package/src/feedback.test.ts +24 -1
- package/src/feedback.ts +17 -8
- package/src/types.ts +5 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cueloop/schema",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.47",
|
|
4
4
|
"description": "The ReviewSession primitive: types, markdown block model, quote-primary anchors, feedback serialization",
|
|
5
5
|
"homepage": "https://github.com/mmurakaru/cueloop#readme",
|
|
6
6
|
"bugs": {
|
package/src/feedback.test.ts
CHANGED
|
@@ -34,7 +34,7 @@ describe("renderFeedback", () => {
|
|
|
34
34
|
artifactContent: PLAN,
|
|
35
35
|
workingCopy: PLAN.replace("one JSON document", "one JSON record"),
|
|
36
36
|
annotations: [],
|
|
37
|
-
|
|
37
|
+
artifactPath: "docs/plan.md",
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
// Assert
|
|
@@ -200,4 +200,27 @@ describe("renderFeedback", () => {
|
|
|
200
200
|
// Assert
|
|
201
201
|
expect(feedback).toContain("(§ Persistence)");
|
|
202
202
|
});
|
|
203
|
+
|
|
204
|
+
test("a prototype annotation locates by its selector and is never orphan-flagged", () => {
|
|
205
|
+
// Act
|
|
206
|
+
const feedback = renderFeedback({
|
|
207
|
+
verdictKind: "request_changes",
|
|
208
|
+
summary: "",
|
|
209
|
+
artifactType: "prototype",
|
|
210
|
+
artifactContent: "<main><div class='card'>Pricing</div></main>",
|
|
211
|
+
annotations: [
|
|
212
|
+
makeAnnotation({
|
|
213
|
+
body: "Tighten the padding.",
|
|
214
|
+
anchor: { quote: "Pricing", prefix: "", suffix: "", selector: "main > div.card" },
|
|
215
|
+
}),
|
|
216
|
+
],
|
|
217
|
+
artifactPath: "proto.html",
|
|
218
|
+
});
|
|
219
|
+
|
|
220
|
+
// Assert
|
|
221
|
+
expect(feedback).toContain("(main > div.card)");
|
|
222
|
+
expect(feedback).toContain("Tighten the padding.");
|
|
223
|
+
expect(feedback).toContain("by its CSS selector");
|
|
224
|
+
expect(feedback).not.toContain("orphaned anchor");
|
|
225
|
+
});
|
|
203
226
|
});
|
package/src/feedback.ts
CHANGED
|
@@ -28,8 +28,8 @@ export interface FeedbackInput {
|
|
|
28
28
|
/** Artifact kind; defaults to "plan". A diff working copy is already a patch. */
|
|
29
29
|
artifactType?: ArtifactType;
|
|
30
30
|
annotations: Annotation[];
|
|
31
|
-
/** Path the agent knows the plan
|
|
32
|
-
|
|
31
|
+
/** Path the agent knows the artifact by (plan or prototype), for direct reference. */
|
|
32
|
+
artifactPath?: string;
|
|
33
33
|
/** Session id, so the document can teach the addressed-ids resubmit call. */
|
|
34
34
|
sessionId?: string;
|
|
35
35
|
}
|
|
@@ -37,7 +37,7 @@ export interface FeedbackInput {
|
|
|
37
37
|
const quoteLines = (text: string) => "> " + text.replace(/\n/g, "\n> ");
|
|
38
38
|
|
|
39
39
|
export function renderFeedback(input: FeedbackInput): string {
|
|
40
|
-
const path = input.
|
|
40
|
+
const path = input.artifactPath ?? "plan.md";
|
|
41
41
|
// agent notes are the submitter's own context - never echoed back as
|
|
42
42
|
// feedback - and annotations a previous revision already addressed stay out
|
|
43
43
|
// of the next document, so the agent only ever sees the open items
|
|
@@ -45,6 +45,7 @@ export function renderFeedback(input: FeedbackInput): string {
|
|
|
45
45
|
(annotation) => !isAgentNote(annotation) && !isAddressed(annotation),
|
|
46
46
|
);
|
|
47
47
|
const isDiff = input.artifactType === "diff";
|
|
48
|
+
const isPrototype = input.artifactType === "prototype";
|
|
48
49
|
// A diff's annotations anchor to the submitted patch rows; resolve against it,
|
|
49
50
|
// not the curated working copy (which may drop the rejected rows).
|
|
50
51
|
const blocks = parseBlocks(
|
|
@@ -98,14 +99,22 @@ export function renderFeedback(input: FeedbackInput): string {
|
|
|
98
99
|
if (annotations.length) {
|
|
99
100
|
lines.push(`## Annotations (${annotations.length})`);
|
|
100
101
|
lines.push("");
|
|
101
|
-
lines.push(
|
|
102
|
+
lines.push(
|
|
103
|
+
isPrototype
|
|
104
|
+
? `Address every item. Locate each one in ${path} by its CSS selector.`
|
|
105
|
+
: `Address every item. Locate each one in ${path} by its quoted text.`,
|
|
106
|
+
);
|
|
102
107
|
lines.push("");
|
|
103
108
|
annotations.forEach((annotation, annotationIndex) => {
|
|
104
|
-
|
|
109
|
+
// a prototype selector anchor is never resolved or orphaned against blocks
|
|
110
|
+
const selector = annotation.anchor.selector;
|
|
111
|
+
const resolved = selector ? null : resolveAnchor(annotation.anchor, blocks);
|
|
105
112
|
const sectionTitle = resolved ? sectionOf(blocks, resolved.blockIndex) : "";
|
|
106
|
-
const location = sectionTitle ? ` (§ ${sectionTitle})` : "";
|
|
113
|
+
const location = selector ? ` (${selector})` : sectionTitle ? ` (§ ${sectionTitle})` : "";
|
|
107
114
|
const orphanFlag =
|
|
108
|
-
resolved === null
|
|
115
|
+
!selector && resolved === null
|
|
116
|
+
? " [orphaned anchor: the quoted text is no longer present]"
|
|
117
|
+
: "";
|
|
109
118
|
lines.push(
|
|
110
119
|
`### ${annotationIndex + 1}. ${capitalize(annotation.kind)}${location}${orphanFlag}`,
|
|
111
120
|
);
|
|
@@ -151,7 +160,7 @@ export function feedbackForSession(
|
|
|
151
160
|
workingCopy: session.workingCopy,
|
|
152
161
|
artifactType: session.artifact.type,
|
|
153
162
|
annotations: session.annotations,
|
|
154
|
-
|
|
163
|
+
artifactPath: session.artifact.meta.prototypePath ?? session.artifact.meta.planPath,
|
|
155
164
|
sessionId: session.id,
|
|
156
165
|
});
|
|
157
166
|
}
|
package/src/types.ts
CHANGED
|
@@ -12,7 +12,7 @@ export interface WorkspaceKey {
|
|
|
12
12
|
branch: string;
|
|
13
13
|
}
|
|
14
14
|
|
|
15
|
-
export type ArtifactType = "plan" | "diff";
|
|
15
|
+
export type ArtifactType = "plan" | "diff" | "prototype";
|
|
16
16
|
|
|
17
17
|
export interface ArtifactMeta {
|
|
18
18
|
cwd?: string;
|
|
@@ -21,6 +21,8 @@ export interface ArtifactMeta {
|
|
|
21
21
|
agentSessionId?: string;
|
|
22
22
|
/** Path to the plan file on disk, so feedback can reference it. */
|
|
23
23
|
planPath?: string;
|
|
24
|
+
/** Path to the prototype's entry HTML file on disk. */
|
|
25
|
+
prototypePath?: string;
|
|
24
26
|
/** Pull request reference the diff came from, so the verdict can be posted back. */
|
|
25
27
|
pr?: string;
|
|
26
28
|
/** herdr pane the submitting agent runs in - the review returns focus there. */
|
|
@@ -67,6 +69,8 @@ export interface Anchor {
|
|
|
67
69
|
/** Character offsets within that block's text (hint). */
|
|
68
70
|
start?: number;
|
|
69
71
|
end?: number;
|
|
72
|
+
/** Prototype anchors: the CSS selector of the annotated element (authority). */
|
|
73
|
+
selector?: string;
|
|
70
74
|
}
|
|
71
75
|
|
|
72
76
|
/** The annotation kind set is open; these are the built-ins. */
|