agent-relay-server 0.65.2 → 0.67.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/docs/openapi.json +1 -1
- package/package.json +2 -2
- package/public/assets/MessageBubble-CG_eCKDI.js +3 -0
- package/public/assets/MessageBubble-CG_eCKDI.js.map +1 -0
- package/public/assets/{PlanGraphPanel-DrHNFbg6.js → PlanGraphPanel-Ba9qh-if.js} +2 -2
- package/public/assets/{PlanGraphPanel-DrHNFbg6.js.map → PlanGraphPanel-Ba9qh-if.js.map} +1 -1
- package/public/assets/{activity-CECdsDpd.js → activity-8eZ4FhxO.js} +2 -2
- package/public/assets/{activity-CECdsDpd.js.map → activity-8eZ4FhxO.js.map} +1 -1
- package/public/assets/{agent-profiles-CHitqihm.js → agent-profiles-1Nx8ROA_.js} +2 -2
- package/public/assets/{agent-profiles-CHitqihm.js.map → agent-profiles-1Nx8ROA_.js.map} +1 -1
- package/public/assets/{agents-GG-aJj6Z.js → agents-C8fM2VwM.js} +2 -2
- package/public/assets/{agents-GG-aJj6Z.js.map → agents-C8fM2VwM.js.map} +1 -1
- package/public/assets/{analytics-y0Yf26cD.js → analytics-D6ffu1ji.js} +2 -2
- package/public/assets/{analytics-y0Yf26cD.js.map → analytics-D6ffu1ji.js.map} +1 -1
- package/public/assets/{automation-CmzftGBn.js → automation-BVmzNi6H.js} +2 -2
- package/public/assets/{automation-CmzftGBn.js.map → automation-BVmzNi6H.js.map} +1 -1
- package/public/assets/{branch-state-badge-Biam17QK.js → branch-state-badge-DrwCnoKR.js} +2 -2
- package/public/assets/{branch-state-badge-Biam17QK.js.map → branch-state-badge-DrwCnoKR.js.map} +1 -1
- package/public/assets/{channels-CmAXppQu.js → channels-BuqbbyaO.js} +2 -2
- package/public/assets/{channels-CmAXppQu.js.map → channels-BuqbbyaO.js.map} +1 -1
- package/public/assets/chat-DCnEGe-x.js +2 -0
- package/public/assets/chat-DCnEGe-x.js.map +1 -0
- package/public/assets/{connectors-bZ0YsSqg.js → connectors-_LpoKQNb.js} +2 -2
- package/public/assets/{connectors-bZ0YsSqg.js.map → connectors-_LpoKQNb.js.map} +1 -1
- package/public/assets/formatted-body-impl-C7ftpr0y.js +3 -0
- package/public/assets/formatted-body-impl-C7ftpr0y.js.map +1 -0
- package/public/assets/index-eCpWfoCA.css +2 -0
- package/public/assets/{index-BSWui_-2.js → index-ksV0Snw6.js} +10 -10
- package/public/assets/index-ksV0Snw6.js.map +1 -0
- package/public/assets/{insights-cC2lVGUs.js → insights-BjRehGVP.js} +2 -2
- package/public/assets/{insights-cC2lVGUs.js.map → insights-BjRehGVP.js.map} +1 -1
- package/public/assets/{integrations--k7_eYP2.js → integrations-DCyxAv8c.js} +2 -2
- package/public/assets/{integrations--k7_eYP2.js.map → integrations-DCyxAv8c.js.map} +1 -1
- package/public/assets/{maintenance-B6wOij_l.js → maintenance-CKiNcUMS.js} +2 -2
- package/public/assets/{maintenance-B6wOij_l.js.map → maintenance-CKiNcUMS.js.map} +1 -1
- package/public/assets/{managed-agents-CDzLSKp1.js → managed-agents-Os_T-7w7.js} +2 -2
- package/public/assets/{managed-agents-CDzLSKp1.js.map → managed-agents-Os_T-7w7.js.map} +1 -1
- package/public/assets/{markdown-preview-impl-D3Y4uUgk.js → markdown-preview-impl-grkpBldu.js} +2 -2
- package/public/assets/{markdown-preview-impl-D3Y4uUgk.js.map → markdown-preview-impl-grkpBldu.js.map} +1 -1
- package/public/assets/{memory-DYzw5EXn.js → memory-YiYlqWUZ.js} +2 -2
- package/public/assets/{memory-DYzw5EXn.js.map → memory-YiYlqWUZ.js.map} +1 -1
- package/public/assets/{messages-ATbJw7jy.js → messages-CVDtrrub.js} +2 -2
- package/public/assets/messages-CVDtrrub.js.map +1 -0
- package/public/assets/orchestrators-Dzup-DDB.js +2 -0
- package/public/assets/{orchestrators-Dtr4zNWI.js.map → orchestrators-Dzup-DDB.js.map} +1 -1
- package/public/assets/{overview-B071A7FM.js → overview-DZltfAFn.js} +2 -2
- package/public/assets/{overview-B071A7FM.js.map → overview-DZltfAFn.js.map} +1 -1
- package/public/assets/{pairs-DgiNK9mA.js → pairs-Q2CmriBh.js} +2 -2
- package/public/assets/{pairs-DgiNK9mA.js.map → pairs-Q2CmriBh.js.map} +1 -1
- package/public/assets/{projects-DhQUdwcb.js → projects-DtJmrhI0.js} +2 -2
- package/public/assets/projects-DtJmrhI0.js.map +1 -0
- package/public/assets/{security-COHkbWIm.js → security-Bur19Sp4.js} +2 -2
- package/public/assets/{security-COHkbWIm.js.map → security-Bur19Sp4.js.map} +1 -1
- package/public/assets/{select-CKPIes_u.js → select-CuzWJuBz.js} +2 -2
- package/public/assets/{select-CKPIes_u.js.map → select-CuzWJuBz.js.map} +1 -1
- package/public/assets/settings-CEMCJ31_.js +4 -0
- package/public/assets/settings-CEMCJ31_.js.map +1 -0
- package/public/assets/store-BeKcuJ2q.js +9 -0
- package/public/assets/store-BeKcuJ2q.js.map +1 -0
- package/public/assets/{tasks-DdVsKCUN.js → tasks-DjwAusKz.js} +2 -2
- package/public/assets/{tasks-DdVsKCUN.js.map → tasks-DjwAusKz.js.map} +1 -1
- package/public/assets/{teams-BLQeR-qJ.js → teams-CFCnB12u.js} +2 -2
- package/public/assets/{teams-BLQeR-qJ.js.map → teams-CFCnB12u.js.map} +1 -1
- package/public/assets/{terminal-viewer-impl-eFq9PBWV.js → terminal-viewer-impl-CWu5RTp2.js} +2 -2
- package/public/assets/{terminal-viewer-impl-eFq9PBWV.js.map → terminal-viewer-impl-CWu5RTp2.js.map} +1 -1
- package/public/assets/{work-queue-OFw-Hwir.js → work-queue-TZQ5Gz0t.js} +2 -2
- package/public/assets/{work-queue-OFw-Hwir.js.map → work-queue-TZQ5Gz0t.js.map} +1 -1
- package/public/assets/{workspaces-zum4lO_O.js → workspaces-Bu4uVUcu.js} +2 -2
- package/public/assets/{workspaces-zum4lO_O.js.map → workspaces-Bu4uVUcu.js.map} +1 -1
- package/public/index.html +3 -3
- package/src/agent-issue-repo.ts +29 -0
- package/src/branch-landed.ts +69 -2
- package/src/cli/index.ts +6 -4
- package/src/config.ts +1 -0
- package/src/context-advisory.ts +93 -15
- package/src/context-threshold-config.ts +14 -2
- package/src/db/migrations.ts +24 -0
- package/src/db/projects.ts +34 -6
- package/src/db/schema.ts +1 -0
- package/src/mcp/tools-workspace.ts +3 -3
- package/src/mcp-project-tools.ts +2 -0
- package/src/notification-router.ts +2 -0
- package/src/provider-catalog-store.ts +35 -0
- package/src/routes/agents.ts +3 -2
- package/src/routes/commands.ts +6 -1
- package/src/routes/provider-config.ts +27 -0
- package/src/services/git-remote.ts +46 -0
- package/src/services/issue-lifecycle.ts +5 -36
- package/src/services/project.ts +23 -3
- package/src/services/register-agent.ts +7 -1
- package/src/services/spawn-agent.ts +7 -9
- package/src/services/spawn-registration-watchdog.ts +34 -12
- package/src/settings/registry.ts +2 -0
- package/src/sse.ts +9 -4
- package/src/workspace-phase.ts +17 -9
- package/public/assets/MessageBubble-DLF9fJLb.js +0 -2
- package/public/assets/MessageBubble-DLF9fJLb.js.map +0 -1
- package/public/assets/chat-C-FI9bLO.js +0 -2
- package/public/assets/chat-C-FI9bLO.js.map +0 -1
- package/public/assets/formatted-body-impl-D--5zVSd.js +0 -3
- package/public/assets/formatted-body-impl-D--5zVSd.js.map +0 -1
- package/public/assets/index-BSWui_-2.js.map +0 -1
- package/public/assets/index-B_On3Osd.css +0 -2
- package/public/assets/messages-ATbJw7jy.js.map +0 -1
- package/public/assets/orchestrators-Dtr4zNWI.js +0 -2
- package/public/assets/projects-DhQUdwcb.js.map +0 -1
- package/public/assets/settings-B4SN1TpB.js +0 -4
- package/public/assets/settings-B4SN1TpB.js.map +0 -1
- package/public/assets/store-DnHOGovN.js +0 -9
- package/public/assets/store-DnHOGovN.js.map +0 -1
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{r as e}from"./chunk-CilyBKbf.js";import{Bn as t,Qn as n}from"./lucide-react-BbMYCUlW.js";import{t as r}from"./store-DnHOGovN.js";import{F as i}from"./display-LAWaAboe.js";import{O as a}from"./index-BSWui_-2.js";import{i as o,n as s,r as c,t as l}from"./lib-CMqRPJG-.js";var u=e(n(),1),d=t(),f=/((?:[A-Za-z0-9][\w.-]*\/[A-Za-z0-9][\w.-]*)?#\d+)\b|(https?:\/\/[^\s`'")\]]+)|((?:\/[\w.@+-][^\s`'")\]]*|(?:\.{1,2}\/|[\w.@+-]+\/)[^\s`'")\]]*))/g,p=/[.,;:!?]+$/,m=new Set([`src`,`app`,`apps`,`lib`,`server`,`client`,`dashboard`,`orchestrator`,`runner`,`sdk`,`codex`,`claude`,`public`,`docs`,`test`,`tests`,`scripts`,`config`,`configs`]),h={...c,attributes:{...c.attributes,code:[...c.attributes?.code||[],[`className`,/^language-[\w-]+$/]]}};function g(e){if(e===`/api`||e.startsWith(`/api/`))return!1;if(e.startsWith(`/`)||e.startsWith(`./`)||e.startsWith(`../`))return!0;let t=e.split(`/`).filter(Boolean),n=t[0]??``,r=t[t.length-1]??``;return n.startsWith(`.`)||m.has(n)?!0:r.includes(`.`)}function _(e,t){let n=[],r=0;for(let i of e.matchAll(f)){let a=i[1],o=i[2],s=i[3],c=a||o||s,l=i.index??0;if(!c||l<r)continue;if(a){let i=a.lastIndexOf(`#`),o=a.slice(0,i)||t,s=a.slice(i+1);o&&(l>r&&n.push({text:e.slice(r,l)}),n.push({text:a,issueUrl:`https://github.com/${o}/issues/${s}`}),r=l+a.length);continue}if(o){let t=o.replace(p,``),i=o.slice(t.length);l>r&&n.push({text:e.slice(r,l)}),n.push({text:t,url:t}),i&&n.push({text:i}),r=l+o.length;continue}if(!c.includes(`/`))continue;let u=c.replace(p,``),d=c.slice(u.length),f=u.match(/^(.*):(\d+)$/),m=f?Number(f[2]):void 0;f&&(u=f[1]),g(u)&&(l>r&&n.push({text:e.slice(r,l)}),n.push({text:u,path:u,line:Number.isFinite(m)?m:void 0}),d&&n.push({text:d}),r=l+c.length)}return r<e.length&&n.push({text:e.slice(r)}),n}function v({text:e,onOpenPath:t,onPreviewPath:n,onPreviewPathEnd:r,isPathLinkable:i,resolvePathTitle:a,issueRepo:o}){let s=_(e,o);return s.length===1&&!s[0]?.path&&!s[0]?.url&&!s[0]?.issueUrl?(0,d.jsx)(d.Fragment,{children:e}):(0,d.jsx)(d.Fragment,{children:s.map((e,o)=>{if(e.issueUrl)return(0,d.jsx)(`a`,{href:e.issueUrl,target:`_blank`,rel:`noreferrer`,className:`font-medium text-primary/90 underline decoration-dotted underline-offset-2 hover:text-primary`,onClick:e=>e.stopPropagation(),children:e.text},`${e.issueUrl}-${o}`);if(e.url)return(0,d.jsx)(`a`,{href:e.url,target:`_blank`,rel:`noreferrer`,className:`underline decoration-dotted underline-offset-2 hover:text-primary`,onClick:e=>e.stopPropagation(),children:e.text},`${e.url}-${o}`);if(e.path&&t){if(i&&!i(e.path,e.line))return(0,d.jsxs)(`span`,{children:[e.text,e.line?`:${e.line}`:``]},`${e.path}-${o}`);let s=a?.(e.path,e.line);return(0,d.jsxs)(`button`,{type:`button`,className:`rounded-sm font-mono underline decoration-dotted underline-offset-2 hover:text-primary`,onClick:n=>{n.stopPropagation(),t(e.path,e.line)},onMouseEnter:t=>n?.(e.path,e.line,t.currentTarget.getBoundingClientRect()),onFocus:t=>n?.(e.path,e.line,t.currentTarget.getBoundingClientRect()),onMouseLeave:()=>r?.(),onBlur:()=>r?.(),title:s?`Open ${s}`:`Open file`,children:[e.text,e.line?`:${e.line}`:``]},`${e.path}-${o}`)}return(0,d.jsx)(`span`,{children:e.text},o)})})}function y(e,t,n,r,i,a,o){return u.Children.map(e,e=>typeof e==`string`?(0,d.jsx)(v,{text:e,onOpenPath:t,onPreviewPath:n,onPreviewPathEnd:r,isPathLinkable:i,resolvePathTitle:a,issueRepo:o}):e)}function b({text:e,rawBody:t,className:n,onOpenPath:c,onPreviewPath:f,onPreviewPathEnd:p,isPathLinkable:m,resolvePathTitle:g}){let _=(0,u.useMemo)(()=>i(t||``),[t]),v=x(_?_.text:e),b=r(e=>e.stats?.defaultIssueRepo),S=(0,u.useMemo)(()=>({p({children:e}){return(0,d.jsx)(`p`,{children:y(e,c,f,p,m,g,b)})},li({children:e}){return(0,d.jsx)(`li`,{children:y(e,c,f,p,m,g,b)})},a({href:e,children:t}){return(0,d.jsx)(`a`,{href:e,target:`_blank`,rel:`noreferrer`,onClick:e=>e.stopPropagation(),children:t})},code({className:e,children:t}){let n=/language-([\w-]+)/.exec(e||``),r=String(t).replace(/\n$/,``);return n?(0,d.jsx)(a,{content:r,path:`.${n[1]}`,languageHint:n[1],compact:!0}):(0,d.jsx)(`code`,{className:e,children:t})}}),[c,f,p,m,g,b]);return(0,d.jsxs)(`div`,{className:n,children:[(0,d.jsx)(`div`,{className:`chat-markdown`,children:(0,d.jsx)(o,{remarkPlugins:[l],rehypePlugins:[[s,h]],components:S,children:v})}),_&&_.meta.length>0&&(0,d.jsx)(`div`,{className:`mt-1.5 flex flex-wrap gap-1`,children:_.meta.map(([e,t])=>(0,d.jsxs)(`span`,{className:`inline-flex text-[10px] leading-tight bg-muted px-1.5 py-0.5 rounded text-muted-foreground font-mono`,children:[e,`: `,t]},e))})]})}function x(e){return e.includes(`\\n`)?e.replace(/\\n/g,`
|
|
2
|
-
`):e}export{b as FormattedBody};
|
|
3
|
-
//# sourceMappingURL=formatted-body-impl-D--5zVSd.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"formatted-body-impl-D--5zVSd.js","names":[],"sources":["../../dashboard/src/components/shared/formatted-body-impl.tsx"],"sourcesContent":["import React, { useMemo } from 'react'\nimport ReactMarkdown from 'react-markdown'\nimport rehypeSanitize, { defaultSchema } from 'rehype-sanitize'\nimport remarkGfm from 'remark-gfm'\nimport { CodePreview } from './code-preview'\nimport { cn } from '@/lib/utils'\nimport { parseJsonBody } from '@/lib/display'\nimport { useRelayStore } from '@/store'\n\nexport interface FormattedBodyProps {\n text: string\n rawBody?: string\n className?: string\n onOpenPath?: (path: string, line?: number) => void\n onPreviewPath?: (path: string, line?: number, anchor?: DOMRect) => void\n onPreviewPathEnd?: () => void\n isPathLinkable?: (path: string, line?: number) => boolean\n resolvePathTitle?: (path: string, line?: number) => string | undefined\n}\n\n// Order matters: the issue-ref alternative (`#NNN` or `owner/repo#NNN`) is FIRST so the\n// path matcher can't swallow `owner/repo#NNN` as a file path. URLs still win when they\n// start earlier (leftmost-match), so a URL fragment like `…/a#12` is never mis-linkified.\nconst LINK_RE = /((?:[A-Za-z0-9][\\w.-]*\\/[A-Za-z0-9][\\w.-]*)?#\\d+)\\b|(https?:\\/\\/[^\\s`'\")\\]]+)|((?:\\/[\\w.@+-][^\\s`'\")\\]]*|(?:\\.{1,2}\\/|[\\w.@+-]+\\/)[^\\s`'\")\\]]*))/g\nconst TRAILING_PUNCTUATION = /[.,;:!?]+$/\nconst KNOWN_PROJECT_DIRS = new Set(['src', 'app', 'apps', 'lib', 'server', 'client', 'dashboard', 'orchestrator', 'runner', 'sdk', 'codex', 'claude', 'public', 'docs', 'test', 'tests', 'scripts', 'config', 'configs'])\n\nconst markdownSchema = {\n ...defaultSchema,\n attributes: {\n ...defaultSchema.attributes,\n code: [\n ...(defaultSchema.attributes?.code || []),\n ['className', /^language-[\\w-]+$/],\n ],\n },\n}\n\nfunction looksLikeFilePath(path: string): boolean {\n if (path === '/api' || path.startsWith('/api/')) return false\n if (path.startsWith('/')) return true\n if (path.startsWith('./') || path.startsWith('../')) return true\n const segments = path.split('/').filter(Boolean)\n const first = segments[0] ?? ''\n const last = segments[segments.length - 1] ?? ''\n if (first.startsWith('.')) return true\n if (KNOWN_PROJECT_DIRS.has(first)) return true\n return last.includes('.')\n}\n\nexport function linkParts(text: string, issueRepo?: string): Array<{ text: string; path?: string; url?: string; line?: number; issueUrl?: string }> {\n const parts: Array<{ text: string; path?: string; url?: string; line?: number; issueUrl?: string }> = []\n let cursor = 0\n for (const match of text.matchAll(LINK_RE)) {\n const rawIssue = match[1]\n const rawUrl = match[2]\n const rawPath = match[3]\n const raw = rawIssue || rawUrl || rawPath\n const index = match.index ?? 0\n if (!raw || index < cursor) continue\n\n if (rawIssue) {\n // `#NNN` (uses the configured default repo) or `owner/repo#NNN` (explicit repo).\n // With no resolvable repo we leave it as plain text — never emit a broken link.\n const hashIdx = rawIssue.lastIndexOf('#')\n const repo = rawIssue.slice(0, hashIdx) || issueRepo\n const num = rawIssue.slice(hashIdx + 1)\n if (repo) {\n if (index > cursor) parts.push({ text: text.slice(cursor, index) })\n parts.push({ text: rawIssue, issueUrl: `https://github.com/${repo}/issues/${num}` })\n cursor = index + rawIssue.length\n }\n continue\n }\n\n if (rawUrl) {\n const url = rawUrl.replace(TRAILING_PUNCTUATION, '')\n const trimmed = rawUrl.slice(url.length)\n if (index > cursor) parts.push({ text: text.slice(cursor, index) })\n parts.push({ text: url, url })\n if (trimmed) parts.push({ text: trimmed })\n cursor = index + rawUrl.length\n continue\n }\n\n if (!raw.includes('/')) continue\n let path = raw.replace(TRAILING_PUNCTUATION, '')\n const trimmed = raw.slice(path.length)\n const lineMatch = path.match(/^(.*):(\\d+)$/)\n const line = lineMatch ? Number(lineMatch[2]) : undefined\n if (lineMatch) path = lineMatch[1]!\n if (!looksLikeFilePath(path)) continue\n if (index > cursor) parts.push({ text: text.slice(cursor, index) })\n parts.push({ text: path, path, line: Number.isFinite(line) ? line : undefined })\n if (trimmed) parts.push({ text: trimmed })\n cursor = index + raw.length\n }\n if (cursor < text.length) parts.push({ text: text.slice(cursor) })\n return parts\n}\n\nfunction TextWithLinks({\n text,\n onOpenPath,\n onPreviewPath,\n onPreviewPathEnd,\n isPathLinkable,\n resolvePathTitle,\n issueRepo,\n}: {\n text: string\n onOpenPath?: (path: string, line?: number) => void\n onPreviewPath?: (path: string, line?: number, anchor?: DOMRect) => void\n onPreviewPathEnd?: () => void\n isPathLinkable?: (path: string, line?: number) => boolean\n resolvePathTitle?: (path: string, line?: number) => string | undefined\n issueRepo?: string\n}) {\n const parts = linkParts(text, issueRepo)\n if (parts.length === 1 && !parts[0]?.path && !parts[0]?.url && !parts[0]?.issueUrl) return <>{text}</>\n return (\n <>\n {parts.map((part, index) => {\n if (part.issueUrl) {\n return (\n <a\n key={`${part.issueUrl}-${index}`}\n href={part.issueUrl}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"font-medium text-primary/90 underline decoration-dotted underline-offset-2 hover:text-primary\"\n onClick={(e) => e.stopPropagation()}\n >\n {part.text}\n </a>\n )\n }\n if (part.url) {\n return (\n <a\n key={`${part.url}-${index}`}\n href={part.url}\n target=\"_blank\"\n rel=\"noreferrer\"\n className=\"underline decoration-dotted underline-offset-2 hover:text-primary\"\n onClick={(e) => e.stopPropagation()}\n >\n {part.text}\n </a>\n )\n }\n if (part.path && onOpenPath) {\n if (isPathLinkable && !isPathLinkable(part.path, part.line)) return <span key={`${part.path}-${index}`}>{part.text}{part.line ? `:${part.line}` : ''}</span>\n const resolvedTitle = resolvePathTitle?.(part.path, part.line)\n return (\n <button\n key={`${part.path}-${index}`}\n type=\"button\"\n className=\"rounded-sm font-mono underline decoration-dotted underline-offset-2 hover:text-primary\"\n onClick={(e) => { e.stopPropagation(); onOpenPath(part.path!, part.line) }}\n onMouseEnter={(e) => onPreviewPath?.(part.path!, part.line, e.currentTarget.getBoundingClientRect())}\n onFocus={(e) => onPreviewPath?.(part.path!, part.line, e.currentTarget.getBoundingClientRect())}\n onMouseLeave={() => onPreviewPathEnd?.()}\n onBlur={() => onPreviewPathEnd?.()}\n title={resolvedTitle ? `Open ${resolvedTitle}` : 'Open file'}\n >\n {part.text}{part.line ? `:${part.line}` : ''}\n </button>\n )\n }\n return <span key={index}>{part.text}</span>\n })}\n </>\n )\n}\n\nfunction processTextChildren(\n children: React.ReactNode,\n onOpenPath?: (path: string, line?: number) => void,\n onPreviewPath?: (path: string, line?: number, anchor?: DOMRect) => void,\n onPreviewPathEnd?: () => void,\n isPathLinkable?: (path: string, line?: number) => boolean,\n resolvePathTitle?: (path: string, line?: number) => string | undefined,\n issueRepo?: string,\n): React.ReactNode {\n return React.Children.map(children, (child) =>\n typeof child === 'string'\n ? <TextWithLinks text={child} onOpenPath={onOpenPath} onPreviewPath={onPreviewPath} onPreviewPathEnd={onPreviewPathEnd} isPathLinkable={isPathLinkable} resolvePathTitle={resolvePathTitle} issueRepo={issueRepo} />\n : child\n )\n}\n\nexport function FormattedBody({ text, rawBody, className, onOpenPath, onPreviewPath, onPreviewPathEnd, isPathLinkable, resolvePathTitle }: FormattedBodyProps) {\n const parsed = useMemo(() => parseJsonBody(rawBody || ''), [rawBody])\n const content = unescapeNewlines(parsed ? parsed.text : text)\n // Configured tracker repo for bare #NNN linkification (#511). Static per server, so this\n // selector never churns; undefined → #NNN stays plain text.\n const issueRepo = useRelayStore((s) => s.stats?.defaultIssueRepo)\n\n const components = useMemo(() => ({\n p({ children }: { children?: React.ReactNode }) {\n return <p>{processTextChildren(children, onOpenPath, onPreviewPath, onPreviewPathEnd, isPathLinkable, resolvePathTitle, issueRepo)}</p>\n },\n li({ children }: { children?: React.ReactNode }) {\n return <li>{processTextChildren(children, onOpenPath, onPreviewPath, onPreviewPathEnd, isPathLinkable, resolvePathTitle, issueRepo)}</li>\n },\n a({ href, children }: { href?: string; children?: React.ReactNode }) {\n return (\n <a href={href} target=\"_blank\" rel=\"noreferrer\" onClick={(e) => e.stopPropagation()}>\n {children}\n </a>\n )\n },\n code({ className: codeClass, children }: { className?: string; children?: React.ReactNode }) {\n const match = /language-([\\w-]+)/.exec(codeClass || '')\n const code = String(children).replace(/\\n$/, '')\n if (match) {\n return <CodePreview content={code} path={`.${match[1]}`} languageHint={match[1]} compact />\n }\n return <code className={codeClass}>{children}</code>\n },\n }), [onOpenPath, onPreviewPath, onPreviewPathEnd, isPathLinkable, resolvePathTitle, issueRepo])\n\n return (\n <div className={className}>\n <div className=\"chat-markdown\">\n <ReactMarkdown remarkPlugins={[remarkGfm]} rehypePlugins={[[rehypeSanitize, markdownSchema]]} components={components}>\n {content}\n </ReactMarkdown>\n </div>\n {parsed && parsed.meta.length > 0 && (\n <div className=\"mt-1.5 flex flex-wrap gap-1\">\n {parsed.meta.map(([k, v]) => (\n <span key={k} className=\"inline-flex text-[10px] leading-tight bg-muted px-1.5 py-0.5 rounded text-muted-foreground font-mono\">\n {k}: {v}\n </span>\n ))}\n </div>\n )}\n </div>\n )\n}\n\nfunction unescapeNewlines(text: string): string {\n if (!text.includes('\\\\n')) return text\n return text.replace(/\\\\n/g, '\\n')\n}\n"],"mappings":"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"}
|