@cellarnode/ui 0.201.1 → 0.203.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/agent/composer.d.ts +6 -1
- package/dist/agent/composer.d.ts.map +1 -1
- package/dist/agent/composer.js +43 -9
- package/dist/agent/composer.js.map +1 -1
- package/dist/agent/conversation.d.ts +20 -2
- package/dist/agent/conversation.d.ts.map +1 -1
- package/dist/agent/conversation.js +39 -5
- package/dist/agent/conversation.js.map +1 -1
- package/dist/agent/copy.d.ts +7 -0
- package/dist/agent/copy.d.ts.map +1 -1
- package/dist/agent/copy.js +9 -0
- package/dist/agent/copy.js.map +1 -1
- package/dist/agent/fixtures.d.ts +34 -0
- package/dist/agent/fixtures.d.ts.map +1 -1
- package/dist/agent/fixtures.js +83 -0
- package/dist/agent/fixtures.js.map +1 -1
- package/dist/agent/index.d.ts +18 -1
- package/dist/agent/index.d.ts.map +1 -1
- package/dist/agent/index.js +18 -1
- package/dist/agent/index.js.map +1 -1
- package/dist/agent/markdown.d.ts +64 -0
- package/dist/agent/markdown.d.ts.map +1 -0
- package/dist/agent/markdown.js +338 -0
- package/dist/agent/markdown.js.map +1 -0
- package/dist/agent/masked-value.d.ts +1 -0
- package/dist/agent/masked-value.d.ts.map +1 -1
- package/dist/agent/masked-value.js +4 -1
- package/dist/agent/masked-value.js.map +1 -1
- package/dist/agent/message.d.ts +26 -6
- package/dist/agent/message.d.ts.map +1 -1
- package/dist/agent/message.js +47 -11
- package/dist/agent/message.js.map +1 -1
- package/dist/agent/panel-frame.js +1 -1
- package/dist/agent/panel-frame.js.map +1 -1
- package/dist/agent/role-cards/card-kit.d.ts +111 -0
- package/dist/agent/role-cards/card-kit.d.ts.map +1 -0
- package/dist/agent/role-cards/card-kit.js +68 -0
- package/dist/agent/role-cards/card-kit.js.map +1 -0
- package/dist/agent/role-cards/data-table-card.d.ts +80 -0
- package/dist/agent/role-cards/data-table-card.d.ts.map +1 -0
- package/dist/agent/role-cards/data-table-card.js +214 -0
- package/dist/agent/role-cards/data-table-card.js.map +1 -0
- package/dist/agent/role-cards/fixtures.d.ts +124 -0
- package/dist/agent/role-cards/fixtures.d.ts.map +1 -0
- package/dist/agent/role-cards/fixtures.js +401 -0
- package/dist/agent/role-cards/fixtures.js.map +1 -0
- package/dist/agent/role-cards/host-contract.d.ts +214 -0
- package/dist/agent/role-cards/host-contract.d.ts.map +1 -0
- package/dist/agent/role-cards/host-contract.js +348 -0
- package/dist/agent/role-cards/host-contract.js.map +1 -0
- package/dist/agent/role-cards/inspector-drawer.d.ts +42 -0
- package/dist/agent/role-cards/inspector-drawer.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-drawer.js +68 -0
- package/dist/agent/role-cards/inspector-drawer.js.map +1 -0
- package/dist/agent/role-cards/inspector-fixtures.d.ts +84 -0
- package/dist/agent/role-cards/inspector-fixtures.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-fixtures.js +162 -0
- package/dist/agent/role-cards/inspector-fixtures.js.map +1 -0
- package/dist/agent/role-cards/inspector-record.d.ts +109 -0
- package/dist/agent/role-cards/inspector-record.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-record.js +346 -0
- package/dist/agent/role-cards/inspector-record.js.map +1 -0
- package/dist/agent/role-cards/inspector-view.d.ts +137 -0
- package/dist/agent/role-cards/inspector-view.d.ts.map +1 -0
- package/dist/agent/role-cards/inspector-view.js +261 -0
- package/dist/agent/role-cards/inspector-view.js.map +1 -0
- package/dist/agent/role-cards/match-card.d.ts +21 -0
- package/dist/agent/role-cards/match-card.d.ts.map +1 -0
- package/dist/agent/role-cards/match-card.js +30 -0
- package/dist/agent/role-cards/match-card.js.map +1 -0
- package/dist/agent/role-cards/offer-card.d.ts +27 -0
- package/dist/agent/role-cards/offer-card.d.ts.map +1 -0
- package/dist/agent/role-cards/offer-card.js +68 -0
- package/dist/agent/role-cards/offer-card.js.map +1 -0
- package/dist/agent/role-cards/opportunity-card.d.ts +26 -0
- package/dist/agent/role-cards/opportunity-card.d.ts.map +1 -0
- package/dist/agent/role-cards/opportunity-card.js +50 -0
- package/dist/agent/role-cards/opportunity-card.js.map +1 -0
- package/dist/agent/role-cards/product-card.d.ts +32 -0
- package/dist/agent/role-cards/product-card.d.ts.map +1 -0
- package/dist/agent/role-cards/product-card.js +50 -0
- package/dist/agent/role-cards/product-card.js.map +1 -0
- package/dist/agent/role-cards/proposal-diff.d.ts +38 -0
- package/dist/agent/role-cards/proposal-diff.d.ts.map +1 -0
- package/dist/agent/role-cards/proposal-diff.js +74 -0
- package/dist/agent/role-cards/proposal-diff.js.map +1 -0
- package/dist/agent/role-cards/registry.d.ts +43 -0
- package/dist/agent/role-cards/registry.d.ts.map +1 -0
- package/dist/agent/role-cards/registry.js +46 -0
- package/dist/agent/role-cards/registry.js.map +1 -0
- package/dist/agent/role-cards/score-meter.d.ts +12 -0
- package/dist/agent/role-cards/score-meter.d.ts.map +1 -0
- package/dist/agent/role-cards/score-meter.js +17 -0
- package/dist/agent/role-cards/score-meter.js.map +1 -0
- package/dist/agent/role-cards/surface-links.d.ts +54 -0
- package/dist/agent/role-cards/surface-links.d.ts.map +1 -0
- package/dist/agent/role-cards/surface-links.js +149 -0
- package/dist/agent/role-cards/surface-links.js.map +1 -0
- package/dist/agent/role-cards/text-safety.d.ts +27 -0
- package/dist/agent/role-cards/text-safety.d.ts.map +1 -0
- package/dist/agent/role-cards/text-safety.js +77 -0
- package/dist/agent/role-cards/text-safety.js.map +1 -0
- package/dist/agent/schema.d.ts +10 -0
- package/dist/agent/schema.d.ts.map +1 -1
- package/dist/agent/schema.js +31 -3
- package/dist/agent/schema.js.map +1 -1
- package/dist/agent/states.d.ts +1 -0
- package/dist/agent/states.d.ts.map +1 -1
- package/dist/agent/states.js +1 -1
- package/dist/agent/states.js.map +1 -1
- package/dist/agent/thinking.d.ts +13 -4
- package/dist/agent/thinking.d.ts.map +1 -1
- package/dist/agent/thinking.js +15 -6
- package/dist/agent/thinking.js.map +1 -1
- package/dist/agent/thread-list.d.ts +45 -2
- package/dist/agent/thread-list.d.ts.map +1 -1
- package/dist/agent/thread-list.js +175 -8
- package/dist/agent/thread-list.js.map +1 -1
- package/dist/agent/thread-title.d.ts +46 -0
- package/dist/agent/thread-title.d.ts.map +1 -0
- package/dist/agent/thread-title.js +99 -0
- package/dist/agent/thread-title.js.map +1 -0
- package/dist/agent/tool-activity-model.d.ts +136 -0
- package/dist/agent/tool-activity-model.d.ts.map +1 -0
- package/dist/agent/tool-activity-model.js +288 -0
- package/dist/agent/tool-activity-model.js.map +1 -0
- package/dist/agent/tool-activity.d.ts +61 -0
- package/dist/agent/tool-activity.d.ts.map +1 -0
- package/dist/agent/tool-activity.js +199 -0
- package/dist/agent/tool-activity.js.map +1 -0
- package/dist/agent/tool-call-card.d.ts +11 -1
- package/dist/agent/tool-call-card.d.ts.map +1 -1
- package/dist/agent/tool-call-card.js +19 -4
- package/dist/agent/tool-call-card.js.map +1 -1
- package/dist/agent/ui.js +1 -1
- package/dist/agent/ui.js.map +1 -1
- package/dist/agent/use-motion.d.ts +15 -0
- package/dist/agent/use-motion.d.ts.map +1 -0
- package/dist/agent/use-motion.js +52 -0
- package/dist/agent/use-motion.js.map +1 -0
- package/dist/chat/use-stick-to-bottom.d.ts +5 -0
- package/dist/chat/use-stick-to-bottom.d.ts.map +1 -1
- package/dist/chat/use-stick-to-bottom.js +11 -1
- package/dist/chat/use-stick-to-bottom.js.map +1 -1
- package/dist/components/sheet.d.ts +3 -1
- package/dist/components/sheet.d.ts.map +1 -1
- package/dist/components/sheet.js +2 -2
- package/dist/components/sheet.js.map +1 -1
- package/dist/portfolio-import/import-job-panels.d.ts +6 -0
- package/dist/portfolio-import/import-job-panels.d.ts.map +1 -1
- package/dist/portfolio-import/import-job-panels.js +11 -4
- package/dist/portfolio-import/import-job-panels.js.map +1 -1
- package/dist/portfolio-import/job-error-copy.d.ts +62 -0
- package/dist/portfolio-import/job-error-copy.d.ts.map +1 -0
- package/dist/portfolio-import/job-error-copy.js +78 -0
- package/dist/portfolio-import/job-error-copy.js.map +1 -0
- package/dist/realtime/organisation-events/schemas.d.ts +2 -2
- package/package.json +4 -1
- package/src/theme/tokens.css +66 -0
package/dist/agent/index.js
CHANGED
|
@@ -13,12 +13,29 @@ export { AgentThinking } from "./thinking.js";
|
|
|
13
13
|
export { AgentEmptyState, AgentError, } from "./states.js";
|
|
14
14
|
export { AgentConfirmCard, DEFAULT_CONFIRM_CARD_COPY, } from "./confirm-card.js";
|
|
15
15
|
export { AgentApprovalLedger, } from "./approval-ledger.js";
|
|
16
|
+
export { AgentToolActivity, } from "./tool-activity.js";
|
|
17
|
+
export { DEFAULT_ACRONYMS, DEFAULT_TOOL_PREFIXES, DEFAULT_TOOL_VERBS, MAX_PREVIEW_CHARS, createToolNamer, formatToolResult, humanizeCardType, humanizeToolName, planMessageParts, unwrapResultEnvelope, } from "./tool-activity-model.js";
|
|
18
|
+
export { AgentMarkdown, classifyHref, resolveLink, } from "./markdown.js";
|
|
19
|
+
/** @deprecated Superseded by `AgentToolActivity`; `AgentMessage` no longer renders it. */
|
|
16
20
|
export { AgentToolCallCard, } from "./tool-call-card.js";
|
|
17
21
|
export { AgentActivityLedger, } from "./activity-ledger.js";
|
|
18
22
|
export { AgentComposer } from "./composer.js";
|
|
19
23
|
export { AgentMessage } from "./message.js";
|
|
20
24
|
export { AgentConversation, } from "./conversation.js";
|
|
21
25
|
export { AgentPanelFrame, } from "./panel-frame.js";
|
|
22
|
-
export { AgentThreadList, } from "./thread-list.js";
|
|
26
|
+
export { AgentThreadList, AgentThreadRenameError, deriveThreadTitle, threadDisplayTitle, THREAD_TITLE_MAX, } from "./thread-list.js";
|
|
23
27
|
export { AgentReadinessChecklist, } from "./readiness-checklist.js";
|
|
28
|
+
export { AgentCardActions, AgentCardFrame, AgentCardLink, AgentChip, AgentField, AgentFieldGrid, AgentCardExtras, } from "./role-cards/card-kit.js";
|
|
29
|
+
export { AgentScoreMeter } from "./role-cards/score-meter.js";
|
|
30
|
+
export { AgentProposalDiff, } from "./role-cards/proposal-diff.js";
|
|
31
|
+
export { AgentOfferCard, } from "./role-cards/offer-card.js";
|
|
32
|
+
export { AgentProductCard, } from "./role-cards/product-card.js";
|
|
33
|
+
export { AgentOpportunityCard, } from "./role-cards/opportunity-card.js";
|
|
34
|
+
export { AgentMatchCard, } from "./role-cards/match-card.js";
|
|
35
|
+
export { AgentDataTableCard, DEFAULT_THIRD_PARTY_COLUMNS, MAX_AGENT_TABLE_ROWS, } from "./role-cards/data-table-card.js";
|
|
36
|
+
export { agentLinkKind, createSurfaceAllowLink, surfaceThirdPartyColumns, } from "./role-cards/surface-links.js";
|
|
37
|
+
export { AgentInspectorDrawer, } from "./role-cards/inspector-drawer.js";
|
|
38
|
+
export { AgentInspectorView, DEFAULT_THIRD_PARTY_PATHS, } from "./role-cards/inspector-view.js";
|
|
39
|
+
export { renderRoleAgentCard, ROLE_AGENT_CARD_TYPES, } from "./role-cards/registry.js";
|
|
40
|
+
export { buildConfirm, planProposalApply, actionsForDisplay, lookupPath, readPath, resolveCardActions, subjectOf, } from "./role-cards/host-contract.js";
|
|
24
41
|
//# sourceMappingURL=index.js.map
|
package/dist/agent/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,cAAc,GAGf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAA+C,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAmD,MAAM,YAAY,CAAC;AAC5F,OAAO,EACL,eAAe,EACf,UAAU,GAMX,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,gBAAgB,EAChB,yBAAyB,GAG1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,iBAAiB,GAGlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAmD,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAiD,MAAM,WAAW,CAAC;AACxF,OAAO,EACL,iBAAiB,GAGlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,GAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/agent/index.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,cAAc,UAAU,CAAC;AACzB,OAAO,EACL,qBAAqB,EACrB,cAAc,GAGf,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EAAE,WAAW,EAA+C,MAAM,gBAAgB,CAAC;AAC1F,OAAO,EAAE,aAAa,EAAmD,MAAM,YAAY,CAAC;AAC5F,OAAO,EACL,eAAe,EACf,UAAU,GAMX,MAAM,UAAU,CAAC;AAClB,OAAO,EACL,gBAAgB,EAChB,yBAAyB,GAG1B,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,iBAAiB,GAGlB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,gBAAgB,EAChB,qBAAqB,EACrB,kBAAkB,EAClB,iBAAiB,EACjB,eAAe,EACf,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,GAcrB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,aAAa,EACb,YAAY,EACZ,WAAW,GAKZ,MAAM,YAAY,CAAC;AACpB,0FAA0F;AAC1F,OAAO,EACL,iBAAiB,GAGlB,MAAM,kBAAkB,CAAC;AAC1B,OAAO,EACL,mBAAmB,GAGpB,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EAAE,aAAa,EAAmD,MAAM,YAAY,CAAC;AAC5F,OAAO,EAAE,YAAY,EAAiD,MAAM,WAAW,CAAC;AACxF,OAAO,EACL,iBAAiB,GAGlB,MAAM,gBAAgB,CAAC;AACxB,OAAO,EACL,eAAe,GAGhB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,eAAe,EACf,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,GAGjB,MAAM,eAAe,CAAC;AACvB,OAAO,EACL,uBAAuB,GAKxB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,gBAAgB,EAChB,cAAc,EACd,aAAa,EACb,SAAS,EACT,UAAU,EACV,cAAc,EAKd,eAAe,GAChB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EACL,iBAAiB,GAGlB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,cAAc,GAGf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,gBAAgB,GAGjB,MAAM,2BAA2B,CAAC;AACnC,OAAO,EACL,oBAAoB,GAGrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,cAAc,GAGf,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,kBAAkB,EAClB,2BAA2B,EAC3B,oBAAoB,GAGrB,MAAM,8BAA8B,CAAC;AACtC,OAAO,EACL,aAAa,EACb,sBAAsB,EACtB,wBAAwB,GAGzB,MAAM,4BAA4B,CAAC;AACpC,OAAO,EACL,oBAAoB,GAIrB,MAAM,+BAA+B,CAAC;AACvC,OAAO,EACL,kBAAkB,EAClB,yBAAyB,GAO1B,MAAM,6BAA6B,CAAC;AACrC,OAAO,EACL,mBAAmB,EACnB,qBAAqB,GAItB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EACL,YAAY,EACZ,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACV,QAAQ,EACR,kBAAkB,EAClB,SAAS,GAcV,MAAM,4BAA4B,CAAC"}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export interface AgentMarkdownCopy {
|
|
2
|
+
/** Read after the text of a link that leaves the app, with its own brackets: "(opens in a new tab)". */
|
|
3
|
+
opensInNewTab: string;
|
|
4
|
+
/** Shown after the text of an external link, so the destination is visible: `{host}` ("example.com"). */
|
|
5
|
+
externalHost: string;
|
|
6
|
+
taskDone: string;
|
|
7
|
+
taskOpen: string;
|
|
8
|
+
}
|
|
9
|
+
export type AgentLinkClass = {
|
|
10
|
+
kind: "external";
|
|
11
|
+
href: string;
|
|
12
|
+
} | {
|
|
13
|
+
kind: "internal";
|
|
14
|
+
href: string;
|
|
15
|
+
} | {
|
|
16
|
+
kind: "blocked";
|
|
17
|
+
};
|
|
18
|
+
/**
|
|
19
|
+
* What the host says about a link: an internal path, an external site, or neither. It can only NARROW what the lib already
|
|
20
|
+
* allows (`http(s)` URLs and internal `/paths`): answering "internal" or "external" for anything else, or for the wrong kind,
|
|
21
|
+
* changes nothing. A host that links to its own routes only answers "blocked" for everything else, including every external URL.
|
|
22
|
+
*/
|
|
23
|
+
export type AgentLinkPolicy = (href: string) => "internal" | "external" | "blocked";
|
|
24
|
+
/**
|
|
25
|
+
* @internal The default link policy, and the floor under every host policy. The agent's text is untrusted (a customer can write
|
|
26
|
+
* text the agent repeats), so a link is live only for `http(s):` or an internal `/path`; everything else (`mailto:`,
|
|
27
|
+
* `javascript:`, `data:`, `//host`, `/\host`, `#frag`, a bare relative path, a URL with control characters) is blocked and
|
|
28
|
+
* renders as plain text.
|
|
29
|
+
*/
|
|
30
|
+
export declare function classifyHref(raw: string | undefined | null): AgentLinkClass;
|
|
31
|
+
/** The lib's floor, then the host's policy (which can only block more). Applied at render, to every link form. */
|
|
32
|
+
export declare function resolveLink(raw: string | undefined | null, policy?: AgentLinkPolicy): AgentLinkClass;
|
|
33
|
+
export interface AgentMarkdownProps {
|
|
34
|
+
text: string;
|
|
35
|
+
/** The text is still arriving: a caret marks the end of the last block. */
|
|
36
|
+
streaming?: boolean;
|
|
37
|
+
/**
|
|
38
|
+
* Called for a click on an internal `/path` link (no modifier key). Pass the router's navigate so the SPA does not
|
|
39
|
+
* reload; without it the link is a plain anchor.
|
|
40
|
+
*/
|
|
41
|
+
onNavigate?: (path: string) => void;
|
|
42
|
+
/**
|
|
43
|
+
* Which links are live. Default: `http(s)` URLs (external) and internal `/paths`. A host that only has its own routes
|
|
44
|
+
* answers "blocked" for everything else, external URLs included. Enforced when a link is drawn, for every form of link
|
|
45
|
+
* (inline, reference, autolink, `www.`, `<...>`).
|
|
46
|
+
*/
|
|
47
|
+
linkPolicy?: AgentLinkPolicy;
|
|
48
|
+
copy?: Partial<AgentMarkdownCopy>;
|
|
49
|
+
className?: string;
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* @internal The assistant's text as markdown. No raw HTML (it is skipped, never rendered), images are never loaded (an image
|
|
53
|
+
* URL is a tracking and data-egress channel; the alt text shows instead), footnotes are plain text, links are limited by
|
|
54
|
+
* `linkPolicy` over the `classifyHref` floor, and an external link opens in a new tab with `rel="noopener noreferrer"`, an icon,
|
|
55
|
+
* and its host written out when the link text does not already say it.
|
|
56
|
+
*
|
|
57
|
+
* Partial markdown (an unclosed `**` or a code fence while streaming) is rendered as it is: an unclosed fence is a code block
|
|
58
|
+
* until it closes, an unclosed `**` shows its asterisks until the closing pair arrives.
|
|
59
|
+
*
|
|
60
|
+
* The rendered elements are stable across prop changes: a new `copy`, `onNavigate` or `linkPolicy` re-renders them in place
|
|
61
|
+
* and does not remount them, so a focused link keeps focus and a running animation is not restarted.
|
|
62
|
+
*/
|
|
63
|
+
export declare const AgentMarkdown: import("react").NamedExoticComponent<AgentMarkdownProps>;
|
|
64
|
+
//# sourceMappingURL=markdown.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.d.ts","sourceRoot":"","sources":["../../src/agent/markdown.tsx"],"names":[],"mappings":"AAoBA,MAAM,WAAW,iBAAiB;IAChC,wGAAwG;IACxG,aAAa,EAAE,MAAM,CAAC;IACtB,yGAAyG;IACzG,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAQD,MAAM,MAAM,cAAc,GACtB;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAClC;IAAE,IAAI,EAAE,SAAS,CAAA;CAAE,CAAC;AAExB;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,CAAC,IAAI,EAAE,MAAM,KAAK,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;AAOpF;;;;;GAKG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,GAAG,cAAc,CAsB3E;AAED,kHAAkH;AAClH,wBAAgB,WAAW,CACzB,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,IAAI,EAC9B,MAAM,CAAC,EAAE,eAAe,GACvB,cAAc,CAYhB;AA6VD,MAAM,WAAW,kBAAkB;IACjC,IAAI,EAAE,MAAM,CAAC;IACb,2EAA2E;IAC3E,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB;;;OAGG;IACH,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC;;;;OAIG;IACH,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,IAAI,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAClC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;;;;;;;;GAWG;AACH,eAAO,MAAM,aAAa,0DAmCxB,CAAC"}
|
|
@@ -0,0 +1,338 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { createContext, Fragment, isValidElement, memo, useContext, useMemo, } from "react";
|
|
3
|
+
import ReactMarkdown from "react-markdown";
|
|
4
|
+
import remarkGfm from "remark-gfm";
|
|
5
|
+
import { ExternalLink } from "lucide-react";
|
|
6
|
+
import { cn } from "../lib/utils.js";
|
|
7
|
+
import { useCopy } from "./copy.js";
|
|
8
|
+
import { stripBidi, stripBidiRuns } from "./role-cards/text-safety.js";
|
|
9
|
+
import { collapseBlankRuns } from "./thread-title.js";
|
|
10
|
+
import { focusRing } from "./ui.js";
|
|
11
|
+
const DEFAULT_COPY = {
|
|
12
|
+
opensInNewTab: "(opens in a new tab)",
|
|
13
|
+
externalHost: "({host})",
|
|
14
|
+
taskDone: "Done",
|
|
15
|
+
taskOpen: "Not done",
|
|
16
|
+
};
|
|
17
|
+
const INTERNAL_BASE = "https://internal.invalid";
|
|
18
|
+
/** A tab, newline or other control character inside a URL is how `java\tscript:` gets past a naive check. */
|
|
19
|
+
const hasControlChars = (s) => Array.from(s).some((ch) => ch.charCodeAt(0) < 0x20 || ch.charCodeAt(0) === 0x7f);
|
|
20
|
+
/**
|
|
21
|
+
* @internal The default link policy, and the floor under every host policy. The agent's text is untrusted (a customer can write
|
|
22
|
+
* text the agent repeats), so a link is live only for `http(s):` or an internal `/path`; everything else (`mailto:`,
|
|
23
|
+
* `javascript:`, `data:`, `//host`, `/\host`, `#frag`, a bare relative path, a URL with control characters) is blocked and
|
|
24
|
+
* renders as plain text.
|
|
25
|
+
*/
|
|
26
|
+
export function classifyHref(raw) {
|
|
27
|
+
if (typeof raw !== "string")
|
|
28
|
+
return { kind: "blocked" };
|
|
29
|
+
const href = raw.trim();
|
|
30
|
+
if (href === "" || hasControlChars(href))
|
|
31
|
+
return { kind: "blocked" };
|
|
32
|
+
if (href.startsWith("/")) {
|
|
33
|
+
if (href.startsWith("//"))
|
|
34
|
+
return { kind: "blocked" };
|
|
35
|
+
try {
|
|
36
|
+
// A backslash is a slash to the browser: `/\evil.example` would leave the app.
|
|
37
|
+
const u = new URL(href, INTERNAL_BASE);
|
|
38
|
+
return u.origin === INTERNAL_BASE ? { kind: "internal", href } : { kind: "blocked" };
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return { kind: "blocked" };
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
try {
|
|
45
|
+
const u = new URL(href);
|
|
46
|
+
if (u.protocol === "http:" || u.protocol === "https:")
|
|
47
|
+
return { kind: "external", href: u.href };
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
/* not an absolute URL */
|
|
51
|
+
}
|
|
52
|
+
return { kind: "blocked" };
|
|
53
|
+
}
|
|
54
|
+
/** The lib's floor, then the host's policy (which can only block more). Applied at render, to every link form. */
|
|
55
|
+
export function resolveLink(raw, policy) {
|
|
56
|
+
const base = classifyHref(raw);
|
|
57
|
+
if (base.kind === "blocked")
|
|
58
|
+
return base;
|
|
59
|
+
if (policy) {
|
|
60
|
+
// A policy that throws is a policy that did not say yes: the link is plain text, the render goes on.
|
|
61
|
+
try {
|
|
62
|
+
if (policy(base.href) === "blocked")
|
|
63
|
+
return { kind: "blocked" };
|
|
64
|
+
}
|
|
65
|
+
catch {
|
|
66
|
+
return { kind: "blocked" };
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
return base;
|
|
70
|
+
}
|
|
71
|
+
const MarkdownContext = createContext({ c: DEFAULT_COPY });
|
|
72
|
+
const REMARK_PLUGINS = [remarkGfm];
|
|
73
|
+
/** Props react-markdown passes that are not DOM attributes. */
|
|
74
|
+
function dom(props) {
|
|
75
|
+
return Object.fromEntries(Object.entries(props).filter(([k]) => k !== "node"));
|
|
76
|
+
}
|
|
77
|
+
const textOf = (node) => {
|
|
78
|
+
if (typeof node === "string" || typeof node === "number")
|
|
79
|
+
return String(node);
|
|
80
|
+
if (Array.isArray(node))
|
|
81
|
+
return node.map(textOf).join("");
|
|
82
|
+
if (isValidElement(node))
|
|
83
|
+
return textOf(node.props.children);
|
|
84
|
+
return "";
|
|
85
|
+
};
|
|
86
|
+
/** Whether a link's content holds an image. An image is never loaded, so its alt text is the only thing the link can show. */
|
|
87
|
+
const hasImage = (node) => {
|
|
88
|
+
if (Array.isArray(node))
|
|
89
|
+
return node.some(hasImage);
|
|
90
|
+
if (!isValidElement(node))
|
|
91
|
+
return false;
|
|
92
|
+
return node.type === MarkdownImage || hasImage(node.props.children);
|
|
93
|
+
};
|
|
94
|
+
/** Set on a link whose text had bidi controls taken out, so what the lib reads about the text is not only what is left of it. */
|
|
95
|
+
const BIDI_STRIPPED = "dataBidiStripped";
|
|
96
|
+
const ALL_BIDI = /[\u061C\u200E\u200F\u202A-\u202E\u2066-\u2069]/u;
|
|
97
|
+
const BIDI_ESCAPE_CLASS = "mx-px rounded-xs bg-muted-foreground/15 px-0.5 text-[0.85em] text-muted-foreground not-italic";
|
|
98
|
+
/** A text node's bidi controls as visible, named escapes (`<U+202E>`), the rest of the text untouched. */
|
|
99
|
+
function escapeBidi(value) {
|
|
100
|
+
if (!ALL_BIDI.test(value))
|
|
101
|
+
return [{ type: "text", value }];
|
|
102
|
+
const out = [];
|
|
103
|
+
let buffer = "";
|
|
104
|
+
for (const ch of value) {
|
|
105
|
+
if (ALL_BIDI.test(ch)) {
|
|
106
|
+
if (buffer)
|
|
107
|
+
out.push({ type: "text", value: buffer });
|
|
108
|
+
buffer = "";
|
|
109
|
+
const code = `U+${(ch.codePointAt(0) ?? 0).toString(16).toUpperCase().padStart(4, "0")}`;
|
|
110
|
+
out.push({
|
|
111
|
+
type: "element",
|
|
112
|
+
tagName: "span",
|
|
113
|
+
properties: {
|
|
114
|
+
className: BIDI_ESCAPE_CLASS,
|
|
115
|
+
title: `Hidden bidirectional control ${code}`,
|
|
116
|
+
role: "img",
|
|
117
|
+
ariaLabel: `Hidden bidirectional control ${code}`,
|
|
118
|
+
dataBidiEscape: code,
|
|
119
|
+
},
|
|
120
|
+
children: [{ type: "text", value: `\u27E8${code}\u27E9` }],
|
|
121
|
+
});
|
|
122
|
+
}
|
|
123
|
+
else
|
|
124
|
+
buffer += ch;
|
|
125
|
+
}
|
|
126
|
+
if (buffer)
|
|
127
|
+
out.push({ type: "text", value: buffer });
|
|
128
|
+
return out;
|
|
129
|
+
}
|
|
130
|
+
/**
|
|
131
|
+
* Bidirectional controls taken out of the message's text, on the syntax tree, before anything is rendered.
|
|
132
|
+
*
|
|
133
|
+
* - A LINK's text loses every one of them (the marks U+200E, U+200F, U+061C too), at any depth (the text of `**bold**` or `code`
|
|
134
|
+
* inside it), for every link form (live or not), and the link is marked when there was one. `\u202E` in front of
|
|
135
|
+
* "evil.example/moc.lapyap" would draw it as "paypal.com/elpmaxe.live", and left open it would reverse the host written after it
|
|
136
|
+
* as well: the label must read in the order it is spelled.
|
|
137
|
+
* - Every other text node loses the embeddings, overrides and isolates (U+202A to U+202E, U+2066 to U+2069) only: an override in
|
|
138
|
+
* the PROSE before a link would otherwise reorder the link's own pieces (its text and the host written after it) and draw prose
|
|
139
|
+
* where the host label belongs. The marks stay in prose: they cannot reorder a run, and right-to-left text needs them.
|
|
140
|
+
*
|
|
141
|
+
* - FENCED code (`pre`) keeps them, as visible escapes with an accessible name, so the reader sees the hidden control (Trojan
|
|
142
|
+
* Source) instead of reading code that is not what it appears to be. Inline code is prose here.
|
|
143
|
+
* - A link's text also has every run of whitespace and blank-looking glyphs collapsed to one space (see {@link collapseBlankRuns}).
|
|
144
|
+
*
|
|
145
|
+
* A linked image's alt text is cleaned where it is drawn ({@link MarkdownImage}).
|
|
146
|
+
*/
|
|
147
|
+
function rehypeLinkBidi() {
|
|
148
|
+
return (tree) => {
|
|
149
|
+
const walk = (node, link, inPre) => {
|
|
150
|
+
const within = node.type === "element" && node.tagName === "a" ? node : link;
|
|
151
|
+
const pre = inPre || (node.type === "element" && node.tagName === "pre");
|
|
152
|
+
if (node.type === "text" && typeof node.value === "string") {
|
|
153
|
+
if (within) {
|
|
154
|
+
const clean = collapseBlankRuns(stripBidi(node.value));
|
|
155
|
+
if (clean !== node.value) {
|
|
156
|
+
// Anything hidden or blank that was taken out means the words were not what they looked like: the host is shown.
|
|
157
|
+
if (/[^\x20-\x7e]/.test(node.value))
|
|
158
|
+
within.properties = { ...within.properties, [BIDI_STRIPPED]: "true" };
|
|
159
|
+
node.value = clean;
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else if (!pre) {
|
|
163
|
+
node.value = stripBidiRuns(node.value);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (pre && !within && node.children) {
|
|
167
|
+
// Fenced code: a hidden control is SHOWN (Trojan Source), never silently removed.
|
|
168
|
+
node.children = node.children.flatMap((child) => child.type === "text" && typeof child.value === "string"
|
|
169
|
+
? escapeBidi(child.value)
|
|
170
|
+
: [child]);
|
|
171
|
+
}
|
|
172
|
+
for (const child of node.children ?? [])
|
|
173
|
+
walk(child, within, pre);
|
|
174
|
+
};
|
|
175
|
+
walk(tree, undefined, false);
|
|
176
|
+
};
|
|
177
|
+
}
|
|
178
|
+
const REHYPE_PLUGINS = [rehypeLinkBidi];
|
|
179
|
+
const PRINTABLE_ASCII = /^[\x20-\x7e]*$/;
|
|
180
|
+
/**
|
|
181
|
+
* Whether a link's own text already tells the reader where it goes: it IS the link's host (or an address on it: the host
|
|
182
|
+
* followed by a path, port, query or fragment), `www.` and a scheme ignored. Anything else, a look-alike, a substring of the
|
|
183
|
+
* host, an address on ANOTHER host, empty text, or an image, does not, so the real host is written out beside it.
|
|
184
|
+
*
|
|
185
|
+
* Text that starts with the host can still mean another one: in `evil.example:@paypal.com` or `evil.example:443@paypal.com/x`
|
|
186
|
+
* the leading `host:` is a username and the address is on `paypal.com`. So text with an `@` never states a host, and the text
|
|
187
|
+
* must also parse as an address whose host is the link's (no credentials, no other host after the prefix).
|
|
188
|
+
*
|
|
189
|
+
* Text states a host only if it is PRINTABLE ASCII, whatever else it says. Anything else can be drawn in another order than it
|
|
190
|
+
* is spelled (a bidi control, or simply a right-to-left letter: an IPv4 host has no strong direction, so `1.2.3.4/<aleph>5.6.7.8`
|
|
191
|
+
* linking to `https://1.2.3.4/` is drawn "5.6.7.8<aleph>/1.2.3.4", the wrong address first and no label), and a zero-width
|
|
192
|
+
* character can make it differ from what it looks like. An IDN host is written as punycode (ASCII) here, so a text that really
|
|
193
|
+
* is the host is ASCII too.
|
|
194
|
+
*/
|
|
195
|
+
function textStatesHost(text, hostname) {
|
|
196
|
+
if (!PRINTABLE_ASCII.test(text.trim()))
|
|
197
|
+
return false;
|
|
198
|
+
const host = hostname.toLowerCase().replace(/^www\./, "");
|
|
199
|
+
const t = text
|
|
200
|
+
.trim()
|
|
201
|
+
.toLowerCase()
|
|
202
|
+
.replace(/^https?:\/\//, "")
|
|
203
|
+
.replace(/^www\./, "");
|
|
204
|
+
if (t === "" || t.includes("@"))
|
|
205
|
+
return false;
|
|
206
|
+
if (t !== host && !["/", ":", "?", "#"].some((sep) => t.startsWith(host + sep)))
|
|
207
|
+
return false;
|
|
208
|
+
// The prefix matched as written (so a non-ASCII look-alike of an xn-- host still does not): now read it as a browser would.
|
|
209
|
+
try {
|
|
210
|
+
return new URL(`https://${t}`).hostname.replace(/^www\./, "") === host;
|
|
211
|
+
}
|
|
212
|
+
catch {
|
|
213
|
+
return false;
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
const inlineCode = "rounded-md bg-muted px-1 py-0.5 font-mono text-xs break-words text-foreground";
|
|
217
|
+
/** Every heading is an `h3` to assistive tech (the panel's own title is the `h2`, so a message can never skip a level); size carries the visual level. */
|
|
218
|
+
const heading = {
|
|
219
|
+
1: "mt-1 text-base/6 font-semibold text-foreground",
|
|
220
|
+
2: "mt-1 text-sm/6 font-semibold text-foreground",
|
|
221
|
+
3: "mt-1 text-sm/6 font-medium text-foreground",
|
|
222
|
+
4: "mt-1 text-sm/6 font-medium text-muted-foreground",
|
|
223
|
+
};
|
|
224
|
+
/** Inline, so the isolate does not depend on a consumer's Tailwind scan finding the class below. */
|
|
225
|
+
const ISOLATE = { unicodeBidi: "isolate" };
|
|
226
|
+
const linkClass = cn(
|
|
227
|
+
// An isolate: whatever is drawn before the link in the paragraph cannot reorder its pieces (the text and the host label).
|
|
228
|
+
"[unicode-bidi:isolate] rounded-sm font-medium text-foreground underline decoration-muted-foreground decoration-1 underline-offset-4 wrap-anywhere transition-colors duration-[var(--duration-micro)] hover:decoration-foreground motion-reduce:transition-none", focusRing);
|
|
229
|
+
/**
|
|
230
|
+
* The destination written after a link's text. The host is the one part of the label the lib wrote itself, and it is what a
|
|
231
|
+
* reader checks: it sits in its own left-to-right isolate (`<bdi dir="ltr">`), so whatever the link's text does (an unclosed
|
|
232
|
+
* override, a right-to-left run) cannot reorder or reverse it, nor it the text. The words of the copy around `{host}` follow the
|
|
233
|
+
* host's own language.
|
|
234
|
+
*/
|
|
235
|
+
function HostLabel({ template, host }) {
|
|
236
|
+
// Every `{host}` is the destination (a copy may name it twice); a copy without one would hide it, so it is written after.
|
|
237
|
+
const parts = template.split("{host}");
|
|
238
|
+
const pieces = parts.length === 1 ? [`${template} `, ""] : parts;
|
|
239
|
+
return (_jsxs(_Fragment, { children: [" ", _jsx("bdi", { className: "text-muted-foreground whitespace-nowrap", children: pieces.map((piece, i) => (
|
|
240
|
+
// The pieces are the copy's fixed text around the destination: their order never changes.
|
|
241
|
+
// eslint-disable-next-line @eslint-react/no-array-index-key
|
|
242
|
+
_jsxs(Fragment, { children: [i > 0 && _jsx("bdi", { dir: "ltr", children: host }), piece] }, i))) })] }));
|
|
243
|
+
}
|
|
244
|
+
/** Links read the host's policy and copy from context, so they are ONE component type for the life of the page. */
|
|
245
|
+
function MarkdownLink(props) {
|
|
246
|
+
const { href, children } = props;
|
|
247
|
+
const { c, onNavigate, policy } = useContext(MarkdownContext);
|
|
248
|
+
// Footnote back-links point at an anchor that does not exist here.
|
|
249
|
+
if ("data-footnote-backref" in props)
|
|
250
|
+
return null;
|
|
251
|
+
const link = resolveLink(href, policy);
|
|
252
|
+
if (link.kind === "blocked")
|
|
253
|
+
return _jsx("span", { children: children });
|
|
254
|
+
if (link.kind === "internal") {
|
|
255
|
+
const onClick = onNavigate
|
|
256
|
+
? (e) => {
|
|
257
|
+
if (e.defaultPrevented || e.button !== 0)
|
|
258
|
+
return;
|
|
259
|
+
if (e.metaKey || e.ctrlKey || e.shiftKey || e.altKey)
|
|
260
|
+
return;
|
|
261
|
+
e.preventDefault();
|
|
262
|
+
onNavigate(link.href);
|
|
263
|
+
}
|
|
264
|
+
: undefined;
|
|
265
|
+
return (_jsx("a", { href: link.href, onClick: onClick, className: linkClass, style: ISOLATE, children: children }));
|
|
266
|
+
}
|
|
267
|
+
// External: the destination is visible unless the link's own text already says it, so "Docs" cannot hide where it goes.
|
|
268
|
+
const url = new URL(link.href);
|
|
269
|
+
const host = url.host.replace(/^www\./, "");
|
|
270
|
+
// Text that had a bidi control (taken out before it got here) never states the host, any more than text that still has a hidden one.
|
|
271
|
+
const showHost = hasImage(children) ||
|
|
272
|
+
"data-bidi-stripped" in props ||
|
|
273
|
+
!textStatesHost(textOf(children), url.hostname);
|
|
274
|
+
return (_jsxs("a", { href: link.href, target: "_blank", rel: "noopener noreferrer", title: link.href, className: linkClass, style: ISOLATE, children: [_jsx("bdi", { className: showHost ? "inline-block max-w-full overflow-hidden align-top" : undefined, style: showHost ? { maxHeight: "2lh" } : undefined, children: children }), showHost && _jsx(HostLabel, { template: c.externalHost, host: host }), _jsx(ExternalLink, { "aria-hidden": true, className: "mx-0.5 inline-block size-3 align-[-0.125em] text-muted-foreground" }), _jsxs("span", { className: "sr-only", children: [" ", c.opensInNewTab] })] }));
|
|
275
|
+
}
|
|
276
|
+
/** Never loads the image: its alt text is shown instead. A named function (not inline) so a link can tell it holds one. */
|
|
277
|
+
function MarkdownImage({ alt }) {
|
|
278
|
+
return alt ? _jsx("span", { className: "text-muted-foreground", children: stripBidi(alt) }) : null;
|
|
279
|
+
}
|
|
280
|
+
function MarkdownCheckbox(props) {
|
|
281
|
+
const { c } = useContext(MarkdownContext);
|
|
282
|
+
if (props.type !== "checkbox")
|
|
283
|
+
return null;
|
|
284
|
+
return (_jsx("input", { type: "checkbox", checked: Boolean(props.checked), readOnly: true, disabled: true, "aria-label": props.checked ? c.taskDone : c.taskOpen, className: "mr-1.5 size-3.5 translate-y-0.5 accent-primary" }));
|
|
285
|
+
}
|
|
286
|
+
/**
|
|
287
|
+
* One object for the life of the module. react-markdown treats a new component TYPE as a new element and remounts every node it
|
|
288
|
+
* renders, so these never close over props: what changes (copy, `onNavigate`, the link policy) arrives by context.
|
|
289
|
+
*/
|
|
290
|
+
const COMPONENTS = {
|
|
291
|
+
h1: (p) => _jsx("h3", { ...dom(p), className: heading[1] }),
|
|
292
|
+
h2: (p) => (p.id === "footnote-label" ? null : _jsx("h3", { ...dom(p), className: heading[2] })),
|
|
293
|
+
h3: (p) => _jsx("h3", { ...dom(p), className: heading[3] }),
|
|
294
|
+
h4: (p) => _jsx("h3", { ...dom(p), className: heading[4] }),
|
|
295
|
+
h5: (p) => _jsx("h3", { ...dom(p), className: heading[4] }),
|
|
296
|
+
h6: (p) => _jsx("h3", { ...dom(p), className: heading[4] }),
|
|
297
|
+
p: (p) => _jsx("p", { ...dom(p), className: "text-sm/6 break-words text-foreground" }),
|
|
298
|
+
strong: (p) => _jsx("strong", { ...dom(p), className: "font-semibold" }),
|
|
299
|
+
em: (p) => _jsx("em", { ...dom(p), className: "italic" }),
|
|
300
|
+
del: (p) => _jsx("del", { ...dom(p), className: "text-muted-foreground line-through" }),
|
|
301
|
+
ul: (p) => (_jsx("ul", { ...dom(p), className: "ml-5 list-disc text-sm/6 text-foreground marker:text-muted-foreground [&>li+li]:mt-1 [&_ol]:mt-1 [&_ul]:mt-1" })),
|
|
302
|
+
ol: (p) => (_jsx("ol", { ...dom(p), className: "ml-5 list-decimal text-sm/6 text-foreground marker:text-muted-foreground [&>li+li]:mt-1 [&_ol]:mt-1 [&_ul]:mt-1" })),
|
|
303
|
+
li: (p) => _jsx("li", { ...dom(p), className: "pl-0.5 break-words" }),
|
|
304
|
+
input: (p) => _jsx(MarkdownCheckbox, { ...dom(p) }),
|
|
305
|
+
blockquote: (p) => (_jsx("blockquote", { ...dom(p), className: "flex flex-col gap-2 rounded-lg bg-muted/60 px-3 py-2 text-muted-foreground [&_p]:text-muted-foreground" })),
|
|
306
|
+
hr: () => _jsx("hr", { className: "my-1 border-t border-border/60" }),
|
|
307
|
+
code: (p) => _jsx("code", { ...dom(p), className: inlineCode }),
|
|
308
|
+
pre: (p) => (_jsx("pre", { ...dom(p), tabIndex: 0, className: cn("overflow-x-auto rounded-xl bg-muted p-3 font-mono text-xs/5 text-foreground", "[&>code]:bg-transparent [&>code]:p-0 [&>code]:break-normal", focusRing) })),
|
|
309
|
+
table: (p) => (_jsx("div", { tabIndex: 0, className: cn("overflow-x-auto rounded-xl ring-1 ring-border/60", focusRing), children: _jsx("table", { ...dom(p), className: "w-full min-w-max border-collapse text-xs/5" }) })),
|
|
310
|
+
thead: (p) => _jsx("thead", { ...dom(p), className: "bg-muted/60" }),
|
|
311
|
+
th: (p) => (_jsx("th", { ...dom(p), className: "px-3 py-2 text-left font-medium whitespace-nowrap text-muted-foreground" })),
|
|
312
|
+
td: (p) => (_jsx("td", { ...dom(p), className: "border-t border-border/60 px-3 py-2 align-top text-foreground" })),
|
|
313
|
+
// An image would be fetched by the browser: never load one the model (or a customer) named.
|
|
314
|
+
img: MarkdownImage,
|
|
315
|
+
a: (p) => _jsx(MarkdownLink, { ...dom(p) }),
|
|
316
|
+
};
|
|
317
|
+
/**
|
|
318
|
+
* @internal The assistant's text as markdown. No raw HTML (it is skipped, never rendered), images are never loaded (an image
|
|
319
|
+
* URL is a tracking and data-egress channel; the alt text shows instead), footnotes are plain text, links are limited by
|
|
320
|
+
* `linkPolicy` over the `classifyHref` floor, and an external link opens in a new tab with `rel="noopener noreferrer"`, an icon,
|
|
321
|
+
* and its host written out when the link text does not already say it.
|
|
322
|
+
*
|
|
323
|
+
* Partial markdown (an unclosed `**` or a code fence while streaming) is rendered as it is: an unclosed fence is a code block
|
|
324
|
+
* until it closes, an unclosed `**` shows its asterisks until the closing pair arrives.
|
|
325
|
+
*
|
|
326
|
+
* The rendered elements are stable across prop changes: a new `copy`, `onNavigate` or `linkPolicy` re-renders them in place
|
|
327
|
+
* and does not remount them, so a focused link keeps focus and a running animation is not restarted.
|
|
328
|
+
*/
|
|
329
|
+
export const AgentMarkdown = memo(function AgentMarkdown({ text, streaming, onNavigate, linkPolicy, copy, className, }) {
|
|
330
|
+
const c = useCopy(DEFAULT_COPY, copy);
|
|
331
|
+
const ctx = useMemo(() => ({ c, onNavigate, policy: linkPolicy }), [c, onNavigate, linkPolicy]);
|
|
332
|
+
return (_jsx(MarkdownContext.Provider, { value: ctx, children: _jsx("div", { "data-streaming": streaming ? "true" : undefined, className: cn("agent-md flex min-w-0 flex-col gap-2.5", className), children: _jsx(ReactMarkdown, { remarkPlugins: REMARK_PLUGINS, rehypePlugins: REHYPE_PLUGINS, skipHtml: true, components: COMPONENTS,
|
|
333
|
+
// GFM footnotes become a `section` and `sup` we do not want; their text stays, as plain text.
|
|
334
|
+
disallowedElements: ["section", "sup"], unwrapDisallowed: true,
|
|
335
|
+
// Defence in depth: a blocked URL never reaches a component as an href.
|
|
336
|
+
urlTransform: (url) => (resolveLink(url, linkPolicy).kind === "blocked" ? "" : url), children: text }) }) }));
|
|
337
|
+
});
|
|
338
|
+
//# sourceMappingURL=markdown.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"markdown.js","sourceRoot":"","sources":["../../src/agent/markdown.tsx"],"names":[],"mappings":"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"}
|
|
@@ -3,6 +3,7 @@ export interface MaskedValueCopy {
|
|
|
3
3
|
ariaLabel: string;
|
|
4
4
|
tooltip: string;
|
|
5
5
|
}
|
|
6
|
+
export declare const DEFAULT_COPY: MaskedValueCopy;
|
|
6
7
|
export interface MaskedValueProps {
|
|
7
8
|
/** `{ masked: true, display }` from the BFF. Raw text is never treated as a mask. */
|
|
8
9
|
value: CellValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masked-value.d.ts","sourceRoot":"","sources":["../../src/agent/masked-value.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;
|
|
1
|
+
{"version":3,"file":"masked-value.d.ts","sourceRoot":"","sources":["../../src/agent/masked-value.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAY,KAAK,SAAS,EAAE,MAAM,UAAU,CAAC;AAEpD,MAAM,WAAW,eAAe;IAC9B,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,eAAO,MAAM,YAAY,EAAE,eAG1B,CAAC;AAEF,MAAM,WAAW,gBAAgB;IAC/B,qFAAqF;IACrF,KAAK,EAAE,SAAS,CAAC;IACjB,IAAI,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IAChC,iEAAiE;IACjE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,wBAAgB,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,EAAE,gBAAgB,2CA4B9E"}
|
|
@@ -3,7 +3,10 @@ import { EyeOff } from "lucide-react";
|
|
|
3
3
|
import { cn } from "../lib/utils.js";
|
|
4
4
|
import { useCopy } from "./copy.js";
|
|
5
5
|
import { isMasked } from "./schema.js";
|
|
6
|
-
const DEFAULT_COPY = {
|
|
6
|
+
export const DEFAULT_COPY = {
|
|
7
|
+
ariaLabel: "masked value",
|
|
8
|
+
tooltip: "Hidden for privacy",
|
|
9
|
+
};
|
|
7
10
|
/**
|
|
8
11
|
* @internal Renders a BFF-masked value so an admin can never mistake a mask for
|
|
9
12
|
* data: dashed outline, mask icon, accessible name and a title tooltip. A plain
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"masked-value.js","sourceRoot":"","sources":["../../src/agent/masked-value.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAkB,MAAM,UAAU,CAAC;AAMpD,MAAM,YAAY,GAAoB,
|
|
1
|
+
{"version":3,"file":"masked-value.js","sourceRoot":"","sources":["../../src/agent/masked-value.tsx"],"names":[],"mappings":";AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,EAAE,EAAE,MAAM,cAAc,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,MAAM,QAAQ,CAAC;AACjC,OAAO,EAAE,QAAQ,EAAkB,MAAM,UAAU,CAAC;AAMpD,MAAM,CAAC,MAAM,YAAY,GAAoB;IAC3C,SAAS,EAAE,cAAc;IACzB,OAAO,EAAE,oBAAoB;CAC9B,CAAC;AAWF;;;;GAIG;AACH,MAAM,UAAU,WAAW,CAAC,EAAE,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAoB;IAC7E,MAAM,CAAC,GAAG,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC;IACtC,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;QACrB,OAAO,CACL,eAAM,SAAS,EAAE,SAAS,YACvB,KAAK,KAAK,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC,CAAC,CAAC,CAChC,YAAG,SAAS,EAAC,uBAAuB,YAAE,KAAK,IAAI,GAAG,GAAK,CACxD,CAAC,CAAC,CAAC,CACF,MAAM,CAAC,KAAK,CAAC,CACd,GACI,CACR,CAAC;IACJ,CAAC;IACD,OAAO,CACL,gBACE,IAAI,EAAC,KAAK,gBACE,GAAG,CAAC,CAAC,SAAS,KAAK,KAAK,CAAC,OAAO,EAAE,EAC9C,KAAK,EAAE,CAAC,CAAC,OAAO,iBACJ,MAAM,EAClB,SAAS,EAAE,EAAE,CACX,+IAA+I,EAC/I,SAAS,CACV,aAED,KAAC,MAAM,yBAAa,SAAS,EAAC,iBAAiB,GAAG,EAClD,8CAAmB,KAAK,CAAC,OAAO,GAAQ,IACnC,CACR,CAAC;AACJ,CAAC"}
|
package/dist/agent/message.d.ts
CHANGED
|
@@ -1,4 +1,7 @@
|
|
|
1
|
-
import type
|
|
1
|
+
import { type ReactNode } from "react";
|
|
2
|
+
import { type AgentLinkPolicy, type AgentMarkdownCopy } from "./markdown.js";
|
|
3
|
+
import { type AgentToolActivityCopy } from "./tool-activity.js";
|
|
4
|
+
import { type AgentToolNaming, type CardCoversCall } from "./tool-activity-model.js";
|
|
2
5
|
import type { AgentApproval, AgentMessageData } from "./schema.js";
|
|
3
6
|
export interface AgentMessageCopy {
|
|
4
7
|
userLabel: string;
|
|
@@ -8,25 +11,42 @@ export interface AgentMessageCopy {
|
|
|
8
11
|
retry: string;
|
|
9
12
|
copy: string;
|
|
10
13
|
copied: string;
|
|
14
|
+
/** @deprecated A thought is a step in the activity trail now: its wording is `activityCopy.thought`. Unused. */
|
|
11
15
|
thinking: string;
|
|
12
16
|
}
|
|
13
|
-
export interface AgentMessageProps {
|
|
17
|
+
export interface AgentMessageProps extends AgentToolNaming {
|
|
14
18
|
message: AgentMessageData;
|
|
15
19
|
/** Effective status per approval (the conversation supersedes stale pending ones). */
|
|
16
20
|
approvalStatus?: ReadonlyMap<string, AgentApproval["status"]>;
|
|
17
21
|
onApproval?: (approvalId: string, decision: "approve" | "reject", typed?: string, attestations?: Record<string, boolean>) => void;
|
|
18
22
|
onRetry?: (messageId: string) => void;
|
|
19
23
|
onRetryTool?: (callId: string) => void;
|
|
20
|
-
/** Renders `card` parts (host-owned domain cards). */
|
|
24
|
+
/** Renders `card` parts (host-owned domain cards). A card that renders nothing leaves no gap. */
|
|
21
25
|
renderCard?: (cardType: string, data: unknown) => ReactNode;
|
|
26
|
+
/**
|
|
27
|
+
* Whether a domain card shows a tool call's data, so its step is marked "shown below". There is no default: a step is
|
|
28
|
+
* marked only when a card part names its call (`forCallId`) or this says so, and only for a card that rendered something.
|
|
29
|
+
*/
|
|
30
|
+
cardCoversCall?: CardCoversCall;
|
|
31
|
+
/** A click on an internal `/path` link in the assistant's text (the router's navigate); without it links are plain anchors. */
|
|
32
|
+
onNavigate?: (path: string) => void;
|
|
33
|
+
/** Which links in the assistant's text are live. Default: `http(s)` URLs and internal `/paths`; see `AgentLinkPolicy`. */
|
|
34
|
+
linkPolicy?: AgentLinkPolicy;
|
|
35
|
+
/** BCP 47 tag for the numbers in the activity trail ("Took 0,6s"). Default: plain "0.6". A malformed tag falls back to it. */
|
|
36
|
+
locale?: string;
|
|
37
|
+
activityCopy?: Partial<AgentToolActivityCopy>;
|
|
38
|
+
markdownCopy?: Partial<AgentMarkdownCopy>;
|
|
39
|
+
/** The message arrived while the conversation was open: it fades and slides in once. Parts added later fade in on their own. */
|
|
40
|
+
entering?: boolean;
|
|
22
41
|
/** Clock override (ms since epoch) for approval expiry; stories and tests pin it. */
|
|
23
42
|
nowMs?: number;
|
|
24
43
|
copy?: Partial<AgentMessageCopy>;
|
|
25
44
|
className?: string;
|
|
26
45
|
}
|
|
27
46
|
/**
|
|
28
|
-
* @internal One message. Assistant messages are append-only (text keeps a stable
|
|
29
|
-
*
|
|
47
|
+
* @internal One message. Assistant messages are append-only (text keeps a stable DOM so assistive tech does not
|
|
48
|
+
* re-read) and render as markdown; user messages are plain text in a right-aligned bubble. A run of tool calls is one
|
|
49
|
+
* activity row, never a card per call; approvals and domain cards stay in place, prominent.
|
|
30
50
|
*/
|
|
31
|
-
export declare function AgentMessage({ message, approvalStatus, onApproval, onRetry, onRetryTool, renderCard, nowMs, copy, className, }: AgentMessageProps): import("react/jsx-runtime").JSX.Element;
|
|
51
|
+
export declare function AgentMessage({ message, approvalStatus, onApproval, onRetry, onRetryTool, renderCard, toolLabels, formatToolLabel, cardLabels, toolWording, cardCoversCall, onNavigate, linkPolicy, locale, activityCopy, markdownCopy, entering, nowMs, copy, className, }: AgentMessageProps): import("react/jsx-runtime").JSX.Element;
|
|
32
52
|
//# sourceMappingURL=message.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/agent/message.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,
|
|
1
|
+
{"version":3,"file":"message.d.ts","sourceRoot":"","sources":["../../src/agent/message.tsx"],"names":[],"mappings":"AAAA,OAAO,EAAqB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM1D,OAAO,EAAiB,KAAK,eAAe,EAAE,KAAK,iBAAiB,EAAE,MAAM,YAAY,CAAC;AACzF,OAAO,EAAqB,KAAK,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAChF,OAAO,EAAoB,KAAK,eAAe,EAAE,KAAK,cAAc,EAAE,MAAM,uBAAuB,CAAC;AACpG,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,UAAU,CAAC;AAGhE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,gHAAgH;IAChH,QAAQ,EAAE,MAAM,CAAC;CAClB;AAYD,MAAM,WAAW,iBAAkB,SAAQ,eAAe;IACxD,OAAO,EAAE,gBAAgB,CAAC;IAC1B,sFAAsF;IACtF,cAAc,CAAC,EAAE,WAAW,CAAC,MAAM,EAAE,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC9D,UAAU,CAAC,EAAE,CACX,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,SAAS,GAAG,QAAQ,EAC9B,KAAK,CAAC,EAAE,MAAM,EACd,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,KACnC,IAAI,CAAC;IACV,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,WAAW,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACvC,iGAAiG;IACjG,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,OAAO,KAAK,SAAS,CAAC;IAC5D;;;OAGG;IACH,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,+HAA+H;IAC/H,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,0HAA0H;IAC1H,UAAU,CAAC,EAAE,eAAe,CAAC;IAC7B,8HAA8H;IAC9H,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,YAAY,CAAC,EAAE,OAAO,CAAC,qBAAqB,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC1C,gIAAgI;IAChI,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,qFAAqF;IACrF,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACjC,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAID;;;;GAIG;AACH,wBAAgB,YAAY,CAAC,EAC3B,OAAO,EACP,cAAc,EACd,UAAU,EACV,OAAO,EACP,WAAW,EACX,UAAU,EACV,UAAU,EACV,eAAe,EACf,UAAU,EACV,WAAW,EACX,cAAc,EACd,UAAU,EACV,UAAU,EACV,MAAM,EACN,YAAY,EACZ,YAAY,EACZ,QAAQ,EACR,KAAK,EACL,IAAI,EACJ,SAAS,GACV,EAAE,iBAAiB,2CAiInB"}
|