@cueloop/daemon 0.1.0-alpha.76 → 0.1.0-alpha.78
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.ts +11 -0
- package/src/capabilities.ts +1 -0
- package/src/client.ts +5 -0
- package/src/review.ts +2 -2
- package/src/server.ts +5 -0
- package/src/validate.test.ts +20 -0
- package/src/validate.ts +6 -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.78",
|
|
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": {
|
|
@@ -35,7 +35,7 @@
|
|
|
35
35
|
"access": "public"
|
|
36
36
|
},
|
|
37
37
|
"dependencies": {
|
|
38
|
-
"@cueloop/schema": "0.1.0-alpha.
|
|
38
|
+
"@cueloop/schema": "0.1.0-alpha.78",
|
|
39
39
|
"@pierre/diffs": "^1.3.6",
|
|
40
40
|
"effect": "^4.0.0-rc.115",
|
|
41
41
|
"valibot": "^1.4.2"
|
package/src/api.ts
CHANGED
|
@@ -432,6 +432,17 @@ export class DaemonCore {
|
|
|
432
432
|
return session;
|
|
433
433
|
}
|
|
434
434
|
|
|
435
|
+
/** Set the private-share allowlist of GitHub logins; presence marks the share private. */
|
|
436
|
+
sessionSetAccess(id: string, githubLogins: string[]): Thread {
|
|
437
|
+
const session = this.mutable(id);
|
|
438
|
+
|
|
439
|
+
session.access = { githubLogins };
|
|
440
|
+
this.store.upsert(session);
|
|
441
|
+
this.emit("session.updated", id);
|
|
442
|
+
|
|
443
|
+
return session;
|
|
444
|
+
}
|
|
445
|
+
|
|
435
446
|
/** Remove a session for good (inbox delete); resolved or pending, both go. */
|
|
436
447
|
sessionDelete(id: string): void {
|
|
437
448
|
const session = this.store.get(id);
|
package/src/capabilities.ts
CHANGED
|
@@ -35,6 +35,7 @@ const PRIMITIVE_ROLES = {
|
|
|
35
35
|
"session.cutBlock": "owner",
|
|
36
36
|
"session.restoreBlock": "owner",
|
|
37
37
|
"session.curate": "owner",
|
|
38
|
+
"session.setAccess": "owner",
|
|
38
39
|
"session.setViewed": "owner",
|
|
39
40
|
"session.setTitle": "owner",
|
|
40
41
|
// reading the local working tree is the owner's alone; a share carries no repo to read
|
package/src/client.ts
CHANGED
|
@@ -88,6 +88,8 @@ export interface SessionClient {
|
|
|
88
88
|
sessionRestoreBlock(id: string, baseBlockIndex: number, line?: number): Promise<Thread>;
|
|
89
89
|
/** Replace a diff review's reject decisions; the working copy follows. */
|
|
90
90
|
sessionCurate(id: string, rejections: HunkRejection[]): Promise<Thread>;
|
|
91
|
+
/** Replace the private-share allowlist of GitHub logins; presence marks the share private. */
|
|
92
|
+
sessionSetAccess(id: string, githubLogins: string[]): Promise<Thread>;
|
|
91
93
|
sessionSetViewed(id: string, viewedPaths: string[]): Promise<Thread>;
|
|
92
94
|
/** Rename a session's display title; an empty title restores the derived default. */
|
|
93
95
|
sessionSetTitle(id: string, title: string): Promise<Thread>;
|
|
@@ -450,6 +452,9 @@ export class DaemonClient implements SessionClient {
|
|
|
450
452
|
sessionCurate(id: string, rejections: HunkRejection[]): Promise<Thread> {
|
|
451
453
|
return this.request("session.curate", { id, rejections }, ThreadRecordSchema);
|
|
452
454
|
}
|
|
455
|
+
sessionSetAccess(id: string, githubLogins: string[]): Promise<Thread> {
|
|
456
|
+
return this.request("session.setAccess", { id, githubLogins }, ThreadRecordSchema);
|
|
457
|
+
}
|
|
453
458
|
sessionSetViewed(id: string, viewedPaths: string[]): Promise<Thread> {
|
|
454
459
|
return this.request("session.setViewed", { id, viewedPaths }, ThreadRecordSchema);
|
|
455
460
|
}
|
package/src/review.ts
CHANGED
|
@@ -196,7 +196,7 @@ export interface AwaitResolveOptions {
|
|
|
196
196
|
}
|
|
197
197
|
|
|
198
198
|
/**
|
|
199
|
-
* Park until a
|
|
199
|
+
* Park until a thread resolves, then return the verdict outcome; null
|
|
200
200
|
* when the signal aborts first. Where ReviewHandle.awaitVerdict needs the handle
|
|
201
201
|
* that opened the review, this needs only a session id - so a background waiter
|
|
202
202
|
* that woke on a session it did not open (a detached Claude Code / Codex waiter,
|
|
@@ -220,7 +220,7 @@ export async function awaitResolve(
|
|
|
220
220
|
return resolved === null ? null : outcome(resolved);
|
|
221
221
|
}
|
|
222
222
|
|
|
223
|
-
/** Open a
|
|
223
|
+
/** Open a thread (or revise the agent session's existing one) and hand back the wait surface. */
|
|
224
224
|
export async function openReview(
|
|
225
225
|
client: DaemonClient,
|
|
226
226
|
options: OpenReviewOptions,
|
package/src/server.ts
CHANGED
|
@@ -385,6 +385,11 @@ export class DaemonServer {
|
|
|
385
385
|
|
|
386
386
|
return this.core.sessionCurate(params.id, params.rejections);
|
|
387
387
|
},
|
|
388
|
+
"session.setAccess": (_connection, request) => {
|
|
389
|
+
const params = parseParams("session.setAccess", request.params);
|
|
390
|
+
|
|
391
|
+
return this.core.sessionSetAccess(params.id, params.githubLogins);
|
|
392
|
+
},
|
|
388
393
|
"session.setViewed": (_connection, request) => {
|
|
389
394
|
const params = parseParams("session.setViewed", request.params);
|
|
390
395
|
|
package/src/validate.test.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { describe, expect, test } from "bun:test";
|
|
2
|
+
import * as v from "valibot";
|
|
2
3
|
import { mkdtempSync, rmSync } from "node:fs";
|
|
3
4
|
import { tmpdir } from "node:os";
|
|
4
5
|
import { join } from "node:path";
|
|
@@ -280,6 +281,7 @@ describe("wire pins", () => {
|
|
|
280
281
|
createdAt: "now",
|
|
281
282
|
shareId: "p_abc123xy",
|
|
282
283
|
owner: "SHA256:owner",
|
|
284
|
+
access: { githubLogins: ["octocat"] },
|
|
283
285
|
participants: [fullIdentity],
|
|
284
286
|
};
|
|
285
287
|
|
|
@@ -346,3 +348,21 @@ describe("wire pins", () => {
|
|
|
346
348
|
}
|
|
347
349
|
});
|
|
348
350
|
});
|
|
351
|
+
|
|
352
|
+
describe("IdentitySchema provider", () => {
|
|
353
|
+
test("accepts a verified github identity", () => {
|
|
354
|
+
const parsed = v.safeParse(IdentitySchema, {
|
|
355
|
+
id: "SHA256:abc",
|
|
356
|
+
provider: "github",
|
|
357
|
+
name: "markus",
|
|
358
|
+
});
|
|
359
|
+
|
|
360
|
+
expect(parsed.success).toBe(true);
|
|
361
|
+
});
|
|
362
|
+
|
|
363
|
+
test("rejects an unknown provider", () => {
|
|
364
|
+
const parsed = v.safeParse(IdentitySchema, { id: "SHA256:abc", provider: "email" });
|
|
365
|
+
|
|
366
|
+
expect(parsed.success).toBe(false);
|
|
367
|
+
});
|
|
368
|
+
});
|
package/src/validate.ts
CHANGED
|
@@ -24,6 +24,7 @@ import {
|
|
|
24
24
|
type HunkRejection,
|
|
25
25
|
type Revision,
|
|
26
26
|
type SessionHistory,
|
|
27
|
+
type ShareAccess,
|
|
27
28
|
validateHistory,
|
|
28
29
|
type Verdict,
|
|
29
30
|
type WorkspaceKey,
|
|
@@ -125,7 +126,7 @@ export const FullAnnotationSchema = v.object({
|
|
|
125
126
|
|
|
126
127
|
export const IdentitySchema = v.object({
|
|
127
128
|
id: NonEmpty,
|
|
128
|
-
provider: v.
|
|
129
|
+
provider: v.picklist(["ssh", "github"]),
|
|
129
130
|
name: v.optional(v.string()),
|
|
130
131
|
handle: v.optional(v.string()),
|
|
131
132
|
} satisfies EntriesOf<Identity>);
|
|
@@ -204,6 +205,7 @@ export const Params = {
|
|
|
204
205
|
"session.fork": v.object({ id: SessionId }),
|
|
205
206
|
"session.refreshDiff": v.object({ id: SessionId }),
|
|
206
207
|
"session.setShareId": v.object({ id: SessionId, shareId: NonEmpty }),
|
|
208
|
+
"session.setAccess": v.object({ id: SessionId, githubLogins: v.array(NonEmpty) }),
|
|
207
209
|
"session.delete": v.object({ id: SessionId }),
|
|
208
210
|
"session.mergeShared": v.object({
|
|
209
211
|
id: SessionId,
|
|
@@ -349,6 +351,9 @@ export const ThreadRecordSchema = v.object({
|
|
|
349
351
|
shareId: v.optional(v.string()),
|
|
350
352
|
shareBranch: v.optional(v.string()),
|
|
351
353
|
owner: v.optional(v.string()),
|
|
354
|
+
access: v.optional(
|
|
355
|
+
v.object({ githubLogins: v.array(NonEmpty) } satisfies EntriesOf<ShareAccess>),
|
|
356
|
+
),
|
|
352
357
|
participants: v.optional(v.array(IdentitySchema)),
|
|
353
358
|
} satisfies EntriesOf<Thread>);
|
|
354
359
|
|