Files
tutti/packages/agent/gui/shared/pastedTextReferenceProjection.ts
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

83 lines
2.5 KiB
TypeScript

import { createRichTextMentionMarkdown } from "@tutti-os/ui-rich-text/core";
import { AGENT_PASTED_TEXT_MENTION_KIND } from "./pastedTextKinds";
// Matches a landed pasted-text archive path (content-addressed .txt under the
// host's agent-prompt-assets dir). The path may contain spaces (e.g. macOS
// "Application Support"), so match from the leading "/" or drive letter up to
// the first ".txt" after "agent-prompt-assets", staying on one line.
const PASTED_TEXT_ARCHIVE_PATH_RE =
/(?:\/|[A-Za-z]:\\)[^\n]*?agent-prompt-assets[^\n]*?\.txt/;
export function pastedTextDraftDisplayName(index: number): string {
return `pasted-text-${index + 1}.txt`;
}
/**
* Extracts landed pasted-text archive paths from a persisted content text block.
*/
export function extractPastedTextArchivePaths(text: string): string[] {
const paths: string[] = [];
for (const line of text.split("\n")) {
const path = firstPastedTextArchivePath(line);
if (path && !paths.includes(path)) {
paths.push(path);
}
}
return paths;
}
/**
* Rewrites persisted pasted-text instructions into the same mention links the
* composer emits, without importing the interactive Composer model.
*/
export function linkifyPastedTextReferences(text: string): string {
if (!PASTED_TEXT_ARCHIVE_PATH_RE.test(text)) {
return text;
}
const lines = text.split("\n");
const out: string[] = [];
let refIndex = 0;
for (let index = 0; index < lines.length; index++) {
const line = lines[index] ?? "";
const path = firstPastedTextArchivePath(line);
if (path) {
out.push(
pastedTextReferenceMentionMarkdown(
firstQuotedPreview(line),
path,
refIndex
)
);
refIndex += 1;
continue;
}
const next = lines[index + 1];
if (next != null && firstPastedTextArchivePath(next)) {
continue;
}
out.push(line);
}
return out.join("\n").trim();
}
function firstPastedTextArchivePath(line: string): string | null {
return line.match(PASTED_TEXT_ARCHIVE_PATH_RE)?.[0].trim() ?? null;
}
function pastedTextReferenceMentionMarkdown(
preview: string,
path: string,
index: number
): string {
return createRichTextMentionMarkdown({
providerId: AGENT_PASTED_TEXT_MENTION_KIND,
entityId: `ref-${index}`,
label: preview.trim() || pastedTextDraftDisplayName(index),
scope: { path }
});
}
function firstQuotedPreview(line: string): string {
return line.match(/"([^"]*)"/)?.[1]?.trim() ?? "";
}