@cueloop/daemon 0.1.0-alpha.38 → 0.1.0-alpha.39
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/api.test.ts +23 -0
- package/src/api.ts +16 -1
- package/src/client.ts +11 -3
- package/src/server.ts +1 -1
- package/src/validate.ts +5 -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.39",
|
|
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": {
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"access": "public"
|
|
29
29
|
},
|
|
30
30
|
"dependencies": {
|
|
31
|
-
"@cueloop/schema": "0.1.0-alpha.
|
|
31
|
+
"@cueloop/schema": "0.1.0-alpha.39",
|
|
32
32
|
"valibot": "^1.4.2"
|
|
33
33
|
},
|
|
34
34
|
"engines": {
|
package/src/api.test.ts
CHANGED
|
@@ -63,6 +63,29 @@ describe("session lifecycle", () => {
|
|
|
63
63
|
expect(core.sessionGet(session.id).annotations.length).toBe(0);
|
|
64
64
|
});
|
|
65
65
|
|
|
66
|
+
test("annotate with an author registers them in the participant registry", () => {
|
|
67
|
+
// Arrange
|
|
68
|
+
const session = core.sessionCreate({ workspace: WS, artifact: PLAN });
|
|
69
|
+
|
|
70
|
+
// Act
|
|
71
|
+
core.sessionAnnotate(
|
|
72
|
+
session.id,
|
|
73
|
+
{
|
|
74
|
+
id: "a1",
|
|
75
|
+
kind: "comment",
|
|
76
|
+
anchor: { quote: "carefully", prefix: "the thing ", suffix: "." },
|
|
77
|
+
body: "A collaborator's note.",
|
|
78
|
+
author: "SHA256:ana",
|
|
79
|
+
},
|
|
80
|
+
"Ana",
|
|
81
|
+
);
|
|
82
|
+
|
|
83
|
+
// Assert
|
|
84
|
+
const stored = core.sessionGet(session.id);
|
|
85
|
+
expect(stored.annotations[0]!.author).toBe("SHA256:ana");
|
|
86
|
+
expect(stored.participants).toEqual([{ id: "SHA256:ana", provider: "ssh", name: "Ana" }]);
|
|
87
|
+
});
|
|
88
|
+
|
|
66
89
|
test("resolve produces feedback.md and maps to the agent contract", () => {
|
|
67
90
|
// Arrange
|
|
68
91
|
const session = core.sessionCreate({ workspace: WS, artifact: PLAN });
|
package/src/api.ts
CHANGED
|
@@ -11,6 +11,7 @@ import {
|
|
|
11
11
|
isAddressed,
|
|
12
12
|
isAgentNote,
|
|
13
13
|
parseBlocks,
|
|
14
|
+
registerParticipant,
|
|
14
15
|
resolveAnchor,
|
|
15
16
|
verdictAllows,
|
|
16
17
|
type Annotation,
|
|
@@ -143,7 +144,15 @@ export class DaemonCore {
|
|
|
143
144
|
});
|
|
144
145
|
}
|
|
145
146
|
|
|
146
|
-
|
|
147
|
+
/**
|
|
148
|
+
* `authorName` registers the annotation's author in the participant registry;
|
|
149
|
+
* a bare author id (no name) keeps its short-handle fallback instead.
|
|
150
|
+
*/
|
|
151
|
+
sessionAnnotate(
|
|
152
|
+
id: string,
|
|
153
|
+
annotation: Omit<Annotation, "createdAt">,
|
|
154
|
+
authorName?: string,
|
|
155
|
+
): ReviewSession {
|
|
147
156
|
const session = this.mutable(id);
|
|
148
157
|
const existing = session.annotations.findIndex((candidate) => candidate.id === annotation.id);
|
|
149
158
|
const full: Annotation = { ...annotation, createdAt: new Date().toISOString() };
|
|
@@ -153,6 +162,12 @@ export class DaemonCore {
|
|
|
153
162
|
...full,
|
|
154
163
|
createdAt: session.annotations[existing]!.createdAt,
|
|
155
164
|
};
|
|
165
|
+
if (annotation.author && authorName)
|
|
166
|
+
session.participants = registerParticipant(
|
|
167
|
+
session,
|
|
168
|
+
annotation.author,
|
|
169
|
+
authorName,
|
|
170
|
+
).participants;
|
|
156
171
|
this.store.upsert(session);
|
|
157
172
|
this.emit("session.updated", id);
|
|
158
173
|
return session;
|
package/src/client.ts
CHANGED
|
@@ -38,7 +38,11 @@ export interface SessionClient {
|
|
|
38
38
|
subscribe(): Promise<void>;
|
|
39
39
|
sessionGet(id: string): Promise<ReviewSession>;
|
|
40
40
|
sessionList(filter?: { status?: "pending" | "resolved" }): Promise<ReviewSession[]>;
|
|
41
|
-
sessionAnnotate(
|
|
41
|
+
sessionAnnotate(
|
|
42
|
+
id: string,
|
|
43
|
+
annotation: Omit<Annotation, "createdAt">,
|
|
44
|
+
authorName?: string,
|
|
45
|
+
): Promise<ReviewSession>;
|
|
42
46
|
sessionRemoveAnnotation(id: string, annotationId: string): Promise<ReviewSession>;
|
|
43
47
|
sessionSetWorkingCopy(id: string, workingCopy: string | undefined): Promise<ReviewSession>;
|
|
44
48
|
sessionSetViewed(id: string, viewedPaths: string[]): Promise<ReviewSession>;
|
|
@@ -188,8 +192,12 @@ export class DaemonClient implements SessionClient {
|
|
|
188
192
|
sessionWait(id: string, timeoutMs: number): Promise<ReviewSession | null> {
|
|
189
193
|
return this.request("session.wait", { id, timeoutMs }, timeoutMs + 10_000);
|
|
190
194
|
}
|
|
191
|
-
sessionAnnotate(
|
|
192
|
-
|
|
195
|
+
sessionAnnotate(
|
|
196
|
+
id: string,
|
|
197
|
+
annotation: Omit<Annotation, "createdAt">,
|
|
198
|
+
authorName?: string,
|
|
199
|
+
): Promise<ReviewSession> {
|
|
200
|
+
return this.request("session.annotate", { id, annotation, authorName });
|
|
193
201
|
}
|
|
194
202
|
sessionRemoveAnnotation(id: string, annotationId: string): Promise<ReviewSession> {
|
|
195
203
|
return this.request("session.removeAnnotation", { id, annotationId });
|
package/src/server.ts
CHANGED
|
@@ -246,7 +246,7 @@ export class DaemonServer {
|
|
|
246
246
|
}
|
|
247
247
|
case "session.annotate": {
|
|
248
248
|
const params = parseParams("session.annotate", request.params);
|
|
249
|
-
return core.sessionAnnotate(params.id, params.annotation);
|
|
249
|
+
return core.sessionAnnotate(params.id, params.annotation, params.authorName);
|
|
250
250
|
}
|
|
251
251
|
case "session.removeAnnotation": {
|
|
252
252
|
const params = parseParams("session.removeAnnotation", request.params);
|
package/src/validate.ts
CHANGED
|
@@ -125,7 +125,11 @@ export const Params = {
|
|
|
125
125
|
60_000,
|
|
126
126
|
),
|
|
127
127
|
}),
|
|
128
|
-
"session.annotate": v.object({
|
|
128
|
+
"session.annotate": v.object({
|
|
129
|
+
id: SessionId,
|
|
130
|
+
annotation: AnnotationSchema,
|
|
131
|
+
authorName: v.optional(v.string()),
|
|
132
|
+
}),
|
|
129
133
|
"session.removeAnnotation": v.object({ id: SessionId, annotationId: NonEmpty }),
|
|
130
134
|
"session.setWorkingCopy": v.object({ id: SessionId, workingCopy: v.optional(v.string()) }),
|
|
131
135
|
"session.setViewed": v.object({ id: SessionId, viewedPaths: v.array(v.string()) }),
|