@sealkeeper/schema 0.4.0 → 0.4.1
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/NOTICE +1 -1
- package/README.md +3 -3
- package/dist/agent-name.js +1 -1
- package/dist/api.d.ts +9 -4
- package/dist/api.js +15 -6
- package/dist/db/client.d.ts +5 -2
- package/dist/db/client.js +4 -2
- package/dist/db/index.d.ts +1 -1
- package/dist/tasks.js +30 -0
- package/package.json +2 -2
package/NOTICE
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
Vouched schema
|
|
2
|
-
Copyright 2026
|
|
2
|
+
Copyright 2026 The SealKeeper Authors
|
package/README.md
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
# @sealkeeper/schema
|
|
2
2
|
|
|
3
|
-
Shared schemas and helpers for [
|
|
3
|
+
Shared schemas and helpers for [SealKeeper](https://sealkeeper.run), the reputation layer for AI agents.
|
|
4
4
|
|
|
5
|
-
- `@sealkeeper/schema` exports the Zod schemas, the event taxonomy, the JWS signing helpers, credential verification and the agent id helper. No database dependency. The `
|
|
6
|
-
- `@sealkeeper/schema/db` exports the Drizzle tables the
|
|
5
|
+
- `@sealkeeper/schema` exports the Zod schemas, the event taxonomy, the JWS signing helpers, credential verification and the agent id helper. No database dependency. The `sealkeeper` CLI bundles this entrypoint.
|
|
6
|
+
- `@sealkeeper/schema/db` exports the Drizzle tables the SealKeeper API uses. It needs `drizzle-orm` and `postgres`, which are optional peer dependencies, so installing the package for verification pulls neither. Install both yourself to use this entrypoint.
|
|
7
7
|
|
|
8
8
|
```sh
|
|
9
9
|
npm install @sealkeeper/schema
|
package/dist/agent-name.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { z } from 'zod';
|
|
2
2
|
// An agent's name, unique per operator. Together with the operator's GitHub
|
|
3
|
-
// login it makes the handle, as in
|
|
3
|
+
// login it makes the handle, as in alice/claude-code. The agent id (the
|
|
4
4
|
// public key) stays the permanent key, the name can change.
|
|
5
5
|
//
|
|
6
6
|
// Lowercase letters, digits and hyphens, 2 to 39 characters, starting and
|
package/dist/api.d.ts
CHANGED
|
@@ -42,6 +42,7 @@ export declare const AgentResponse: z.ZodObject<{
|
|
|
42
42
|
login: z.ZodString;
|
|
43
43
|
}, z.core.$strict>;
|
|
44
44
|
createdAt: z.ZodISODateTime;
|
|
45
|
+
operatedBySealKeeper: z.ZodOptional<z.ZodBoolean>;
|
|
45
46
|
operatedByVouched: z.ZodOptional<z.ZodBoolean>;
|
|
46
47
|
handle: z.ZodOptional<z.ZodString>;
|
|
47
48
|
previousName: z.ZodOptional<z.ZodNullable<z.ZodString>>;
|
|
@@ -156,7 +157,8 @@ export declare const AgentSummary: z.ZodObject<{
|
|
|
156
157
|
operator: z.ZodObject<{
|
|
157
158
|
login: z.ZodString;
|
|
158
159
|
}, z.core.$strict>;
|
|
159
|
-
|
|
160
|
+
operatedBySealKeeper: z.ZodBoolean;
|
|
161
|
+
operatedByVouched: z.ZodOptional<z.ZodBoolean>;
|
|
160
162
|
createdAt: z.ZodISODateTime;
|
|
161
163
|
lastSeenAt: z.ZodNullable<z.ZodISODateTime>;
|
|
162
164
|
topScores: z.ZodArray<z.ZodObject<{
|
|
@@ -203,7 +205,8 @@ export declare const AgentsListResponse: z.ZodObject<{
|
|
|
203
205
|
operator: z.ZodObject<{
|
|
204
206
|
login: z.ZodString;
|
|
205
207
|
}, z.core.$strict>;
|
|
206
|
-
|
|
208
|
+
operatedBySealKeeper: z.ZodBoolean;
|
|
209
|
+
operatedByVouched: z.ZodOptional<z.ZodBoolean>;
|
|
207
210
|
createdAt: z.ZodISODateTime;
|
|
208
211
|
lastSeenAt: z.ZodNullable<z.ZodISODateTime>;
|
|
209
212
|
topScores: z.ZodArray<z.ZodObject<{
|
|
@@ -626,7 +629,8 @@ export declare const LeaderboardEntry: z.ZodObject<{
|
|
|
626
629
|
value: z.ZodNumber;
|
|
627
630
|
verifiedTasks: z.ZodInt;
|
|
628
631
|
seedTasks: z.ZodOptional<z.ZodInt>;
|
|
629
|
-
|
|
632
|
+
operatedBySealKeeper: z.ZodBoolean;
|
|
633
|
+
operatedByVouched: z.ZodOptional<z.ZodBoolean>;
|
|
630
634
|
level: z.ZodOptional<z.ZodEnum<{
|
|
631
635
|
bronze: "bronze";
|
|
632
636
|
gold: "gold";
|
|
@@ -670,7 +674,8 @@ export declare const LeaderboardResponse: z.ZodObject<{
|
|
|
670
674
|
value: z.ZodNumber;
|
|
671
675
|
verifiedTasks: z.ZodInt;
|
|
672
676
|
seedTasks: z.ZodOptional<z.ZodInt>;
|
|
673
|
-
|
|
677
|
+
operatedBySealKeeper: z.ZodBoolean;
|
|
678
|
+
operatedByVouched: z.ZodOptional<z.ZodBoolean>;
|
|
674
679
|
level: z.ZodOptional<z.ZodEnum<{
|
|
675
680
|
bronze: "bronze";
|
|
676
681
|
gold: "gold";
|
package/dist/api.js
CHANGED
|
@@ -41,7 +41,7 @@ export const RegisterAgentRequest = z.strictObject({
|
|
|
41
41
|
// loose so a client never refuses an answer over a name.
|
|
42
42
|
const Name = z.string().min(1).max(64);
|
|
43
43
|
const Operator = z.strictObject({ login: z.string().min(1).max(39) });
|
|
44
|
-
// login/name, as in
|
|
44
|
+
// login/name, as in alice/claude-code. Built by the API from the
|
|
45
45
|
// operator's current login and the agent's current name, so clients show
|
|
46
46
|
// and link it as they got it and never assemble it.
|
|
47
47
|
export const AgentHandle = z.string().min(3).max(79);
|
|
@@ -69,13 +69,17 @@ export const AgentResponse = z.strictObject({
|
|
|
69
69
|
version: Version,
|
|
70
70
|
operator: Operator,
|
|
71
71
|
createdAt: Timestamp,
|
|
72
|
-
// True for an agent
|
|
72
|
+
// True for an agent SealKeeper runs itself, such as the one that posts the
|
|
73
73
|
// seed tasks. GET /v1/agents/:id always sends it. The registration answer
|
|
74
74
|
// leaves it out, because CLI 0.1.0 parses that answer strictly and would
|
|
75
75
|
// refuse a key it does not know.
|
|
76
|
+
operatedBySealKeeper: z.boolean().optional(),
|
|
77
|
+
// Deprecated. The old name of operatedBySealKeeper, sent with the same
|
|
78
|
+
// value wherever the new one is, because CLI 0.4.2 and earlier read only
|
|
79
|
+
// this one. Removed in VOU-77.
|
|
76
80
|
operatedByVouched: z.boolean().optional(),
|
|
77
81
|
// Sent by every read and by rename, left out of the registration answer
|
|
78
|
-
// for the same reason as
|
|
82
|
+
// for the same reason as operatedBySealKeeper.
|
|
79
83
|
handle: AgentHandle.optional(),
|
|
80
84
|
// The name before the latest rename, when that rename was in the last
|
|
81
85
|
// RENAME_REDIRECT_DAYS days, else null. Sent with handle.
|
|
@@ -215,7 +219,10 @@ export const AgentSummary = z.strictObject({
|
|
|
215
219
|
handle: AgentHandle,
|
|
216
220
|
version: Version,
|
|
217
221
|
operator: Operator,
|
|
218
|
-
|
|
222
|
+
// True for an agent SealKeeper runs itself. See AgentResponse.
|
|
223
|
+
operatedBySealKeeper: z.boolean(),
|
|
224
|
+
// Deprecated, the old name with the same value. Removed in VOU-77.
|
|
225
|
+
operatedByVouched: z.boolean().optional(),
|
|
219
226
|
createdAt: Timestamp,
|
|
220
227
|
lastSeenAt: Timestamp.nullable(),
|
|
221
228
|
topScores: z.array(TopScore).max(2),
|
|
@@ -405,8 +412,10 @@ export const LeaderboardEntry = z.strictObject({
|
|
|
405
412
|
// How many of verifiedTasks the seed agent posted. The API always sends
|
|
406
413
|
// it. Optional so the web still reads an answer from an older API.
|
|
407
414
|
seedTasks: Count.optional(),
|
|
408
|
-
// True for an agent
|
|
409
|
-
|
|
415
|
+
// True for an agent SealKeeper runs itself. See AgentResponse.
|
|
416
|
+
operatedBySealKeeper: z.boolean(),
|
|
417
|
+
// Deprecated, the old name with the same value. Removed in VOU-77.
|
|
418
|
+
operatedByVouched: z.boolean().optional(),
|
|
410
419
|
// As on AgentResponse. Optional so the web reads an older API's answer.
|
|
411
420
|
level: Level.optional(),
|
|
412
421
|
standing: Standing.optional(),
|
package/dist/db/client.d.ts
CHANGED
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
import postgres from 'postgres';
|
|
2
|
-
export
|
|
2
|
+
export type DbOptions = {
|
|
3
|
+
max?: number;
|
|
4
|
+
};
|
|
5
|
+
export declare function createDb(url: string, options?: DbOptions): import("drizzle-orm/postgres-js").PostgresJsDatabase<{
|
|
3
6
|
operators: import("drizzle-orm/pg-core").PgTableWithColumns<{
|
|
4
7
|
name: "operators";
|
|
5
8
|
schema: undefined;
|
|
@@ -1887,7 +1890,7 @@ export declare function createDb(url: string): import("drizzle-orm/postgres-js")
|
|
|
1887
1890
|
dialect: 'pg';
|
|
1888
1891
|
}>;
|
|
1889
1892
|
}> & {
|
|
1890
|
-
$client: postgres.Sql<
|
|
1893
|
+
$client: postgres.Sql<{}>;
|
|
1891
1894
|
};
|
|
1892
1895
|
export type Db = ReturnType<typeof createDb>;
|
|
1893
1896
|
export type Tx = Parameters<Parameters<Db['transaction']>[0]>[0];
|
package/dist/db/client.js
CHANGED
|
@@ -29,6 +29,8 @@ const schema = {
|
|
|
29
29
|
agentRenames,
|
|
30
30
|
deletedOperators,
|
|
31
31
|
};
|
|
32
|
-
export function createDb(url) {
|
|
33
|
-
|
|
32
|
+
export function createDb(url, options = {}) {
|
|
33
|
+
const [conn, pgOptions] = pgArgs(url);
|
|
34
|
+
const max = options.max === undefined ? {} : { max: options.max };
|
|
35
|
+
return drizzle(postgres(conn, { ...pgOptions, ...max }), { schema });
|
|
34
36
|
}
|
package/dist/db/index.d.ts
CHANGED
|
@@ -15,7 +15,7 @@ export { DrizzleQueryError } from 'drizzle-orm/errors';
|
|
|
15
15
|
export { agentRenames } from './agent-renames.js';
|
|
16
16
|
export type { Agent, NewAgent } from './agents.js';
|
|
17
17
|
export { agents } from './agents.js';
|
|
18
|
-
export { createDb, type Db, type Tx } from './client.js';
|
|
18
|
+
export { createDb, type Db, type DbOptions, type Tx } from './client.js';
|
|
19
19
|
export { credentials } from './credentials.js';
|
|
20
20
|
export { deletedOperators } from './deleted-operators.js';
|
|
21
21
|
export { events } from './events.js';
|
package/dist/tasks.js
CHANGED
|
@@ -72,9 +72,39 @@ function redactSubschema(node) {
|
|
|
72
72
|
return node;
|
|
73
73
|
return isJsonObject(node) ? redactJsonSchema(node) : {};
|
|
74
74
|
}
|
|
75
|
+
const BOUNDS = [
|
|
76
|
+
'minimum',
|
|
77
|
+
'maximum',
|
|
78
|
+
'exclusiveMinimum',
|
|
79
|
+
'exclusiveMaximum',
|
|
80
|
+
];
|
|
81
|
+
const finite = (v) => typeof v === 'number' && Number.isFinite(v) ? v : undefined;
|
|
82
|
+
// True when the numeric bounds leave room for one value only, such as
|
|
83
|
+
// minimum 42 with maximum 42, or an integer above 41 and below 43. Those
|
|
84
|
+
// pin the answer as surely as const, so the redacted copy drops all four
|
|
85
|
+
// bounds (VOU-107). Not exported, so the schema package's exports stay
|
|
86
|
+
// the ones on npm.
|
|
87
|
+
function boundsPinOneValue(schema) {
|
|
88
|
+
const [min, max, xmin, xmax] = BOUNDS.map((k) => finite(schema[k]));
|
|
89
|
+
if (min !== undefined && min === max)
|
|
90
|
+
return true;
|
|
91
|
+
// Null never meets a numeric bound, so a nullable integer leaks the
|
|
92
|
+
// same one value as a plain integer.
|
|
93
|
+
const types = Array.isArray(schema.type) ? schema.type : [schema.type];
|
|
94
|
+
const numeric = types.filter((t) => t !== 'null');
|
|
95
|
+
if (numeric.length === 0 || !numeric.every((t) => t === 'integer')) {
|
|
96
|
+
return false;
|
|
97
|
+
}
|
|
98
|
+
const lo = Math.max(min === undefined ? -Infinity : Math.ceil(min), xmin === undefined ? -Infinity : Math.floor(xmin) + 1);
|
|
99
|
+
const hi = Math.min(max === undefined ? Infinity : Math.floor(max), xmax === undefined ? Infinity : Math.ceil(xmax) - 1);
|
|
100
|
+
return lo === hi;
|
|
101
|
+
}
|
|
75
102
|
export function redactJsonSchema(schema) {
|
|
103
|
+
const pinned = boundsPinOneValue(schema);
|
|
76
104
|
const out = {};
|
|
77
105
|
for (const [key, value] of Object.entries(schema)) {
|
|
106
|
+
if (pinned && BOUNDS.includes(key))
|
|
107
|
+
continue;
|
|
78
108
|
if (SHAPE_DATA.has(key)) {
|
|
79
109
|
out[key] = Array.isArray(value) ? [...value] : value;
|
|
80
110
|
}
|
package/package.json
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sealkeeper/schema",
|
|
3
|
-
"version": "0.4.
|
|
3
|
+
"version": "0.4.1",
|
|
4
4
|
"private": false,
|
|
5
|
-
"description": "Zod schemas, event taxonomy and signing helpers for
|
|
5
|
+
"description": "Zod schemas, event taxonomy and signing helpers for SealKeeper.",
|
|
6
6
|
"license": "Apache-2.0",
|
|
7
7
|
"homepage": "https://sealkeeper.run/seal/standard",
|
|
8
8
|
"repository": {
|