@cueloop/daemon 0.1.0-alpha.62 → 0.1.0-alpha.63
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 +2 -2
- package/src/review.test.ts +24 -0
- package/src/review.ts +6 -2
- package/src/validate.test.ts +9 -6
- package/src/validate.ts +4 -1
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cueloop/daemon",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.63",
|
|
4
4
|
"description": "The cueloop session daemon and its client: socket protocol, atomic store, resumable waits",
|
|
5
5
|
"homepage": "https://github.com/mmurakaru/cueloop#readme",
|
|
6
6
|
"bugs": {
|
|
@@ -33,7 +33,7 @@
|
|
|
33
33
|
"access": "public"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@cueloop/schema": "0.1.0-alpha.
|
|
36
|
+
"@cueloop/schema": "0.1.0-alpha.63",
|
|
37
37
|
"valibot": "^1.4.2"
|
|
38
38
|
},
|
|
39
39
|
"engines": {
|
package/src/review.test.ts
CHANGED
|
@@ -159,6 +159,30 @@ describe("openReview", () => {
|
|
|
159
159
|
expect(other.id).not.toBe(first.id);
|
|
160
160
|
});
|
|
161
161
|
|
|
162
|
+
test("the same agentSessionId with a different type opens a new session, never a type mismatch", async () => {
|
|
163
|
+
// Arrange - the agent session's plan review is open
|
|
164
|
+
const plan = await openReview(client, {
|
|
165
|
+
type: "plan",
|
|
166
|
+
content: PLAN,
|
|
167
|
+
cwd: home,
|
|
168
|
+
agentSessionId: "agent-cross",
|
|
169
|
+
});
|
|
170
|
+
|
|
171
|
+
// Act - the same agent session now submits a reply for review
|
|
172
|
+
const reply = await openReview(client, {
|
|
173
|
+
type: "reply",
|
|
174
|
+
content: "# Findings\n\nThe cache is fine.\n",
|
|
175
|
+
cwd: home,
|
|
176
|
+
agentSessionId: "agent-cross",
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Assert - a fresh reply session; the plan session keeps its type and history
|
|
180
|
+
expect(reply.id).not.toBe(plan.id);
|
|
181
|
+
expect(reply.session.artifact.type).toBe("reply");
|
|
182
|
+
expect(reply.session.revisions.length).toBe(1);
|
|
183
|
+
expect((await client.sessionGet(plan.id)).artifact.type).toBe("plan");
|
|
184
|
+
});
|
|
185
|
+
|
|
162
186
|
test("per-file notes land as note annotations anchored at the file path", async () => {
|
|
163
187
|
// Act
|
|
164
188
|
const review = await openReview(client, {
|
package/src/review.ts
CHANGED
|
@@ -245,10 +245,14 @@ export async function openReview(
|
|
|
245
245
|
const cwd = options.cwd ?? process.cwd();
|
|
246
246
|
const workspace = options.workspace ?? (await resolveWorkspace(cwd));
|
|
247
247
|
|
|
248
|
-
// Resubmits from the same agent session become revisions, not new sessions
|
|
248
|
+
// Resubmits from the same agent session become revisions, not new sessions -
|
|
249
|
+
// but only within the same primitive: a different artifact type is a new
|
|
250
|
+
// review, never a silent type mismatch on the old session.
|
|
249
251
|
if (options.agentSessionId !== undefined) {
|
|
250
252
|
const existing = (await client.sessionList()).find(
|
|
251
|
-
(candidate) =>
|
|
253
|
+
(candidate) =>
|
|
254
|
+
candidate.artifact.meta.agentSessionId === options.agentSessionId &&
|
|
255
|
+
candidate.artifact.type === options.type,
|
|
252
256
|
);
|
|
253
257
|
|
|
254
258
|
if (existing !== undefined) {
|
package/src/validate.test.ts
CHANGED
|
@@ -19,6 +19,7 @@ import {
|
|
|
19
19
|
validateSessionRecord,
|
|
20
20
|
} from "./validate";
|
|
21
21
|
import {
|
|
22
|
+
ARTIFACT_TYPES,
|
|
22
23
|
SCHEMA_VERSION,
|
|
23
24
|
type Anchor,
|
|
24
25
|
type Annotation,
|
|
@@ -61,13 +62,15 @@ describe("parseParams", () => {
|
|
|
61
62
|
}
|
|
62
63
|
});
|
|
63
64
|
|
|
64
|
-
test("accepts
|
|
65
|
-
const
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
65
|
+
test("accepts every artifact type in the schema union", () => {
|
|
66
|
+
for (const type of ARTIFACT_TYPES) {
|
|
67
|
+
const params = parseParams("session.create", {
|
|
68
|
+
workspace: { repoRoot: "/repo", branch: "main" },
|
|
69
|
+
artifact: { type, content: "body" },
|
|
70
|
+
});
|
|
69
71
|
|
|
70
|
-
|
|
72
|
+
expect(params.artifact.type).toBe(type);
|
|
73
|
+
}
|
|
71
74
|
});
|
|
72
75
|
|
|
73
76
|
test("rejects an unknown artifact type", () => {
|
package/src/validate.ts
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
|
|
12
12
|
import * as v from "valibot";
|
|
13
13
|
import {
|
|
14
|
+
ARTIFACT_TYPES,
|
|
14
15
|
SCHEMA_VERSION,
|
|
15
16
|
type Anchor,
|
|
16
17
|
type Annotation,
|
|
@@ -60,7 +61,9 @@ export const DiffFileContentsSchema = v.object({
|
|
|
60
61
|
} satisfies EntriesOf<DiffFileContents>);
|
|
61
62
|
|
|
62
63
|
export const ArtifactSchema = v.object({
|
|
63
|
-
|
|
64
|
+
// Derived from the schema's runtime union: a new primitive extends the wire
|
|
65
|
+
// contract without touching this file.
|
|
66
|
+
type: v.picklist(ARTIFACT_TYPES),
|
|
64
67
|
content: v.string(),
|
|
65
68
|
meta: v.optional(ArtifactMetaSchema, {}),
|
|
66
69
|
files: v.optional(v.array(DiffFileContentsSchema)),
|