@byok-sdk/core 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/attestation.d.ts +7 -0
- package/dist/blob.d.ts +42 -1
- package/dist/device-assertion.d.ts +224 -0
- package/dist/errors.d.ts +4 -0
- package/dist/in-memory/index.d.ts +1 -0
- package/dist/in-memory/skill-pack.d.ts +25 -0
- package/dist/index.d.ts +11 -6
- package/dist/index.js +524 -41
- package/dist/index.js.map +1 -1
- package/dist/mailbox.d.ts +14 -2
- package/dist/pairing.d.ts +38 -0
- package/dist/ports-contract.d.ts +18 -1
- package/dist/skill-pack.d.ts +251 -0
- package/dist/stores.d.ts +10 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -13,6 +13,12 @@ var CORE_ERROR_CODES = {
|
|
|
13
13
|
// device proof (§12.6.3)
|
|
14
14
|
proof_envelope_invalid: "proof_envelope_invalid",
|
|
15
15
|
proof_canonicalization_failed: "proof_canonicalization_failed",
|
|
16
|
+
// device assertion (plan device-assertion-broker) — deliberately its own
|
|
17
|
+
// code rather than reusing `proof_envelope_invalid`: the two envelopes are
|
|
18
|
+
// non-interchangeable by design, and one shared "envelope was bad" code is
|
|
19
|
+
// exactly how a log stops being able to say which authentication surface was
|
|
20
|
+
// probed.
|
|
21
|
+
assertion_envelope_invalid: "assertion_envelope_invalid",
|
|
16
22
|
// mailbox (§12.7.3)
|
|
17
23
|
mailbox_message_not_found: "mailbox_message_not_found",
|
|
18
24
|
mailbox_cursor_regression: "mailbox_cursor_regression",
|
|
@@ -33,6 +39,7 @@ var CORE_ERROR_CODES = {
|
|
|
33
39
|
hint_ttl_invalid: "hint_ttl_invalid",
|
|
34
40
|
hint_rate_limited: "hint_rate_limited",
|
|
35
41
|
// object manifest (§12.7.4, §12.7.8)
|
|
42
|
+
object_key_prefix_invalid: "object_key_prefix_invalid",
|
|
36
43
|
object_not_found: "object_not_found",
|
|
37
44
|
object_state_invalid: "object_state_invalid",
|
|
38
45
|
// storage entitlement / usage / reservation (§12.7.6-12.7.7)
|
|
@@ -43,7 +50,10 @@ var CORE_ERROR_CODES = {
|
|
|
43
50
|
storage_quota_exceeded: "storage_quota_exceeded",
|
|
44
51
|
storage_reservation_expired: "storage_reservation_expired",
|
|
45
52
|
storage_integrity_mismatch: "storage_integrity_mismatch",
|
|
46
|
-
storage_write_suspended: "storage_write_suspended"
|
|
53
|
+
storage_write_suspended: "storage_write_suspended",
|
|
54
|
+
// skill packs (plan `skill-pack-delivery-channel`)
|
|
55
|
+
skill_pack_manifest_invalid: "skill_pack_manifest_invalid",
|
|
56
|
+
skill_pack_frontmatter_invalid: "skill_pack_frontmatter_invalid"
|
|
47
57
|
};
|
|
48
58
|
var ByokCoreError = class extends Error {
|
|
49
59
|
code;
|
|
@@ -179,9 +189,20 @@ function contentHash(value) {
|
|
|
179
189
|
function isContentHash(value) {
|
|
180
190
|
return typeof value === "string" && CONTENT_HASH_PATTERN.test(value);
|
|
181
191
|
}
|
|
182
|
-
|
|
192
|
+
var OBJECT_KEY_PREFIX_PATTERN = /^[a-z0-9][a-z0-9._-]*(\/[a-z0-9][a-z0-9._-]*)*$/;
|
|
193
|
+
function objectKeyPrefix(value) {
|
|
194
|
+
if (!OBJECT_KEY_PREFIX_PATTERN.test(value)) {
|
|
195
|
+
throw new ByokCoreError(
|
|
196
|
+
"object_key_prefix_invalid",
|
|
197
|
+
`Object key prefix must match ${OBJECT_KEY_PREFIX_PATTERN.source}, received ${JSON.stringify(value)}.`
|
|
198
|
+
);
|
|
199
|
+
}
|
|
200
|
+
return value;
|
|
201
|
+
}
|
|
202
|
+
function tenantObjectKey(tenant, hash, prefix) {
|
|
183
203
|
const hex = hash.slice("sha256:".length);
|
|
184
|
-
|
|
204
|
+
const key = `tenants/${tenant}/objects/sha256/${hex}`;
|
|
205
|
+
return prefix === void 0 ? key : `${prefix}/${key}`;
|
|
185
206
|
}
|
|
186
207
|
var OBJECT_STATES = ["pending", "committed", "delete_pending", "deleted"];
|
|
187
208
|
var OBJECT_STATE_TRANSITIONS = {
|
|
@@ -259,6 +280,248 @@ function assertCapability(declaration, capability) {
|
|
|
259
280
|
);
|
|
260
281
|
}
|
|
261
282
|
}
|
|
283
|
+
var SKILL_PACK_MANIFEST_SCHEMA_ID = "byok-skill-pack-v1";
|
|
284
|
+
var SKILL_PACK_NAME_PATTERN = /^[a-z0-9][a-z0-9._-]*$/;
|
|
285
|
+
var SKILL_PACK_NAME_MAX_LENGTH = 64;
|
|
286
|
+
var SKILL_PACK_DESCRIPTION_MAX_LENGTH = 1024;
|
|
287
|
+
var SKILL_PACK_VERSION_PATTERN = /^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)$/;
|
|
288
|
+
var SKILL_PACK_FILE_PATH_PATTERN = /^[A-Za-z0-9][A-Za-z0-9._-]*(\/[A-Za-z0-9][A-Za-z0-9._-]*)*$/;
|
|
289
|
+
var SKILL_PACK_FILE_PATH_MAX_LENGTH = 200;
|
|
290
|
+
var SKILL_PACK_ENTRY_PATH = "SKILL.md";
|
|
291
|
+
var SKILL_PACK_FILE_MAX_BYTES = 262144;
|
|
292
|
+
var SKILL_PACK_MAX_BYTES = 1048576;
|
|
293
|
+
var SKILL_PACK_MAX_FILES = 64;
|
|
294
|
+
var SKILL_PACK_FORBIDDEN_FIELDS = [
|
|
295
|
+
"exec",
|
|
296
|
+
"command",
|
|
297
|
+
"entrypoint",
|
|
298
|
+
"run",
|
|
299
|
+
"script",
|
|
300
|
+
"shell",
|
|
301
|
+
"env",
|
|
302
|
+
"environment",
|
|
303
|
+
"credential",
|
|
304
|
+
"credentials",
|
|
305
|
+
"secret",
|
|
306
|
+
"secrets",
|
|
307
|
+
"token",
|
|
308
|
+
"apiKey",
|
|
309
|
+
"api_key",
|
|
310
|
+
"allowedTools",
|
|
311
|
+
"allowed-tools",
|
|
312
|
+
"hooks",
|
|
313
|
+
"preinstall",
|
|
314
|
+
"postinstall"
|
|
315
|
+
];
|
|
316
|
+
var ContentHashSchema = z.string().regex(CONTENT_HASH_PATTERN).transform((value) => contentHash(value));
|
|
317
|
+
var SkillPackFileSchema = z.strictObject({
|
|
318
|
+
path: z.string().min(1).max(SKILL_PACK_FILE_PATH_MAX_LENGTH).regex(SKILL_PACK_FILE_PATH_PATTERN),
|
|
319
|
+
contentHash: ContentHashSchema,
|
|
320
|
+
byteSize: z.number().int().nonnegative().max(SKILL_PACK_FILE_MAX_BYTES)
|
|
321
|
+
});
|
|
322
|
+
var SkillPackManifestSchema = z.strictObject({
|
|
323
|
+
schema: z.literal(SKILL_PACK_MANIFEST_SCHEMA_ID),
|
|
324
|
+
name: z.string().min(1).max(SKILL_PACK_NAME_MAX_LENGTH).regex(SKILL_PACK_NAME_PATTERN),
|
|
325
|
+
version: z.string().regex(SKILL_PACK_VERSION_PATTERN),
|
|
326
|
+
description: z.string().min(1).max(SKILL_PACK_DESCRIPTION_MAX_LENGTH),
|
|
327
|
+
files: z.array(SkillPackFileSchema).min(1).max(SKILL_PACK_MAX_FILES),
|
|
328
|
+
contentHash: ContentHashSchema
|
|
329
|
+
});
|
|
330
|
+
function parseSkillPackManifest(input) {
|
|
331
|
+
if (typeof input === "object" && input !== null) {
|
|
332
|
+
const present = SKILL_PACK_FORBIDDEN_FIELDS.filter(
|
|
333
|
+
(field) => Object.prototype.hasOwnProperty.call(input, field)
|
|
334
|
+
);
|
|
335
|
+
if (present.length > 0) {
|
|
336
|
+
throw new ByokCoreError(
|
|
337
|
+
"skill_pack_manifest_invalid",
|
|
338
|
+
`A skill pack manifest carries no executable or credential surface; refusing ${present.map((field) => JSON.stringify(field)).join(", ")}.`
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
const result = SkillPackManifestSchema.safeParse(input);
|
|
343
|
+
if (!result.success) {
|
|
344
|
+
throw new ByokCoreError(
|
|
345
|
+
"skill_pack_manifest_invalid",
|
|
346
|
+
`Invalid skill pack manifest: ${result.error.issues.map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ")}`,
|
|
347
|
+
{ cause: result.error }
|
|
348
|
+
);
|
|
349
|
+
}
|
|
350
|
+
return result.data;
|
|
351
|
+
}
|
|
352
|
+
function skillPackContentHashInput(manifest) {
|
|
353
|
+
const rows = [...manifest.files].sort((left, right) => left.path < right.path ? -1 : left.path > right.path ? 1 : 0).map((file) => `${file.path}
|
|
354
|
+
${file.contentHash}
|
|
355
|
+
${file.byteSize}
|
|
356
|
+
`);
|
|
357
|
+
return [
|
|
358
|
+
`${SKILL_PACK_MANIFEST_SCHEMA_ID}
|
|
359
|
+
`,
|
|
360
|
+
`${manifest.name}
|
|
361
|
+
`,
|
|
362
|
+
`${manifest.version}
|
|
363
|
+
`,
|
|
364
|
+
`${manifest.description.length}
|
|
365
|
+
`,
|
|
366
|
+
`${manifest.description}
|
|
367
|
+
`,
|
|
368
|
+
`${manifest.files.length}
|
|
369
|
+
`,
|
|
370
|
+
...rows
|
|
371
|
+
].join("");
|
|
372
|
+
}
|
|
373
|
+
var SKILL_PACK_REJECTIONS = [
|
|
374
|
+
"path-unsafe",
|
|
375
|
+
"duplicate-path",
|
|
376
|
+
"entry-missing",
|
|
377
|
+
"file-count-over-cap",
|
|
378
|
+
"file-over-cap",
|
|
379
|
+
"pack-over-cap",
|
|
380
|
+
"size-mismatch",
|
|
381
|
+
"hash-mismatch",
|
|
382
|
+
"name-mismatch"
|
|
383
|
+
];
|
|
384
|
+
function isSkillPackPathSafe(path) {
|
|
385
|
+
return path.length > 0 && path.length <= SKILL_PACK_FILE_PATH_MAX_LENGTH && SKILL_PACK_FILE_PATH_PATTERN.test(path);
|
|
386
|
+
}
|
|
387
|
+
function checkSkillPackManifest(manifest) {
|
|
388
|
+
if (manifest.files.length > SKILL_PACK_MAX_FILES) {
|
|
389
|
+
return {
|
|
390
|
+
ok: false,
|
|
391
|
+
reason: "file-count-over-cap",
|
|
392
|
+
detail: `${manifest.files.length} files exceeds the ${SKILL_PACK_MAX_FILES} file limit.`
|
|
393
|
+
};
|
|
394
|
+
}
|
|
395
|
+
const seen = /* @__PURE__ */ new Set();
|
|
396
|
+
let bytes = 0;
|
|
397
|
+
for (const file of manifest.files) {
|
|
398
|
+
if (!isSkillPackPathSafe(file.path)) {
|
|
399
|
+
return { ok: false, reason: "path-unsafe", detail: `${JSON.stringify(file.path)} is not a safe relative path.` };
|
|
400
|
+
}
|
|
401
|
+
if (seen.has(file.path)) {
|
|
402
|
+
return { ok: false, reason: "duplicate-path", detail: `${JSON.stringify(file.path)} is declared twice.` };
|
|
403
|
+
}
|
|
404
|
+
seen.add(file.path);
|
|
405
|
+
if (file.byteSize > SKILL_PACK_FILE_MAX_BYTES) {
|
|
406
|
+
return {
|
|
407
|
+
ok: false,
|
|
408
|
+
reason: "file-over-cap",
|
|
409
|
+
detail: `${JSON.stringify(file.path)} declares ${file.byteSize} bytes, over the ${SKILL_PACK_FILE_MAX_BYTES} byte per-file limit.`
|
|
410
|
+
};
|
|
411
|
+
}
|
|
412
|
+
bytes += file.byteSize;
|
|
413
|
+
}
|
|
414
|
+
if (!seen.has(SKILL_PACK_ENTRY_PATH)) {
|
|
415
|
+
return {
|
|
416
|
+
ok: false,
|
|
417
|
+
reason: "entry-missing",
|
|
418
|
+
detail: `A skill pack must carry ${SKILL_PACK_ENTRY_PATH}.`
|
|
419
|
+
};
|
|
420
|
+
}
|
|
421
|
+
if (bytes > SKILL_PACK_MAX_BYTES) {
|
|
422
|
+
return {
|
|
423
|
+
ok: false,
|
|
424
|
+
reason: "pack-over-cap",
|
|
425
|
+
detail: `${bytes} declared bytes exceeds the ${SKILL_PACK_MAX_BYTES} byte pack limit.`
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
return { ok: true, bytes };
|
|
429
|
+
}
|
|
430
|
+
function checkSkillPackFileContent(declared, observed) {
|
|
431
|
+
if (!isSkillPackPathSafe(declared.path)) {
|
|
432
|
+
return { ok: false, reason: "path-unsafe", detail: `${JSON.stringify(declared.path)} is not a safe relative path.` };
|
|
433
|
+
}
|
|
434
|
+
if (observed.byteSize > SKILL_PACK_FILE_MAX_BYTES) {
|
|
435
|
+
return {
|
|
436
|
+
ok: false,
|
|
437
|
+
reason: "file-over-cap",
|
|
438
|
+
detail: `${JSON.stringify(declared.path)} delivered ${observed.byteSize} bytes, over the ${SKILL_PACK_FILE_MAX_BYTES} byte per-file limit.`
|
|
439
|
+
};
|
|
440
|
+
}
|
|
441
|
+
if (observed.byteSize !== declared.byteSize) {
|
|
442
|
+
return {
|
|
443
|
+
ok: false,
|
|
444
|
+
reason: "size-mismatch",
|
|
445
|
+
detail: `${JSON.stringify(declared.path)} declared ${declared.byteSize} bytes and delivered ${observed.byteSize}.`
|
|
446
|
+
};
|
|
447
|
+
}
|
|
448
|
+
if (observed.contentHash !== declared.contentHash) {
|
|
449
|
+
return {
|
|
450
|
+
ok: false,
|
|
451
|
+
reason: "hash-mismatch",
|
|
452
|
+
detail: `${JSON.stringify(declared.path)} declared ${declared.contentHash} and delivered ${observed.contentHash}.`
|
|
453
|
+
};
|
|
454
|
+
}
|
|
455
|
+
return { ok: true, bytes: observed.byteSize };
|
|
456
|
+
}
|
|
457
|
+
var SKILL_FRONTMATTER_FIELDS = ["name", "description"];
|
|
458
|
+
var FRONTMATTER_DELIMITER = "---";
|
|
459
|
+
var FRONTMATTER_LINE_PATTERN = /^([A-Za-z][A-Za-z0-9_-]*):[ \t]*(.*)$/;
|
|
460
|
+
function unquote(value) {
|
|
461
|
+
const trimmed = value.trim();
|
|
462
|
+
if (trimmed.length >= 2) {
|
|
463
|
+
const first = trimmed[0];
|
|
464
|
+
const last = trimmed[trimmed.length - 1];
|
|
465
|
+
if (first === '"' && last === '"' || first === "'" && last === "'") {
|
|
466
|
+
const inner = trimmed.slice(1, -1);
|
|
467
|
+
return inner.includes(first) ? void 0 : inner;
|
|
468
|
+
}
|
|
469
|
+
}
|
|
470
|
+
return trimmed;
|
|
471
|
+
}
|
|
472
|
+
function parseSkillFrontmatter(text) {
|
|
473
|
+
const reject = (message) => {
|
|
474
|
+
throw new ByokCoreError("skill_pack_frontmatter_invalid", message);
|
|
475
|
+
};
|
|
476
|
+
const lines = text.split("\n");
|
|
477
|
+
if (lines[0]?.trimEnd() !== FRONTMATTER_DELIMITER) {
|
|
478
|
+
reject(`A skill file must open with a ${FRONTMATTER_DELIMITER} frontmatter delimiter.`);
|
|
479
|
+
}
|
|
480
|
+
const closing = lines.findIndex((line, index) => index > 0 && line.trimEnd() === FRONTMATTER_DELIMITER);
|
|
481
|
+
if (closing < 0) reject(`The frontmatter block is not closed by a ${FRONTMATTER_DELIMITER} line.`);
|
|
482
|
+
const fields = /* @__PURE__ */ new Map();
|
|
483
|
+
for (const line of lines.slice(1, closing)) {
|
|
484
|
+
if (line.trim().length === 0) continue;
|
|
485
|
+
const match = FRONTMATTER_LINE_PATTERN.exec(line);
|
|
486
|
+
if (match === null) reject(`Frontmatter line ${JSON.stringify(line)} is not a \`key: value\` pair.`);
|
|
487
|
+
const key = match[1];
|
|
488
|
+
if (!SKILL_FRONTMATTER_FIELDS.includes(key)) {
|
|
489
|
+
reject(
|
|
490
|
+
`Frontmatter key ${JSON.stringify(key)} is not one of ${SKILL_FRONTMATTER_FIELDS.join(", ")}; a skill declares no tools, hooks, or environment.`
|
|
491
|
+
);
|
|
492
|
+
}
|
|
493
|
+
if (fields.has(key)) reject(`Frontmatter key ${JSON.stringify(key)} is declared twice.`);
|
|
494
|
+
const value = unquote(match[2]);
|
|
495
|
+
if (value === void 0 || value.length === 0) {
|
|
496
|
+
reject(`Frontmatter key ${JSON.stringify(key)} has no usable value.`);
|
|
497
|
+
}
|
|
498
|
+
fields.set(key, value);
|
|
499
|
+
}
|
|
500
|
+
const name = fields.get("name");
|
|
501
|
+
const description = fields.get("description");
|
|
502
|
+
if (name === void 0) reject("Frontmatter is missing `name`.");
|
|
503
|
+
if (description === void 0) reject("Frontmatter is missing `description`.");
|
|
504
|
+
if (name.length > SKILL_PACK_NAME_MAX_LENGTH || !SKILL_PACK_NAME_PATTERN.test(name)) {
|
|
505
|
+
reject(
|
|
506
|
+
`Frontmatter \`name\` must match ${SKILL_PACK_NAME_PATTERN.source} and be at most ${SKILL_PACK_NAME_MAX_LENGTH} characters.`
|
|
507
|
+
);
|
|
508
|
+
}
|
|
509
|
+
if (description.length > SKILL_PACK_DESCRIPTION_MAX_LENGTH) {
|
|
510
|
+
reject(`Frontmatter \`description\` exceeds ${SKILL_PACK_DESCRIPTION_MAX_LENGTH} characters.`);
|
|
511
|
+
}
|
|
512
|
+
return { name, description };
|
|
513
|
+
}
|
|
514
|
+
function checkSkillPackEntry(manifest, entryText) {
|
|
515
|
+
const frontmatter = parseSkillFrontmatter(entryText);
|
|
516
|
+
if (frontmatter.name !== manifest.name) {
|
|
517
|
+
return {
|
|
518
|
+
ok: false,
|
|
519
|
+
reason: "name-mismatch",
|
|
520
|
+
detail: `${SKILL_PACK_ENTRY_PATH} declares ${JSON.stringify(frontmatter.name)} but the manifest declares ${JSON.stringify(manifest.name)}.`
|
|
521
|
+
};
|
|
522
|
+
}
|
|
523
|
+
return { ok: true, bytes: new TextEncoder().encode(entryText).length };
|
|
524
|
+
}
|
|
262
525
|
|
|
263
526
|
// src/stores.ts
|
|
264
527
|
var CORE_STORE_NAMES = [
|
|
@@ -268,10 +531,12 @@ var CORE_STORE_NAMES = [
|
|
|
268
531
|
"presence",
|
|
269
532
|
"activity",
|
|
270
533
|
"objects",
|
|
271
|
-
"quota"
|
|
534
|
+
"quota",
|
|
535
|
+
"skillPacks"
|
|
272
536
|
];
|
|
273
537
|
|
|
274
538
|
// src/ports-contract.ts
|
|
539
|
+
var CORE_NON_COMPOSITION_PORT_NAMES = [];
|
|
275
540
|
var CORE_PORT_METHODS = {
|
|
276
541
|
mailbox: ["append", "readAfter", "advanceCursor", "readCursor", "collectRetired"],
|
|
277
542
|
board: ["create", "get", "list", "claim", "unclaim", "updateStatus"],
|
|
@@ -299,7 +564,8 @@ var CORE_PORT_METHODS = {
|
|
|
299
564
|
"abortReservation",
|
|
300
565
|
"expireReservations",
|
|
301
566
|
"applyMailboxDelta"
|
|
302
|
-
]
|
|
567
|
+
],
|
|
568
|
+
skillPacks: ["publish", "get", "list", "readFile"]
|
|
303
569
|
};
|
|
304
570
|
var CORE_PORT_INTERFACES = {
|
|
305
571
|
mailbox: "MailboxStore",
|
|
@@ -308,12 +574,14 @@ var CORE_PORT_INTERFACES = {
|
|
|
308
574
|
presence: "PresenceStore",
|
|
309
575
|
activity: "ActivityStore",
|
|
310
576
|
objects: "ObjectStore",
|
|
311
|
-
quota: "QuotaStore"
|
|
577
|
+
quota: "QuotaStore",
|
|
578
|
+
skillPacks: "SkillPackStore"
|
|
312
579
|
};
|
|
313
580
|
var DEVICE_PROOF_SCHEMA_ID = "byok-device-proof-v1";
|
|
314
581
|
var DEVICE_PROOF_DOMAIN_PREFIX = "byok-device-proof-v1\n";
|
|
315
582
|
var DEVICE_PROOF_VERSION = 1;
|
|
316
583
|
var DEVICE_PROOF_ALGORITHMS = ["ed25519"];
|
|
584
|
+
var DEVICE_PROOF_HEADER = "x-byok-device-proof";
|
|
317
585
|
var BASE64URL_PATTERN = /^[A-Za-z0-9_-]+$/;
|
|
318
586
|
var HTTP_METHOD_PATTERN = /^[A-Z]+$/;
|
|
319
587
|
function canonicalizationFailure(path, reason) {
|
|
@@ -478,6 +746,122 @@ function deviceProofSigningInput(claims) {
|
|
|
478
746
|
DEVICE_PROOF_DOMAIN_PREFIX + deviceProofCanonicalJson(claims)
|
|
479
747
|
);
|
|
480
748
|
}
|
|
749
|
+
var DEVICE_ASSERTION_SCHEMA_ID = "byok-device-assertion-v1";
|
|
750
|
+
var DEVICE_ASSERTION_DOMAIN_PREFIX = "byok-device-assertion-v1\n";
|
|
751
|
+
var DEVICE_ASSERTION_VERSION = 1;
|
|
752
|
+
var DEVICE_ASSERTION_ALGORITHMS = ["ed25519"];
|
|
753
|
+
var DEVICE_ASSERTION_DEFAULT_TTL_MS = 12e4;
|
|
754
|
+
var DEVICE_ASSERTION_MAX_TTL_MS = 3e5;
|
|
755
|
+
var DEVICE_ASSERTION_AUDIENCE_MAX_BYTES = 256;
|
|
756
|
+
var JTI_PATTERN = /^[A-Za-z0-9_-]{22}$/;
|
|
757
|
+
var SIGNATURE_PATTERN = /^[A-Za-z0-9_-]{86}$/;
|
|
758
|
+
function utf8ByteLength(value) {
|
|
759
|
+
return new TextEncoder().encode(value).length;
|
|
760
|
+
}
|
|
761
|
+
var DeviceAssertionClaimsSchema = z.strictObject({
|
|
762
|
+
version: z.literal(DEVICE_ASSERTION_VERSION),
|
|
763
|
+
/** The paired server's origin, normalized (`new URL(serverUrl).origin`). */
|
|
764
|
+
issuer: z.string().min(1),
|
|
765
|
+
productId: z.string().min(1),
|
|
766
|
+
/** The device row this assertion claims to be. A lookup key, never authority — the row is the authority. */
|
|
767
|
+
deviceId: z.string().min(1),
|
|
768
|
+
/** Exactly one audience, compared with `===` by every verifier. Never an array, never a prefix. */
|
|
769
|
+
audience: z.string().min(1).refine((value) => utf8ByteLength(value) <= DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, {
|
|
770
|
+
message: `audience must be at most ${DEVICE_ASSERTION_AUDIENCE_MAX_BYTES} UTF-8 bytes`
|
|
771
|
+
}),
|
|
772
|
+
/** 128-bit CSPRNG token, base64url unpadded. The verifier burns it; the signer never reuses one. */
|
|
773
|
+
jti: z.string().regex(JTI_PATTERN),
|
|
774
|
+
issuedAt: z.iso.datetime(),
|
|
775
|
+
expiresAt: z.iso.datetime()
|
|
776
|
+
});
|
|
777
|
+
var DeviceAssertionEnvelopeV1Schema = z.strictObject({
|
|
778
|
+
schema: z.literal(DEVICE_ASSERTION_SCHEMA_ID),
|
|
779
|
+
algorithm: z.enum(DEVICE_ASSERTION_ALGORITHMS),
|
|
780
|
+
protected: DeviceAssertionClaimsSchema,
|
|
781
|
+
/** Raw 64-byte Ed25519 signature, base64url unpadded. */
|
|
782
|
+
signature: z.string().regex(SIGNATURE_PATTERN)
|
|
783
|
+
});
|
|
784
|
+
function parseDeviceAssertionEnvelope(input) {
|
|
785
|
+
const result = DeviceAssertionEnvelopeV1Schema.safeParse(input);
|
|
786
|
+
if (!result.success) {
|
|
787
|
+
throw new ByokCoreError(
|
|
788
|
+
"assertion_envelope_invalid",
|
|
789
|
+
`Invalid device assertion envelope: ${result.error.issues.map((issue) => `${issue.path.join(".") || "<root>"}: ${issue.message}`).join("; ")}`,
|
|
790
|
+
{ cause: result.error }
|
|
791
|
+
);
|
|
792
|
+
}
|
|
793
|
+
return result.data;
|
|
794
|
+
}
|
|
795
|
+
function deviceAssertionCanonicalClaims(claims) {
|
|
796
|
+
const canonical = {
|
|
797
|
+
version: claims.version,
|
|
798
|
+
issuer: claims.issuer,
|
|
799
|
+
productId: claims.productId,
|
|
800
|
+
deviceId: claims.deviceId,
|
|
801
|
+
audience: claims.audience,
|
|
802
|
+
jti: claims.jti,
|
|
803
|
+
issuedAt: claims.issuedAt,
|
|
804
|
+
expiresAt: claims.expiresAt
|
|
805
|
+
};
|
|
806
|
+
return canonical;
|
|
807
|
+
}
|
|
808
|
+
function deviceAssertionCanonicalJson(claims) {
|
|
809
|
+
return canonicalizeJson(deviceAssertionCanonicalClaims(claims));
|
|
810
|
+
}
|
|
811
|
+
function deviceAssertionSigningInput(claims) {
|
|
812
|
+
return new TextEncoder().encode(
|
|
813
|
+
DEVICE_ASSERTION_DOMAIN_PREFIX + deviceAssertionCanonicalJson(claims)
|
|
814
|
+
);
|
|
815
|
+
}
|
|
816
|
+
function parseInstant(value) {
|
|
817
|
+
const parsed = Date.parse(value);
|
|
818
|
+
return Number.isFinite(parsed) ? parsed : void 0;
|
|
819
|
+
}
|
|
820
|
+
var EDDSA_JWK_X_PATTERN = /^[A-Za-z0-9_-]{43}$/;
|
|
821
|
+
function isUsableDeviceRow(row) {
|
|
822
|
+
if (row === null || typeof row !== "object") return false;
|
|
823
|
+
if (row.revoked !== false) return false;
|
|
824
|
+
const key = row.publicKeyJwkX;
|
|
825
|
+
return typeof key === "string" && EDDSA_JWK_X_PATTERN.test(key);
|
|
826
|
+
}
|
|
827
|
+
async function verifyDeviceAssertion(input, deps) {
|
|
828
|
+
const maxLifetimeMs = deps.maxLifetimeMs ?? DEVICE_ASSERTION_MAX_TTL_MS;
|
|
829
|
+
if (!Number.isSafeInteger(maxLifetimeMs) || maxLifetimeMs <= 0 || maxLifetimeMs > DEVICE_ASSERTION_MAX_TTL_MS) {
|
|
830
|
+
return void 0;
|
|
831
|
+
}
|
|
832
|
+
let envelope;
|
|
833
|
+
try {
|
|
834
|
+
envelope = parseDeviceAssertionEnvelope(input);
|
|
835
|
+
} catch {
|
|
836
|
+
return void 0;
|
|
837
|
+
}
|
|
838
|
+
const claims = envelope.protected;
|
|
839
|
+
const row = await deps.lookupDevice(claims.deviceId);
|
|
840
|
+
if (!isUsableDeviceRow(row)) return void 0;
|
|
841
|
+
const issuedAt = parseInstant(claims.issuedAt);
|
|
842
|
+
const expiresAt = parseInstant(claims.expiresAt);
|
|
843
|
+
if (issuedAt === void 0 || expiresAt === void 0) return void 0;
|
|
844
|
+
if (expiresAt <= issuedAt) return void 0;
|
|
845
|
+
if (expiresAt - issuedAt > maxLifetimeMs) return void 0;
|
|
846
|
+
const now = deps.now.getTime();
|
|
847
|
+
if (!Number.isFinite(now)) return void 0;
|
|
848
|
+
if (now < issuedAt || now >= expiresAt) return void 0;
|
|
849
|
+
const verified = await deps.verifier.verify({
|
|
850
|
+
algorithm: envelope.algorithm,
|
|
851
|
+
// The row's key, never an envelope-supplied one.
|
|
852
|
+
publicKey: row.publicKeyJwkX,
|
|
853
|
+
signature: envelope.signature,
|
|
854
|
+
signingInput: deviceAssertionSigningInput(claims)
|
|
855
|
+
});
|
|
856
|
+
if (!verified) return void 0;
|
|
857
|
+
return claims;
|
|
858
|
+
}
|
|
859
|
+
|
|
860
|
+
// src/pairing.ts
|
|
861
|
+
var NONCE_SIGNING_DOMAIN = "byok-nonce-v1\n";
|
|
862
|
+
function nonceSigningBytes(nonce) {
|
|
863
|
+
return new TextEncoder().encode(NONCE_SIGNING_DOMAIN + nonce);
|
|
864
|
+
}
|
|
481
865
|
|
|
482
866
|
// src/in-memory/presence.ts
|
|
483
867
|
function assertTtl(ttlMs) {
|
|
@@ -810,23 +1194,30 @@ var InMemoryMailboxStore = class {
|
|
|
810
1194
|
}
|
|
811
1195
|
async append(tenant, input) {
|
|
812
1196
|
const device = this.#device(tenant, input.deviceId);
|
|
813
|
-
const
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
823
|
-
|
|
824
|
-
|
|
825
|
-
|
|
826
|
-
|
|
827
|
-
|
|
828
|
-
|
|
829
|
-
|
|
1197
|
+
const appended = device.mutationTail.then(async () => {
|
|
1198
|
+
const existing = device.byMessageId.get(input.messageId);
|
|
1199
|
+
if (existing !== void 0) return existing;
|
|
1200
|
+
const seq = device.nextSeq;
|
|
1201
|
+
const materialized = await input.materialize(seq);
|
|
1202
|
+
const message = {
|
|
1203
|
+
tenantId: tenant,
|
|
1204
|
+
deviceId: input.deviceId,
|
|
1205
|
+
seq,
|
|
1206
|
+
messageId: input.messageId,
|
|
1207
|
+
...materialized,
|
|
1208
|
+
state: "pending",
|
|
1209
|
+
appendedAt: this.#now()
|
|
1210
|
+
};
|
|
1211
|
+
device.nextSeq += 1;
|
|
1212
|
+
device.messages.push(message);
|
|
1213
|
+
device.byMessageId.set(message.messageId, message);
|
|
1214
|
+
return message;
|
|
1215
|
+
});
|
|
1216
|
+
device.mutationTail = appended.then(
|
|
1217
|
+
() => void 0,
|
|
1218
|
+
() => void 0
|
|
1219
|
+
);
|
|
1220
|
+
return appended;
|
|
830
1221
|
}
|
|
831
1222
|
async readAfter(tenant, query) {
|
|
832
1223
|
const device = this.#devices.get(tenantKey(tenant, query.deviceId));
|
|
@@ -847,23 +1238,30 @@ var InMemoryMailboxStore = class {
|
|
|
847
1238
|
}
|
|
848
1239
|
async advanceCursor(tenant, input) {
|
|
849
1240
|
const device = this.#device(tenant, input.deviceId);
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
device.ackedSeq = input.ackedSeq;
|
|
859
|
-
device.cursorUpdatedAt = this.#now();
|
|
860
|
-
for (const [index, message] of device.messages.entries()) {
|
|
861
|
-
if (message.state === "pending" && message.seq <= input.ackedSeq) {
|
|
862
|
-
device.messages[index] = { ...message, state: "acked" };
|
|
863
|
-
device.byMessageId.set(message.messageId, device.messages[index]);
|
|
1241
|
+
const advanced = device.mutationTail.then(() => {
|
|
1242
|
+
if (input.ackedSeq < device.ackedSeq) {
|
|
1243
|
+
throw new CoreConflictError(
|
|
1244
|
+
"mailbox_cursor_regression",
|
|
1245
|
+
`Cursor for device ${input.deviceId} is at ${device.ackedSeq}; refusing to move it back to ${input.ackedSeq}.`,
|
|
1246
|
+
this.#cursorState(tenant, input.deviceId, device),
|
|
1247
|
+
this.#now()
|
|
1248
|
+
);
|
|
864
1249
|
}
|
|
865
|
-
|
|
866
|
-
|
|
1250
|
+
device.ackedSeq = input.ackedSeq;
|
|
1251
|
+
device.cursorUpdatedAt = this.#now();
|
|
1252
|
+
for (const [index, message] of device.messages.entries()) {
|
|
1253
|
+
if (message.state === "pending" && message.seq <= input.ackedSeq) {
|
|
1254
|
+
device.messages[index] = { ...message, state: "acked" };
|
|
1255
|
+
device.byMessageId.set(message.messageId, device.messages[index]);
|
|
1256
|
+
}
|
|
1257
|
+
}
|
|
1258
|
+
return this.#cursorState(tenant, input.deviceId, device);
|
|
1259
|
+
});
|
|
1260
|
+
device.mutationTail = advanced.then(
|
|
1261
|
+
() => void 0,
|
|
1262
|
+
() => void 0
|
|
1263
|
+
);
|
|
1264
|
+
return advanced;
|
|
867
1265
|
}
|
|
868
1266
|
async readCursor(tenant, deviceId) {
|
|
869
1267
|
const device = this.#devices.get(tenantKey(tenant, deviceId));
|
|
@@ -911,6 +1309,7 @@ var InMemoryMailboxStore = class {
|
|
|
911
1309
|
nextSeq: 1,
|
|
912
1310
|
ackedSeq: 0,
|
|
913
1311
|
cursorUpdatedAt: this.#now(),
|
|
1312
|
+
mutationTail: Promise.resolve(),
|
|
914
1313
|
messages: [],
|
|
915
1314
|
byMessageId: /* @__PURE__ */ new Map()
|
|
916
1315
|
};
|
|
@@ -1360,6 +1759,89 @@ var InMemoryQuotaStore = class {
|
|
|
1360
1759
|
}
|
|
1361
1760
|
};
|
|
1362
1761
|
|
|
1762
|
+
// src/in-memory/skill-pack.ts
|
|
1763
|
+
var DEFAULT_LIST_LIMIT3 = 50;
|
|
1764
|
+
var InMemorySkillPackStore = class {
|
|
1765
|
+
#packs = /* @__PURE__ */ new Map();
|
|
1766
|
+
async publish(tenant, input) {
|
|
1767
|
+
const { manifest } = input;
|
|
1768
|
+
const structural = checkSkillPackManifest(manifest);
|
|
1769
|
+
if (!structural.ok) {
|
|
1770
|
+
throw new ByokCoreError(
|
|
1771
|
+
"skill_pack_manifest_invalid",
|
|
1772
|
+
`Refusing to publish ${JSON.stringify(manifest.name)}: ${structural.reason} \u2014 ${structural.detail}`
|
|
1773
|
+
);
|
|
1774
|
+
}
|
|
1775
|
+
const contents = /* @__PURE__ */ new Map();
|
|
1776
|
+
for (const file of input.files) {
|
|
1777
|
+
if (contents.has(file.path)) {
|
|
1778
|
+
throw new ByokCoreError(
|
|
1779
|
+
"skill_pack_manifest_invalid",
|
|
1780
|
+
`Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(file.path)} was supplied twice.`
|
|
1781
|
+
);
|
|
1782
|
+
}
|
|
1783
|
+
contents.set(file.path, file.content);
|
|
1784
|
+
}
|
|
1785
|
+
for (const declared of manifest.files) {
|
|
1786
|
+
const content = contents.get(declared.path);
|
|
1787
|
+
if (content === void 0) {
|
|
1788
|
+
throw new ByokCoreError(
|
|
1789
|
+
"skill_pack_manifest_invalid",
|
|
1790
|
+
`Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(declared.path)} is declared but was not supplied.`
|
|
1791
|
+
);
|
|
1792
|
+
}
|
|
1793
|
+
const bytes = new TextEncoder().encode(content).length;
|
|
1794
|
+
if (bytes !== declared.byteSize) {
|
|
1795
|
+
throw new ByokCoreError(
|
|
1796
|
+
"skill_pack_manifest_invalid",
|
|
1797
|
+
`Refusing to publish ${JSON.stringify(manifest.name)}: ${JSON.stringify(declared.path)} declares ${declared.byteSize} bytes and supplies ${bytes}.`
|
|
1798
|
+
);
|
|
1799
|
+
}
|
|
1800
|
+
}
|
|
1801
|
+
if (contents.size !== manifest.files.length) {
|
|
1802
|
+
throw new ByokCoreError(
|
|
1803
|
+
"skill_pack_manifest_invalid",
|
|
1804
|
+
`Refusing to publish ${JSON.stringify(manifest.name)}: ${contents.size} files were supplied for ${manifest.files.length} declared rows.`
|
|
1805
|
+
);
|
|
1806
|
+
}
|
|
1807
|
+
const entry = checkSkillPackEntry(manifest, contents.get(SKILL_PACK_ENTRY_PATH));
|
|
1808
|
+
if (!entry.ok) {
|
|
1809
|
+
throw new ByokCoreError(
|
|
1810
|
+
"skill_pack_manifest_invalid",
|
|
1811
|
+
`Refusing to publish ${JSON.stringify(manifest.name)}: ${entry.reason} \u2014 ${entry.detail}`
|
|
1812
|
+
);
|
|
1813
|
+
}
|
|
1814
|
+
this.#packs.set(tenantKey(tenant, manifest.name), { manifest, contents });
|
|
1815
|
+
return manifest;
|
|
1816
|
+
}
|
|
1817
|
+
async get(tenant, name) {
|
|
1818
|
+
return this.#packs.get(tenantKey(tenant, name))?.manifest;
|
|
1819
|
+
}
|
|
1820
|
+
async list(tenant, query) {
|
|
1821
|
+
const prefix = tenantKey(tenant, "");
|
|
1822
|
+
const manifests = [];
|
|
1823
|
+
for (const [key, pack] of this.#packs.entries()) {
|
|
1824
|
+
if (!key.startsWith(prefix)) continue;
|
|
1825
|
+
manifests.push(pack.manifest);
|
|
1826
|
+
}
|
|
1827
|
+
manifests.sort((left, right) => left.name < right.name ? -1 : left.name > right.name ? 1 : 0);
|
|
1828
|
+
return manifests.slice(0, query.limit ?? DEFAULT_LIST_LIMIT3);
|
|
1829
|
+
}
|
|
1830
|
+
async readFile(tenant, name, path) {
|
|
1831
|
+
const pack = this.#packs.get(tenantKey(tenant, name));
|
|
1832
|
+
if (pack === void 0) return void 0;
|
|
1833
|
+
const declared = pack.manifest.files.find((file) => file.path === path);
|
|
1834
|
+
const content = pack.contents.get(path);
|
|
1835
|
+
if (declared === void 0 || content === void 0) return void 0;
|
|
1836
|
+
return {
|
|
1837
|
+
path: declared.path,
|
|
1838
|
+
contentHash: declared.contentHash,
|
|
1839
|
+
byteSize: declared.byteSize,
|
|
1840
|
+
content
|
|
1841
|
+
};
|
|
1842
|
+
}
|
|
1843
|
+
};
|
|
1844
|
+
|
|
1363
1845
|
// src/in-memory/truth.ts
|
|
1364
1846
|
var DEFAULT_MANIFEST_LIMIT = 100;
|
|
1365
1847
|
var InMemoryTruthStore = class {
|
|
@@ -1484,7 +1966,8 @@ function createInMemoryCoreStores(options = {}) {
|
|
|
1484
1966
|
presence: new InMemoryPresenceStore(clock),
|
|
1485
1967
|
activity: new InMemoryActivityStore(clock),
|
|
1486
1968
|
objects,
|
|
1487
|
-
quota: new InMemoryQuotaStore(clock, objects)
|
|
1969
|
+
quota: new InMemoryQuotaStore(clock, objects),
|
|
1970
|
+
skillPacks: new InMemorySkillPackStore()
|
|
1488
1971
|
};
|
|
1489
1972
|
return { stores, clock };
|
|
1490
1973
|
}
|
|
@@ -1493,6 +1976,6 @@ function createInMemoryCoreCompositionWithClock() {
|
|
|
1493
1976
|
return { stores: createInMemoryCoreStores({ clock }).stores, clock };
|
|
1494
1977
|
}
|
|
1495
1978
|
|
|
1496
|
-
export { BOARD_STATUSES, BOARD_TRANSITIONS, ByokCoreError, CANONICAL_TIMESTAMP_PATTERN, CAPABILITY_DECLARATION_SCHEMA_ID, CAPABILITY_NAME_PATTERN, CONTENT_HASH_PATTERN, CORE_ERROR_CODES, CORE_PORT_INTERFACES, CORE_PORT_METHODS, CORE_STORE_NAMES, CapabilityDeclarationSchema, CoreConflictError, DEFAULT_ACTIVITY_CAPACITY, DEVICE_PROOF_ALGORITHMS, DEVICE_PROOF_DOMAIN_PREFIX, DEVICE_PROOF_SCHEMA_ID, DEVICE_PROOF_VERSION, DeviceProofEnvelopeV1Schema, DeviceProofProtectedClaimsSchema, IN_MEMORY_CLOCK_EPOCH, InMemoryActivityStore, InMemoryBoardStore, InMemoryMailboxStore, InMemoryObjectStore, InMemoryPresenceStore, InMemoryQuotaStore, InMemoryTruthStore, MAILBOX_MESSAGE_STATES, OBJECT_STATES, OBJECT_STATE_TRANSITIONS, PRESENCE_LEVELS, PRINCIPAL_KINDS, STORAGE_ERROR_CODES, STORAGE_ERROR_HTTP_STATUS, STORAGE_RESERVATION_STATES, STORAGE_WRITE_KINDS, STORAGE_WRITE_POSTURES, TENANT_ID_MAX_LENGTH, TENANT_KEY_SEPARATOR, TRUTH_RECORD_KINDS, assertCanonicalTimestamp, assertCapability, canonicalizeJson, canonicalizeJsonBytes, contentHash, createInMemoryCoreCompositionWithClock, createInMemoryCoreStores, createMutableClock, deviceProofCanonicalClaims, deviceProofCanonicalJson, deviceProofSigningInput, hasCapability, isCanonicalTimestamp, isContentHash, isControlPlanePrincipal, isCoreConflictError, isCoreError, isDevicePrincipal, isLegalBoardTransition, isLegalObjectTransition, isTenantId, parseCapabilityDeclaration, parseDeviceProofEnvelope, principalTenant, tenantId, tenantKey, tenantObjectKey };
|
|
1979
|
+
export { BOARD_STATUSES, BOARD_TRANSITIONS, ByokCoreError, CANONICAL_TIMESTAMP_PATTERN, CAPABILITY_DECLARATION_SCHEMA_ID, CAPABILITY_NAME_PATTERN, CONTENT_HASH_PATTERN, CORE_ERROR_CODES, CORE_NON_COMPOSITION_PORT_NAMES, CORE_PORT_INTERFACES, CORE_PORT_METHODS, CORE_STORE_NAMES, CapabilityDeclarationSchema, CoreConflictError, DEFAULT_ACTIVITY_CAPACITY, DEVICE_ASSERTION_ALGORITHMS, DEVICE_ASSERTION_AUDIENCE_MAX_BYTES, DEVICE_ASSERTION_DEFAULT_TTL_MS, DEVICE_ASSERTION_DOMAIN_PREFIX, DEVICE_ASSERTION_MAX_TTL_MS, DEVICE_ASSERTION_SCHEMA_ID, DEVICE_ASSERTION_VERSION, DEVICE_PROOF_ALGORITHMS, DEVICE_PROOF_DOMAIN_PREFIX, DEVICE_PROOF_HEADER, DEVICE_PROOF_SCHEMA_ID, DEVICE_PROOF_VERSION, DeviceAssertionClaimsSchema, DeviceAssertionEnvelopeV1Schema, DeviceProofEnvelopeV1Schema, DeviceProofProtectedClaimsSchema, IN_MEMORY_CLOCK_EPOCH, InMemoryActivityStore, InMemoryBoardStore, InMemoryMailboxStore, InMemoryObjectStore, InMemoryPresenceStore, InMemoryQuotaStore, InMemorySkillPackStore, InMemoryTruthStore, MAILBOX_MESSAGE_STATES, NONCE_SIGNING_DOMAIN, OBJECT_KEY_PREFIX_PATTERN, OBJECT_STATES, OBJECT_STATE_TRANSITIONS, PRESENCE_LEVELS, PRINCIPAL_KINDS, SKILL_FRONTMATTER_FIELDS, SKILL_PACK_DESCRIPTION_MAX_LENGTH, SKILL_PACK_ENTRY_PATH, SKILL_PACK_FILE_MAX_BYTES, SKILL_PACK_FILE_PATH_MAX_LENGTH, SKILL_PACK_FILE_PATH_PATTERN, SKILL_PACK_FORBIDDEN_FIELDS, SKILL_PACK_MANIFEST_SCHEMA_ID, SKILL_PACK_MAX_BYTES, SKILL_PACK_MAX_FILES, SKILL_PACK_NAME_MAX_LENGTH, SKILL_PACK_NAME_PATTERN, SKILL_PACK_REJECTIONS, SKILL_PACK_VERSION_PATTERN, STORAGE_ERROR_CODES, STORAGE_ERROR_HTTP_STATUS, STORAGE_RESERVATION_STATES, STORAGE_WRITE_KINDS, STORAGE_WRITE_POSTURES, SkillPackFileSchema, SkillPackManifestSchema, TENANT_ID_MAX_LENGTH, TENANT_KEY_SEPARATOR, TRUTH_RECORD_KINDS, assertCanonicalTimestamp, assertCapability, canonicalizeJson, canonicalizeJsonBytes, checkSkillPackEntry, checkSkillPackFileContent, checkSkillPackManifest, contentHash, createInMemoryCoreCompositionWithClock, createInMemoryCoreStores, createMutableClock, deviceAssertionCanonicalClaims, deviceAssertionCanonicalJson, deviceAssertionSigningInput, deviceProofCanonicalClaims, deviceProofCanonicalJson, deviceProofSigningInput, hasCapability, isCanonicalTimestamp, isContentHash, isControlPlanePrincipal, isCoreConflictError, isCoreError, isDevicePrincipal, isLegalBoardTransition, isLegalObjectTransition, isSkillPackPathSafe, isTenantId, nonceSigningBytes, objectKeyPrefix, parseCapabilityDeclaration, parseDeviceAssertionEnvelope, parseDeviceProofEnvelope, parseSkillFrontmatter, parseSkillPackManifest, principalTenant, skillPackContentHashInput, tenantId, tenantKey, tenantObjectKey, verifyDeviceAssertion };
|
|
1497
1980
|
//# sourceMappingURL=index.js.map
|
|
1498
1981
|
//# sourceMappingURL=index.js.map
|