chore: sync local workspace changes

This commit is contained in:
2026-05-07 11:03:47 +09:00
parent 2df0ba30cb
commit 82c0d8a197
217 changed files with 44873 additions and 1678 deletions

View File

@@ -16,6 +16,11 @@ function normalizeUrl(value: string) {
return '';
}
const malformedResourceMatch = normalized.match(/^https?:\/(api\/chat\/resources\/.+)$/i);
if (malformedResourceMatch?.[1]) {
return `/${malformedResourceMatch[1]}`;
}
if (/^(?:https?:\/\/|\/)/i.test(normalized)) {
return normalized;
}
@@ -23,11 +28,43 @@ function normalizeUrl(value: string) {
return '';
}
function decodeUrlComponentSafely(value: string) {
try {
return decodeURIComponent(value);
} catch {
return value;
}
}
function resolveLinkCardUrlAndActionLabel(rawUrl: string, rawActionLabel?: string) {
let resolvedUrl = normalizeText(rawUrl);
let resolvedActionLabel = normalizeText(rawActionLabel);
if (!resolvedActionLabel) {
const decodedUrl = decodeUrlComponentSafely(resolvedUrl);
const dividerIndex = decodedUrl.lastIndexOf('|');
if (dividerIndex > 0 && dividerIndex < decodedUrl.length - 1) {
resolvedUrl = decodedUrl.slice(0, dividerIndex).trim();
resolvedActionLabel = decodedUrl.slice(dividerIndex + 1).trim();
}
}
return {
url: normalizeUrl(resolvedUrl),
actionLabel: resolvedActionLabel || null,
};
}
function hasKnownFileExtension(url: string) {
const pathname = url.split('?')[0] ?? '';
return /\.[a-z0-9]{1,8}$/i.test(pathname);
}
function isInternalResourceUrl(url: string) {
return RESOURCE_PATH_PREFIXES.some((prefix) => url.startsWith(prefix));
}
function isStructuredLinkCardCandidate(url: string) {
const normalized = normalizeUrl(url);
@@ -35,15 +72,11 @@ function isStructuredLinkCardCandidate(url: string) {
return false;
}
if (RESOURCE_PATH_PREFIXES.some((prefix) => normalized.startsWith(prefix))) {
if (isInternalResourceUrl(normalized)) {
return false;
}
if (/^https?:\/\//i.test(normalized)) {
return !hasKnownFileExtension(normalized);
}
return !hasKnownFileExtension(normalized);
return /^https?:\/\//i.test(normalized) && !hasKnownFileExtension(normalized);
}
function buildFallbackLinkTitle(url: string) {
@@ -88,8 +121,7 @@ function buildLinkCardPart(rawBody: string): ChatMessagePart | null {
const [rawTitle, rawUrl, rawActionLabel] = segments;
const title = normalizeText(rawTitle);
const url = normalizeUrl(rawUrl);
const actionLabel = normalizeText(rawActionLabel) || null;
const { url, actionLabel } = resolveLinkCardUrlAndActionLabel(rawUrl, rawActionLabel);
if (!title || !url) {
return null;
@@ -154,6 +186,14 @@ export function extractChatMessageParts(text: string) {
if (!pushPart(buildLinkCardPart(matched[1] ?? ''))) {
keptLines.push(line);
continue;
}
const latestPart = parts.at(-1);
if (latestPart && isInternalResourceUrl(latestPart.url)) {
parts.pop();
seenLinkKeys.delete(`${latestPart.type}:${latestPart.title}:${latestPart.url}:${latestPart.actionLabel ?? ''}`);
keptLines.push(latestPart.url);
}
}