@phosphorco/bb-cross-references 0.1.1 → 0.4.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/CONTRACT.md +263 -0
- package/README.md +41 -0
- package/dist/bb.js +1159 -66
- package/dist/index.js +1053 -65
- package/dist/react.js +991 -82
- package/dist/testing.js +67 -2
- package/dist/types/bb.d.ts +3196 -1
- package/dist/types/evidence-v2.d.ts +1608 -0
- package/dist/types/index.d.ts +789 -0
- package/dist/types/lookup.d.ts +10 -0
- package/dist/types/producer.d.ts +2270 -0
- package/dist/types/recognition.d.ts +29 -0
- package/dist/types/testing.d.ts +27 -0
- package/package.json +4 -3
package/dist/bb.js
CHANGED
|
@@ -365,7 +365,915 @@ function referenceLabelError(value) {
|
|
|
365
365
|
}
|
|
366
366
|
|
|
367
367
|
// src/index.ts
|
|
368
|
+
import { z as z4 } from "zod";
|
|
369
|
+
|
|
370
|
+
// src/recognition.ts
|
|
368
371
|
import { z } from "zod";
|
|
372
|
+
import { canonicalJson, SourceIdentitySchema, SafeHrefSchema } from "@phosphorco/bb-context-recognition";
|
|
373
|
+
var RECOGNITION_CODEC_VERSION = 1;
|
|
374
|
+
var MAX_RECOGNITION_IDENTITY_BYTES = 16384;
|
|
375
|
+
function recognitionIdentity(source, verified) {
|
|
376
|
+
const parsed = SourceIdentitySchema.parse(source);
|
|
377
|
+
if (parsed.provider === "bb.thread") {
|
|
378
|
+
if (!verified || verified.id !== parsed.id || verified.deletedAt != null)
|
|
379
|
+
throw new Error("A verified existing thread is required.");
|
|
380
|
+
return threadIdentity(verified.projectId, verified.id);
|
|
381
|
+
}
|
|
382
|
+
if (parsed.provider === "bb.file")
|
|
383
|
+
throw new Error("Use verifiedFileIdentity with verified frame metadata.");
|
|
384
|
+
if (parsed.provider === "bb.url") {
|
|
385
|
+
const href = SafeHrefSchema.parse(parsed.id);
|
|
386
|
+
return { provider: "url", keys: canonicalizeIdentity({ provider: "url", keys: { href: new URL(href).href } }).keys };
|
|
387
|
+
}
|
|
388
|
+
return { provider: "recognition", keys: { provider: parsed.provider, identity: sha256Hex(canonicalJson([parsed.provider, parsed.id])) } };
|
|
389
|
+
}
|
|
390
|
+
function recognitionIdentityRecord(source) {
|
|
391
|
+
const parsed = SourceIdentitySchema.parse(source);
|
|
392
|
+
const json = canonicalJson({ provider: parsed.provider, id: parsed.id });
|
|
393
|
+
if (new TextEncoder().encode(json).length > MAX_RECOGNITION_IDENTITY_BYTES)
|
|
394
|
+
throw new Error("Recognition identity mapping exceeds its bound.");
|
|
395
|
+
return json;
|
|
396
|
+
}
|
|
397
|
+
var VerifiedFileTargetSchema = z.discriminatedUnion("kind", [
|
|
398
|
+
z.strictObject({ kind: z.literal("workspace"), environmentId: fileOwnerId(), path: verifiedFilePath() }),
|
|
399
|
+
z.strictObject({ kind: z.literal("thread-storage"), threadId: fileOwnerId(), path: verifiedFilePath() })
|
|
400
|
+
]);
|
|
401
|
+
function fileOwnerId() {
|
|
402
|
+
return z.string().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/);
|
|
403
|
+
}
|
|
404
|
+
function verifiedFilePath() {
|
|
405
|
+
return z.string().min(1).max(4096).refine((path) => !path.startsWith("/") && !/[\\:%?#\u0000-\u001f\u007f]/u.test(path) && path.split("/").every((part) => part.length > 0 && part !== "." && part !== ".."), "Expected a canonical relative file path.");
|
|
406
|
+
}
|
|
407
|
+
function verifiedFileIdentity(value) {
|
|
408
|
+
const file = VerifiedFileTargetSchema.parse(value);
|
|
409
|
+
const owner = file.kind === "workspace" ? file.environmentId : file.threadId;
|
|
410
|
+
return { provider: "recognition", keys: { provider: "bb.file", identity: sha256Hex(canonicalJson(["bb.file", file.kind, owner, file.path])) } };
|
|
411
|
+
}
|
|
412
|
+
function verifiedFileIdentityRecord(value) {
|
|
413
|
+
const json = canonicalJson({ provider: "bb.file", verifiedFile: VerifiedFileTargetSchema.parse(value) });
|
|
414
|
+
if (new TextEncoder().encode(json).length > MAX_RECOGNITION_IDENTITY_BYTES)
|
|
415
|
+
throw new Error("Verified file mapping exceeds its bound.");
|
|
416
|
+
return json;
|
|
417
|
+
}
|
|
418
|
+
// src/producer.ts
|
|
419
|
+
import { z as z2 } from "zod";
|
|
420
|
+
import { canonicalJson as canonicalJson2, SafeHrefSchema as SafeHrefSchema2, SourceIdentitySchema as SourceIdentitySchema2 } from "@phosphorco/bb-context-recognition";
|
|
421
|
+
var PRODUCER_METHODS = Object.freeze({ describe: "crossReferencesProducer.describe", getState: "crossReferencesProducerV1GetState", apply: "crossReferencesProducerV1Apply", reportStatus: "crossReferencesProducerV1ReportStatus" });
|
|
422
|
+
var BRIEF_NAVIGATION_METHODS = Object.freeze({ describe: "threadBriefNavigation.describe", resolve: "threadBriefNavigationV1ResolveHeading" });
|
|
423
|
+
var BRIEF_LIMITS = Object.freeze({ inputBytes: 1048576, statusBytes: 16384, responseBytes: 1048576, locations: 512, perTarget: 100, headingBytes: 256, describeMs: 1000, callMs: 5000, readMs: 2000, navigationInputBytes: 8192, navigationOutputBytes: 16384 });
|
|
424
|
+
var DISPLAY_POLICY_LIMITS = Object.freeze({ valueChars: 1048576, valueBytes: 1048576, fields: 8192, distinct: 4096, sourceBytes: 2097152, work: 8388608, views: 4, tokens: 128, tokenChars: 4096, tokenBytes: 16384 });
|
|
425
|
+
var BRIEF_LIMIT_CODES = ["target-count", "projection-bytes", "occurrence-count", "per-target-occurrences", "heading-bytes", "envelope-bytes", "presentation-label-bytes", "presentation-detail-bytes", "presentation-url-bytes", "presentation-bytes"];
|
|
426
|
+
var roles = ["heading", "source-label", "target-label", "detail", "presentation-href", "provenance", "codec", "authored-url", "required-identity"];
|
|
427
|
+
function wellFormed(s) {
|
|
428
|
+
for (const c of s) {
|
|
429
|
+
const n = c.codePointAt(0);
|
|
430
|
+
if (n >= 55296 && n <= 57343)
|
|
431
|
+
return false;
|
|
432
|
+
}
|
|
433
|
+
return true;
|
|
434
|
+
}
|
|
435
|
+
function control(s) {
|
|
436
|
+
for (const c of s) {
|
|
437
|
+
const n = c.codePointAt(0);
|
|
438
|
+
if (n < 32 || n >= 127 && n <= 159)
|
|
439
|
+
return true;
|
|
440
|
+
}
|
|
441
|
+
return false;
|
|
442
|
+
}
|
|
443
|
+
var space = (c) => c.trim() === "";
|
|
444
|
+
|
|
445
|
+
class PolicyStop {
|
|
446
|
+
reason;
|
|
447
|
+
constructor(reason) {
|
|
448
|
+
this.reason = reason;
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
class PolicyHit {
|
|
453
|
+
reason;
|
|
454
|
+
constructor(reason) {
|
|
455
|
+
this.reason = reason;
|
|
456
|
+
}
|
|
457
|
+
}
|
|
458
|
+
function charge(m, n) {
|
|
459
|
+
if (n < 0 || m.work + n > DISPLAY_POLICY_LIMITS.work)
|
|
460
|
+
throw new PolicyStop("source-work-limit");
|
|
461
|
+
m.work += n;
|
|
462
|
+
}
|
|
463
|
+
var entities = { amp: "&", colon: ":", sol: "/", bsol: "\\", quest: "?", num: "#", percnt: "%", equals: "=", commat: "@", semi: ";", Tab: "\t", NewLine: `
|
|
464
|
+
` };
|
|
465
|
+
function decodeView(s, m) {
|
|
466
|
+
charge(m, s.length * 2);
|
|
467
|
+
const out = [];
|
|
468
|
+
let changed = false;
|
|
469
|
+
for (let i = 0;i < s.length; ) {
|
|
470
|
+
const c = s[i];
|
|
471
|
+
if (c === "%" && /[0-9a-f]/i.test(s[i + 1] ?? "")) {
|
|
472
|
+
const bytes = [];
|
|
473
|
+
while (s[i] === "%") {
|
|
474
|
+
const h = s.slice(i + 1, i + 3);
|
|
475
|
+
if (h.length !== 2 || !/^[0-9a-f]{2}$/i.test(h))
|
|
476
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
477
|
+
bytes.push(parseInt(h, 16));
|
|
478
|
+
i += 3;
|
|
479
|
+
}
|
|
480
|
+
try {
|
|
481
|
+
out.push(new TextDecoder("utf-8", { fatal: true }).decode(Uint8Array.from(bytes)));
|
|
482
|
+
} catch {
|
|
483
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
484
|
+
}
|
|
485
|
+
changed = true;
|
|
486
|
+
continue;
|
|
487
|
+
}
|
|
488
|
+
if (c === "\\") {
|
|
489
|
+
const n = s[i + 1];
|
|
490
|
+
if (n === "u") {
|
|
491
|
+
const h = s.slice(i + 2, i + 6);
|
|
492
|
+
if (!/^[0-9a-f]{4}$/i.test(h))
|
|
493
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
494
|
+
let value = String.fromCharCode(parseInt(h, 16));
|
|
495
|
+
i += 6;
|
|
496
|
+
if (value.charCodeAt(0) >= 55296 && value.charCodeAt(0) <= 56319) {
|
|
497
|
+
if (s.slice(i, i + 2) !== "\\u" || !/^[0-9a-f]{4}$/i.test(s.slice(i + 2, i + 6)))
|
|
498
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
499
|
+
value += String.fromCharCode(parseInt(s.slice(i + 2, i + 6), 16));
|
|
500
|
+
i += 6;
|
|
501
|
+
}
|
|
502
|
+
if (!wellFormed(value))
|
|
503
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
504
|
+
out.push(value);
|
|
505
|
+
changed = true;
|
|
506
|
+
continue;
|
|
507
|
+
}
|
|
508
|
+
const escape = { "/": "/", "\\": "\\", '"': '"', b: "\b", f: "\f", n: `
|
|
509
|
+
`, r: "\r", t: "\t" };
|
|
510
|
+
if (n === undefined || escape[n] === undefined)
|
|
511
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
512
|
+
out.push(escape[n]);
|
|
513
|
+
i += 2;
|
|
514
|
+
changed = true;
|
|
515
|
+
continue;
|
|
516
|
+
}
|
|
517
|
+
if (c === "&" && /[A-Za-z0-9_#]/.test(s[i + 1] ?? "")) {
|
|
518
|
+
let j = i + 1;
|
|
519
|
+
while (j < s.length && j - i <= 32 && !space(s[j]) && s[j] !== ";" && s[j] !== "&")
|
|
520
|
+
j++;
|
|
521
|
+
if (s[j] === ";") {
|
|
522
|
+
const name = s.slice(i + 1, j);
|
|
523
|
+
let decoded;
|
|
524
|
+
if (name.startsWith("#")) {
|
|
525
|
+
const hex = name[1]?.toLowerCase() === "x", digits = name.slice(hex ? 2 : 1);
|
|
526
|
+
if (!(hex ? /^[a-f0-9]+$/i : /^[0-9]+$/).test(digits))
|
|
527
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
528
|
+
const cp = parseInt(digits, hex ? 16 : 10);
|
|
529
|
+
if (cp > 1114111 || cp >= 55296 && cp <= 57343)
|
|
530
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
531
|
+
decoded = String.fromCodePoint(cp);
|
|
532
|
+
} else
|
|
533
|
+
decoded = Object.hasOwn(entities, name) ? entities[name] : undefined;
|
|
534
|
+
if (decoded === undefined)
|
|
535
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
536
|
+
out.push(decoded);
|
|
537
|
+
i = j + 1;
|
|
538
|
+
changed = true;
|
|
539
|
+
continue;
|
|
540
|
+
}
|
|
541
|
+
const partial = s.slice(i + 1, j);
|
|
542
|
+
if (s[i + 1] === "#" || j - i > 32 || !partial.includes("=") && Object.keys(entities).some((name) => name.startsWith(partial) || partial.startsWith(name)))
|
|
543
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
544
|
+
}
|
|
545
|
+
out.push(c);
|
|
546
|
+
i++;
|
|
547
|
+
}
|
|
548
|
+
return { text: out.join(""), changed };
|
|
549
|
+
}
|
|
550
|
+
function scanPolicy(s, m, tokens) {
|
|
551
|
+
charge(m, s.length * 4);
|
|
552
|
+
const token = (value) => {
|
|
553
|
+
if (++tokens.count > DISPLAY_POLICY_LIMITS.tokens)
|
|
554
|
+
throw new PolicyStop("token-limit");
|
|
555
|
+
if (value.length > DISPLAY_POLICY_LIMITS.tokenChars)
|
|
556
|
+
throw new PolicyStop("token-limit");
|
|
557
|
+
charge(m, value.length * 2);
|
|
558
|
+
if (utf8ByteLength(value) > DISPLAY_POLICY_LIMITS.tokenBytes)
|
|
559
|
+
throw new PolicyStop("token-limit");
|
|
560
|
+
};
|
|
561
|
+
const url = (value) => {
|
|
562
|
+
token(value);
|
|
563
|
+
let u;
|
|
564
|
+
try {
|
|
565
|
+
u = new URL(value, "https://display-policy.invalid");
|
|
566
|
+
} catch {
|
|
567
|
+
throw new PolicyStop("encoding-ambiguity");
|
|
568
|
+
}
|
|
569
|
+
if (u.username || u.password)
|
|
570
|
+
throw new PolicyHit("url-credentials");
|
|
571
|
+
if (hasSensitiveUrlParameter(u))
|
|
572
|
+
throw new PolicyHit("sensitive-url-parameter");
|
|
573
|
+
if (!SafeHrefSchema2.safeParse(value).success)
|
|
574
|
+
throw new PolicyHit("unsafe-url-form");
|
|
575
|
+
};
|
|
576
|
+
for (let at = 0;at < s.length; ) {
|
|
577
|
+
while (at < s.length && space(s[at]))
|
|
578
|
+
at++;
|
|
579
|
+
const start = at;
|
|
580
|
+
while (at < s.length && !space(s[at]))
|
|
581
|
+
at++;
|
|
582
|
+
const run = s.slice(start, at);
|
|
583
|
+
if (!run)
|
|
584
|
+
continue;
|
|
585
|
+
let hasScheme = false;
|
|
586
|
+
for (let i = 0;i < run.length; i++) {
|
|
587
|
+
const tail = run.slice(i, i + 8).toLowerCase();
|
|
588
|
+
if (tail.startsWith("http://") || tail.startsWith("https://")) {
|
|
589
|
+
hasScheme = true;
|
|
590
|
+
if (run.length - i > DISPLAY_POLICY_LIMITS.tokenChars)
|
|
591
|
+
throw new PolicyStop("token-limit");
|
|
592
|
+
url(run.slice(i));
|
|
593
|
+
} else if (run[i] === ":" && run.slice(i + 1, i + 3) === "//" && i > 0 && !run.slice(Math.max(0, i - 5), i).toLowerCase().endsWith("http") && !run.slice(Math.max(0, i - 5), i).toLowerCase().endsWith("https"))
|
|
594
|
+
throw new PolicyHit("unsafe-url-form");
|
|
595
|
+
}
|
|
596
|
+
if (!hasScheme) {
|
|
597
|
+
const slash = run.indexOf("/");
|
|
598
|
+
if (slash >= 0) {
|
|
599
|
+
if (run.length - slash > DISPLAY_POLICY_LIMITS.tokenChars)
|
|
600
|
+
throw new PolicyStop("token-limit");
|
|
601
|
+
url(run.slice(slash));
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
for (let i = 0;i < run.length; i++)
|
|
605
|
+
if (run[i] === "=") {
|
|
606
|
+
let begin = i;
|
|
607
|
+
while (begin > 0 && /[A-Za-z0-9_%.-]/.test(run[begin - 1]))
|
|
608
|
+
begin--;
|
|
609
|
+
const name = run.slice(begin, i);
|
|
610
|
+
if (!name)
|
|
611
|
+
continue;
|
|
612
|
+
token(name);
|
|
613
|
+
const u = new URL("https://display-policy.invalid");
|
|
614
|
+
u.search = "?" + name + "=value";
|
|
615
|
+
if (hasSensitiveUrlParameter(u))
|
|
616
|
+
throw new PolicyHit("credential-shaped-token");
|
|
617
|
+
}
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
function classify(value, m) {
|
|
621
|
+
const before = m.work;
|
|
622
|
+
let views = 0;
|
|
623
|
+
const tokens = { count: 0 };
|
|
624
|
+
const result = (extra) => ({ version: 1, workUnits: m.work - before, decodedViews: views, ...extra });
|
|
625
|
+
try {
|
|
626
|
+
if (value.length > DISPLAY_POLICY_LIMITS.valueChars)
|
|
627
|
+
throw new PolicyStop("input-limit");
|
|
628
|
+
charge(m, value.length * 3);
|
|
629
|
+
if (!wellFormed(value))
|
|
630
|
+
throw new PolicyStop("ill-formed-unicode");
|
|
631
|
+
if (utf8ByteLength(value) > DISPLAY_POLICY_LIMITS.valueBytes)
|
|
632
|
+
throw new PolicyStop("input-limit");
|
|
633
|
+
let current = value;
|
|
634
|
+
for (let i = 0;i < DISPLAY_POLICY_LIMITS.views; i++) {
|
|
635
|
+
views++;
|
|
636
|
+
if (control(current))
|
|
637
|
+
throw new PolicyStop("control-character");
|
|
638
|
+
scanPolicy(current, m, tokens);
|
|
639
|
+
const decoded = decodeView(current, m);
|
|
640
|
+
if (!decoded.changed)
|
|
641
|
+
return result({ state: "safe", coverage: "complete" });
|
|
642
|
+
if (i === DISPLAY_POLICY_LIMITS.views - 1)
|
|
643
|
+
throw new PolicyStop("encoding-limit");
|
|
644
|
+
current = decoded.text;
|
|
645
|
+
}
|
|
646
|
+
throw new PolicyStop("encoding-limit");
|
|
647
|
+
} catch (e) {
|
|
648
|
+
if (e instanceof PolicyHit)
|
|
649
|
+
return result({ state: "unsafe", coverage: "complete-for-hit", reason: e.reason });
|
|
650
|
+
if (e instanceof PolicyStop)
|
|
651
|
+
return result({ state: "unclassified", coverage: "incomplete", reason: e.reason });
|
|
652
|
+
throw e;
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
function classifyBriefDisplayTextV1(value) {
|
|
656
|
+
if (typeof value !== "string")
|
|
657
|
+
throw new Error("Invalid display-policy argument.");
|
|
658
|
+
return classify(value, { work: 0 });
|
|
659
|
+
}
|
|
660
|
+
function classifyBriefDisplayFieldsV1(fields) {
|
|
661
|
+
if (!Array.isArray(fields) || fields.length > DISPLAY_POLICY_LIMITS.fields)
|
|
662
|
+
return { version: 1, state: "unclassified", reason: "field-limit", results: [], usage: { distinctValues: 0, originalUtf8Bytes: 0, workUnits: 0 }, complete: false };
|
|
663
|
+
for (const f of fields)
|
|
664
|
+
if (!f || !Array.isArray(f.key) || f.key.length > 8 || f.key.some((n) => typeof n !== "number" || !Number.isSafeInteger(n) || n < 0 || n > 8191) || !roles.includes(f.role) || typeof f.value !== "string")
|
|
665
|
+
throw new Error("Invalid display-policy field.");
|
|
666
|
+
const ordered = fields.map((f, i) => ({ f, i })).sort((a, b) => Number(b.f.role === "required-identity") - Number(a.f.role === "required-identity") || compareNumbers(a.f.key, b.f.key) || a.i - b.i);
|
|
667
|
+
const meter = { work: 0 }, cache = new Map, results = { version: 1, state: "classified", results: [], usage: { distinctValues: 0, originalUtf8Bytes: 0, workUnits: 0 }, complete: true };
|
|
668
|
+
for (const { f, i } of ordered) {
|
|
669
|
+
let r = cache.get(f.value);
|
|
670
|
+
if (!r) {
|
|
671
|
+
const incomplete = (reason) => ({ version: 1, state: "unclassified", coverage: "incomplete", reason, workUnits: 0, decodedViews: 0 });
|
|
672
|
+
if (cache.size >= DISPLAY_POLICY_LIMITS.distinct)
|
|
673
|
+
r = incomplete("field-limit");
|
|
674
|
+
else {
|
|
675
|
+
try {
|
|
676
|
+
if (f.value.length > DISPLAY_POLICY_LIMITS.valueChars)
|
|
677
|
+
r = incomplete("input-limit");
|
|
678
|
+
else {
|
|
679
|
+
charge(meter, f.value.length);
|
|
680
|
+
const bytes = utf8ByteLength(f.value);
|
|
681
|
+
if (results.usage.originalUtf8Bytes + bytes > DISPLAY_POLICY_LIMITS.sourceBytes)
|
|
682
|
+
r = incomplete("source-work-limit");
|
|
683
|
+
else {
|
|
684
|
+
results.usage.originalUtf8Bytes += bytes;
|
|
685
|
+
r = classify(f.value, meter);
|
|
686
|
+
}
|
|
687
|
+
}
|
|
688
|
+
} catch (e) {
|
|
689
|
+
if (e instanceof PolicyStop)
|
|
690
|
+
r = incomplete(e.reason);
|
|
691
|
+
else
|
|
692
|
+
throw e;
|
|
693
|
+
}
|
|
694
|
+
cache.set(f.value, r);
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
results.results[i] = { key: f.key, result: r };
|
|
698
|
+
if (r.state !== "safe")
|
|
699
|
+
results.complete = false;
|
|
700
|
+
}
|
|
701
|
+
results.usage.distinctValues = cache.size;
|
|
702
|
+
results.usage.workUnits = meter.work;
|
|
703
|
+
return results;
|
|
704
|
+
}
|
|
705
|
+
function compareNumbers(a, b) {
|
|
706
|
+
for (let i = 0;i < Math.min(a.length, b.length); i++)
|
|
707
|
+
if (a[i] !== b[i])
|
|
708
|
+
return a[i] - b[i];
|
|
709
|
+
return a.length - b.length;
|
|
710
|
+
}
|
|
711
|
+
var integer = z2.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
712
|
+
var positive = integer.min(1);
|
|
713
|
+
var digest = z2.string().regex(/^[a-f0-9]{64}$/);
|
|
714
|
+
var bytes = (n) => z2.string().refine(wellFormed, "Malformed Unicode.").refine((v) => utf8ByteLength(v) <= n, "Text byte bound exceeded.");
|
|
715
|
+
var plugin = z2.string().regex(/^[a-z][a-z0-9._-]{0,63}$/);
|
|
716
|
+
var identity = z2.strictObject({ provider: z2.string(), keys: z2.record(z2.string(), z2.string()) }).superRefine((v, c) => {
|
|
717
|
+
try {
|
|
718
|
+
canonicalizeIdentity(v);
|
|
719
|
+
} catch {
|
|
720
|
+
c.addIssue({ code: "custom", message: "Invalid resource identity." });
|
|
721
|
+
}
|
|
722
|
+
});
|
|
723
|
+
var briefFileSchema = z2.strictObject({ kind: z2.literal("thread-storage"), threadId: z2.string().regex(/^[A-Za-z0-9_-]{1,128}$/), path: z2.literal("BRIEF.md") });
|
|
724
|
+
var safeHref = SafeHrefSchema2.refine((v) => utf8ByteLength(v) <= 16384 && !hasSensitiveUrlParameter(new URL(v, "https://display-policy.invalid")), "Unsafe URL.");
|
|
725
|
+
var cause = z2.enum(["policy", "unclassified"]);
|
|
726
|
+
var withheld = (display) => z2.strictObject({ state: z2.literal("withheld"), digest, display: z2.literal(display), cause });
|
|
727
|
+
var briefHeadingSchema = z2.union([z2.null(), z2.strictObject({ state: z2.literal("named"), text: bytes(256) }), withheld("Heading withheld")]);
|
|
728
|
+
var labelText = bytes(256).refine((v) => !control(v) && v.trim().length > 0, "Invalid label.");
|
|
729
|
+
var briefSourceLabelSchema = z2.union([z2.strictObject({ state: z2.literal("safe"), text: labelText }), withheld("Brief")]);
|
|
730
|
+
var briefTargetLabelSchema = z2.union([z2.strictObject({ state: z2.literal("safe"), text: labelText }), withheld("Reference")]);
|
|
731
|
+
var detail = z2.union([z2.null(), z2.strictObject({ state: z2.literal("safe"), text: bytes(1024).refine((v) => !control(v) && v.trim().length > 0) }), withheld("Details withheld")]);
|
|
732
|
+
var presentationHref = z2.union([z2.strictObject({ state: z2.literal("absent") }), z2.strictObject({ state: z2.literal("exact"), href: safeHref.refine((v) => utf8ByteLength(v) <= 2048 && !control(v) && v.trim().length > 0) }), withheld("Destination withheld")]);
|
|
733
|
+
var presentation = (label) => z2.strictObject({ label, detail, url: presentationHref });
|
|
734
|
+
var briefSourcePresentationSchema = presentation(briefSourceLabelSchema);
|
|
735
|
+
var briefTargetPresentationSchema = presentation(briefTargetLabelSchema);
|
|
736
|
+
var span = z2.strictObject({ start: integer, end: positive }).refine((v) => v.end > v.start);
|
|
737
|
+
var provenanceValue = z2.strictObject({
|
|
738
|
+
pluginId: plugin,
|
|
739
|
+
origin: z2.enum(["builtin", "contributed"]),
|
|
740
|
+
confidence: z2.enum(["high", "medium", "low"]),
|
|
741
|
+
recognition: z2.strictObject({ basis: z2.enum(["explicit", "text-url", "existing-link", "git-remote", "context"]), explanation: bytes(1024).min(1), evidence: z2.strictObject({ span: span.optional(), link: integer.optional(), remote: bytes(1024).optional() }).optional() }),
|
|
742
|
+
source: SourceIdentitySchema2.strict(),
|
|
743
|
+
authoredHref: safeHref.optional(),
|
|
744
|
+
verifiedFile: VerifiedFileTargetSchema.optional()
|
|
745
|
+
});
|
|
746
|
+
var provenanceSummary = z2.strictObject({ pluginId: plugin, origin: z2.enum(["builtin", "contributed"]), confidence: z2.enum(["high", "medium", "low"]), basis: z2.enum(["explicit", "text-url", "existing-link", "git-remote", "context"]) });
|
|
747
|
+
var briefProvenanceSchema = z2.union([z2.strictObject({ state: z2.literal("safe"), value: provenanceValue }), withheld("Recognition details withheld").extend({ summary: provenanceSummary })]);
|
|
748
|
+
var codecProof = z2.discriminatedUnion("kind", [
|
|
749
|
+
z2.strictObject({ kind: z2.literal("recognition"), source: SourceIdentitySchema2.strict() }),
|
|
750
|
+
z2.strictObject({ kind: z2.literal("thread"), source: SourceIdentitySchema2.strict(), verified: z2.strictObject({ id: z2.string(), projectId: z2.string() }) }),
|
|
751
|
+
z2.strictObject({ kind: z2.literal("file"), verified: VerifiedFileTargetSchema }),
|
|
752
|
+
z2.strictObject({ kind: z2.literal("url"), href: safeHref })
|
|
753
|
+
]);
|
|
754
|
+
var codec = z2.union([z2.strictObject({ state: z2.literal("available"), value: codecProof }), withheld("Identity metadata withheld")]);
|
|
755
|
+
var briefAuthoredUrlSchema = z2.union([z2.strictObject({ state: z2.literal("exact"), href: safeHref }), z2.strictObject({ state: z2.literal("not-url") }), z2.strictObject({ state: z2.literal("unknown") }), withheld("Destination withheld")]);
|
|
756
|
+
var briefFrameSchema = z2.strictObject({
|
|
757
|
+
codec: z2.literal("utf8-fatal-bom-consumed-v1"),
|
|
758
|
+
rawBytes: integer.max(1048576),
|
|
759
|
+
bomBytes: z2.union([z2.literal(0), z2.literal(3)]),
|
|
760
|
+
fileUtf16Length: integer.max(1048576),
|
|
761
|
+
bodyBase: z2.strictObject({ startUtf16: integer, startLine: positive, utf16Length: integer }),
|
|
762
|
+
lineMapping: z2.strictObject({ codec: z2.literal("native-file-lines-v1"), fileLineCount: positive })
|
|
763
|
+
}).superRefine((v, c) => {
|
|
764
|
+
if (v.rawBytes < v.bomBytes || v.bodyBase.startUtf16 + v.bodyBase.utf16Length > v.fileUtf16Length || v.bodyBase.startLine > v.lineMapping.fileLineCount)
|
|
765
|
+
c.addIssue({ code: "custom", message: "Invalid source frame." });
|
|
766
|
+
});
|
|
767
|
+
var briefLocatorSchema = z2.strictObject({
|
|
768
|
+
kind: z2.literal("thread-brief"),
|
|
769
|
+
threadId: z2.string().regex(/^[A-Za-z0-9_-]{1,128}$/),
|
|
770
|
+
file: briefFileSchema,
|
|
771
|
+
sourceContentRevision: digest,
|
|
772
|
+
section: z2.strictObject({ heading: briefHeadingSchema, line: positive }),
|
|
773
|
+
location: z2.strictObject({ kind: z2.literal("line"), line: positive, column: positive.nullable(), endLine: positive.nullable() }),
|
|
774
|
+
span: z2.strictObject({ frame: z2.enum(["file-utf16", "body-utf16"]), start: integer, end: positive }).refine((v) => v.end > v.start).optional()
|
|
775
|
+
});
|
|
776
|
+
var briefOccurrenceSchema = z2.strictObject({ occurrenceKey: digest, sourceOccurrenceId: bytes(256).regex(/^ref-(0|[1-9]\d{0,2})$/).refine((v) => Number(v.slice(4)) < 512), target: identity, locator: briefLocatorSchema, provenance: briefProvenanceSchema, authoredUrl: briefAuthoredUrlSchema });
|
|
777
|
+
var briefTargetDescriptorSchema = z2.strictObject({ target: identity, presentation: briefTargetPresentationSchema, codec });
|
|
778
|
+
var briefEvidenceSchema = z2.strictObject({
|
|
779
|
+
kind: z2.literal("thread-brief"),
|
|
780
|
+
sourceFile: briefFileSchema,
|
|
781
|
+
sourceState: z2.enum(["present", "absent", "empty"]),
|
|
782
|
+
sourceContentRevision: digest.nullable(),
|
|
783
|
+
completeness: z2.strictObject({ state: z2.literal("complete"), codecVersion: z2.literal(1) }),
|
|
784
|
+
metadataPolicyVersion: z2.literal(1),
|
|
785
|
+
frame: briefFrameSchema.nullable(),
|
|
786
|
+
sourcePresentation: briefSourcePresentationSchema,
|
|
787
|
+
targetDescriptors: z2.array(briefTargetDescriptorSchema).max(256),
|
|
788
|
+
occurrences: z2.array(briefOccurrenceSchema).max(512)
|
|
789
|
+
});
|
|
790
|
+
function briefWithheldDigest(role, original) {
|
|
791
|
+
if (!roles.includes(role))
|
|
792
|
+
throw new Error("Invalid withheld role.");
|
|
793
|
+
return sha256Hex(canonicalJson2(["brief-withheld", 1, role, original]));
|
|
794
|
+
}
|
|
795
|
+
function briefOccurrenceKey(rawRevision, target, locator, sourceOccurrenceId) {
|
|
796
|
+
return sha256Hex(canonicalJson2(["brief-occurrence", 1, rawRevision, identityValue(target), locator, sourceOccurrenceId]));
|
|
797
|
+
}
|
|
798
|
+
function identityValue(v) {
|
|
799
|
+
const c = canonicalizeIdentity(v);
|
|
800
|
+
return { provider: c.provider, keys: c.keys };
|
|
801
|
+
}
|
|
802
|
+
function briefEvidenceDigest(input) {
|
|
803
|
+
const e = briefEvidenceSchema.parse(input);
|
|
804
|
+
return sha256Hex(canonicalJson2(["brief-evidence", 1, {
|
|
805
|
+
...e,
|
|
806
|
+
targetDescriptors: e.targetDescriptors.map((d) => ({ ...d, target: identityValue(d.target) })).sort((a, b) => canonicalJson2(a.target) < canonicalJson2(b.target) ? -1 : canonicalJson2(a.target) > canonicalJson2(b.target) ? 1 : 0),
|
|
807
|
+
occurrences: e.occurrences.map((o) => ({ ...o, target: identityValue(o.target) })).sort((a, b) => a.occurrenceKey < b.occurrenceKey ? -1 : a.occurrenceKey > b.occurrenceKey ? 1 : 0)
|
|
808
|
+
}]));
|
|
809
|
+
}
|
|
810
|
+
function briefPresentation(p) {
|
|
811
|
+
return { label: p.label.state === "safe" ? p.label.text : p.label.display, ...p.detail?.state === "safe" ? { detail: p.detail.text } : {}, ...p.url.state === "exact" ? { url: p.url.href } : {} };
|
|
812
|
+
}
|
|
813
|
+
function briefApplyLimitCodes(input) {
|
|
814
|
+
const codes = new Set;
|
|
815
|
+
const { evidence: e, projection: p } = input;
|
|
816
|
+
if (utf8ByteLength(JSON.stringify(input)) > BRIEF_LIMITS.inputBytes)
|
|
817
|
+
codes.add("envelope-bytes");
|
|
818
|
+
if (p.targets.length > 256)
|
|
819
|
+
codes.add("target-count");
|
|
820
|
+
if (e.occurrences.length > 512)
|
|
821
|
+
codes.add("occurrence-count");
|
|
822
|
+
const per = new Map;
|
|
823
|
+
for (const o of e.occurrences) {
|
|
824
|
+
const k = canonicalJson2(o.target);
|
|
825
|
+
per.set(k, (per.get(k) ?? 0) + 1);
|
|
826
|
+
if (o.locator.section.heading?.state === "named" && utf8ByteLength(o.locator.section.heading.text) > 256)
|
|
827
|
+
codes.add("heading-bytes");
|
|
828
|
+
}
|
|
829
|
+
if ([...per.values()].some((n) => n > 100))
|
|
830
|
+
codes.add("per-target-occurrences");
|
|
831
|
+
for (const witness of [e.sourcePresentation, ...e.targetDescriptors.map((d) => d.presentation)]) {
|
|
832
|
+
const v = briefPresentation(witness);
|
|
833
|
+
if (witness.label.state === "safe" && utf8ByteLength(witness.label.text) > 256)
|
|
834
|
+
codes.add("presentation-label-bytes");
|
|
835
|
+
if (witness.detail?.state === "safe" && utf8ByteLength(witness.detail.text) > 1024)
|
|
836
|
+
codes.add("presentation-detail-bytes");
|
|
837
|
+
if (witness.url.state === "exact" && utf8ByteLength(witness.url.href) > 2048)
|
|
838
|
+
codes.add("presentation-url-bytes");
|
|
839
|
+
if (utf8ByteLength(JSON.stringify(v)) > 4096)
|
|
840
|
+
codes.add("presentation-bytes");
|
|
841
|
+
}
|
|
842
|
+
for (const r of [p.source, ...p.targets]) {
|
|
843
|
+
const v = r.presentation;
|
|
844
|
+
if (typeof v.label === "string" && utf8ByteLength(v.label) > 256)
|
|
845
|
+
codes.add("presentation-label-bytes");
|
|
846
|
+
if (typeof v.detail === "string" && utf8ByteLength(v.detail) > 1024)
|
|
847
|
+
codes.add("presentation-detail-bytes");
|
|
848
|
+
if (typeof v.url === "string" && utf8ByteLength(v.url) > 2048)
|
|
849
|
+
codes.add("presentation-url-bytes");
|
|
850
|
+
if (utf8ByteLength(JSON.stringify(v)) > 4096)
|
|
851
|
+
codes.add("presentation-bytes");
|
|
852
|
+
}
|
|
853
|
+
if (utf8ByteLength(JSON.stringify({ protocolVersion: 1, producerPluginId: p.producerPluginId, source: p.source, tombstone: p.tombstone, targets: p.targets })) > 262144)
|
|
854
|
+
codes.add("projection-bytes");
|
|
855
|
+
return [...codes].sort();
|
|
856
|
+
}
|
|
857
|
+
|
|
858
|
+
class BriefAdmissionError extends Error {
|
|
859
|
+
code;
|
|
860
|
+
limits;
|
|
861
|
+
constructor(code, limits = []) {
|
|
862
|
+
super(code === "over-limit" ? "Brief references exceed admitted limits." : code === "identity-unrepresentable" ? "Brief identity cannot be represented safely." : "Invalid brief evidence.");
|
|
863
|
+
this.code = code;
|
|
864
|
+
this.limits = limits;
|
|
865
|
+
this.name = "BriefAdmissionError";
|
|
866
|
+
}
|
|
867
|
+
}
|
|
868
|
+
function assertBriefDisplaySafe(e) {
|
|
869
|
+
const fields = [];
|
|
870
|
+
let index = 0;
|
|
871
|
+
const strings = (v, role) => {
|
|
872
|
+
if (typeof v === "string")
|
|
873
|
+
fields.push({ key: [index++], role, value: v });
|
|
874
|
+
else if (Array.isArray(v))
|
|
875
|
+
for (const x of v)
|
|
876
|
+
strings(x, role);
|
|
877
|
+
else if (v && typeof v === "object")
|
|
878
|
+
for (const x of Object.values(v))
|
|
879
|
+
strings(x, role);
|
|
880
|
+
};
|
|
881
|
+
strings(verifiedFileIdentity(e.sourceFile), "required-identity");
|
|
882
|
+
for (const d of e.targetDescriptors)
|
|
883
|
+
strings(identityValue(d.target), "required-identity");
|
|
884
|
+
const p = (v, source) => {
|
|
885
|
+
if (v.label.state === "safe")
|
|
886
|
+
strings(v.label.text, source ? "source-label" : "target-label");
|
|
887
|
+
if (v.detail?.state === "safe")
|
|
888
|
+
strings(v.detail.text, "detail");
|
|
889
|
+
if (v.url.state === "exact")
|
|
890
|
+
strings(v.url.href, "presentation-href");
|
|
891
|
+
};
|
|
892
|
+
p(e.sourcePresentation, true);
|
|
893
|
+
for (const d of e.targetDescriptors) {
|
|
894
|
+
p(d.presentation, false);
|
|
895
|
+
if (d.codec.state === "available")
|
|
896
|
+
strings(d.codec.value, "codec");
|
|
897
|
+
}
|
|
898
|
+
for (const o of e.occurrences) {
|
|
899
|
+
if (o.locator.section.heading?.state === "named")
|
|
900
|
+
strings(o.locator.section.heading.text, "heading");
|
|
901
|
+
if (o.provenance.state === "safe")
|
|
902
|
+
strings(o.provenance.value, "provenance");
|
|
903
|
+
if (o.authoredUrl.state === "exact")
|
|
904
|
+
strings(o.authoredUrl.href, "authored-url");
|
|
905
|
+
}
|
|
906
|
+
const result = classifyBriefDisplayFieldsV1(fields);
|
|
907
|
+
if (result.state !== "classified")
|
|
908
|
+
throw new BriefAdmissionError("identity-unrepresentable");
|
|
909
|
+
for (let i = 0;i < result.results.length; i++)
|
|
910
|
+
if (result.results[i].result.state !== "safe")
|
|
911
|
+
throw new BriefAdmissionError(fields[i].role === "required-identity" ? "identity-unrepresentable" : "invalid");
|
|
912
|
+
}
|
|
913
|
+
function validateBriefCommand(projection, evidence, evidenceDigest) {
|
|
914
|
+
const e = briefEvidenceSchema.parse(evidence);
|
|
915
|
+
if (projection.producerPluginId !== "thread-brief" || canonicalJson2(identityValue({ provider: projection.source.provider, keys: projection.source.keys })) !== canonicalJson2(verifiedFileIdentity(e.sourceFile)))
|
|
916
|
+
throw new BriefAdmissionError("invalid");
|
|
917
|
+
if (canonicalJson2(projection.source.presentation) !== canonicalJson2(briefPresentation(e.sourcePresentation)))
|
|
918
|
+
throw new BriefAdmissionError("invalid");
|
|
919
|
+
const targets = new Map(projection.targets.map((t) => {
|
|
920
|
+
const c = canonicalizeResource(t);
|
|
921
|
+
return [c.identityDigest, c];
|
|
922
|
+
}));
|
|
923
|
+
if (targets.size !== projection.targets.length || targets.size !== e.targetDescriptors.length)
|
|
924
|
+
throw new BriefAdmissionError("invalid");
|
|
925
|
+
const descriptors = new Set;
|
|
926
|
+
for (const d of e.targetDescriptors) {
|
|
927
|
+
const key = canonicalizeIdentity(d.target).identityDigest, t = targets.get(key);
|
|
928
|
+
if (!t || descriptors.has(key) || canonicalJson2(t.presentation) !== canonicalJson2(briefPresentation(d.presentation)))
|
|
929
|
+
throw new BriefAdmissionError("invalid");
|
|
930
|
+
descriptors.add(key);
|
|
931
|
+
if (d.codec.state === "available") {
|
|
932
|
+
const p = d.codec.value;
|
|
933
|
+
const decoded = p.kind === "file" ? verifiedFileIdentity(p.verified) : p.kind === "url" ? { provider: "url", keys: { href: new URL(p.href).href } } : recognitionIdentity(p.source, p.kind === "thread" ? p.verified : undefined);
|
|
934
|
+
if (canonicalJson2(identityValue(decoded)) !== canonicalJson2(identityValue(d.target)))
|
|
935
|
+
throw new BriefAdmissionError("invalid");
|
|
936
|
+
}
|
|
937
|
+
}
|
|
938
|
+
const limits = [], keys = new Set, ids = new Set, counts = new Map;
|
|
939
|
+
if (e.sourceState === "absent") {
|
|
940
|
+
if (e.sourceContentRevision !== null || e.frame !== null || e.occurrences.length || targets.size || !projection.tombstone)
|
|
941
|
+
throw new BriefAdmissionError("invalid");
|
|
942
|
+
} else {
|
|
943
|
+
if (e.sourceContentRevision === null || e.frame === null || e.sourceState === "empty" && (e.occurrences.length > 0 || targets.size > 0 || !projection.tombstone) || e.sourceState === "present" && projection.tombstone)
|
|
944
|
+
throw new BriefAdmissionError("invalid");
|
|
945
|
+
}
|
|
946
|
+
if (e.sourceState === "empty") {
|
|
947
|
+
const f = e.frame;
|
|
948
|
+
if (f.fileUtf16Length !== 0 || f.bodyBase.startUtf16 !== 0 || f.bodyBase.utf16Length !== 0 || f.bodyBase.startLine !== 1 || f.lineMapping.fileLineCount !== 1 || f.rawBytes !== f.bomBytes || e.sourceContentRevision !== sha256Hex(f.bomBytes === 3 ? "\uFEFF" : ""))
|
|
949
|
+
throw new BriefAdmissionError("invalid");
|
|
950
|
+
}
|
|
951
|
+
for (const o of e.occurrences) {
|
|
952
|
+
const key = canonicalizeIdentity(o.target).identityDigest;
|
|
953
|
+
counts.set(key, (counts.get(key) ?? 0) + 1);
|
|
954
|
+
if (!targets.has(key) || keys.has(o.occurrenceKey) || ids.has(o.sourceOccurrenceId) || o.locator.threadId !== e.sourceFile.threadId || canonicalJson2(o.locator.file) !== canonicalJson2(e.sourceFile) || o.locator.sourceContentRevision !== e.sourceContentRevision || o.occurrenceKey !== briefOccurrenceKey(e.sourceContentRevision, o.target, o.locator, o.sourceOccurrenceId))
|
|
955
|
+
throw new BriefAdmissionError("invalid");
|
|
956
|
+
const f = e.frame;
|
|
957
|
+
if (o.locator.section.line > f.lineMapping.fileLineCount || o.locator.location.line > f.lineMapping.fileLineCount || o.locator.location.endLine !== null && (o.locator.location.endLine < o.locator.location.line || o.locator.location.endLine > f.lineMapping.fileLineCount) || o.locator.span && o.locator.span.end > (o.locator.span.frame === "file-utf16" ? f.fileUtf16Length : f.bodyBase.utf16Length))
|
|
958
|
+
throw new BriefAdmissionError("invalid");
|
|
959
|
+
keys.add(o.occurrenceKey);
|
|
960
|
+
ids.add(o.sourceOccurrenceId);
|
|
961
|
+
}
|
|
962
|
+
if (counts.size !== targets.size)
|
|
963
|
+
throw new BriefAdmissionError("invalid");
|
|
964
|
+
if ([...counts.values()].some((n) => n > 100))
|
|
965
|
+
limits.push("per-target-occurrences");
|
|
966
|
+
if (limits.length)
|
|
967
|
+
throw new BriefAdmissionError("over-limit", limits);
|
|
968
|
+
assertBriefDisplaySafe(e);
|
|
969
|
+
if (briefEvidenceDigest(e) !== evidenceDigest)
|
|
970
|
+
throw new BriefAdmissionError("invalid");
|
|
971
|
+
return e;
|
|
972
|
+
}
|
|
973
|
+
var limitCodes = z2.array(z2.enum(BRIEF_LIMIT_CODES)).max(10).refine((v) => new Set(v).size === v.length && v.every((x, i) => i === 0 || v[i - 1] < x));
|
|
974
|
+
var identityCodes = z2.array(z2.enum(["unsafe-required-identity", "unsupported-required-codec", "required-identity-bound"])).min(1).max(3).refine((v) => new Set(v).size === v.length && v.every((x, i) => i === 0 || v[i - 1] < x));
|
|
975
|
+
var blockedBriefStatusSchema = z2.discriminatedUnion("state", [
|
|
976
|
+
z2.strictObject({ state: z2.literal("over-limit"), sourceContentRevision: digest, limits: limitCodes.refine((v) => v.length > 0) }),
|
|
977
|
+
z2.strictObject({ state: z2.literal("identity-unrepresentable"), sourceContentRevision: digest, identityReasons: identityCodes, limits: limitCodes })
|
|
978
|
+
]);
|
|
979
|
+
function briefStatusDigest(producerPluginId, source, sourceFile, status) {
|
|
980
|
+
const s = blockedBriefStatusSchema.parse(status);
|
|
981
|
+
return sha256Hex(canonicalJson2(["brief-status", 1, producerPluginId, identityValue(source), briefFileSchema.parse(sourceFile), { ...s, limits: [...s.limits].sort(), ..."identityReasons" in s ? { identityReasons: [...s.identityReasons].sort() } : {} }]));
|
|
982
|
+
}
|
|
983
|
+
var producerGetStateInputSchema = z2.strictObject({ version: z2.literal(1), producerPluginId: z2.literal("thread-brief"), source: identity });
|
|
984
|
+
var producerReportStatusInputSchema = producerGetStateInputSchema.extend({ sourceFile: briefFileSchema, attemptRevision: positive, expectedRevision: integer, statusDigest: digest, status: blockedBriefStatusSchema }).superRefine((v, c) => {
|
|
985
|
+
if (canonicalJson2(identityValue(v.source)) !== canonicalJson2(verifiedFileIdentity(v.sourceFile)) || briefStatusDigest(v.producerPluginId, v.source, v.sourceFile, v.status) !== v.statusDigest)
|
|
986
|
+
c.addIssue({ code: "custom", message: "Invalid brief status binding." });
|
|
987
|
+
});
|
|
988
|
+
var presentationOut = z2.object({ label: labelText, detail: bytes(1024).refine((v) => !control(v) && v.trim().length > 0).optional(), url: bytes(2048).optional() }).passthrough();
|
|
989
|
+
var resourceOut = z2.object({ provider: z2.string(), keys: z2.record(z2.string(), z2.string()), presentation: presentationOut }).passthrough();
|
|
990
|
+
var projectionOut = z2.object({ producerPluginId: plugin, source: resourceOut, revision: integer, mutationId: z2.string(), payloadDigest: digest, tombstone: z2.boolean(), targets: z2.array(resourceOut).max(256) }).passthrough();
|
|
991
|
+
var statusOut = z2.union([
|
|
992
|
+
blockedBriefStatusSchema.options[0].extend({ attemptRevision: positive, statusDigest: digest, sourceFile: briefFileSchema.passthrough(), applicability: z2.enum(["current", "superseded-by-graph"]) }).passthrough(),
|
|
993
|
+
blockedBriefStatusSchema.options[1].extend({ attemptRevision: positive, statusDigest: digest, sourceFile: briefFileSchema.passthrough(), applicability: z2.enum(["current", "superseded-by-graph"]) }).passthrough()
|
|
994
|
+
]);
|
|
995
|
+
var producerStateSchema = z2.object({ version: z2.literal(1), projection: projectionOut.nullable(), evidence: z2.object({ kind: z2.literal("thread-brief"), graphRevision: positive, graphPayloadDigest: digest, evidenceDigest: digest, sourceContentRevision: digest.nullable(), state: z2.enum(["bound", "unconfirmed"]), sourceState: z2.enum(["present", "absent", "empty"]), occurrenceCount: integer.max(512) }).passthrough().nullable(), status: statusOut.nullable(), revisionHighWater: integer }).passthrough();
|
|
996
|
+
var producerDescribeInputSchema = z2.null();
|
|
997
|
+
var producerDescribeOutputSchema = z2.object({ protocol: z2.literal("cross-references-producer"), versions: z2.array(positive).max(16), sourceKinds: z2.array(z2.literal("thread-brief")).max(1), limits: z2.object({ inputBytes: positive, statusBytes: positive, locations: positive, perTarget: positive, headingBytes: positive, limitCodes: z2.array(z2.string()).max(32) }).passthrough() }).passthrough();
|
|
998
|
+
var producerDescribe = () => ({ protocol: "cross-references-producer", versions: [1], sourceKinds: ["thread-brief"], limits: { inputBytes: BRIEF_LIMITS.inputBytes, statusBytes: BRIEF_LIMITS.statusBytes, locations: 512, perTarget: 100, headingBytes: 256, limitCodes: [...BRIEF_LIMIT_CODES] } });
|
|
999
|
+
function projectionValue(value) {
|
|
1000
|
+
const resource = (r) => ({ provider: r.provider, keys: r.keys, presentation: { label: r.presentation.label, ...r.presentation.detail === undefined ? {} : { detail: r.presentation.detail }, ...r.presentation.url === undefined ? {} : { url: r.presentation.url } } });
|
|
1001
|
+
return { protocolVersion: value.protocolVersion, producerPluginId: value.producerPluginId, mutationId: value.mutationId, source: resource(value.source), revision: value.revision, expectedRevision: value.expectedRevision, payloadDigest: value.payloadDigest, tombstone: value.tombstone, targets: value.targets.map(resource) };
|
|
1002
|
+
}
|
|
1003
|
+
function createProducerSchemas(projection) {
|
|
1004
|
+
const admittedProjection = projection.transform(projectionValue);
|
|
1005
|
+
return {
|
|
1006
|
+
[PRODUCER_METHODS.describe]: { input: producerDescribeInputSchema, output: producerDescribeOutputSchema },
|
|
1007
|
+
[PRODUCER_METHODS.getState]: { input: producerGetStateInputSchema, output: producerStateSchema },
|
|
1008
|
+
[PRODUCER_METHODS.apply]: { input: z2.strictObject({ version: z2.literal(1), projection: admittedProjection, evidence: briefEvidenceSchema, evidenceDigest: digest }), output: z2.object({ version: z2.literal(1), outcome: z2.enum(["applied", "duplicate", "equal", "stale", "conflict", "cas-mismatch"]), currentRevision: integer, currentDigest: digest.nullable(), evidenceDisposition: z2.enum(["installed", "replayed", "conflict", "not-applied"]), state: producerStateSchema }).passthrough() },
|
|
1009
|
+
[PRODUCER_METHODS.reportStatus]: { input: producerReportStatusInputSchema, output: z2.object({ version: z2.literal(1), outcome: z2.enum(["recorded", "duplicate", "stale", "conflict", "cas-mismatch"]), state: producerStateSchema }).passthrough() }
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
var briefNavigationInputSchema = z2.strictObject({ version: z2.literal(1), sourceFile: briefFileSchema, sourceContentRevision: digest, frame: briefFrameSchema, section: z2.strictObject({ heading: briefHeadingSchema, originalLine: positive }) });
|
|
1013
|
+
var briefNavigationOutputSchema = z2.discriminatedUnion("state", [
|
|
1014
|
+
z2.object({ version: z2.literal(1), state: z2.literal("ready"), sourceFile: briefFileSchema.passthrough(), sourceContentRevision: digest, location: z2.object({ kind: z2.literal("line"), line: positive, column: z2.null() }).passthrough(), proof: z2.object({ kind: z2.literal("accepted-revision-revalidated"), acceptedRevision: digest, selection: z2.literal("same-revision"), frame: briefFrameSchema.safeExtend({ bodyBase: briefFrameSchema.shape.bodyBase.passthrough(), lineMapping: briefFrameSchema.shape.lineMapping.passthrough() }).passthrough() }).passthrough() }).passthrough(),
|
|
1015
|
+
z2.object({ version: z2.literal(1), state: z2.literal("fallback"), sourceFile: briefFileSchema.passthrough(), location: z2.null(), reason: z2.enum(["stale", "no-accepted-document", "ambiguous", "heading-unavailable", "source-unavailable", "over-limit"]) }).passthrough()
|
|
1016
|
+
]);
|
|
1017
|
+
var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16) }).passthrough();
|
|
1018
|
+
var briefNavigationRpcSchemas = { [BRIEF_NAVIGATION_METHODS.describe]: { input: z2.null(), output: briefNavigationDescribeOutputSchema }, [BRIEF_NAVIGATION_METHODS.resolve]: { input: briefNavigationInputSchema, output: briefNavigationOutputSchema } };
|
|
1019
|
+
var outWithheld = (display) => withheld(display).passthrough();
|
|
1020
|
+
var briefHeadingOutputSchema = z2.union([z2.null(), z2.object({ state: z2.literal("named"), text: bytes(256) }).passthrough(), outWithheld("Heading withheld")]);
|
|
1021
|
+
var briefFileOutputSchema = briefFileSchema.passthrough();
|
|
1022
|
+
var briefFrameOutputSchema = briefFrameSchema.safeExtend({ bodyBase: briefFrameSchema.shape.bodyBase.passthrough(), lineMapping: briefFrameSchema.shape.lineMapping.passthrough() }).passthrough();
|
|
1023
|
+
var briefLocatorOutputSchema = briefLocatorSchema.extend({ file: briefFileOutputSchema, section: z2.object({ heading: briefHeadingOutputSchema, line: positive }).passthrough(), location: briefLocatorSchema.shape.location.passthrough(), span: briefLocatorSchema.shape.span.unwrap().passthrough().optional() }).passthrough();
|
|
1024
|
+
var verifiedFileOutput = z2.union([VerifiedFileTargetSchema.options[0].passthrough(), VerifiedFileTargetSchema.options[1].passthrough()]);
|
|
1025
|
+
var provenanceValueOutput = provenanceValue.extend({ source: SourceIdentitySchema2.passthrough(), verifiedFile: verifiedFileOutput.optional(), recognition: provenanceValue.shape.recognition.extend({ evidence: provenanceValue.shape.recognition.shape.evidence.unwrap().extend({ span: span.passthrough().optional() }).passthrough().optional() }).passthrough() }).passthrough();
|
|
1026
|
+
var briefProvenanceOutputSchema = z2.union([z2.object({ state: z2.literal("safe"), value: provenanceValueOutput }).passthrough(), outWithheld("Recognition details withheld").extend({ summary: provenanceSummary.passthrough() })]);
|
|
1027
|
+
var briefAuthoredUrlOutputSchema = z2.union([z2.object({ state: z2.literal("exact"), href: safeHref }).passthrough(), z2.object({ state: z2.literal("not-url") }).passthrough(), z2.object({ state: z2.literal("unknown") }).passthrough(), outWithheld("Destination withheld")]);
|
|
1028
|
+
function validateBriefNavigationResultV1(input, raw) {
|
|
1029
|
+
const value = briefNavigationOutputSchema.parse(raw), file = value.sourceFile;
|
|
1030
|
+
if (file.kind !== input.sourceFile.kind || file.threadId !== input.sourceFile.threadId || file.path !== input.sourceFile.path)
|
|
1031
|
+
throw new Error("Brief navigation target mismatch.");
|
|
1032
|
+
if (value.state === "ready" && (value.sourceContentRevision !== input.sourceContentRevision || value.proof.acceptedRevision !== input.sourceContentRevision || canonicalJson2(knownFrame(value.proof.frame)) !== canonicalJson2(knownFrame(input.frame)) || value.location.line !== input.section.originalLine || value.location.line > input.frame.lineMapping.fileLineCount))
|
|
1033
|
+
throw new Error("Brief navigation proof mismatch.");
|
|
1034
|
+
return value;
|
|
1035
|
+
}
|
|
1036
|
+
function knownFrame(f) {
|
|
1037
|
+
return { codec: f.codec, rawBytes: f.rawBytes, bomBytes: f.bomBytes, fileUtf16Length: f.fileUtf16Length, bodyBase: { startUtf16: f.bodyBase.startUtf16, startLine: f.bodyBase.startLine, utf16Length: f.bodyBase.utf16Length }, lineMapping: { codec: f.lineMapping.codec, fileLineCount: f.lineMapping.fileLineCount } };
|
|
1038
|
+
}
|
|
1039
|
+
|
|
1040
|
+
// src/evidence-v2.ts
|
|
1041
|
+
import { z as z3 } from "zod";
|
|
1042
|
+
import { ContextBundleV1Schema, SafeHrefSchema as SafeHrefSchema3, CandidateV1Schema, SourceIdentitySchema as SourceIdentitySchema3 } from "@phosphorco/bb-context-recognition";
|
|
1043
|
+
var MENTION_V2_LIMITS = Object.freeze({
|
|
1044
|
+
responseBytes: 1048576,
|
|
1045
|
+
inputBytes: 65536,
|
|
1046
|
+
pageSize: 100,
|
|
1047
|
+
cursorBytes: 4096,
|
|
1048
|
+
excerptCodePoints: 320,
|
|
1049
|
+
excerptBytes: 1280,
|
|
1050
|
+
rowBytes: 131072,
|
|
1051
|
+
readMs: 2000,
|
|
1052
|
+
callMs: 5000,
|
|
1053
|
+
lookupMs: 1500,
|
|
1054
|
+
lookupCalls: 8
|
|
1055
|
+
});
|
|
1056
|
+
var MENTION_V2_METHODS = Object.freeze({ list: "crossReferencesV2ListMentions", resolve: "crossReferencesV2ResolveLookup" });
|
|
1057
|
+
var integer2 = () => z3.number().int().nonnegative().max(Number.MAX_SAFE_INTEGER);
|
|
1058
|
+
var time = () => integer2().max(8640000000000000);
|
|
1059
|
+
var digest2 = z3.string().regex(/^[a-f0-9]{64}$/);
|
|
1060
|
+
var text = (n) => z3.string().max(n).refine((v) => utf8ByteLength(v) <= n, "UTF8 byte bound exceeded.");
|
|
1061
|
+
var id = z3.string().min(1).max(256).refine((v) => !/[\p{Cc}]/u.test(v));
|
|
1062
|
+
var producer = z3.string().regex(/^[a-z][a-z0-9._-]{0,63}$/);
|
|
1063
|
+
var keys = z3.record(z3.string(), z3.string()).refine((v) => Object.keys(v).length <= 16);
|
|
1064
|
+
function isUtf16CodePointBoundary(text2, offset) {
|
|
1065
|
+
if (!Number.isSafeInteger(offset) || offset < 0 || offset > text2.length)
|
|
1066
|
+
return false;
|
|
1067
|
+
const before = text2.charCodeAt(offset - 1), after = text2.charCodeAt(offset);
|
|
1068
|
+
return !(before >= 55296 && before <= 56319 && after >= 56320 && after <= 57343);
|
|
1069
|
+
}
|
|
1070
|
+
function wellFormedUtf16(text2) {
|
|
1071
|
+
for (const point of text2) {
|
|
1072
|
+
const value = point.codePointAt(0);
|
|
1073
|
+
if (value >= 55296 && value <= 57343)
|
|
1074
|
+
return false;
|
|
1075
|
+
}
|
|
1076
|
+
return true;
|
|
1077
|
+
}
|
|
1078
|
+
var identityShape = { provider: z3.string().min(1).max(64), keys };
|
|
1079
|
+
var identityInputV2Schema = z3.strictObject(identityShape).superRefine((v, c) => {
|
|
1080
|
+
try {
|
|
1081
|
+
canonicalizeIdentity(v);
|
|
1082
|
+
} catch {
|
|
1083
|
+
c.addIssue({ code: "custom", message: "Invalid resource identity." });
|
|
1084
|
+
}
|
|
1085
|
+
});
|
|
1086
|
+
var presentation2 = z3.object({ label: text(256).min(1), url: text(2048).optional(), detail: text(1024).optional() }).passthrough();
|
|
1087
|
+
var resourceOutputV2Schema = z3.object({ ...identityShape, presentation: presentation2 }).passthrough().superRefine((v, c) => {
|
|
1088
|
+
try {
|
|
1089
|
+
canonicalizeResource({ provider: v.provider, keys: v.keys, presentation: { label: v.presentation.label, ...v.presentation.url === undefined ? {} : { url: v.presentation.url }, ...v.presentation.detail === undefined ? {} : { detail: v.presentation.detail } } });
|
|
1090
|
+
} catch {
|
|
1091
|
+
c.addIssue({ code: "custom", message: "Invalid resource." });
|
|
1092
|
+
}
|
|
1093
|
+
});
|
|
1094
|
+
var safeAuthoredHrefSchema = SafeHrefSchema3.refine((v) => utf8ByteLength(v) <= 16384 && !hasSensitiveUrlParameter(new URL(v, "https://local.invalid")), "Unsafe destination.");
|
|
1095
|
+
var mentionQueryV2Schema = z3.discriminatedUnion("kind", [
|
|
1096
|
+
z3.strictObject({ kind: z3.literal("resource"), target: identityInputV2Schema, relation: z3.enum(["self", "github-pr-family"]) }).refine((v) => v.relation === "self" || v.target.provider === "recognition" && v.target.keys.provider === "github" && /^[a-f0-9]{64}$/.test(v.target.keys.identity ?? ""), "Expected a GitHub root identity."),
|
|
1097
|
+
z3.strictObject({ kind: z3.literal("authored-url"), href: safeAuthoredHrefSchema })
|
|
1098
|
+
]);
|
|
1099
|
+
var listMentionsInputV2Schema = z3.strictObject({
|
|
1100
|
+
version: z3.literal(2),
|
|
1101
|
+
query: mentionQueryV2Schema,
|
|
1102
|
+
source: identityInputV2Schema.optional(),
|
|
1103
|
+
producerPluginId: producer.optional(),
|
|
1104
|
+
pageSize: z3.number().int().min(1).max(100).optional(),
|
|
1105
|
+
cursor: text(4096).optional(),
|
|
1106
|
+
ifSnapshot: digest2.optional()
|
|
1107
|
+
}).refine((v) => !(v.cursor !== undefined && v.ifSnapshot !== undefined), "Cursor and conditional are exclusive.");
|
|
1108
|
+
var spanShape = { start: integer2(), end: integer2() };
|
|
1109
|
+
var spanOutputV2Schema = z3.object(spanShape).passthrough().refine((v) => v.end > v.start);
|
|
1110
|
+
var readyShape = {
|
|
1111
|
+
state: z3.literal("ready"),
|
|
1112
|
+
text: z3.string().refine(wellFormedUtf16, "Excerpt text must be well-formed UTF16.").refine((v) => [...v].length <= 320 && utf8ByteLength(v) <= 1280),
|
|
1113
|
+
sourceSpan: spanOutputV2Schema,
|
|
1114
|
+
matchSpan: spanOutputV2Schema,
|
|
1115
|
+
clippedBefore: z3.boolean(),
|
|
1116
|
+
clippedAfter: z3.boolean(),
|
|
1117
|
+
matchClippedBefore: z3.boolean(),
|
|
1118
|
+
matchClippedAfter: z3.boolean(),
|
|
1119
|
+
codecVersion: z3.literal(1)
|
|
1120
|
+
};
|
|
1121
|
+
var readyCoordinates = (v) => v.matchSpan.end <= v.text.length && v.sourceSpan.end - v.sourceSpan.start === v.text.length && isUtf16CodePointBoundary(v.text, v.matchSpan.start) && isUtf16CodePointBoundary(v.text, v.matchSpan.end);
|
|
1122
|
+
var excerptV2Schema = z3.discriminatedUnion("state", [
|
|
1123
|
+
z3.object(readyShape).passthrough().refine(readyCoordinates, "Excerpt bounds must be code-point aligned."),
|
|
1124
|
+
z3.object({ state: z3.literal("unavailable"), reason: z3.enum(["not-materialized", "indivisible-word", "no-eligible-context"]), codecVersion: z3.literal(1) }).passthrough()
|
|
1125
|
+
]);
|
|
1126
|
+
var excerptRecordV2Schema = z3.discriminatedUnion("state", [
|
|
1127
|
+
z3.strictObject({ ...readyShape, sourceSpan: z3.strictObject(spanShape).refine((v) => v.end > v.start), matchSpan: z3.strictObject(spanShape).refine((v) => v.end > v.start) }).refine(readyCoordinates, "Excerpt bounds must be code-point aligned."),
|
|
1128
|
+
z3.strictObject({ state: z3.literal("unavailable"), reason: z3.enum(["indivisible-word", "no-eligible-context"]), codecVersion: z3.literal(1) })
|
|
1129
|
+
]);
|
|
1130
|
+
var locatorOutputV2Schema = z3.object({ kind: z3.literal("conversation"), threadId: id, messageId: id, messageSeq: integer2(), anchorSeq: integer2().nullable(), role: z3.enum(["user", "assistant"]) }).passthrough();
|
|
1131
|
+
var recognitionProvenance = z3.object({
|
|
1132
|
+
pluginId: id,
|
|
1133
|
+
origin: z3.enum(["builtin", "contributed"]),
|
|
1134
|
+
confidence: CandidateV1Schema.shape.confidence,
|
|
1135
|
+
recognition: z3.object({
|
|
1136
|
+
basis: z3.enum(["explicit", "text-url", "existing-link", "git-remote", "context"]),
|
|
1137
|
+
explanation: z3.string().min(1).max(200),
|
|
1138
|
+
evidence: z3.object({ span: spanOutputV2Schema.optional(), link: integer2().optional(), remote: id.optional() }).passthrough().optional()
|
|
1139
|
+
}).passthrough(),
|
|
1140
|
+
source: SourceIdentitySchema3.passthrough(),
|
|
1141
|
+
authoredHref: safeAuthoredHrefSchema.optional(),
|
|
1142
|
+
verifiedFile: VerifiedFileTargetSchema.optional()
|
|
1143
|
+
}).passthrough();
|
|
1144
|
+
var verifiedFileOutput2 = z3.union([
|
|
1145
|
+
z3.object({ kind: z3.literal("workspace"), environmentId: id, path: z3.string().min(1).max(4096) }).passthrough(),
|
|
1146
|
+
z3.object({ kind: z3.literal("thread-storage"), threadId: id, path: z3.string().min(1).max(4096) }).passthrough()
|
|
1147
|
+
]);
|
|
1148
|
+
var provenanceOutput = recognitionProvenance.extend({ verifiedFile: verifiedFileOutput2.optional() });
|
|
1149
|
+
var claimShape = {
|
|
1150
|
+
source: resourceOutputV2Schema,
|
|
1151
|
+
target: resourceOutputV2Schema,
|
|
1152
|
+
producerPluginId: producer,
|
|
1153
|
+
graphRevision: integer2(),
|
|
1154
|
+
cap: z3.object({ state: z3.enum(["uncapped", "capped", "unknown"]), limit: z3.literal(100).nullable(), sourceHistoryUnknown: z3.boolean().nullable() }).passthrough()
|
|
1155
|
+
};
|
|
1156
|
+
var knownItem = z3.discriminatedUnion("kind", [
|
|
1157
|
+
z3.object({
|
|
1158
|
+
...claimShape,
|
|
1159
|
+
kind: z3.literal("brief-occurrence"),
|
|
1160
|
+
evidenceRevision: integer2().min(1),
|
|
1161
|
+
occurrenceKey: digest2,
|
|
1162
|
+
sourceOccurrenceId: text(256),
|
|
1163
|
+
locator: briefLocatorOutputSchema,
|
|
1164
|
+
sourceContentRevision: digest2,
|
|
1165
|
+
frame: briefFrameOutputSchema,
|
|
1166
|
+
excerpt: z3.object({ state: z3.literal("unavailable"), reason: z3.literal("not-materialized"), codecVersion: z3.literal(1) }).passthrough(),
|
|
1167
|
+
provenance: briefProvenanceOutputSchema,
|
|
1168
|
+
authoredUrl: briefAuthoredUrlOutputSchema,
|
|
1169
|
+
authoredUrlState: z3.enum(["exact", "not-url", "unknown", "withheld"]),
|
|
1170
|
+
confirmation: z3.enum(["producer-attested", "retained-unconfirmed"])
|
|
1171
|
+
}).passthrough().refine((v) => v.authoredUrlState === v.authoredUrl.state && v.sourceContentRevision === v.locator.sourceContentRevision && v.locator.threadId === v.locator.file.threadId, "Inconsistent Brief item."),
|
|
1172
|
+
z3.object({
|
|
1173
|
+
...claimShape,
|
|
1174
|
+
kind: z3.literal("occurrence"),
|
|
1175
|
+
evidenceRevision: integer2().min(1),
|
|
1176
|
+
occurrenceKey: digest2,
|
|
1177
|
+
locator: locatorOutputV2Schema,
|
|
1178
|
+
sourceContentRevision: digest2,
|
|
1179
|
+
span: spanOutputV2Schema,
|
|
1180
|
+
excerpt: excerptV2Schema,
|
|
1181
|
+
messageCreatedAt: time(),
|
|
1182
|
+
observedAt: time(),
|
|
1183
|
+
confirmation: z3.enum(["observed", "retained-unconfirmed"]),
|
|
1184
|
+
provenance: provenanceOutput,
|
|
1185
|
+
authoredUrlState: z3.enum(["exact", "not-url", "unknown"])
|
|
1186
|
+
}).passthrough(),
|
|
1187
|
+
z3.object({ ...claimShape, kind: z3.literal("claim-without-evidence"), reason: z3.enum(["legacy", "producer-no-evidence", "not-yet-collected"]), matchBasis: z3.enum(["primary-resource", "primary-url-identity"]) }).passthrough(),
|
|
1188
|
+
z3.object({ ...claimShape, kind: z3.literal("unsupported"), reason: z3.literal("unsupported-format") }).passthrough()
|
|
1189
|
+
]);
|
|
1190
|
+
var mentionItemV2Schema = z3.unknown().transform((raw, ctx) => {
|
|
1191
|
+
const r = raw;
|
|
1192
|
+
const unknown = (value, known) => typeof value === "string" && !known.includes(value);
|
|
1193
|
+
const future = !!r && typeof r === "object" && (unknown(r.kind, ["occurrence", "brief-occurrence", "claim-without-evidence", "unsupported"]) || r.kind === "occurrence" && (unknown(r.locator?.kind, ["conversation"]) || unknown(r.excerpt?.state, ["ready", "unavailable"]) || typeof r.excerpt?.codecVersion === "number" && r.excerpt.codecVersion !== 1 || unknown(r.confirmation, ["observed", "retained-unconfirmed"]) || unknown(r.authoredUrlState, ["exact", "not-url", "unknown"]) || unknown(r.locator?.role, ["user", "assistant"]) || unknown(r.provenance?.origin, ["builtin", "contributed"]) || unknown(r.provenance?.confidence, ["high", "medium", "low"]) || unknown(r.provenance?.recognition?.basis, ["explicit", "text-url", "existing-link", "git-remote", "context"]) || r.excerpt?.state === "unavailable" && unknown(r.excerpt.reason, ["not-materialized", "indivisible-word", "no-eligible-context"])) || r.kind === "brief-occurrence" && (unknown(r.locator?.kind, ["thread-brief"]) || unknown(r.confirmation, ["producer-attested", "retained-unconfirmed"]) || unknown(r.authoredUrlState, ["exact", "not-url", "unknown", "withheld"]) || unknown(r.provenance?.state, ["safe", "withheld"]) || unknown(r.locator?.section?.heading?.state, ["named", "withheld"]) || unknown(r.locator?.section?.heading?.cause, ["policy", "unclassified"]) || unknown(r.provenance?.cause, ["policy", "unclassified"]) || unknown(r.authoredUrl?.state, ["exact", "not-url", "unknown", "withheld"]) || unknown(r.authoredUrl?.cause, ["policy", "unclassified"]) || unknown(r.frame?.codec, ["utf8-fatal-bom-consumed-v1"]) || unknown(r.frame?.lineMapping?.codec, ["native-file-lines-v1"]) || unknown(r.locator?.location?.kind, ["line"]) || unknown(r.locator?.span?.frame, ["file-utf16", "body-utf16"]) || unknown(r.excerpt?.state, ["unavailable"]) || unknown(r.excerpt?.reason, ["not-materialized"]) || typeof r.excerpt?.codecVersion === "number" && r.excerpt.codecVersion !== 1) || r.kind === "claim-without-evidence" && (unknown(r.reason, ["legacy", "producer-no-evidence", "not-yet-collected"]) || unknown(r.matchBasis, ["primary-resource", "primary-url-identity"])) || unknown(r.cap?.state, ["uncapped", "capped", "unknown"]));
|
|
1194
|
+
if (future && (!r.cap || !z3.object({ state: z3.string(), limit: z3.literal(100).nullable(), sourceHistoryUnknown: z3.boolean().nullable() }).safeParse(r.cap).success)) {
|
|
1195
|
+
ctx.addIssue({ code: "custom", message: "Invalid required claim cap." });
|
|
1196
|
+
return z3.NEVER;
|
|
1197
|
+
}
|
|
1198
|
+
const candidate = future ? {
|
|
1199
|
+
source: r.source,
|
|
1200
|
+
target: r.target,
|
|
1201
|
+
producerPluginId: r.producerPluginId,
|
|
1202
|
+
graphRevision: r.graphRevision,
|
|
1203
|
+
cap: { state: "unknown", limit: null, sourceHistoryUnknown: null },
|
|
1204
|
+
kind: "unsupported",
|
|
1205
|
+
reason: "unsupported-format"
|
|
1206
|
+
} : raw;
|
|
1207
|
+
const parsed = knownItem.safeParse(candidate);
|
|
1208
|
+
if (parsed.success)
|
|
1209
|
+
return parsed.data;
|
|
1210
|
+
ctx.addIssue({ code: "custom", message: "Invalid mention item." });
|
|
1211
|
+
return z3.NEVER;
|
|
1212
|
+
});
|
|
1213
|
+
var mentionCountsV2Schema = z3.object({ retainedOccurrences: integer2(), confirmedOccurrences: integer2(), unconfirmedOccurrences: integer2(), producerClaims: integer2(), indexedSources: integer2(), claimsWithoutLocations: integer2(), excerptUnavailable: integer2() }).passthrough().refine((v) => v.confirmedOccurrences + v.unconfirmedOccurrences === v.retainedOccurrences && v.claimsWithoutLocations <= v.producerClaims && v.indexedSources <= v.producerClaims && v.excerptUnavailable <= v.retainedOccurrences);
|
|
1214
|
+
var coverageV2Schema = z3.object({
|
|
1215
|
+
scope: z3.literal("known-sources"),
|
|
1216
|
+
collectionIncomplete: z3.boolean(),
|
|
1217
|
+
retentionLimited: z3.boolean(),
|
|
1218
|
+
capHistoryUnknown: z3.boolean(),
|
|
1219
|
+
legacyClaimsPresent: z3.boolean(),
|
|
1220
|
+
evidenceStateUnknown: z3.boolean(),
|
|
1221
|
+
authoredUrlCoverage: z3.object({ state: z3.enum(["complete-for-known-locations", "partial"]), unknownLocations: integer2(), scope: z3.literal("known-locations"), watermark: digest2 }).passthrough(),
|
|
1222
|
+
reasons: z3.array(text(128)).max(32),
|
|
1223
|
+
reasonsClipped: z3.boolean(),
|
|
1224
|
+
checkedAt: time().nullable()
|
|
1225
|
+
}).passthrough();
|
|
1226
|
+
var listMentionsOutputV2Schema = z3.discriminatedUnion("status", [
|
|
1227
|
+
z3.object({ version: z3.literal(2), status: z3.literal("page"), snapshot: digest2, items: z3.array(mentionItemV2Schema).max(100), counts: mentionCountsV2Schema, coverage: coverageV2Schema, nextCursor: text(4096).nullable() }).passthrough(),
|
|
1228
|
+
z3.object({ version: z3.literal(2), status: z3.literal("not-modified"), snapshot: digest2, coverage: coverageV2Schema }).passthrough(),
|
|
1229
|
+
z3.object({ version: z3.literal(2), status: z3.literal("restart"), reason: z3.literal("snapshot-changed"), snapshot: digest2 }).passthrough(),
|
|
1230
|
+
z3.object({ version: z3.literal(2), status: z3.literal("unavailable"), reason: z3.enum(["index-warming", "read-budget"]), retryable: z3.boolean() }).passthrough()
|
|
1231
|
+
]);
|
|
1232
|
+
var lookupContextV2Schema = ContextBundleV1Schema.omit({ consumer: true, links: true }).extend({ links: z3.array(z3.strictObject({ href: safeAuthoredHrefSchema })).max(16).optional() });
|
|
1233
|
+
var resolveLookupInputV2Schema = z3.strictObject({ version: z3.literal(2), text: z3.string().min(1).max(4096).refine((v) => utf8ByteLength(v) <= 16384), mode: z3.enum(["recognize", "exact-url"]), context: lookupContextV2Schema.optional() });
|
|
1234
|
+
var identityOutput = z3.object(identityShape).passthrough().superRefine((v, c) => {
|
|
1235
|
+
try {
|
|
1236
|
+
canonicalizeIdentity({ provider: v.provider, keys: v.keys });
|
|
1237
|
+
} catch {
|
|
1238
|
+
c.addIssue({ code: "custom", message: "Invalid lookup identity." });
|
|
1239
|
+
}
|
|
1240
|
+
});
|
|
1241
|
+
var queryOutput = z3.discriminatedUnion("kind", [
|
|
1242
|
+
z3.object({ kind: z3.literal("resource"), target: identityOutput, relation: z3.enum(["self", "github-pr-family"]) }).passthrough(),
|
|
1243
|
+
z3.object({ kind: z3.literal("authored-url"), href: safeAuthoredHrefSchema }).passthrough()
|
|
1244
|
+
]);
|
|
1245
|
+
var resolveLookupOutputV2Schema = z3.object({
|
|
1246
|
+
version: z3.literal(2),
|
|
1247
|
+
state: z3.enum(["ready", "ambiguous", "unrecognized", "incomplete"]),
|
|
1248
|
+
options: z3.array(z3.object({ query: queryOutput, label: text(256), inputSpan: spanOutputV2Schema, basis: z3.enum(["supplier", "native", "stored-codec"]), reasons: z3.array(text(128)).max(16) }).passthrough()).max(8),
|
|
1249
|
+
reasons: z3.array(text(128)).max(16)
|
|
1250
|
+
}).passthrough();
|
|
1251
|
+
var crossReferencesV2RpcSchemas = {
|
|
1252
|
+
crossReferencesV2ListMentions: { input: listMentionsInputV2Schema, output: listMentionsOutputV2Schema },
|
|
1253
|
+
crossReferencesV2ResolveLookup: { input: resolveLookupInputV2Schema, output: resolveLookupOutputV2Schema }
|
|
1254
|
+
};
|
|
1255
|
+
var mentionsChangedV2Schema = z3.object({ version: z3.literal(2), producerPluginId: producer, sourceIdentityDigest: digest2, graphRevision: integer2(), evidenceRevision: integer2().nullable(), affectedIdentityDigests: z3.array(digest2).max(512), scopeListClipped: z3.boolean() }).passthrough();
|
|
1256
|
+
var MENTIONS_V2_CHANNEL = "cross-references-mentions-v2-changed";
|
|
1257
|
+
// src/lookup.ts
|
|
1258
|
+
function githubLookup(value) {
|
|
1259
|
+
if (!safeAuthoredHrefSchema.safeParse(value).success)
|
|
1260
|
+
return null;
|
|
1261
|
+
let u;
|
|
1262
|
+
try {
|
|
1263
|
+
u = new URL(value);
|
|
1264
|
+
} catch {
|
|
1265
|
+
return null;
|
|
1266
|
+
}
|
|
1267
|
+
if (u.hostname.toLowerCase() !== "github.com" || u.port || u.username || u.password)
|
|
1268
|
+
return null;
|
|
1269
|
+
const p = u.pathname.replace(/\/$/, "").split("/").slice(1);
|
|
1270
|
+
if (!/^[a-z0-9](?:[a-z0-9-]{0,37}[a-z0-9])?$/i.test(p[0] ?? "") || !/^[a-z0-9_.-]{1,100}$/i.test(p[1] ?? "") || [".", ".."].includes(p[1] ?? "") || !["pull", "issues"].includes(p[2] ?? "") || !/^[1-9]\d*$/.test(p[3] ?? "") || !Number.isSafeInteger(Number(p[3])))
|
|
1271
|
+
return null;
|
|
1272
|
+
const repo = `${p[0]}/${p[1]}`.toLowerCase(), n = String(Number(p[3])), kind = p[2] === "pull" ? "pull-request" : "issue";
|
|
1273
|
+
const source = { provider: "github", id: `github.com/${repo}#${n}`, kind };
|
|
1274
|
+
return { source, query: { kind: "resource", target: recognitionIdentity(source), relation: kind === "pull-request" ? "github-pr-family" : "self" }, label: `${repo}#${n}` };
|
|
1275
|
+
}
|
|
1276
|
+
// src/index.ts
|
|
369
1277
|
var FORWARD_REFERENCE_CHECK_LIMIT = 10;
|
|
370
1278
|
function assertInputRecord(value) {
|
|
371
1279
|
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
@@ -439,130 +1347,130 @@ var namePattern = /^[a-z][a-z0-9._-]{0,63}$/;
|
|
|
439
1347
|
var uuidPattern = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;
|
|
440
1348
|
var digestPattern = /^[0-9a-f]{64}$/;
|
|
441
1349
|
var safeInteger = (schema) => schema.refine(Number.isSafeInteger, { message: "must be a safe integer" });
|
|
442
|
-
var presentationSchema =
|
|
443
|
-
label:
|
|
444
|
-
detail:
|
|
445
|
-
url:
|
|
1350
|
+
var presentationSchema = z4.object({
|
|
1351
|
+
label: z4.string().max(MAX_PRESENTATION_LABEL_BYTES),
|
|
1352
|
+
detail: z4.string().max(MAX_PRESENTATION_DETAIL_BYTES).optional(),
|
|
1353
|
+
url: z4.string().max(MAX_PRESENTATION_URL_BYTES).optional()
|
|
446
1354
|
}).strict().superRefine((value, context) => {
|
|
447
1355
|
try {
|
|
448
1356
|
canonicalizeResource({ provider: "test", keys: { resource: "placeholder" }, presentation: value });
|
|
449
|
-
} catch (
|
|
450
|
-
context.addIssue({ code: "custom", message:
|
|
1357
|
+
} catch (cause2) {
|
|
1358
|
+
context.addIssue({ code: "custom", message: cause2 instanceof Error ? cause2.message : String(cause2) });
|
|
451
1359
|
}
|
|
452
1360
|
});
|
|
453
|
-
var resourceSchema =
|
|
454
|
-
provider:
|
|
455
|
-
keys:
|
|
1361
|
+
var resourceSchema = z4.object({
|
|
1362
|
+
provider: z4.string().max(64).regex(namePattern),
|
|
1363
|
+
keys: z4.record(z4.string().max(64), z4.string().max(MAX_KEY_VALUE_BYTES)),
|
|
456
1364
|
presentation: presentationSchema
|
|
457
1365
|
}).strict().superRefine((value, context) => {
|
|
458
1366
|
try {
|
|
459
1367
|
canonicalizeResource(value);
|
|
460
|
-
} catch (
|
|
461
|
-
context.addIssue({ code: "custom", message:
|
|
1368
|
+
} catch (cause2) {
|
|
1369
|
+
context.addIssue({ code: "custom", message: cause2 instanceof Error ? cause2.message : String(cause2) });
|
|
462
1370
|
}
|
|
463
1371
|
});
|
|
464
|
-
var resourceIdentitySchema =
|
|
465
|
-
provider:
|
|
466
|
-
keys:
|
|
1372
|
+
var resourceIdentitySchema = z4.object({
|
|
1373
|
+
provider: z4.string().max(64).regex(namePattern),
|
|
1374
|
+
keys: z4.record(z4.string().max(64), z4.string().max(MAX_KEY_VALUE_BYTES))
|
|
467
1375
|
}).strict().superRefine((value, context) => {
|
|
468
1376
|
try {
|
|
469
1377
|
canonicalizeIdentity(value);
|
|
470
|
-
} catch (
|
|
471
|
-
context.addIssue({ code: "custom", message:
|
|
1378
|
+
} catch (cause2) {
|
|
1379
|
+
context.addIssue({ code: "custom", message: cause2 instanceof Error ? cause2.message : String(cause2) });
|
|
472
1380
|
}
|
|
473
1381
|
});
|
|
474
|
-
var producerPluginIdSchema =
|
|
475
|
-
var mutationIdSchema =
|
|
476
|
-
var revisionSchema = safeInteger(
|
|
477
|
-
var applyProjectionInputSchema =
|
|
478
|
-
protocolVersion:
|
|
1382
|
+
var producerPluginIdSchema = z4.string().max(64).regex(namePattern);
|
|
1383
|
+
var mutationIdSchema = z4.string().max(MAX_MUTATION_ID_BYTES).regex(uuidPattern);
|
|
1384
|
+
var revisionSchema = safeInteger(z4.number().int());
|
|
1385
|
+
var applyProjectionInputSchema = z4.object({
|
|
1386
|
+
protocolVersion: z4.literal(PROTOCOL_VERSION),
|
|
479
1387
|
producerPluginId: producerPluginIdSchema,
|
|
480
1388
|
mutationId: mutationIdSchema,
|
|
481
1389
|
source: resourceSchema,
|
|
482
1390
|
revision: revisionSchema.positive(),
|
|
483
1391
|
expectedRevision: revisionSchema.nonnegative(),
|
|
484
|
-
payloadDigest:
|
|
485
|
-
tombstone:
|
|
486
|
-
targets:
|
|
1392
|
+
payloadDigest: z4.string().regex(digestPattern),
|
|
1393
|
+
tombstone: z4.boolean(),
|
|
1394
|
+
targets: z4.array(resourceSchema).max(MAX_TARGETS)
|
|
487
1395
|
}).strict().superRefine((value, context) => {
|
|
488
1396
|
try {
|
|
489
1397
|
normalizeProjectionCommand(value);
|
|
490
|
-
} catch (
|
|
491
|
-
context.addIssue({ code: "custom", message:
|
|
1398
|
+
} catch (cause2) {
|
|
1399
|
+
context.addIssue({ code: "custom", message: cause2 instanceof Error ? cause2.message : String(cause2) });
|
|
492
1400
|
}
|
|
493
1401
|
});
|
|
494
|
-
var applyProjectionResponseSchema =
|
|
495
|
-
outcome:
|
|
1402
|
+
var applyProjectionResponseSchema = z4.object({
|
|
1403
|
+
outcome: z4.enum(["applied", "duplicate", "equal", "stale", "conflict", "cas-mismatch"]),
|
|
496
1404
|
currentRevision: revisionSchema.nonnegative(),
|
|
497
|
-
currentDigest:
|
|
1405
|
+
currentDigest: z4.string().regex(digestPattern).nullable()
|
|
498
1406
|
}).strict();
|
|
499
|
-
var projectionSchema =
|
|
1407
|
+
var projectionSchema = z4.object({
|
|
500
1408
|
producerPluginId: producerPluginIdSchema,
|
|
501
1409
|
source: resourceSchema,
|
|
502
1410
|
revision: revisionSchema.nonnegative(),
|
|
503
1411
|
mutationId: mutationIdSchema,
|
|
504
|
-
payloadDigest:
|
|
505
|
-
tombstone:
|
|
506
|
-
targets:
|
|
1412
|
+
payloadDigest: z4.string().regex(digestPattern),
|
|
1413
|
+
tombstone: z4.boolean(),
|
|
1414
|
+
targets: z4.array(resourceSchema).max(MAX_TARGETS)
|
|
507
1415
|
}).strict();
|
|
508
|
-
var getProjectionInputSchema =
|
|
1416
|
+
var getProjectionInputSchema = z4.object({
|
|
509
1417
|
producerPluginId: producerPluginIdSchema,
|
|
510
1418
|
source: resourceIdentitySchema
|
|
511
1419
|
}).strict();
|
|
512
|
-
var getProjectionOutputSchema =
|
|
513
|
-
var backlinkRowSchema =
|
|
1420
|
+
var getProjectionOutputSchema = z4.object({ projection: projectionSchema.nullable() }).strict();
|
|
1421
|
+
var backlinkRowSchema = z4.object({
|
|
514
1422
|
source: resourceSchema,
|
|
515
1423
|
producerPluginId: producerPluginIdSchema,
|
|
516
1424
|
revision: revisionSchema.nonnegative(),
|
|
517
1425
|
targetPresentation: presentationSchema,
|
|
518
|
-
position:
|
|
1426
|
+
position: z4.number().int().min(0).max(MAX_TARGETS - 1).refine(Number.isSafeInteger),
|
|
519
1427
|
lastSeenAt: revisionSchema.nonnegative().nullable().optional()
|
|
520
1428
|
}).strict();
|
|
521
|
-
var listBacklinksInputSchema =
|
|
1429
|
+
var listBacklinksInputSchema = z4.object({
|
|
522
1430
|
target: resourceIdentitySchema,
|
|
523
|
-
pageSize:
|
|
524
|
-
cursor:
|
|
1431
|
+
pageSize: z4.number().int().min(1).max(100).refine(Number.isSafeInteger).optional(),
|
|
1432
|
+
cursor: z4.string().max(4096).optional()
|
|
525
1433
|
}).strict();
|
|
526
|
-
var listBacklinksOutputSchema =
|
|
527
|
-
rows:
|
|
1434
|
+
var listBacklinksOutputSchema = z4.object({
|
|
1435
|
+
rows: z4.array(backlinkRowSchema).max(100),
|
|
528
1436
|
total: revisionSchema.nonnegative(),
|
|
529
|
-
nextCursor:
|
|
1437
|
+
nextCursor: z4.string().max(4096).nullable()
|
|
530
1438
|
}).strict();
|
|
531
|
-
var forwardReferenceRowSchema =
|
|
1439
|
+
var forwardReferenceRowSchema = z4.object({
|
|
532
1440
|
target: resourceSchema,
|
|
533
1441
|
producerPluginId: producerPluginIdSchema,
|
|
534
1442
|
revision: revisionSchema.nonnegative(),
|
|
535
|
-
position:
|
|
1443
|
+
position: z4.number().int().min(0).max(MAX_TARGETS - 1).refine(Number.isSafeInteger),
|
|
536
1444
|
lastSeenAt: revisionSchema.nonnegative().nullable().optional()
|
|
537
1445
|
}).strict();
|
|
538
|
-
var listForwardReferencesInputSchema =
|
|
1446
|
+
var listForwardReferencesInputSchema = z4.object({
|
|
539
1447
|
source: resourceIdentitySchema,
|
|
540
1448
|
producerPluginId: producerPluginIdSchema.optional(),
|
|
541
|
-
pageSize:
|
|
542
|
-
cursor:
|
|
1449
|
+
pageSize: z4.number().int().min(1).max(100).refine(Number.isSafeInteger).optional(),
|
|
1450
|
+
cursor: z4.string().max(4096).optional()
|
|
543
1451
|
}).strict();
|
|
544
|
-
var listForwardReferencesOutputSchema =
|
|
545
|
-
rows:
|
|
1452
|
+
var listForwardReferencesOutputSchema = z4.object({
|
|
1453
|
+
rows: z4.array(forwardReferenceRowSchema).max(100),
|
|
546
1454
|
total: revisionSchema.nonnegative(),
|
|
547
|
-
nextCursor:
|
|
1455
|
+
nextCursor: z4.string().max(4096).nullable()
|
|
548
1456
|
}).strict();
|
|
549
|
-
var checkForwardReferencesInputSchema =
|
|
1457
|
+
var checkForwardReferencesInputSchema = z4.object({
|
|
550
1458
|
source: resourceIdentitySchema,
|
|
551
1459
|
producerPluginId: producerPluginIdSchema.optional()
|
|
552
1460
|
}).strict();
|
|
553
|
-
var forwardReferenceStatusSchema =
|
|
554
|
-
url:
|
|
555
|
-
status:
|
|
556
|
-
label:
|
|
1461
|
+
var forwardReferenceStatusSchema = z4.object({
|
|
1462
|
+
url: z4.string().max(MAX_PRESENTATION_URL_BYTES),
|
|
1463
|
+
status: z4.number().int().min(100).max(599).nullable(),
|
|
1464
|
+
label: z4.string().min(1).max(128)
|
|
557
1465
|
}).strict();
|
|
558
|
-
var checkForwardReferencesOutputSchema =
|
|
1466
|
+
var checkForwardReferencesOutputSchema = z4.array(forwardReferenceStatusSchema).max(FORWARD_REFERENCE_CHECK_LIMIT);
|
|
559
1467
|
var CROSS_REFERENCES_PLUGIN_ID = "cross-references";
|
|
560
1468
|
var CROSS_REFERENCES_PROTOCOL = "cross-references";
|
|
561
1469
|
var LIMITS = Object.freeze({ callMs: 5000, describeMs: 1000, responseBytes: 1024 * 1024 });
|
|
562
|
-
var describeInputSchema =
|
|
563
|
-
var describeOutputSchema =
|
|
564
|
-
protocol:
|
|
565
|
-
versions:
|
|
1470
|
+
var describeInputSchema = z4.null();
|
|
1471
|
+
var describeOutputSchema = z4.object({
|
|
1472
|
+
protocol: z4.literal(CROSS_REFERENCES_PROTOCOL),
|
|
1473
|
+
versions: z4.array(z4.number().int().positive().refine(Number.isSafeInteger)).max(16)
|
|
566
1474
|
});
|
|
567
1475
|
var crossReferencesRpcSchemas = {
|
|
568
1476
|
"crossReferences.describe": { input: describeInputSchema, output: describeOutputSchema },
|
|
@@ -572,14 +1480,16 @@ var crossReferencesRpcSchemas = {
|
|
|
572
1480
|
listForwardReferences: { input: listForwardReferencesInputSchema, output: listForwardReferencesOutputSchema },
|
|
573
1481
|
checkForwardReferences: { input: checkForwardReferencesInputSchema, output: checkForwardReferencesOutputSchema }
|
|
574
1482
|
};
|
|
575
|
-
var referenceSnapshotSchema =
|
|
1483
|
+
var referenceSnapshotSchema = z4.object({
|
|
576
1484
|
revision: revisionSchema.nonnegative(),
|
|
577
|
-
targets:
|
|
578
|
-
status:
|
|
1485
|
+
targets: z4.array(resourceSchema).max(MAX_TARGETS),
|
|
1486
|
+
status: z4.object({ state: z4.enum(["synced", "pending", "degraded", "blocked"]), error: z4.string().max(4096).nullable() })
|
|
579
1487
|
});
|
|
1488
|
+
var crossReferencesProducerRpcSchemas = createProducerSchemas(applyProjectionInputSchema);
|
|
580
1489
|
|
|
581
1490
|
// src/bb.ts
|
|
582
|
-
import {
|
|
1491
|
+
import { defineRpcContract } from "@get-bb/plugin-sdk";
|
|
1492
|
+
import { z as z5 } from "zod";
|
|
583
1493
|
class CrossReferencesProtocolError extends Error {
|
|
584
1494
|
code = "incompatible_protocol";
|
|
585
1495
|
constructor(message) {
|
|
@@ -620,7 +1530,7 @@ function createCrossReferencesClient(sdk, targetPluginId = CROSS_REFERENCES_PLUG
|
|
|
620
1530
|
}, method === "crossReferences.describe" ? describeMs : callMs);
|
|
621
1531
|
try {
|
|
622
1532
|
const value = await Promise.race([
|
|
623
|
-
sdk.plugins.callRpc({ pluginId, method, input: JSON.parse(JSON.stringify(parsedInput)), outputSchema:
|
|
1533
|
+
sdk.plugins.callRpc({ pluginId, method, input: JSON.parse(JSON.stringify(parsedInput)), outputSchema: z5.unknown(), signal: controller.signal }),
|
|
624
1534
|
cancelled
|
|
625
1535
|
]);
|
|
626
1536
|
const json = JSON.stringify(value);
|
|
@@ -659,7 +1569,190 @@ function createCrossReferencesClient(sdk, targetPluginId = CROSS_REFERENCES_PLUG
|
|
|
659
1569
|
checkForwardReferences: (input, signal) => operation("checkForwardReferences", input, signal)
|
|
660
1570
|
};
|
|
661
1571
|
}
|
|
1572
|
+
function createCrossReferencesV2Client(sdk, targetPluginId = CROSS_REFERENCES_PLUGIN_ID, options = {}) {
|
|
1573
|
+
const pluginId = validateProducerPluginId(targetPluginId), callMs = budget(options.callMs, LIMITS.callMs), describeMs = budget(options.describeMs, LIMITS.describeMs);
|
|
1574
|
+
async function call(method, input, inputSchema, outputSchema, signal) {
|
|
1575
|
+
const parsed = inputSchema.parse(input), json = JSON.stringify(parsed);
|
|
1576
|
+
if (utf8ByteLength(json) > MENTION_V2_LIMITS.inputBytes)
|
|
1577
|
+
throw new CrossReferencesProtocolError("V2 input exceeds its byte bound.");
|
|
1578
|
+
signal?.throwIfAborted();
|
|
1579
|
+
const controller = new AbortController;
|
|
1580
|
+
let reject;
|
|
1581
|
+
const cancelled = new Promise((_, r) => {
|
|
1582
|
+
reject = r;
|
|
1583
|
+
});
|
|
1584
|
+
const abort = () => {
|
|
1585
|
+
const e = signal?.reason ?? new DOMException("Request aborted", "AbortError");
|
|
1586
|
+
controller.abort(e);
|
|
1587
|
+
reject(e);
|
|
1588
|
+
};
|
|
1589
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
1590
|
+
const timer = setTimeout(() => {
|
|
1591
|
+
const e = Object.assign(new Error("Cross References V2 timed out."), { name: "TimeoutError", code: "timeout" });
|
|
1592
|
+
controller.abort(e);
|
|
1593
|
+
reject(e);
|
|
1594
|
+
}, method === "crossReferences.describe" ? describeMs : callMs);
|
|
1595
|
+
try {
|
|
1596
|
+
const value = await Promise.race([sdk.plugins.callRpc({ pluginId, method, input: JSON.parse(json), outputSchema: z5.unknown(), signal: controller.signal }), cancelled]);
|
|
1597
|
+
const encoded = JSON.stringify(value);
|
|
1598
|
+
if (encoded === undefined || utf8ByteLength(encoded) > MENTION_V2_LIMITS.responseBytes)
|
|
1599
|
+
throw new CrossReferencesProtocolError("V2 response exceeds its canonical JSON byte bound.");
|
|
1600
|
+
return outputSchema.parse(value);
|
|
1601
|
+
} finally {
|
|
1602
|
+
clearTimeout(timer);
|
|
1603
|
+
signal?.removeEventListener("abort", abort);
|
|
1604
|
+
controller.abort();
|
|
1605
|
+
}
|
|
1606
|
+
}
|
|
1607
|
+
return {
|
|
1608
|
+
pluginId,
|
|
1609
|
+
async describe(signal) {
|
|
1610
|
+
const s = crossReferencesRpcSchemas["crossReferences.describe"];
|
|
1611
|
+
const d = await call("crossReferences.describe", null, s.input, s.output, signal);
|
|
1612
|
+
if (!d.versions.includes(2))
|
|
1613
|
+
throw new CrossReferencesProtocolError("Wire V2 unavailable.");
|
|
1614
|
+
return { protocol: CROSS_REFERENCES_PROTOCOL, version: 2 };
|
|
1615
|
+
},
|
|
1616
|
+
listMentions: (input, signal) => call("crossReferencesV2ListMentions", input, crossReferencesV2RpcSchemas.crossReferencesV2ListMentions.input, crossReferencesV2RpcSchemas.crossReferencesV2ListMentions.output, signal),
|
|
1617
|
+
resolveLookup: (input, signal) => call("crossReferencesV2ResolveLookup", input, crossReferencesV2RpcSchemas.crossReferencesV2ResolveLookup.input, crossReferencesV2RpcSchemas.crossReferencesV2ResolveLookup.output, signal)
|
|
1618
|
+
};
|
|
1619
|
+
}
|
|
1620
|
+
function sdkSchema(schema) {
|
|
1621
|
+
return { "~standard": {
|
|
1622
|
+
version: 1,
|
|
1623
|
+
vendor: "bb-cross-references",
|
|
1624
|
+
jsonSchema: {
|
|
1625
|
+
input: () => z5.toJSONSchema(schema, { io: "input", unrepresentable: "any" }),
|
|
1626
|
+
output: () => z5.toJSONSchema(schema, { io: "output", unrepresentable: "any" })
|
|
1627
|
+
},
|
|
1628
|
+
validate(value) {
|
|
1629
|
+
const parsed = schema.safeParse(value);
|
|
1630
|
+
return parsed.success ? { value: parsed.data } : { issues: parsed.error.issues.map((issue) => ({ message: issue.message, path: issue.path })) };
|
|
1631
|
+
}
|
|
1632
|
+
} };
|
|
1633
|
+
}
|
|
1634
|
+
var crossReferencesV2RpcContract = defineRpcContract({
|
|
1635
|
+
crossReferencesV2ListMentions: { input: sdkSchema(crossReferencesV2RpcSchemas.crossReferencesV2ListMentions.input), output: sdkSchema(crossReferencesV2RpcSchemas.crossReferencesV2ListMentions.output) },
|
|
1636
|
+
crossReferencesV2ResolveLookup: { input: sdkSchema(crossReferencesV2RpcSchemas.crossReferencesV2ResolveLookup.input), output: sdkSchema(crossReferencesV2RpcSchemas.crossReferencesV2ResolveLookup.output) }
|
|
1637
|
+
});
|
|
1638
|
+
function registerCrossReferencesV2(bb, handlers) {
|
|
1639
|
+
bb.rpc.register(crossReferencesV2RpcContract, handlers);
|
|
1640
|
+
}
|
|
1641
|
+
function byteSdkSchema(schema, bytes2) {
|
|
1642
|
+
const base = sdkSchema(schema);
|
|
1643
|
+
return { "~standard": { ...base["~standard"], validate(value) {
|
|
1644
|
+
try {
|
|
1645
|
+
const json = JSON.stringify(value);
|
|
1646
|
+
if (json === undefined || utf8ByteLength(json) > bytes2)
|
|
1647
|
+
return { issues: [{ message: "Protocol byte bound exceeded." }] };
|
|
1648
|
+
} catch {
|
|
1649
|
+
return { issues: [{ message: "Invalid protocol JSON." }] };
|
|
1650
|
+
}
|
|
1651
|
+
return base["~standard"].validate(value);
|
|
1652
|
+
} } };
|
|
1653
|
+
}
|
|
1654
|
+
var ps = crossReferencesProducerRpcSchemas;
|
|
1655
|
+
var ns = briefNavigationRpcSchemas;
|
|
1656
|
+
var crossReferencesProducerRpcContract = defineRpcContract({
|
|
1657
|
+
[PRODUCER_METHODS.describe]: { input: byteSdkSchema(ps[PRODUCER_METHODS.describe].input, BRIEF_LIMITS.statusBytes), output: byteSdkSchema(ps[PRODUCER_METHODS.describe].output, BRIEF_LIMITS.statusBytes) },
|
|
1658
|
+
[PRODUCER_METHODS.getState]: { input: byteSdkSchema(ps[PRODUCER_METHODS.getState].input, BRIEF_LIMITS.statusBytes), output: byteSdkSchema(ps[PRODUCER_METHODS.getState].output, BRIEF_LIMITS.responseBytes) },
|
|
1659
|
+
[PRODUCER_METHODS.apply]: { input: byteSdkSchema(ps[PRODUCER_METHODS.apply].input, BRIEF_LIMITS.inputBytes), output: byteSdkSchema(ps[PRODUCER_METHODS.apply].output, BRIEF_LIMITS.responseBytes) },
|
|
1660
|
+
[PRODUCER_METHODS.reportStatus]: { input: byteSdkSchema(ps[PRODUCER_METHODS.reportStatus].input, BRIEF_LIMITS.statusBytes), output: byteSdkSchema(ps[PRODUCER_METHODS.reportStatus].output, BRIEF_LIMITS.responseBytes) }
|
|
1661
|
+
});
|
|
1662
|
+
function registerCrossReferencesProducer(bb, handlers) {
|
|
1663
|
+
bb.rpc.register(crossReferencesProducerRpcContract, handlers);
|
|
1664
|
+
}
|
|
1665
|
+
var briefNavigationRpcContract = defineRpcContract({
|
|
1666
|
+
[BRIEF_NAVIGATION_METHODS.describe]: { input: byteSdkSchema(ns[BRIEF_NAVIGATION_METHODS.describe].input, 8192), output: byteSdkSchema(ns[BRIEF_NAVIGATION_METHODS.describe].output, 16384) },
|
|
1667
|
+
[BRIEF_NAVIGATION_METHODS.resolve]: { input: byteSdkSchema(ns[BRIEF_NAVIGATION_METHODS.resolve].input, 8192), output: byteSdkSchema(ns[BRIEF_NAVIGATION_METHODS.resolve].output, 16384) }
|
|
1668
|
+
});
|
|
1669
|
+
function registerBriefNavigation(bb, handlers) {
|
|
1670
|
+
bb.rpc.register(briefNavigationRpcContract, handlers);
|
|
1671
|
+
}
|
|
1672
|
+
function boundedFamilyCall(sdk, pluginId, options = {}) {
|
|
1673
|
+
validateProducerPluginId(pluginId);
|
|
1674
|
+
const callMs = budget(options.callMs, 5000), describeMs = budget(options.describeMs, 1000);
|
|
1675
|
+
return async function call(method, input, inputSchema, outputSchema, inputBytes, outputBytes, signal) {
|
|
1676
|
+
const before = JSON.stringify(input);
|
|
1677
|
+
if (before === undefined || utf8ByteLength(before) > inputBytes)
|
|
1678
|
+
throw new CrossReferencesProtocolError("Protocol input exceeds its byte bound.");
|
|
1679
|
+
const parsed = inputSchema.parse(input);
|
|
1680
|
+
signal?.throwIfAborted();
|
|
1681
|
+
const controller = new AbortController;
|
|
1682
|
+
let reject;
|
|
1683
|
+
const cancelled = new Promise((_, r) => {
|
|
1684
|
+
reject = r;
|
|
1685
|
+
});
|
|
1686
|
+
const abort = () => {
|
|
1687
|
+
const e = signal?.reason ?? new DOMException("Request aborted", "AbortError");
|
|
1688
|
+
controller.abort(e);
|
|
1689
|
+
reject(e);
|
|
1690
|
+
};
|
|
1691
|
+
signal?.addEventListener("abort", abort, { once: true });
|
|
1692
|
+
const timer = setTimeout(() => {
|
|
1693
|
+
const e = Object.assign(new Error("Protocol call timed out."), { name: "TimeoutError", code: "timeout" });
|
|
1694
|
+
controller.abort(e);
|
|
1695
|
+
reject(e);
|
|
1696
|
+
}, method.endsWith(".describe") ? describeMs : callMs);
|
|
1697
|
+
try {
|
|
1698
|
+
const value = await Promise.race([sdk.plugins.callRpc({ pluginId, method, input: JSON.parse(JSON.stringify(parsed)), outputSchema: z5.unknown(), signal: controller.signal }), cancelled]);
|
|
1699
|
+
const json = JSON.stringify(value);
|
|
1700
|
+
if (json === undefined || utf8ByteLength(json) > outputBytes)
|
|
1701
|
+
throw new CrossReferencesProtocolError("Protocol output exceeds its byte bound.");
|
|
1702
|
+
return outputSchema.parse(value);
|
|
1703
|
+
} finally {
|
|
1704
|
+
clearTimeout(timer);
|
|
1705
|
+
signal?.removeEventListener("abort", abort);
|
|
1706
|
+
controller.abort();
|
|
1707
|
+
}
|
|
1708
|
+
};
|
|
1709
|
+
}
|
|
1710
|
+
function createCrossReferencesProducerClient(sdk, pluginId = CROSS_REFERENCES_PLUGIN_ID, options = {}) {
|
|
1711
|
+
const call = boundedFamilyCall(sdk, pluginId, options);
|
|
1712
|
+
return {
|
|
1713
|
+
pluginId,
|
|
1714
|
+
async describe(signal) {
|
|
1715
|
+
const d = await call(PRODUCER_METHODS.describe, null, ps[PRODUCER_METHODS.describe].input, ps[PRODUCER_METHODS.describe].output, 16384, 16384, signal);
|
|
1716
|
+
if (!d.versions.includes(1))
|
|
1717
|
+
throw new CrossReferencesProtocolError("Producer protocol unavailable.");
|
|
1718
|
+
return d;
|
|
1719
|
+
},
|
|
1720
|
+
getState: (input, signal) => call(PRODUCER_METHODS.getState, input, ps[PRODUCER_METHODS.getState].input, ps[PRODUCER_METHODS.getState].output, 16384, 1048576, signal),
|
|
1721
|
+
apply(input, signal) {
|
|
1722
|
+
const limits = briefApplyLimitCodes(input);
|
|
1723
|
+
if (limits.length)
|
|
1724
|
+
return Promise.reject(new BriefAdmissionError("over-limit", limits));
|
|
1725
|
+
validateBriefCommand(input.projection, input.evidence, input.evidenceDigest);
|
|
1726
|
+
return call(PRODUCER_METHODS.apply, input, ps[PRODUCER_METHODS.apply].input, ps[PRODUCER_METHODS.apply].output, 1048576, 1048576, signal);
|
|
1727
|
+
},
|
|
1728
|
+
reportStatus: (input, signal) => call(PRODUCER_METHODS.reportStatus, input, ps[PRODUCER_METHODS.reportStatus].input, ps[PRODUCER_METHODS.reportStatus].output, 16384, 1048576, signal)
|
|
1729
|
+
};
|
|
1730
|
+
}
|
|
1731
|
+
function createBriefNavigationClient(sdk, options = {}) {
|
|
1732
|
+
const call = boundedFamilyCall(sdk, "thread-brief", options);
|
|
1733
|
+
return {
|
|
1734
|
+
async describe(signal) {
|
|
1735
|
+
const d = await call(BRIEF_NAVIGATION_METHODS.describe, null, ns[BRIEF_NAVIGATION_METHODS.describe].input, ns[BRIEF_NAVIGATION_METHODS.describe].output, 8192, 16384, signal);
|
|
1736
|
+
if (!d.versions.includes(1))
|
|
1737
|
+
throw new CrossReferencesProtocolError("Brief navigation unavailable.");
|
|
1738
|
+
return d;
|
|
1739
|
+
},
|
|
1740
|
+
async resolve(input, signal) {
|
|
1741
|
+
const value = await call(BRIEF_NAVIGATION_METHODS.resolve, input, ns[BRIEF_NAVIGATION_METHODS.resolve].input, ns[BRIEF_NAVIGATION_METHODS.resolve].output, 8192, 16384, signal);
|
|
1742
|
+
return validateBriefNavigationResultV1(input, value);
|
|
1743
|
+
}
|
|
1744
|
+
};
|
|
1745
|
+
}
|
|
662
1746
|
export {
|
|
1747
|
+
registerCrossReferencesV2,
|
|
1748
|
+
registerCrossReferencesProducer,
|
|
1749
|
+
registerBriefNavigation,
|
|
1750
|
+
crossReferencesV2RpcContract,
|
|
1751
|
+
crossReferencesProducerRpcContract,
|
|
1752
|
+
createCrossReferencesV2Client,
|
|
1753
|
+
createCrossReferencesProducerClient,
|
|
663
1754
|
createCrossReferencesClient,
|
|
1755
|
+
createBriefNavigationClient,
|
|
1756
|
+
briefNavigationRpcContract,
|
|
664
1757
|
CrossReferencesProtocolError
|
|
665
1758
|
};
|