@phosphorco/bb-cross-references 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CONTRACT.md CHANGED
@@ -370,3 +370,30 @@ insufficient. Missing authority is independently scoped partial coverage using
370
370
  `pr-family-authority-unknown`, including an all-unknown empty result; known issue
371
371
  alone is excluded without fabricated unknown. Exact-self/literal semantics stay
372
372
  unchanged, and no parser/secondary graph edge/target enumeration is added.
373
+
374
+ ### Rendered Brief reader destination (0.4.1)
375
+
376
+ The navigation describe envelope may advertise `renderedReaderVersions: [1]`.
377
+ After explicit negotiation, either existing ready or fallback result may add
378
+ `reader` with literal kind `thread-brief-reader`, version `1`, owner
379
+ `thread-brief`, path `reveal`, the exact source thread id, and a bounded opaque
380
+ UUIDv4 token. Existing proof, source-file, frame, line and fallback meanings do
381
+ not change. Older clients continue using the fixed native file preview.
382
+
383
+ `encodeBriefReaderPath` constructs only the declared same-origin native plugin
384
+ route; `decodeBriefReaderPath` accepts only that exact path grammar. Consumers
385
+ must project known fields and use the shared codec, never an arbitrary returned
386
+ href, scheme, origin, owner or panel. A malformed, unnegotiated or cross-thread
387
+ destination cannot grant another navigation target. Primary dispatch remains
388
+ owned by the existing one-surface intent generation. Modifier/auxiliary/menu
389
+ navigation retains the semantic fixed native FileLink.
390
+
391
+ The opaque token is a presentation handle, not access authority. The Thread
392
+ Brief owner binds it to the original input and accepted record, and checks the
393
+ accepted/displayed raw revision, frame and section again before scrolling its
394
+ own section ref. Missing, expired, withheld, changed or ambiguous selections
395
+ open the known thread's brief at TOP with a short note, or honestly report
396
+ unavailability; they never relocate by heading text. The route provides a back
397
+ to thread action, is lazy, and reuses the accepted reader service and rendering
398
+ without a second parser or recognition pipeline. Dispatch/conformance is not
399
+ proof that the native rendered heading is visible; that requires live proof.
package/README.md CHANGED
@@ -81,3 +81,8 @@ fixture; it never supplies a fake freshness proof. Explicitly compile
81
81
  ESM imports and physical roots; resolver fixtures are not package/registry proof.
82
82
  See CONTRACT.md for display withholding, bounds, revision fencing and the still
83
83
  separate TB raw-reader/public navigation adoption duties.
84
+
85
+ In 0.4.1, Brief navigation can negotiate a rendered Thread Brief reader route.
86
+ The optional fixed destination and shared path codec preserve the existing
87
+ same-revision proof and native-file fallback. The reader owner validates the
88
+ accepted section again; stale or expired selections stay at the top with a note.
package/dist/bb.js CHANGED
@@ -1009,12 +1009,27 @@ function createProducerSchemas(projection) {
1009
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
1010
  };
1011
1011
  }
1012
+ var BRIEF_READER_ROUTE = Object.freeze({ kind: "thread-brief-reader", version: 1, owner: "thread-brief", path: "reveal" });
1013
+ var briefReaderDestinationSchema = z2.object({ kind: z2.literal(BRIEF_READER_ROUTE.kind), version: z2.literal(1), owner: z2.literal(BRIEF_READER_ROUTE.owner), path: z2.literal(BRIEF_READER_ROUTE.path), threadId: z2.string().regex(/^thr_[23456789abcdefghijkmnpqrstuvwxyz]{10}$/u), token: z2.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u) }).passthrough();
1014
+ function encodeBriefReaderPath(raw) {
1015
+ const d = briefReaderDestinationSchema.parse(raw);
1016
+ return `/plugins/${BRIEF_READER_ROUTE.owner}/${BRIEF_READER_ROUTE.path}/v1/${d.threadId}/${d.token}`;
1017
+ }
1018
+ function decodeBriefReaderPath(path) {
1019
+ if (path.length > 256)
1020
+ return null;
1021
+ const match = /^\/plugins\/thread-brief\/reveal\/v1\/(thr_[23456789abcdefghijkmnpqrstuvwxyz]{10})\/([a-f0-9-]{36})$/u.exec(path);
1022
+ if (!match)
1023
+ return null;
1024
+ const parsed = briefReaderDestinationSchema.safeParse({ ...BRIEF_READER_ROUTE, threadId: match[1], token: match[2] });
1025
+ return parsed.success ? parsed.data : null;
1026
+ }
1012
1027
  var briefNavigationInputSchema = z2.strictObject({ version: z2.literal(1), sourceFile: briefFileSchema, sourceContentRevision: digest, frame: briefFrameSchema, section: z2.strictObject({ heading: briefHeadingSchema, originalLine: positive }) });
1013
1028
  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()
1029
+ 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(), reader: briefReaderDestinationSchema.optional() }).passthrough(),
1030
+ 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"]), reader: briefReaderDestinationSchema.optional() }).passthrough()
1016
1031
  ]);
1017
- var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16) }).passthrough();
1032
+ var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16), renderedReaderVersions: z2.array(positive).max(16).optional() }).passthrough();
1018
1033
  var briefNavigationRpcSchemas = { [BRIEF_NAVIGATION_METHODS.describe]: { input: z2.null(), output: briefNavigationDescribeOutputSchema }, [BRIEF_NAVIGATION_METHODS.resolve]: { input: briefNavigationInputSchema, output: briefNavigationOutputSchema } };
1019
1034
  var outWithheld = (display) => withheld(display).passthrough();
1020
1035
  var briefHeadingOutputSchema = z2.union([z2.null(), z2.object({ state: z2.literal("named"), text: bytes(256) }).passthrough(), outWithheld("Heading withheld")]);
@@ -1029,6 +1044,8 @@ function validateBriefNavigationResultV1(input, raw) {
1029
1044
  const value = briefNavigationOutputSchema.parse(raw), file = value.sourceFile;
1030
1045
  if (file.kind !== input.sourceFile.kind || file.threadId !== input.sourceFile.threadId || file.path !== input.sourceFile.path)
1031
1046
  throw new Error("Brief navigation target mismatch.");
1047
+ if (value.reader && value.reader.threadId !== input.sourceFile.threadId)
1048
+ throw new Error("Brief reader target mismatch.");
1032
1049
  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
1050
  throw new Error("Brief navigation proof mismatch.");
1034
1051
  return value;
@@ -1730,15 +1747,19 @@ function createCrossReferencesProducerClient(sdk, pluginId = CROSS_REFERENCES_PL
1730
1747
  }
1731
1748
  function createBriefNavigationClient(sdk, options = {}) {
1732
1749
  const call = boundedFamilyCall(sdk, "thread-brief", options);
1750
+ let reader = false;
1733
1751
  return {
1734
1752
  async describe(signal) {
1735
1753
  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
1754
  if (!d.versions.includes(1))
1737
1755
  throw new CrossReferencesProtocolError("Brief navigation unavailable.");
1756
+ reader = d.renderedReaderVersions?.includes(1) === true;
1738
1757
  return d;
1739
1758
  },
1740
1759
  async resolve(input, signal) {
1741
1760
  const value = await call(BRIEF_NAVIGATION_METHODS.resolve, input, ns[BRIEF_NAVIGATION_METHODS.resolve].input, ns[BRIEF_NAVIGATION_METHODS.resolve].output, 8192, 16384, signal);
1761
+ if (value.reader && !reader)
1762
+ throw new CrossReferencesProtocolError("Brief reader destination was not negotiated.");
1742
1763
  return validateBriefNavigationResultV1(input, value);
1743
1764
  }
1744
1765
  };
package/dist/index.js CHANGED
@@ -1009,12 +1009,27 @@ function createProducerSchemas(projection) {
1009
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
1010
  };
1011
1011
  }
1012
+ var BRIEF_READER_ROUTE = Object.freeze({ kind: "thread-brief-reader", version: 1, owner: "thread-brief", path: "reveal" });
1013
+ var briefReaderDestinationSchema = z2.object({ kind: z2.literal(BRIEF_READER_ROUTE.kind), version: z2.literal(1), owner: z2.literal(BRIEF_READER_ROUTE.owner), path: z2.literal(BRIEF_READER_ROUTE.path), threadId: z2.string().regex(/^thr_[23456789abcdefghijkmnpqrstuvwxyz]{10}$/u), token: z2.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u) }).passthrough();
1014
+ function encodeBriefReaderPath(raw) {
1015
+ const d = briefReaderDestinationSchema.parse(raw);
1016
+ return `/plugins/${BRIEF_READER_ROUTE.owner}/${BRIEF_READER_ROUTE.path}/v1/${d.threadId}/${d.token}`;
1017
+ }
1018
+ function decodeBriefReaderPath(path) {
1019
+ if (path.length > 256)
1020
+ return null;
1021
+ const match = /^\/plugins\/thread-brief\/reveal\/v1\/(thr_[23456789abcdefghijkmnpqrstuvwxyz]{10})\/([a-f0-9-]{36})$/u.exec(path);
1022
+ if (!match)
1023
+ return null;
1024
+ const parsed = briefReaderDestinationSchema.safeParse({ ...BRIEF_READER_ROUTE, threadId: match[1], token: match[2] });
1025
+ return parsed.success ? parsed.data : null;
1026
+ }
1012
1027
  var briefNavigationInputSchema = z2.strictObject({ version: z2.literal(1), sourceFile: briefFileSchema, sourceContentRevision: digest, frame: briefFrameSchema, section: z2.strictObject({ heading: briefHeadingSchema, originalLine: positive }) });
1013
1028
  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()
1029
+ 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(), reader: briefReaderDestinationSchema.optional() }).passthrough(),
1030
+ 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"]), reader: briefReaderDestinationSchema.optional() }).passthrough()
1016
1031
  ]);
1017
- var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16) }).passthrough();
1032
+ var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16), renderedReaderVersions: z2.array(positive).max(16).optional() }).passthrough();
1018
1033
  var briefNavigationRpcSchemas = { [BRIEF_NAVIGATION_METHODS.describe]: { input: z2.null(), output: briefNavigationDescribeOutputSchema }, [BRIEF_NAVIGATION_METHODS.resolve]: { input: briefNavigationInputSchema, output: briefNavigationOutputSchema } };
1019
1034
  var outWithheld = (display) => withheld(display).passthrough();
1020
1035
  var briefHeadingOutputSchema = z2.union([z2.null(), z2.object({ state: z2.literal("named"), text: bytes(256) }).passthrough(), outWithheld("Heading withheld")]);
@@ -1029,6 +1044,8 @@ function validateBriefNavigationResultV1(input, raw) {
1029
1044
  const value = briefNavigationOutputSchema.parse(raw), file = value.sourceFile;
1030
1045
  if (file.kind !== input.sourceFile.kind || file.threadId !== input.sourceFile.threadId || file.path !== input.sourceFile.path)
1031
1046
  throw new Error("Brief navigation target mismatch.");
1047
+ if (value.reader && value.reader.threadId !== input.sourceFile.threadId)
1048
+ throw new Error("Brief reader target mismatch.");
1032
1049
  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
1050
  throw new Error("Brief navigation proof mismatch.");
1034
1051
  return value;
@@ -1554,9 +1571,11 @@ export {
1554
1571
  forwardReferenceStatusSchema,
1555
1572
  excerptV2Schema,
1556
1573
  excerptRecordV2Schema,
1574
+ encodeBriefReaderPath,
1557
1575
  describeOutputSchema,
1558
1576
  describeInputSchema,
1559
1577
  defaultPageSize,
1578
+ decodeBriefReaderPath,
1560
1579
  crossReferencesV2RpcSchemas,
1561
1580
  crossReferencesRpcSchemas,
1562
1581
  crossReferencesProducerRpcSchemas,
@@ -1575,6 +1594,7 @@ export {
1575
1594
  briefStatusDigest,
1576
1595
  briefSourcePresentationSchema,
1577
1596
  briefSourceLabelSchema,
1597
+ briefReaderDestinationSchema,
1578
1598
  briefProvenanceSchema,
1579
1599
  briefProvenanceOutputSchema,
1580
1600
  briefPresentation,
@@ -1631,6 +1651,7 @@ export {
1631
1651
  CROSS_REFERENCES_PROTOCOL,
1632
1652
  CROSS_REFERENCES_PLUGIN_ID,
1633
1653
  BriefAdmissionError,
1654
+ BRIEF_READER_ROUTE,
1634
1655
  BRIEF_NAVIGATION_METHODS,
1635
1656
  BRIEF_LIMIT_CODES,
1636
1657
  BRIEF_LIMITS
package/dist/react.js CHANGED
@@ -1009,12 +1009,27 @@ function createProducerSchemas(projection) {
1009
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
1010
  };
1011
1011
  }
1012
+ var BRIEF_READER_ROUTE = Object.freeze({ kind: "thread-brief-reader", version: 1, owner: "thread-brief", path: "reveal" });
1013
+ var briefReaderDestinationSchema = z2.object({ kind: z2.literal(BRIEF_READER_ROUTE.kind), version: z2.literal(1), owner: z2.literal(BRIEF_READER_ROUTE.owner), path: z2.literal(BRIEF_READER_ROUTE.path), threadId: z2.string().regex(/^thr_[23456789abcdefghijkmnpqrstuvwxyz]{10}$/u), token: z2.string().regex(/^[a-f0-9]{8}-[a-f0-9]{4}-4[a-f0-9]{3}-[89ab][a-f0-9]{3}-[a-f0-9]{12}$/u) }).passthrough();
1014
+ function encodeBriefReaderPath(raw) {
1015
+ const d = briefReaderDestinationSchema.parse(raw);
1016
+ return `/plugins/${BRIEF_READER_ROUTE.owner}/${BRIEF_READER_ROUTE.path}/v1/${d.threadId}/${d.token}`;
1017
+ }
1018
+ function decodeBriefReaderPath(path) {
1019
+ if (path.length > 256)
1020
+ return null;
1021
+ const match = /^\/plugins\/thread-brief\/reveal\/v1\/(thr_[23456789abcdefghijkmnpqrstuvwxyz]{10})\/([a-f0-9-]{36})$/u.exec(path);
1022
+ if (!match)
1023
+ return null;
1024
+ const parsed = briefReaderDestinationSchema.safeParse({ ...BRIEF_READER_ROUTE, threadId: match[1], token: match[2] });
1025
+ return parsed.success ? parsed.data : null;
1026
+ }
1012
1027
  var briefNavigationInputSchema = z2.strictObject({ version: z2.literal(1), sourceFile: briefFileSchema, sourceContentRevision: digest, frame: briefFrameSchema, section: z2.strictObject({ heading: briefHeadingSchema, originalLine: positive }) });
1013
1028
  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()
1029
+ 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(), reader: briefReaderDestinationSchema.optional() }).passthrough(),
1030
+ 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"]), reader: briefReaderDestinationSchema.optional() }).passthrough()
1016
1031
  ]);
1017
- var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16) }).passthrough();
1032
+ var briefNavigationDescribeOutputSchema = z2.object({ protocol: z2.literal("thread-brief-navigation"), versions: z2.array(positive).max(16), renderedReaderVersions: z2.array(positive).max(16).optional() }).passthrough();
1018
1033
  var briefNavigationRpcSchemas = { [BRIEF_NAVIGATION_METHODS.describe]: { input: z2.null(), output: briefNavigationDescribeOutputSchema }, [BRIEF_NAVIGATION_METHODS.resolve]: { input: briefNavigationInputSchema, output: briefNavigationOutputSchema } };
1019
1034
  var outWithheld = (display) => withheld(display).passthrough();
1020
1035
  var briefHeadingOutputSchema = z2.union([z2.null(), z2.object({ state: z2.literal("named"), text: bytes(256) }).passthrough(), outWithheld("Heading withheld")]);
@@ -1029,6 +1044,8 @@ function validateBriefNavigationResultV1(input, raw) {
1029
1044
  const value = briefNavigationOutputSchema.parse(raw), file = value.sourceFile;
1030
1045
  if (file.kind !== input.sourceFile.kind || file.threadId !== input.sourceFile.threadId || file.path !== input.sourceFile.path)
1031
1046
  throw new Error("Brief navigation target mismatch.");
1047
+ if (value.reader && value.reader.threadId !== input.sourceFile.threadId)
1048
+ throw new Error("Brief reader target mismatch.");
1032
1049
  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
1050
  throw new Error("Brief navigation proof mismatch.");
1034
1051
  return value;
package/dist/testing.js CHANGED
@@ -103,7 +103,15 @@ async function runBriefNavigationConformance(options) {
103
103
  await client.describe();
104
104
  const result = await client.resolve(options.input);
105
105
  await options.assertResult(result);
106
- return { level: "source-conformance", pluginId: "thread-brief", checks: ["navigation-describe", "fixed-file-same-revision-proof"] };
106
+ const checks = ["navigation-describe", "fixed-file-same-revision-proof"];
107
+ if (result.reader) {
108
+ const { encodeBriefReaderPath, decodeBriefReaderPath } = await import("./index.js");
109
+ const decoded = decodeBriefReaderPath(encodeBriefReaderPath(result.reader));
110
+ if (!decoded || decoded.threadId !== options.input.sourceFile.threadId || decoded.token !== result.reader.token)
111
+ throw new Error("Rendered Brief destination roundtrip failed.");
112
+ checks.push("declared-rendered-reader-destination");
113
+ }
114
+ return { level: "source-conformance", pluginId: "thread-brief", checks };
107
115
  }
108
116
  export {
109
117
  runCrossReferencesV2Conformance,
@@ -1502,6 +1502,7 @@ declare const ps: {
1502
1502
  readonly output: z.ZodObject<{
1503
1503
  protocol: z.ZodLiteral<"thread-brief-navigation">;
1504
1504
  versions: z.ZodArray<z.ZodNumber>;
1505
+ renderedReaderVersions: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
1505
1506
  }, z.core.$loose>;
1506
1507
  };
1507
1508
  readonly threadBriefNavigationV1ResolveHeading: {
@@ -1578,6 +1579,14 @@ declare const ps: {
1578
1579
  }, z.core.$loose>;
1579
1580
  }, z.core.$loose>;
1580
1581
  }, z.core.$loose>;
1582
+ reader: z.ZodOptional<z.ZodObject<{
1583
+ kind: z.ZodLiteral<"thread-brief-reader">;
1584
+ version: z.ZodLiteral<1>;
1585
+ owner: z.ZodLiteral<"thread-brief">;
1586
+ path: z.ZodLiteral<"reveal">;
1587
+ threadId: z.ZodString;
1588
+ token: z.ZodString;
1589
+ }, z.core.$loose>>;
1581
1590
  }, z.core.$loose>, z.ZodObject<{
1582
1591
  version: z.ZodLiteral<1>;
1583
1592
  state: z.ZodLiteral<"fallback">;
@@ -1595,6 +1604,14 @@ declare const ps: {
1595
1604
  "heading-unavailable": "heading-unavailable";
1596
1605
  "source-unavailable": "source-unavailable";
1597
1606
  }>;
1607
+ reader: z.ZodOptional<z.ZodObject<{
1608
+ kind: z.ZodLiteral<"thread-brief-reader">;
1609
+ version: z.ZodLiteral<1>;
1610
+ owner: z.ZodLiteral<"thread-brief">;
1611
+ path: z.ZodLiteral<"reveal">;
1612
+ threadId: z.ZodString;
1613
+ token: z.ZodString;
1614
+ }, z.core.$loose>>;
1598
1615
  }, z.core.$loose>], "state">;
1599
1616
  };
1600
1617
  };
@@ -2709,10 +2726,12 @@ export declare const briefNavigationRpcContract: {
2709
2726
  [x: string]: unknown;
2710
2727
  protocol: "thread-brief-navigation";
2711
2728
  versions: number[];
2729
+ renderedReaderVersions?: number[] | undefined;
2712
2730
  }, {
2713
2731
  [x: string]: unknown;
2714
2732
  protocol: "thread-brief-navigation";
2715
2733
  versions: number[];
2734
+ renderedReaderVersions?: number[] | undefined;
2716
2735
  }>;
2717
2736
  };
2718
2737
  readonly threadBriefNavigationV1ResolveHeading: {
@@ -2828,6 +2847,15 @@ export declare const briefNavigationRpcContract: {
2828
2847
  };
2829
2848
  };
2830
2849
  };
2850
+ reader?: {
2851
+ [x: string]: unknown;
2852
+ kind: "thread-brief-reader";
2853
+ version: 1;
2854
+ owner: "thread-brief";
2855
+ path: "reveal";
2856
+ threadId: string;
2857
+ token: string;
2858
+ } | undefined;
2831
2859
  } | {
2832
2860
  [x: string]: unknown;
2833
2861
  version: 1;
@@ -2840,6 +2868,15 @@ export declare const briefNavigationRpcContract: {
2840
2868
  };
2841
2869
  location: null;
2842
2870
  reason: "stale" | "over-limit" | "no-accepted-document" | "ambiguous" | "heading-unavailable" | "source-unavailable";
2871
+ reader?: {
2872
+ [x: string]: unknown;
2873
+ kind: "thread-brief-reader";
2874
+ version: 1;
2875
+ owner: "thread-brief";
2876
+ path: "reveal";
2877
+ threadId: string;
2878
+ token: string;
2879
+ } | undefined;
2843
2880
  }, {
2844
2881
  [x: string]: unknown;
2845
2882
  version: 1;
@@ -2881,6 +2918,15 @@ export declare const briefNavigationRpcContract: {
2881
2918
  };
2882
2919
  };
2883
2920
  };
2921
+ reader?: {
2922
+ [x: string]: unknown;
2923
+ kind: "thread-brief-reader";
2924
+ version: 1;
2925
+ owner: "thread-brief";
2926
+ path: "reveal";
2927
+ threadId: string;
2928
+ token: string;
2929
+ } | undefined;
2884
2930
  } | {
2885
2931
  [x: string]: unknown;
2886
2932
  version: 1;
@@ -2893,6 +2939,15 @@ export declare const briefNavigationRpcContract: {
2893
2939
  };
2894
2940
  location: null;
2895
2941
  reason: "stale" | "over-limit" | "no-accepted-document" | "ambiguous" | "heading-unavailable" | "source-unavailable";
2942
+ reader?: {
2943
+ [x: string]: unknown;
2944
+ kind: "thread-brief-reader";
2945
+ version: 1;
2946
+ owner: "thread-brief";
2947
+ path: "reveal";
2948
+ threadId: string;
2949
+ token: string;
2950
+ } | undefined;
2896
2951
  }>;
2897
2952
  };
2898
2953
  };
@@ -3165,6 +3220,7 @@ export declare function createBriefNavigationClient(sdk: CrossReferencesSdk, opt
3165
3220
  [x: string]: unknown;
3166
3221
  protocol: "thread-brief-navigation";
3167
3222
  versions: number[];
3223
+ renderedReaderVersions?: number[] | undefined;
3168
3224
  }>;
3169
3225
  resolve(input: BriefNavigationInput, signal?: AbortSignal): Promise<{
3170
3226
  [x: string]: unknown;
@@ -3207,6 +3263,15 @@ export declare function createBriefNavigationClient(sdk: CrossReferencesSdk, opt
3207
3263
  };
3208
3264
  };
3209
3265
  };
3266
+ reader?: {
3267
+ [x: string]: unknown;
3268
+ kind: "thread-brief-reader";
3269
+ version: 1;
3270
+ owner: "thread-brief";
3271
+ path: "reveal";
3272
+ threadId: string;
3273
+ token: string;
3274
+ } | undefined;
3210
3275
  } | {
3211
3276
  [x: string]: unknown;
3212
3277
  version: 1;
@@ -3219,6 +3284,15 @@ export declare function createBriefNavigationClient(sdk: CrossReferencesSdk, opt
3219
3284
  };
3220
3285
  location: null;
3221
3286
  reason: "stale" | "over-limit" | "no-accepted-document" | "ambiguous" | "heading-unavailable" | "source-unavailable";
3287
+ reader?: {
3288
+ [x: string]: unknown;
3289
+ kind: "thread-brief-reader";
3290
+ version: 1;
3291
+ owner: "thread-brief";
3292
+ path: "reveal";
3293
+ threadId: string;
3294
+ token: string;
3295
+ } | undefined;
3222
3296
  }>;
3223
3297
  };
3224
3298
  export {};
@@ -1904,6 +1904,25 @@ export type ProducerReportStatusOutput = {
1904
1904
  outcome: 'recorded' | 'duplicate' | 'stale' | 'conflict' | 'cas-mismatch';
1905
1905
  state: ProducerState;
1906
1906
  };
1907
+ /** A declared native plugin route, never an arbitrary href. Only these known
1908
+ * fields participate in navigation; additive output fields are ignored. */
1909
+ export declare const BRIEF_READER_ROUTE: Readonly<{
1910
+ readonly kind: "thread-brief-reader";
1911
+ readonly version: 1;
1912
+ readonly owner: "thread-brief";
1913
+ readonly path: "reveal";
1914
+ }>;
1915
+ export declare const briefReaderDestinationSchema: z.ZodObject<{
1916
+ kind: z.ZodLiteral<"thread-brief-reader">;
1917
+ version: z.ZodLiteral<1>;
1918
+ owner: z.ZodLiteral<"thread-brief">;
1919
+ path: z.ZodLiteral<"reveal">;
1920
+ threadId: z.ZodString;
1921
+ token: z.ZodString;
1922
+ }, z.core.$loose>;
1923
+ export type BriefReaderDestination = z.infer<typeof briefReaderDestinationSchema>;
1924
+ export declare function encodeBriefReaderPath(raw: BriefReaderDestination): string;
1925
+ export declare function decodeBriefReaderPath(path: string): BriefReaderDestination | null;
1907
1926
  export declare const briefNavigationInputSchema: z.ZodObject<{
1908
1927
  version: z.ZodLiteral<1>;
1909
1928
  sourceFile: z.ZodObject<{
@@ -1977,6 +1996,14 @@ export declare const briefNavigationOutputSchema: z.ZodDiscriminatedUnion<[z.Zod
1977
1996
  }, z.core.$loose>;
1978
1997
  }, z.core.$loose>;
1979
1998
  }, z.core.$loose>;
1999
+ reader: z.ZodOptional<z.ZodObject<{
2000
+ kind: z.ZodLiteral<"thread-brief-reader">;
2001
+ version: z.ZodLiteral<1>;
2002
+ owner: z.ZodLiteral<"thread-brief">;
2003
+ path: z.ZodLiteral<"reveal">;
2004
+ threadId: z.ZodString;
2005
+ token: z.ZodString;
2006
+ }, z.core.$loose>>;
1980
2007
  }, z.core.$loose>, z.ZodObject<{
1981
2008
  version: z.ZodLiteral<1>;
1982
2009
  state: z.ZodLiteral<"fallback">;
@@ -1994,10 +2021,19 @@ export declare const briefNavigationOutputSchema: z.ZodDiscriminatedUnion<[z.Zod
1994
2021
  "heading-unavailable": "heading-unavailable";
1995
2022
  "source-unavailable": "source-unavailable";
1996
2023
  }>;
2024
+ reader: z.ZodOptional<z.ZodObject<{
2025
+ kind: z.ZodLiteral<"thread-brief-reader">;
2026
+ version: z.ZodLiteral<1>;
2027
+ owner: z.ZodLiteral<"thread-brief">;
2028
+ path: z.ZodLiteral<"reveal">;
2029
+ threadId: z.ZodString;
2030
+ token: z.ZodString;
2031
+ }, z.core.$loose>>;
1997
2032
  }, z.core.$loose>], "state">;
1998
2033
  export declare const briefNavigationDescribeOutputSchema: z.ZodObject<{
1999
2034
  protocol: z.ZodLiteral<"thread-brief-navigation">;
2000
2035
  versions: z.ZodArray<z.ZodNumber>;
2036
+ renderedReaderVersions: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
2001
2037
  }, z.core.$loose>;
2002
2038
  export declare const briefNavigationRpcSchemas: {
2003
2039
  readonly "threadBriefNavigation.describe": {
@@ -2005,6 +2041,7 @@ export declare const briefNavigationRpcSchemas: {
2005
2041
  readonly output: z.ZodObject<{
2006
2042
  protocol: z.ZodLiteral<"thread-brief-navigation">;
2007
2043
  versions: z.ZodArray<z.ZodNumber>;
2044
+ renderedReaderVersions: z.ZodOptional<z.ZodArray<z.ZodNumber>>;
2008
2045
  }, z.core.$loose>;
2009
2046
  };
2010
2047
  readonly threadBriefNavigationV1ResolveHeading: {
@@ -2081,6 +2118,14 @@ export declare const briefNavigationRpcSchemas: {
2081
2118
  }, z.core.$loose>;
2082
2119
  }, z.core.$loose>;
2083
2120
  }, z.core.$loose>;
2121
+ reader: z.ZodOptional<z.ZodObject<{
2122
+ kind: z.ZodLiteral<"thread-brief-reader">;
2123
+ version: z.ZodLiteral<1>;
2124
+ owner: z.ZodLiteral<"thread-brief">;
2125
+ path: z.ZodLiteral<"reveal">;
2126
+ threadId: z.ZodString;
2127
+ token: z.ZodString;
2128
+ }, z.core.$loose>>;
2084
2129
  }, z.core.$loose>, z.ZodObject<{
2085
2130
  version: z.ZodLiteral<1>;
2086
2131
  state: z.ZodLiteral<"fallback">;
@@ -2098,6 +2143,14 @@ export declare const briefNavigationRpcSchemas: {
2098
2143
  "heading-unavailable": "heading-unavailable";
2099
2144
  "source-unavailable": "source-unavailable";
2100
2145
  }>;
2146
+ reader: z.ZodOptional<z.ZodObject<{
2147
+ kind: z.ZodLiteral<"thread-brief-reader">;
2148
+ version: z.ZodLiteral<1>;
2149
+ owner: z.ZodLiteral<"thread-brief">;
2150
+ path: z.ZodLiteral<"reveal">;
2151
+ threadId: z.ZodString;
2152
+ token: z.ZodString;
2153
+ }, z.core.$loose>>;
2101
2154
  }, z.core.$loose>], "state">;
2102
2155
  };
2103
2156
  };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@phosphorco/bb-cross-references",
3
- "version": "0.4.0",
3
+ "version": "0.4.1",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Shared Cross References v1 codecs, explicit clients, and reference controls.",
@@ -76,7 +76,7 @@
76
76
  "react": "19.2.1",
77
77
  "react-dom": "19.2.1",
78
78
  "typescript": "5.9.3",
79
- "jsdom": "26.1.0",
79
+ "jsdom": "^27.0.0",
80
80
  "@types/jsdom": "21.1.7"
81
81
  },
82
82
  "scripts": {