@brett_lamy/docstream 0.5.7 → 0.6.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brett_lamy/docstream",
3
- "version": "0.5.7",
3
+ "version": "0.6.0",
4
4
  "description": "GitBook-aware readonly markdown and AI stream renderer.",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -1,5 +1,5 @@
1
1
  import { createContext, useContext, useId, useState, type ReactNode } from "react"
2
- import { ArrowUpRight, AtSign, Globe, Hash } from "lucide-react"
2
+ import { ArrowUpRight, AtSign, FolderGit2, Globe, Hash } from "lucide-react"
3
3
 
4
4
  import type { CitationDef, ReferenceNode } from "../gitbook/ast"
5
5
 
@@ -112,7 +112,7 @@ export function InlineReference({ node }: { node: ReferenceNode }) {
112
112
  )
113
113
  }
114
114
 
115
- const Icon = node.kind === "mention" ? AtSign : Hash
115
+ const Icon = node.kind === "mention" ? AtSign : node.kind === "codebase" ? FolderGit2 : Hash
116
116
  return (
117
117
  <button
118
118
  type="button"
@@ -23,7 +23,7 @@ export interface InlineImageNode {
23
23
  link?: string
24
24
  }
25
25
 
26
- export type ReferenceKind = "mention" | "tag" | "citation"
26
+ export type ReferenceKind = "mention" | "tag" | "codebase" | "citation"
27
27
 
28
28
  /**
29
29
  * Inline reference chip: `@mention`, `#tag`, or footnote-style citation `[^id]`.
@@ -10,8 +10,13 @@ export const refDefinitions = new Map<string, string>()
10
10
  // parseMarkdown and consumed here to resolve [^id] markers.
11
11
  export const footnoteDefinitions = new Map<string, { url: string; label?: string }>()
12
12
 
13
- // @mention / #tag body: letter/underscore start, then word chars, dots, dashes.
13
+ // @mention / #tag / $codebase body: letter/underscore start, then word chars, dots,
14
+ // dashes. Codebase ids may also carry `/` (`$org/repo`). A letter start keeps prices
15
+ // like $5 plain text.
14
16
  const REFERENCE_BODY_RE = /^[@#]([A-Za-z_][\w.-]*)/
17
+ const CODEBASE_BODY_RE = /^\$([A-Za-z_][\w.\/-]*)/
18
+ const SIGIL_KIND = { "@": "mention", "#": "tag", $: "codebase" } as const
19
+ const KIND_SIGIL = { mention: "@", tag: "#", codebase: "$" } as const
15
20
  // Chips are only recognized at start-of-input or after whitespace/open brackets,
16
21
  // so brett@replay.io and C# stay plain text.
17
22
  const isReferenceBoundary = (prev: string | undefined) =>
@@ -131,14 +136,14 @@ export function parseInline(src: string, marks: Marks = {}): Inline[] {
131
136
  continue
132
137
  }
133
138
 
134
- // @mention / #tag chips, only at a word boundary
135
- if ((rest[0] === "@" || rest[0] === "#") && isReferenceBoundary(src[i - 1])) {
136
- const m = rest.match(REFERENCE_BODY_RE)
139
+ // @mention / #tag / $codebase chips, only at a word boundary
140
+ if ((rest[0] === "@" || rest[0] === "#" || rest[0] === "$") && isReferenceBoundary(src[i - 1])) {
141
+ const m = rest.match(rest[0] === "$" ? CODEBASE_BODY_RE : REFERENCE_BODY_RE)
137
142
  if (m) {
138
- const id = m[1].replace(/[.-]+$/, "")
143
+ const id = m[1].replace(/[./-]+$/, "")
139
144
  if (id) {
140
145
  flush()
141
- out.push({ type: "reference", kind: rest[0] === "@" ? "mention" : "tag", id })
146
+ out.push({ type: "reference", kind: SIGIL_KIND[rest[0] as "@" | "#" | "$"], id })
142
147
  i += 1 + id.length
143
148
  continue
144
149
  }
@@ -200,14 +205,14 @@ export function parseInline(src: string, marks: Marks = {}): Inline[] {
200
205
  const escapeText = (t: string) =>
201
206
  t
202
207
  .replace(/([*_~`[\]\\])/g, "\\$1")
203
- // Escape @/# only at a chip boundary so emails/C# survive untouched.
208
+ // Escape @/#/$ only at a chip boundary so emails/C#/$5 survive untouched.
204
209
  // Note: node-local — a boundary formed across adjacent inline nodes
205
210
  // (previous node ending in whitespace) is not caught; rare, accepted.
206
- .replace(/(^|[\s([{])([@#])(?=[A-Za-z_])/g, "$1\\$2")
211
+ .replace(/(^|[\s([{])([@#$])(?=[A-Za-z_])/g, "$1\\$2")
207
212
 
208
213
  export function serializeReference(n: ReferenceNode): string {
209
214
  if (n.kind === "citation") return `[^${n.id}]`
210
- return `${n.kind === "mention" ? "@" : "#"}${n.id}`
215
+ return `${KIND_SIGIL[n.kind]}${n.id}`
211
216
  }
212
217
 
213
218
  function serializeImage(n: InlineImageNode): string {
package/src/styles.css CHANGED
@@ -1073,6 +1073,16 @@
1073
1073
  color: var(--gb-accent-foreground);
1074
1074
  }
1075
1075
 
1076
+ .docs-ref-codebase {
1077
+ border: 1px solid rgba(34, 197, 94, 0.45);
1078
+ background: rgba(34, 197, 94, 0.1);
1079
+ color: rgb(74, 222, 128);
1080
+ }
1081
+
1082
+ .docs-ref-codebase:hover {
1083
+ background: rgba(34, 197, 94, 0.18);
1084
+ }
1085
+
1076
1086
  .docs-cite-wrap {
1077
1087
  position: relative;
1078
1088
  display: inline-block;