@primusclaw/personal-agent-runtime 0.2.0 → 0.3.0
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/index.js
CHANGED
|
@@ -3360,6 +3360,7 @@ var SqliteIdempotencyRepository = class {
|
|
|
3360
3360
|
};
|
|
3361
3361
|
|
|
3362
3362
|
// packages/runtime/src/sqlite/link-repository.ts
|
|
3363
|
+
import { createHash as createHash2 } from "node:crypto";
|
|
3363
3364
|
import {
|
|
3364
3365
|
CODE_ALPHABET,
|
|
3365
3366
|
CODE_LENGTH,
|
|
@@ -3378,8 +3379,12 @@ function forgetRepos(db, userId) {
|
|
|
3378
3379
|
}
|
|
3379
3380
|
|
|
3380
3381
|
// packages/runtime/src/sqlite/link-repository.ts
|
|
3382
|
+
function tokenHash(credential) {
|
|
3383
|
+
return createHash2("sha256").update(credential).digest("hex");
|
|
3384
|
+
}
|
|
3381
3385
|
var PERSON_TABLES = [
|
|
3382
3386
|
"links",
|
|
3387
|
+
"bound_users",
|
|
3383
3388
|
"sessions",
|
|
3384
3389
|
"conversation_refs",
|
|
3385
3390
|
"held_events",
|
|
@@ -3478,6 +3483,7 @@ var SqliteLinkRepository = class {
|
|
|
3478
3483
|
col.bytes(row, "key_enc"),
|
|
3479
3484
|
now
|
|
3480
3485
|
);
|
|
3486
|
+
db.run("DELETE FROM bound_users WHERE aad_id = ?", userId);
|
|
3481
3487
|
forgetNotifySub(db, userId);
|
|
3482
3488
|
forgetRepos(db, userId);
|
|
3483
3489
|
db.run("DELETE FROM sessions WHERE aad_id = ?", userId);
|
|
@@ -3510,12 +3516,39 @@ var SqliteLinkRepository = class {
|
|
|
3510
3516
|
setClawUserId(userId, clawUserId) {
|
|
3511
3517
|
this.ctx.db.run("UPDATE links SET claw_user_id = ? WHERE aad_id = ?", clawUserId, userId);
|
|
3512
3518
|
}
|
|
3519
|
+
boundClawUser(userId, credential) {
|
|
3520
|
+
const row = this.ctx.db.get("SELECT claw_user_id, token_hash FROM bound_users WHERE aad_id = ?", userId);
|
|
3521
|
+
if (row === void 0) return null;
|
|
3522
|
+
return { clawUserId: col.str(row, "claw_user_id"), current: col.str(row, "token_hash") === tokenHash(credential) };
|
|
3523
|
+
}
|
|
3524
|
+
/** Ignored for a linked person (a link's id is read for its key). Another account than before forgets the subscription. */
|
|
3525
|
+
setBoundClawUser(userId, clawUserId, credential) {
|
|
3526
|
+
const { db } = this.ctx;
|
|
3527
|
+
if (db.get("SELECT 1 AS one FROM links WHERE aad_id = ?", userId) !== void 0) return;
|
|
3528
|
+
const before = db.get("SELECT claw_user_id FROM bound_users WHERE aad_id = ?", userId);
|
|
3529
|
+
if (before !== void 0 && col.str(before, "claw_user_id") !== clawUserId) forgetNotifySub(db, userId);
|
|
3530
|
+
db.run(
|
|
3531
|
+
"INSERT OR REPLACE INTO bound_users (aad_id, claw_user_id, token_hash, updated_at) VALUES (?, ?, ?, ?)",
|
|
3532
|
+
userId,
|
|
3533
|
+
clawUserId,
|
|
3534
|
+
tokenHash(credential),
|
|
3535
|
+
this.ctx.now()
|
|
3536
|
+
);
|
|
3537
|
+
}
|
|
3538
|
+
/** Ignored for a linked person: their link keeps its own subscription. */
|
|
3539
|
+
forgetBound(userId) {
|
|
3540
|
+
const { db } = this.ctx;
|
|
3541
|
+
if (db.get("SELECT 1 AS one FROM links WHERE aad_id = ?", userId) !== void 0) return;
|
|
3542
|
+
if (db.run("DELETE FROM bound_users WHERE aad_id = ?", userId) > 0) forgetNotifySub(db, userId);
|
|
3543
|
+
}
|
|
3513
3544
|
needsClawUserId(userId) {
|
|
3514
3545
|
const row = this.ctx.db.get("SELECT claw_user_id FROM links WHERE aad_id = ?", userId);
|
|
3515
3546
|
return row !== void 0 && !col.bool(row, "claw_user_id");
|
|
3516
3547
|
}
|
|
3548
|
+
/** The link's (a linked person's id is never taken from anywhere else), else the bound person's. */
|
|
3517
3549
|
clawUserIdOf(userId) {
|
|
3518
|
-
const
|
|
3550
|
+
const { db } = this.ctx;
|
|
3551
|
+
const row = db.get("SELECT claw_user_id FROM links WHERE aad_id = ?", userId) ?? db.get("SELECT claw_user_id FROM bound_users WHERE aad_id = ?", userId);
|
|
3519
3552
|
return row && col.bool(row, "claw_user_id") ? col.str(row, "claw_user_id") : null;
|
|
3520
3553
|
}
|
|
3521
3554
|
linkedUsers() {
|
package/dist/sqlite/schema.sql
CHANGED
|
@@ -122,3 +122,5 @@ CREATE TABLE IF NOT EXISTS observe_cards (
|
|
|
122
122
|
CREATE INDEX IF NOT EXISTS observe_cards_by_suggestion ON observe_cards (aad_id, run_id, seq);
|
|
123
123
|
CREATE TABLE IF NOT EXISTS group_context_off (
|
|
124
124
|
conversation_id TEXT PRIMARY KEY, updated_at REAL NOT NULL);
|
|
125
|
+
CREATE TABLE IF NOT EXISTS bound_users (
|
|
126
|
+
aad_id TEXT PRIMARY KEY, claw_user_id TEXT NOT NULL, token_hash TEXT NOT NULL, updated_at REAL NOT NULL);
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
/** LinkRepository on SQLite (tables `links`, `pending_keys`, `link_attempts`). */
|
|
2
1
|
import { type LinkLimits, type LinkRepository, type RedeemOutcome } from "@primusclaw/personal-agent";
|
|
3
2
|
import { type StoreContext, type SecurityEventSink } from "./context.js";
|
|
4
3
|
export declare class SqliteLinkRepository implements LinkRepository {
|
|
@@ -19,7 +18,16 @@ export declare class SqliteLinkRepository implements LinkRepository {
|
|
|
19
18
|
getKey(userId: string): string | null;
|
|
20
19
|
unlink(userId: string): void;
|
|
21
20
|
setClawUserId(userId: string, clawUserId: string): void;
|
|
21
|
+
boundClawUser(userId: string, credential: string): {
|
|
22
|
+
clawUserId: string;
|
|
23
|
+
current: boolean;
|
|
24
|
+
} | null;
|
|
25
|
+
/** Ignored for a linked person (a link's id is read for its key). Another account than before forgets the subscription. */
|
|
26
|
+
setBoundClawUser(userId: string, clawUserId: string, credential: string): void;
|
|
27
|
+
/** Ignored for a linked person: their link keeps its own subscription. */
|
|
28
|
+
forgetBound(userId: string): void;
|
|
22
29
|
needsClawUserId(userId: string): boolean;
|
|
30
|
+
/** The link's (a linked person's id is never taken from anywhere else), else the bound person's. */
|
|
23
31
|
clawUserIdOf(userId: string): string | null;
|
|
24
32
|
linkedUsers(): string[];
|
|
25
33
|
userForClawUser(clawUserId: string): string | null;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@primusclaw/personal-agent-runtime",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.0",
|
|
4
4
|
"description": "Node adapters for the personal agent's ports: clock, randomness, logging (and, as the port lands, storage, Claw, metrics, HTTP).",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"access": "public"
|
|
30
30
|
},
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@primusclaw/personal-agent": "0.
|
|
32
|
+
"@primusclaw/personal-agent": "0.3.0",
|
|
33
33
|
"fastify": "^5.12.8",
|
|
34
34
|
"zod": "^4.6.7"
|
|
35
35
|
}
|