diff --git a/apps/desktop/src/app/artifacts/artifact-utils.ts b/apps/desktop/src/app/artifacts/artifact-utils.ts index c86fcc672c..8e48bf29b5 100644 --- a/apps/desktop/src/app/artifacts/artifact-utils.ts +++ b/apps/desktop/src/app/artifacts/artifact-utils.ts @@ -30,7 +30,7 @@ export interface ArtifactLoadResult { const MARKDOWN_IMAGE_RE = /!\[([^\]]*)\]\(([^)\s]+)\)/g const MARKDOWN_LINK_RE = /\[([^\]]+)\]\(([^)\s]+)\)/g -const URL_RE = /https?:\/\/[^\s<>"')]+/g +const URL_RE = /https?:\/\/[^\s<>"')`]+/g const PATH_RE = /(^|[\s("'`])((?:\/|~[\\/]|\.\.?[\\/]|\\\\)[^\s"'`<>]+(?:\.[a-z0-9]{1,8})?)/gi const WINDOWS_PATH_RE = /(^|[\s("'`])([A-Za-z]:[\\/][^\s"'`<>]+(?:\.[a-z0-9]{1,8})?)/gi const IMAGE_EXT_RE = /\.(?:png|jpe?g|gif|webp|svg|bmp)(?:\?.*)?$/i diff --git a/apps/desktop/src/app/artifacts/index.test.ts b/apps/desktop/src/app/artifacts/index.test.ts index f07146ea4e..e3ab56cc12 100644 --- a/apps/desktop/src/app/artifacts/index.test.ts +++ b/apps/desktop/src/app/artifacts/index.test.ts @@ -65,6 +65,26 @@ describe('collectArtifactsForSession', () => { }) }) + it('stops a URL capture at a closing backtick even when punctuation follows it', () => { + // The closing delimiter can carry trailing punctuation (`…`,) — the + // trailing-punctuation trim alone would leave the backtick behind, so the + // capture itself must refuse it. + const artifacts = collectArtifactsForSession(makeSession(), [ + { + content: 'Deployed at `https://voice.qwickapps.com`, take a look.', + role: 'assistant', + timestamp: 2000 + } + ]) + + expect(artifacts).toHaveLength(1) + expect(artifacts[0]).toMatchObject({ + href: 'https://voice.qwickapps.com', + kind: 'link', + value: 'https://voice.qwickapps.com' + }) + }) + it('does not index passive links and paths observed in tool output', () => { const messages: SessionMessage[] = [ {