@xyne/workflow-ui 1.3.11 → 1.3.12

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.
Files changed (61) hide show
  1. package/dist/components/execution/CitationSourcePanel.d.ts +23 -0
  2. package/dist/components/execution/CitationSourcePanel.d.ts.map +1 -0
  3. package/dist/components/execution/CitationSourcePanel.js +14 -0
  4. package/dist/components/execution/CitationSourcePanel.js.map +1 -0
  5. package/dist/components/execution/ExecutionTabs.d.ts.map +1 -1
  6. package/dist/components/execution/ExecutionTabs.js +26 -19
  7. package/dist/components/execution/ExecutionTabs.js.map +1 -1
  8. package/dist/components/execution/ExecutionViewer.d.ts.map +1 -1
  9. package/dist/components/execution/ExecutionViewer.js +37 -26
  10. package/dist/components/execution/ExecutionViewer.js.map +1 -1
  11. package/dist/components/execution/SchemaAwareRenderer.d.ts +7 -1
  12. package/dist/components/execution/SchemaAwareRenderer.d.ts.map +1 -1
  13. package/dist/components/execution/SchemaAwareRenderer.js +25 -18
  14. package/dist/components/execution/SchemaAwareRenderer.js.map +1 -1
  15. package/dist/components/execution/StepDetailPanel.d.ts.map +1 -1
  16. package/dist/components/execution/StepDetailPanel.js +6 -2
  17. package/dist/components/execution/StepDetailPanel.js.map +1 -1
  18. package/dist/components/execution/origin/citation-resolver.d.ts +39 -0
  19. package/dist/components/execution/origin/citation-resolver.d.ts.map +1 -0
  20. package/dist/components/execution/origin/citation-resolver.js +94 -0
  21. package/dist/components/execution/origin/citation-resolver.js.map +1 -0
  22. package/dist/components/index.d.ts +2 -0
  23. package/dist/components/index.d.ts.map +1 -1
  24. package/dist/components/index.js +1 -0
  25. package/dist/components/index.js.map +1 -1
  26. package/dist/components/shared/AttachmentCard.d.ts +16 -0
  27. package/dist/components/shared/AttachmentCard.d.ts.map +1 -1
  28. package/dist/components/shared/AttachmentCard.js +2 -2
  29. package/dist/components/shared/AttachmentCard.js.map +1 -1
  30. package/dist/components/shared/CitationArrow.d.ts +37 -0
  31. package/dist/components/shared/CitationArrow.d.ts.map +1 -0
  32. package/dist/components/shared/CitationArrow.js +83 -0
  33. package/dist/components/shared/CitationArrow.js.map +1 -0
  34. package/dist/components/shared/MarkdownCitation.d.ts +25 -0
  35. package/dist/components/shared/MarkdownCitation.d.ts.map +1 -0
  36. package/dist/components/shared/MarkdownCitation.js +31 -0
  37. package/dist/components/shared/MarkdownCitation.js.map +1 -0
  38. package/dist/components/shared/MarkdownView.d.ts.map +1 -1
  39. package/dist/components/shared/MarkdownView.js +19 -2
  40. package/dist/components/shared/MarkdownView.js.map +1 -1
  41. package/dist/components/shared/citation-context.d.ts +35 -0
  42. package/dist/components/shared/citation-context.d.ts.map +1 -0
  43. package/dist/components/shared/citation-context.js +34 -0
  44. package/dist/components/shared/citation-context.js.map +1 -0
  45. package/dist/components/shared/citation.d.ts +55 -0
  46. package/dist/components/shared/citation.d.ts.map +1 -0
  47. package/dist/components/shared/citation.js +83 -0
  48. package/dist/components/shared/citation.js.map +1 -0
  49. package/dist/components/shared/markdown-citation-directive.d.ts +34 -0
  50. package/dist/components/shared/markdown-citation-directive.d.ts.map +1 -0
  51. package/dist/components/shared/markdown-citation-directive.js +110 -0
  52. package/dist/components/shared/markdown-citation-directive.js.map +1 -0
  53. package/dist/index.d.ts +2 -2
  54. package/dist/index.d.ts.map +1 -1
  55. package/dist/index.js +1 -1
  56. package/dist/index.js.map +1 -1
  57. package/dist/layout-engine/components.d.ts.map +1 -1
  58. package/dist/layout-engine/components.js +50 -29
  59. package/dist/layout-engine/components.js.map +1 -1
  60. package/dist/styles.css +1 -1
  61. package/package.json +4 -2
@@ -0,0 +1,83 @@
1
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
2
+ /**
3
+ * The reader-facing citation affordance: a compact ↗ beside a data point that
4
+ * opens the source it came from.
5
+ *
6
+ * One marker per citation — a value backed by three sources shows three markers,
7
+ * each opening its own. No popover: every source stays one click away, and the
8
+ * count itself tells the reader how well-backed the value is.
9
+ */
10
+ import { useState } from 'react';
11
+ import { cn } from './cn.js';
12
+ import { AttachmentPreviewModal } from './AttachmentCard.js';
13
+ import { useCitationOrigin, useCitationOpener } from './citation-context.js';
14
+ import { useWorkflowClient } from '../../hooks/use-workflow-client.js';
15
+ import { resolveCitationRef, } from '../execution/origin/citation-resolver.js';
16
+ /** Beyond this many markers the row turns to noise; the rest collapse to "+k". */
17
+ const MAX_INLINE_MARKERS = 6;
18
+ function hostOf(url) {
19
+ try {
20
+ return new URL(url).host;
21
+ }
22
+ catch {
23
+ return url;
24
+ }
25
+ }
26
+ /** What the marker says on hover — enough to know where it goes before clicking. */
27
+ function titleFor(resolved, ref) {
28
+ if (!resolved) {
29
+ return ref.kind === 'ref' ? `Source: ${ref.ref} (no document)` : 'Source';
30
+ }
31
+ if (resolved.kind === 'url')
32
+ return `Source: ${resolved.title ?? hostOf(resolved.url)}`;
33
+ const page = resolved.page !== undefined ? `, p.${String(resolved.page)}` : '';
34
+ return `Source: ${resolved.attachment.name}${page}`;
35
+ }
36
+ /**
37
+ * A single citation marker. Clicking opens its source directly: a document at
38
+ * its cited page with the quoted passage highlighted, or an external link.
39
+ *
40
+ * Renders nothing outside a {@link CitationOriginContext} provider — without an
41
+ * execution in scope there's nothing to resolve against.
42
+ */
43
+ export function CitationArrow({ citation, index, className }) {
44
+ const client = useWorkflowClient();
45
+ const ctx = useCitationOrigin();
46
+ const openInPanel = useCitationOpener();
47
+ const [openDoc, setOpenDoc] = useState(null);
48
+ const resolved = ctx ? resolveCitationRef(citation, ctx) : undefined;
49
+ if (!ctx)
50
+ return null;
51
+ const open = () => {
52
+ if (!resolved)
53
+ return;
54
+ if (resolved.kind === 'url') {
55
+ window.open(resolved.url, '_blank', 'noopener,noreferrer');
56
+ return;
57
+ }
58
+ // Side-by-side where the surface can host it (the run view) — a modal would
59
+ // cover the very data you're checking. Modal only as a fallback.
60
+ if (openInPanel)
61
+ openInPanel(resolved);
62
+ else
63
+ setOpenDoc(resolved);
64
+ };
65
+ return (_jsxs(_Fragment, { children: [_jsxs("button", { type: "button", onClick: open, disabled: !resolved, title: titleFor(resolved, citation), className: cn('inline-flex shrink-0 items-center gap-px rounded-[var(--wui-radius-sm)] px-0.5 align-middle transition-colors', resolved
66
+ ? 'text-[var(--wui-fg-muted)] hover:bg-[color-mix(in_srgb,var(--wui-primary)_12%,transparent)] hover:text-[var(--wui-primary)]'
67
+ // A cited value whose source can't be opened still shows a marker —
68
+ // the agent claimed a source, and hiding that would read as uncited.
69
+ : 'cursor-default text-[var(--wui-border-strong)]', className), children: [_jsxs("svg", { width: "11", height: "11", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2.5, strokeLinecap: "round", strokeLinejoin: "round", "aria-hidden": "true", children: [_jsx("line", { x1: "7", y1: "17", x2: "17", y2: "7" }), _jsx("polyline", { points: "7 7 17 7 17 17" })] }), index !== undefined && (_jsx("sup", { className: "text-[8px] font-semibold leading-none", children: index }))] }), openDoc && (_jsx(AttachmentPreviewModal, { attachment: openDoc.attachment, url: client.uploads.url(openDoc.attachment), page: openDoc.page, highlightQuery: openDoc.quote, onClose: () => { setOpenDoc(null); } }))] }));
70
+ }
71
+ /**
72
+ * Every citation on one data point, as one marker each — numbered once there's
73
+ * more than one to tell apart. Renders nothing when uncited, so an uncited value
74
+ * looks exactly as it did before citations existed.
75
+ */
76
+ export function CitationMarks({ refs, className }) {
77
+ if (!refs || refs.length === 0)
78
+ return null;
79
+ const shown = refs.slice(0, MAX_INLINE_MARKERS);
80
+ const overflow = refs.length - shown.length;
81
+ return (_jsxs("span", { className: cn('inline-flex shrink-0 items-center gap-px', className), children: [shown.map((ref, i) => (_jsx(CitationArrow, { citation: ref, index: refs.length > 1 ? i + 1 : undefined }, `${ref.kind}-${ref.kind === 'ref' ? ref.ref : ref.url}-${String(i)}`))), overflow > 0 && (_jsxs("span", { className: "text-[9px] font-semibold text-[var(--wui-fg-muted)]", title: `${String(overflow)} more source(s)`, children: ["+", overflow] }))] }));
82
+ }
83
+ //# sourceMappingURL=CitationArrow.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CitationArrow.js","sourceRoot":"","sources":["../../../src/components/shared/CitationArrow.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ /**
2
+ * Renders a `:::citation{…}` block: the statement as normal prose, trailed by a
3
+ * ↗ marker opening the source it came from.
4
+ *
5
+ * Named `MarkdownCitation`, not `Citation` — the SDK already has a `Citation`,
6
+ * the author-time overlay attached to a step's *config* in the builder. Same
7
+ * word, different concept; keeping the names apart keeps the two from being
8
+ * confused for one another.
9
+ */
10
+ import type { ReactNode } from 'react';
11
+ export interface MarkdownCitationProps {
12
+ /** Ref path into the workflow, as shown to the agent in a `[source: …]` label. */
13
+ ref?: string | undefined;
14
+ /** 1-based page within the resolved document. Arrives as a string from markdown. */
15
+ page?: string | undefined;
16
+ /** External source, as an alternative to `ref`. */
17
+ url?: string | undefined;
18
+ /** The exact source text, highlighted once the document opens. */
19
+ quote?: string | undefined;
20
+ /** Label for the url form. */
21
+ title?: string | undefined;
22
+ children?: ReactNode;
23
+ }
24
+ export declare function MarkdownCitation(props: MarkdownCitationProps): import("react").JSX.Element;
25
+ //# sourceMappingURL=MarkdownCitation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownCitation.d.ts","sourceRoot":"","sources":["../../../src/components/shared/MarkdownCitation.tsx"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC;AAIvC,MAAM,WAAW,qBAAqB;IACpC,kFAAkF;IAClF,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,oFAAoF;IACpF,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,mDAAmD;IACnD,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IACzB,kEAAkE;IAClE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,8BAA8B;IAC9B,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC3B,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AA2BD,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,+BAQ5D"}
@@ -0,0 +1,31 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { CitationArrow } from './CitationArrow.js';
3
+ /** Directive attributes are always strings; a page must survive as a real number. */
4
+ function toPage(page) {
5
+ if (page === undefined)
6
+ return undefined;
7
+ const n = Number(page);
8
+ return Number.isInteger(n) && n >= 1 ? n : undefined;
9
+ }
10
+ function toCitation(props) {
11
+ // Checked here as well as in the sanitize schema: markdown reaches this
12
+ // component from an LLM, and a `javascript:` target must not become a link.
13
+ if (props.url !== undefined && /^https?:\/\//i.test(props.url)) {
14
+ return { kind: 'url', url: props.url, ...(props.title ? { title: props.title } : {}) };
15
+ }
16
+ if (props.ref !== undefined && props.ref !== '') {
17
+ const page = toPage(props.page);
18
+ return {
19
+ kind: 'ref',
20
+ ref: props.ref,
21
+ ...(page !== undefined ? { page } : {}),
22
+ ...(props.quote ? { quote: props.quote } : {}),
23
+ };
24
+ }
25
+ return undefined;
26
+ }
27
+ export function MarkdownCitation(props) {
28
+ const citation = toCitation(props);
29
+ return (_jsxs("span", { className: "wui-citation", children: [props.children, citation && _jsx(CitationArrow, { citation: citation })] }));
30
+ }
31
+ //# sourceMappingURL=MarkdownCitation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"MarkdownCitation.js","sourceRoot":"","sources":["../../../src/components/shared/MarkdownCitation.tsx"],"names":[],"mappings":";AAWA,OAAO,EAAE,aAAa,EAAE,MAAM,oBAAoB,CAAC;AAgBnD,qFAAqF;AACrF,SAAS,MAAM,CAAC,IAAwB;IACtC,IAAI,IAAI,KAAK,SAAS;QAAE,OAAO,SAAS,CAAC;IACzC,MAAM,CAAC,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC;IACvB,OAAO,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC;AACvD,CAAC;AAED,SAAS,UAAU,CAAC,KAA4B;IAC9C,wEAAwE;IACxE,4EAA4E;IAC5E,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,eAAe,CAAC,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/D,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,GAAG,EAAE,KAAK,CAAC,GAAG,EAAE,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC;IACzF,CAAC;IACD,IAAI,KAAK,CAAC,GAAG,KAAK,SAAS,IAAI,KAAK,CAAC,GAAG,KAAK,EAAE,EAAE,CAAC;QAChD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QAChC,OAAO;YACL,IAAI,EAAE,KAAK;YACX,GAAG,EAAE,KAAK,CAAC,GAAG;YACd,GAAG,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;YACvC,GAAG,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;SAC/C,CAAC;IACJ,CAAC;IACD,OAAO,SAAS,CAAC;AACnB,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,KAA4B;IAC3D,MAAM,QAAQ,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IACnC,OAAO,CACL,gBAAM,SAAS,EAAC,cAAc,aAC3B,KAAK,CAAC,QAAQ,EACd,QAAQ,IAAI,KAAC,aAAa,IAAC,QAAQ,EAAE,QAAQ,GAAI,IAC7C,CACR,CAAC;AACJ,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownView.d.ts","sourceRoot":"","sources":["../../../src/components/shared/MarkdownView.tsx"],"names":[],"mappings":"AAOA,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,iBAAiB,+BA4D5E"}
1
+ {"version":3,"file":"MarkdownView.d.ts","sourceRoot":"","sources":["../../../src/components/shared/MarkdownView.tsx"],"names":[],"mappings":"AAUA,MAAM,WAAW,iBAAiB;IAChC,2BAA2B;IAC3B,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC/B;;;;OAIG;IACH,IAAI,CAAC,EAAE,OAAO,GAAG,SAAS,CAAC;CAC5B;AAED;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,IAAI,EAAE,EAAE,iBAAiB,+BAmE5E"}
@@ -1,10 +1,13 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
- import ReactMarkdown from 'react-markdown';
2
+ import ReactMarkdown, {} from 'react-markdown';
3
3
  import remarkGfm from 'remark-gfm';
4
+ import remarkDirective from 'remark-directive';
4
5
  import rehypeRaw from 'rehype-raw';
5
6
  import rehypeSanitize from 'rehype-sanitize';
6
7
  import { cn } from './cn.js';
7
8
  import { JsonView, tryParseJson } from './JsonView.js';
9
+ import { MarkdownCitation } from './MarkdownCitation.js';
10
+ import { remarkCitationDirective, citationSanitizeSchema } from './markdown-citation-directive.js';
8
11
  /**
9
12
  * Renders markdown (GitHub-flavored) to safe React nodes — no
10
13
  * `dangerouslySetInnerHTML`. Used for the workflow summary in both the builder
@@ -12,7 +15,20 @@ import { JsonView, tryParseJson } from './JsonView.js';
12
15
  * it works without a Tailwind typography plugin.
13
16
  */
14
17
  export function MarkdownView({ children, className, bare }) {
15
- return (_jsx("div", { className: cn('wui-markdown min-w-0 max-w-full', !bare && 'text-[13px] leading-relaxed text-[var(--wui-fg)]', className), children: _jsx(ReactMarkdown, { remarkPlugins: [remarkGfm], rehypePlugins: [rehypeRaw, rehypeSanitize], components: {
18
+ return (_jsx("div", { className: cn('wui-markdown min-w-0 max-w-full', !bare && 'text-[13px] leading-relaxed text-[var(--wui-fg)]', className), children: _jsx(ReactMarkdown
19
+ // remarkDirective must precede remarkCitationDirective (the nodes have to
20
+ // exist before we map them). rehypeRaw stays ahead of rehypeSanitize so
21
+ // raw HTML is still sanitized — our <citation> survives the round-trip
22
+ // because the schema below admits it.
23
+ , {
24
+ // remarkDirective must precede remarkCitationDirective (the nodes have to
25
+ // exist before we map them). rehypeRaw stays ahead of rehypeSanitize so
26
+ // raw HTML is still sanitized — our <citation> survives the round-trip
27
+ // because the schema below admits it.
28
+ remarkPlugins: [remarkGfm, remarkDirective, remarkCitationDirective], rehypePlugins: [rehypeRaw, [rehypeSanitize, citationSanitizeSchema]],
29
+ // `citation` isn't an intrinsic element, so the map needs the cast;
30
+ // hast-util-to-jsx-runtime dispatches any tag present here by name.
31
+ components: {
16
32
  h1: ({ node: _n, ...p }) => _jsx("h1", { className: "mb-2.5 mt-4 border-b border-[var(--wui-border)] pb-1.5 text-[15px] font-semibold text-[var(--wui-fg)] first:mt-0", ...p }),
17
33
  h2: ({ node: _n, ...p }) => _jsx("h2", { className: "mb-2 mt-4 border-b border-[var(--wui-border)] pb-1 text-[13.5px] font-semibold text-[var(--wui-fg)] first:mt-0", ...p }),
18
34
  h3: ({ node: _n, ...p }) => _jsx("h3", { className: "mb-1.5 mt-3 text-[12.5px] font-semibold text-[var(--wui-fg)] first:mt-0", ...p }),
@@ -45,6 +61,7 @@ export function MarkdownView({ children, className, bare }) {
45
61
  th: ({ node: _n, ...p }) => _jsx("th", { className: "border-b border-[var(--wui-border)] bg-[var(--wui-bg-muted)] px-3 py-2 text-left font-semibold text-[var(--wui-fg)] [&:not(:last-child)]:border-r [&:not(:last-child)]:border-[var(--wui-border)]", ...p }),
46
62
  td: ({ node: _n, ...p }) => _jsx("td", { className: "border-b border-[var(--wui-border)] px-3 py-2 align-top text-[var(--wui-fg)] [&:not(:last-child)]:border-r [&:not(:last-child)]:border-[var(--wui-border)]", ...p }),
47
63
  hr: ({ node: _n, ...p }) => _jsx("hr", { className: "my-4 border-t border-[var(--wui-border)]", ...p }),
64
+ citation: MarkdownCitation,
48
65
  }, children: children }) }));
49
66
  }
50
67
  //# sourceMappingURL=MarkdownView.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"MarkdownView.js","sourceRoot":"","sources":["../../../src/components/shared/MarkdownView.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"MarkdownView.js","sourceRoot":"","sources":["../../../src/components/shared/MarkdownView.tsx"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ import type { OriginResolverCtx } from '../execution/origin/origin-resolver.js';
2
+ import type { ResolvedCitation } from '../execution/origin/citation-resolver.js';
3
+ /**
4
+ * What a citation marker needs to turn a cited ref into an openable source: the
5
+ * workflow config + step outputs of the execution being read.
6
+ *
7
+ * Supplied by context rather than props because markers mount deep inside
8
+ * renderers that are otherwise data-only — the layout DSL's components and the
9
+ * markdown renderer — and threading a resolver through every one of them (and
10
+ * every existing caller) would be invasive for something most surfaces don't use.
11
+ *
12
+ * The default is `null`, and markers render nothing without it. So a surface that
13
+ * has no execution in scope (a summary, an approval reason, any of the many
14
+ * string-only markdown callers) keeps working untouched, and citations light up
15
+ * only where a provider is mounted.
16
+ */
17
+ export declare const CitationOriginContext: import("react").Context<OriginResolverCtx | null>;
18
+ export declare function useCitationOrigin(): OriginResolverCtx | null;
19
+ /** Show a cited document. */
20
+ export type OpenCitationDoc = (doc: Extract<ResolvedCitation, {
21
+ kind: 'doc';
22
+ }>) => void;
23
+ /**
24
+ * Where a cited document should open.
25
+ *
26
+ * A surface that can host a side-by-side panel (the run view) provides this, and
27
+ * the source opens as a resizable column beside the data — you keep the value and
28
+ * its evidence on screen together, which is the whole point of checking a citation.
29
+ *
30
+ * Without a provider the marker falls back to a modal, so surfaces with nowhere to
31
+ * put a panel (a preview, an embedded snippet) still open their sources.
32
+ */
33
+ export declare const CitationOpenContext: import("react").Context<OpenCitationDoc | null>;
34
+ export declare function useCitationOpener(): OpenCitationDoc | null;
35
+ //# sourceMappingURL=citation-context.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation-context.d.ts","sourceRoot":"","sources":["../../../src/components/shared/citation-context.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wCAAwC,CAAC;AAChF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0CAA0C,CAAC;AAEjF;;;;;;;;;;;;;GAaG;AACH,eAAO,MAAM,qBAAqB,mDAAgD,CAAC;AAEnF,wBAAgB,iBAAiB,IAAI,iBAAiB,GAAG,IAAI,CAE5D;AAED,6BAA6B;AAC7B,MAAM,MAAM,eAAe,GAAG,CAAC,GAAG,EAAE,OAAO,CAAC,gBAAgB,EAAE;IAAE,IAAI,EAAE,KAAK,CAAA;CAAE,CAAC,KAAK,IAAI,CAAC;AAExF;;;;;;;;;GASG;AACH,eAAO,MAAM,mBAAmB,iDAA8C,CAAC;AAE/E,wBAAgB,iBAAiB,IAAI,eAAe,GAAG,IAAI,CAE1D"}
@@ -0,0 +1,34 @@
1
+ import { createContext, useContext } from 'react';
2
+ /**
3
+ * What a citation marker needs to turn a cited ref into an openable source: the
4
+ * workflow config + step outputs of the execution being read.
5
+ *
6
+ * Supplied by context rather than props because markers mount deep inside
7
+ * renderers that are otherwise data-only — the layout DSL's components and the
8
+ * markdown renderer — and threading a resolver through every one of them (and
9
+ * every existing caller) would be invasive for something most surfaces don't use.
10
+ *
11
+ * The default is `null`, and markers render nothing without it. So a surface that
12
+ * has no execution in scope (a summary, an approval reason, any of the many
13
+ * string-only markdown callers) keeps working untouched, and citations light up
14
+ * only where a provider is mounted.
15
+ */
16
+ export const CitationOriginContext = createContext(null);
17
+ export function useCitationOrigin() {
18
+ return useContext(CitationOriginContext);
19
+ }
20
+ /**
21
+ * Where a cited document should open.
22
+ *
23
+ * A surface that can host a side-by-side panel (the run view) provides this, and
24
+ * the source opens as a resizable column beside the data — you keep the value and
25
+ * its evidence on screen together, which is the whole point of checking a citation.
26
+ *
27
+ * Without a provider the marker falls back to a modal, so surfaces with nowhere to
28
+ * put a panel (a preview, an embedded snippet) still open their sources.
29
+ */
30
+ export const CitationOpenContext = createContext(null);
31
+ export function useCitationOpener() {
32
+ return useContext(CitationOpenContext);
33
+ }
34
+ //# sourceMappingURL=citation-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation-context.js","sourceRoot":"","sources":["../../../src/components/shared/citation-context.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,EAAE,UAAU,EAAE,MAAM,OAAO,CAAC;AAIlD;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,qBAAqB,GAAG,aAAa,CAA2B,IAAI,CAAC,CAAC;AAEnF,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,qBAAqB,CAAC,CAAC;AAC3C,CAAC;AAKD;;;;;;;;;GASG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAyB,IAAI,CAAC,CAAC;AAE/E,MAAM,UAAU,iBAAiB;IAC/B,OAAO,UAAU,CAAC,mBAAmB,CAAC,CAAC;AACzC,CAAC"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Runtime-citation helpers for the reader side.
3
+ *
4
+ * The types live in the SDK (`@xyne/workflow-sdk/common`) — one definition, so
5
+ * the producer (agent step) and the renderers can't drift. This module adds only
6
+ * what reading needs: unwrapping a cited agent response, and walking the
7
+ * citation mirror alongside the data.
8
+ */
9
+ import type { CitationRef, CitationMap } from '@xyne/workflow-sdk/common';
10
+ import { isCitationRef, isCitationRefArray } from '@xyne/workflow-sdk/common';
11
+ export type { CitationRef, CitationMap };
12
+ export { isCitationRef, isCitationRefArray };
13
+ /**
14
+ * The citation branch belonging to a child, indexed exactly as the value is.
15
+ *
16
+ * How containers walk data and citations in lockstep: since the mirror follows
17
+ * the value's shape, the key or index used to descend into one descends into the
18
+ * other. `undefined` in, `undefined` out — an uncited subtree just stays quiet.
19
+ */
20
+ export declare function citeAt(cite: unknown, key: string | number): unknown;
21
+ /**
22
+ * The citations for one data point, addressed by its path into the rendered data
23
+ * (`['response', 'total']`, `['response', 'lineItems', 0, 'amount']`).
24
+ *
25
+ * Exact match, not prefix: the mirror follows the data exactly, so a hit is the
26
+ * citations *for that leaf* and nothing is inherited from an ancestor. (Contrast
27
+ * `getFieldCitations` in origin-resolver, which is prefix-aware because author
28
+ * citations are written at a different granularity than they're read.)
29
+ */
30
+ export declare function citationsAt(map: CitationMap, path: ReadonlyArray<string | number>): CitationRef[];
31
+ /**
32
+ * Split a step's output into the data to render and a citation mirror **aligned
33
+ * to it**.
34
+ *
35
+ * A cited agent returns `output.response = { value, citation }`. We hoist `value`
36
+ * back into `response` so the panel shows the data itself rather than a wrapper,
37
+ * and nest the mirror under the same key — leaving citation and data the same
38
+ * shape, so one walk indexes both (`data.response.total` ↔ `citation.response.total`).
39
+ *
40
+ * Everything else — uncited agents, every other step type — passes through with
41
+ * `citation: undefined`, so renderers can call this unconditionally.
42
+ */
43
+ export declare function unwrapResponse(output: Record<string, unknown> | undefined): {
44
+ data: Record<string, unknown>;
45
+ citation: CitationMap | undefined;
46
+ };
47
+ /**
48
+ * The matching unwrap for the declared output schema: `resolveOutputJsonSchema`
49
+ * describes a cited response as `{ value, citation }`, so hoist `value` back to
50
+ * `response` exactly as {@link unwrapResponse} does to the data. Without this the
51
+ * schema and the data would disagree about what `response` is, and the
52
+ * schema-driven renderer would fall back to a raw JSON dump.
53
+ */
54
+ export declare function unwrapResponseSchema(schema: Record<string, unknown> | undefined, output: Record<string, unknown> | undefined): Record<string, unknown> | undefined;
55
+ //# sourceMappingURL=citation.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation.d.ts","sourceRoot":"","sources":["../../../src/components/shared/citation.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,OAAO,KAAK,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,2BAA2B,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAE9E,YAAY,EAAE,WAAW,EAAE,WAAW,EAAE,CAAC;AACzC,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;AAE7C;;;;;;GAMG;AACH,wBAAgB,MAAM,CAAC,IAAI,EAAE,OAAO,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,OAAO,CAInE;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CACzB,GAAG,EAAE,WAAW,EAChB,IAAI,EAAE,aAAa,CAAC,MAAM,GAAG,MAAM,CAAC,GACnC,WAAW,EAAE,CAOf;AAkBD;;;;;;;;;;;GAWG;AACH,wBAAgB,cAAc,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAAG;IAC3E,IAAI,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC9B,QAAQ,EAAE,WAAW,GAAG,SAAS,CAAC;CACnC,CAQA;AAED;;;;;;GAMG;AACH,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,EAC3C,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,GAC1C,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAOrC"}
@@ -0,0 +1,83 @@
1
+ import { isCitationRef, isCitationRefArray } from '@xyne/workflow-sdk/common';
2
+ export { isCitationRef, isCitationRefArray };
3
+ /**
4
+ * The citation branch belonging to a child, indexed exactly as the value is.
5
+ *
6
+ * How containers walk data and citations in lockstep: since the mirror follows
7
+ * the value's shape, the key or index used to descend into one descends into the
8
+ * other. `undefined` in, `undefined` out — an uncited subtree just stays quiet.
9
+ */
10
+ export function citeAt(cite, key) {
11
+ return cite !== null && typeof cite === 'object'
12
+ ? cite[key]
13
+ : undefined;
14
+ }
15
+ /**
16
+ * The citations for one data point, addressed by its path into the rendered data
17
+ * (`['response', 'total']`, `['response', 'lineItems', 0, 'amount']`).
18
+ *
19
+ * Exact match, not prefix: the mirror follows the data exactly, so a hit is the
20
+ * citations *for that leaf* and nothing is inherited from an ancestor. (Contrast
21
+ * `getFieldCitations` in origin-resolver, which is prefix-aware because author
22
+ * citations are written at a different granularity than they're read.)
23
+ */
24
+ export function citationsAt(map, path) {
25
+ let cur = map;
26
+ for (const seg of path) {
27
+ if (cur === null || typeof cur !== 'object')
28
+ return [];
29
+ cur = cur[seg];
30
+ }
31
+ return isCitationRefArray(cur) ? cur : [];
32
+ }
33
+ function citedWrapper(output) {
34
+ const response = output?.['response'];
35
+ if (response === null
36
+ || typeof response !== 'object'
37
+ || Array.isArray(response)
38
+ || !('value' in response || 'citation' in response)) {
39
+ return undefined;
40
+ }
41
+ const w = response;
42
+ return { value: w.value, citation: w.citation ?? {} };
43
+ }
44
+ /**
45
+ * Split a step's output into the data to render and a citation mirror **aligned
46
+ * to it**.
47
+ *
48
+ * A cited agent returns `output.response = { value, citation }`. We hoist `value`
49
+ * back into `response` so the panel shows the data itself rather than a wrapper,
50
+ * and nest the mirror under the same key — leaving citation and data the same
51
+ * shape, so one walk indexes both (`data.response.total` ↔ `citation.response.total`).
52
+ *
53
+ * Everything else — uncited agents, every other step type — passes through with
54
+ * `citation: undefined`, so renderers can call this unconditionally.
55
+ */
56
+ export function unwrapResponse(output) {
57
+ const wrapper = citedWrapper(output);
58
+ if (!wrapper)
59
+ return { data: output ?? {}, citation: undefined };
60
+ return {
61
+ // Sibling agent fields (attachments, usage, toolCalls) are preserved.
62
+ data: { ...output, response: wrapper.value },
63
+ citation: { response: wrapper.citation },
64
+ };
65
+ }
66
+ /**
67
+ * The matching unwrap for the declared output schema: `resolveOutputJsonSchema`
68
+ * describes a cited response as `{ value, citation }`, so hoist `value` back to
69
+ * `response` exactly as {@link unwrapResponse} does to the data. Without this the
70
+ * schema and the data would disagree about what `response` is, and the
71
+ * schema-driven renderer would fall back to a raw JSON dump.
72
+ */
73
+ export function unwrapResponseSchema(schema, output) {
74
+ if (!schema || !citedWrapper(output))
75
+ return schema;
76
+ const props = schema['properties'];
77
+ const response = props?.['response'];
78
+ const inner = response?.['properties']?.['value'];
79
+ if (!props || !inner)
80
+ return schema;
81
+ return { ...schema, properties: { ...props, response: inner } };
82
+ }
83
+ //# sourceMappingURL=citation.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"citation.js","sourceRoot":"","sources":["../../../src/components/shared/citation.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAG9E,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,CAAC;AAE7C;;;;;;GAMG;AACH,MAAM,UAAU,MAAM,CAAC,IAAa,EAAE,GAAoB;IACxD,OAAO,IAAI,KAAK,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;QAC9C,CAAC,CAAE,IAAqC,CAAC,GAAG,CAAC;QAC7C,CAAC,CAAC,SAAS,CAAC;AAChB,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,WAAW,CACzB,GAAgB,EAChB,IAAoC;IAEpC,IAAI,GAAG,GAAY,GAAG,CAAC;IACvB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ;YAAE,OAAO,EAAE,CAAC;QACvD,GAAG,GAAI,GAAoC,CAAC,GAAG,CAAC,CAAC;IACnD,CAAC;IACD,OAAO,kBAAkB,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;AAC5C,CAAC;AAED,SAAS,YAAY,CACnB,MAA2C;IAE3C,MAAM,QAAQ,GAAG,MAAM,EAAE,CAAC,UAAU,CAAC,CAAC;IACtC,IACE,QAAQ,KAAK,IAAI;WACd,OAAO,QAAQ,KAAK,QAAQ;WAC5B,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC;WACvB,CAAC,CAAC,OAAO,IAAI,QAAQ,IAAI,UAAU,IAAI,QAAQ,CAAC,EACnD,CAAC;QACD,OAAO,SAAS,CAAC;IACnB,CAAC;IACD,MAAM,CAAC,GAAG,QAAuD,CAAC;IAClE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,QAAQ,IAAI,EAAE,EAAE,CAAC;AACxD,CAAC;AAED;;;;;;;;;;;GAWG;AACH,MAAM,UAAU,cAAc,CAAC,MAA2C;IAIxE,MAAM,OAAO,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACrC,IAAI,CAAC,OAAO;QAAE,OAAO,EAAE,IAAI,EAAE,MAAM,IAAI,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,CAAC;IACjE,OAAO;QACL,sEAAsE;QACtE,IAAI,EAAE,EAAE,GAAG,MAAM,EAAE,QAAQ,EAAE,OAAO,CAAC,KAAK,EAAE;QAC5C,QAAQ,EAAE,EAAE,QAAQ,EAAE,OAAO,CAAC,QAAQ,EAAE;KACzC,CAAC;AACJ,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,oBAAoB,CAClC,MAA2C,EAC3C,MAA2C;IAE3C,IAAI,CAAC,MAAM,IAAI,CAAC,YAAY,CAAC,MAAM,CAAC;QAAE,OAAO,MAAM,CAAC;IACpD,MAAM,KAAK,GAAG,MAAM,CAAC,YAAY,CAAwC,CAAC;IAC1E,MAAM,QAAQ,GAAG,KAAK,EAAE,CAAC,UAAU,CAAwC,CAAC;IAC5E,MAAM,KAAK,GAAI,QAAQ,EAAE,CAAC,YAAY,CAAyC,EAAE,CAAC,OAAO,CAAC,CAAC;IAC3F,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK;QAAE,OAAO,MAAM,CAAC;IACpC,OAAO,EAAE,GAAG,MAAM,EAAE,UAAU,EAAE,EAAE,GAAG,KAAK,EAAE,QAAQ,EAAE,KAAK,EAAE,EAAE,CAAC;AAClE,CAAC"}
@@ -0,0 +1,34 @@
1
+ import type { Root } from 'mdast';
2
+ import type { VFile } from 'vfile';
3
+ /** The element the directive becomes; `components` maps it to MarkdownCitation. */
4
+ export declare const CITATION_TAG = "citation";
5
+ /**
6
+ * Map `:::citation{…}` onto a `<citation>` element carrying its attributes, and
7
+ * neutralise every other directive (see {@link revertToSource}).
8
+ */
9
+ export declare function remarkCitationDirective(): (tree: Root, file: VFile) => void;
10
+ /**
11
+ * `defaultSchema` plus the `citation` element.
12
+ *
13
+ * Without this, sanitize doesn't merely ignore `<citation>` — it **unwraps** it,
14
+ * dropping the marker while keeping the text, so citations would silently vanish.
15
+ * Only our five attributes are allowed through, and `url` is confined to http(s),
16
+ * so the directive can't smuggle in markup or a `javascript:` target.
17
+ */
18
+ export declare const citationSanitizeSchema: {
19
+ tagNames: string[];
20
+ attributes: {
21
+ citation: ("ref" | "title" | "url" | "page" | "quote")[];
22
+ };
23
+ protocols: {
24
+ url: string[];
25
+ };
26
+ allowComments?: boolean | null | undefined;
27
+ allowDoctypes?: boolean | null | undefined;
28
+ ancestors?: Record<string, Array<string>> | null | undefined;
29
+ clobber?: Array<string> | null | undefined;
30
+ clobberPrefix?: string | null | undefined;
31
+ required?: Record<string, Record<string, import("hast").Properties[keyof import("hast").Properties]>> | null | undefined;
32
+ strip?: Array<string> | null | undefined;
33
+ };
34
+ //# sourceMappingURL=markdown-citation-directive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-citation-directive.d.ts","sourceRoot":"","sources":["../../../src/components/shared/markdown-citation-directive.ts"],"names":[],"mappings":"AAaA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAClC,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,OAAO,CAAC;AAInC,mFAAmF;AACnF,eAAO,MAAM,YAAY,aAAa,CAAC;AAgDvC;;;GAGG;AACH,wBAAgB,uBAAuB,KAC7B,MAAM,IAAI,EAAE,MAAM,KAAK,KAAG,IAAI,CAiCvC;AAED;;;;;;;GAOG;AACH,eAAO,MAAM,sBAAsB;;;;;;;;;;;;;;;CAWlC,CAAC"}
@@ -0,0 +1,110 @@
1
+ /**
2
+ * `:::citation{…}` support for {@link MarkdownView} — the markdown half of runtime
3
+ * citations, mirroring what `cite={…}` does for structured data.
4
+ *
5
+ * An agent writing prose wraps each sourced statement in a container directive:
6
+ *
7
+ * :::citation{ref="steps.ocr.output.results.0.data" page=3 quote="TOTAL 5000"}
8
+ * The invoice totals ₹5,000.
9
+ * :::
10
+ *
11
+ * which renders the statement plus a ↗ marker opening the source.
12
+ */
13
+ import { visit, SKIP } from 'unist-util-visit';
14
+ import { defaultSchema } from 'rehype-sanitize';
15
+ import { CITATION_DIRECTIVE_ATTRS } from '@xyne/workflow-sdk/common';
16
+ /** The element the directive becomes; `components` maps it to MarkdownCitation. */
17
+ export const CITATION_TAG = 'citation';
18
+ const DIRECTIVE_TYPES = new Set(['containerDirective', 'leafDirective', 'textDirective']);
19
+ /**
20
+ * Replace a node with the exact markdown it was parsed from.
21
+ *
22
+ * Enabling remark-directive turns on `:name` / `::name` / `:::name` **globally**,
23
+ * for every MarkdownView caller — so text that merely looks like a directive
24
+ * (`:release:`, a `:shrug` shortcode) would parse into an unknown node that
25
+ * rehype-sanitize then unwraps, silently deleting the author's words. Restoring
26
+ * the original source keeps this feature from changing any prose but our own.
27
+ *
28
+ * The source is sliced by the node's own offsets, so it round-trips exactly
29
+ * rather than being re-serialised approximately.
30
+ */
31
+ function revertToSource(node, source) {
32
+ const start = node.position?.start.offset;
33
+ const end = node.position?.end.offset;
34
+ if (start === undefined || end === undefined)
35
+ return false;
36
+ const literal = source.slice(start, end);
37
+ delete node.name;
38
+ delete node.attributes;
39
+ delete node.data;
40
+ if (node.type === 'textDirective') {
41
+ node.type = 'text';
42
+ node.value = literal;
43
+ delete node.children;
44
+ return true;
45
+ }
46
+ // Block-level: `text` isn't valid where a block directive sat, so wrap it.
47
+ node.type = 'paragraph';
48
+ node.children = [{ type: 'text', value: literal }];
49
+ return true;
50
+ }
51
+ /**
52
+ * Map `:::citation{…}` onto a `<citation>` element carrying its attributes, and
53
+ * neutralise every other directive (see {@link revertToSource}).
54
+ */
55
+ export function remarkCitationDirective() {
56
+ return (tree, file) => {
57
+ const source = String(file.value);
58
+ visit(tree, (node) => {
59
+ const n = node;
60
+ if (!DIRECTIVE_TYPES.has(n.type))
61
+ return;
62
+ if (n.type === 'containerDirective' && n.name === CITATION_TAG) {
63
+ const attrs = n.attributes ?? {};
64
+ const props = {};
65
+ for (const key of CITATION_DIRECTIVE_ATTRS) {
66
+ const v = attrs[key];
67
+ if (typeof v === 'string' && v !== '')
68
+ props[key] = v;
69
+ }
70
+ // A lone paragraph would put a block inside our inline wrapper and push
71
+ // the marker onto its own line; unwrap it so the marker trails the text.
72
+ const kids = n.children;
73
+ if (Array.isArray(kids) && kids.length === 1) {
74
+ const only = kids[0];
75
+ if (only.type === 'paragraph' && Array.isArray(only.children)) {
76
+ n.children = only.children;
77
+ }
78
+ }
79
+ const data = n.data ?? (n.data = {});
80
+ data['hName'] = CITATION_TAG;
81
+ data['hProperties'] = props;
82
+ return;
83
+ }
84
+ if (revertToSource(n, source))
85
+ return SKIP;
86
+ return;
87
+ });
88
+ };
89
+ }
90
+ /**
91
+ * `defaultSchema` plus the `citation` element.
92
+ *
93
+ * Without this, sanitize doesn't merely ignore `<citation>` — it **unwraps** it,
94
+ * dropping the marker while keeping the text, so citations would silently vanish.
95
+ * Only our five attributes are allowed through, and `url` is confined to http(s),
96
+ * so the directive can't smuggle in markup or a `javascript:` target.
97
+ */
98
+ export const citationSanitizeSchema = {
99
+ ...defaultSchema,
100
+ tagNames: [...(defaultSchema.tagNames ?? []), CITATION_TAG],
101
+ attributes: {
102
+ ...defaultSchema.attributes,
103
+ [CITATION_TAG]: [...CITATION_DIRECTIVE_ATTRS],
104
+ },
105
+ protocols: {
106
+ ...defaultSchema.protocols,
107
+ url: ['http', 'https'],
108
+ },
109
+ };
110
+ //# sourceMappingURL=markdown-citation-directive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-citation-directive.js","sourceRoot":"","sources":["../../../src/components/shared/markdown-citation-directive.ts"],"names":[],"mappings":"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"}