Add clickable keep-prompt snippets for video and image.
Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -0,0 +1,85 @@
|
||||
export type KeepPromptKind = 'video' | 'image'
|
||||
|
||||
export type KeepPrompt = {
|
||||
id: string
|
||||
label: string
|
||||
text: string
|
||||
}
|
||||
|
||||
export type KeepPromptLists = {
|
||||
video: KeepPrompt[]
|
||||
image: KeepPrompt[]
|
||||
}
|
||||
|
||||
export const KEEP_PROMPT_MAX = 40
|
||||
export const KEEP_PROMPT_TEXT_MAX = 500
|
||||
export const KEEP_PROMPT_LABEL_MAX = 40
|
||||
|
||||
export function emptyKeepPrompts(): KeepPromptLists {
|
||||
return { video: [], image: [] }
|
||||
}
|
||||
|
||||
export function sanitizeKeepPromptText(raw: unknown) {
|
||||
return String(raw || '')
|
||||
.replace(/\r\n/g, '\n')
|
||||
.replace(/[\0\r]/g, '')
|
||||
.trim()
|
||||
.slice(0, KEEP_PROMPT_TEXT_MAX)
|
||||
}
|
||||
|
||||
export function sanitizeKeepPromptLabel(raw: unknown, fallback = '') {
|
||||
const label = String(raw || '').replace(/\s+/g, ' ').trim().slice(0, KEEP_PROMPT_LABEL_MAX)
|
||||
if (label) return label
|
||||
const fromText = sanitizeKeepPromptText(fallback).replace(/\s+/g, ' ').slice(0, KEEP_PROMPT_LABEL_MAX)
|
||||
return fromText
|
||||
}
|
||||
|
||||
function normalizeItem(raw: unknown): KeepPrompt | null {
|
||||
if (!raw || typeof raw !== 'object') return null
|
||||
const rec = raw as Record<string, unknown>
|
||||
const text = sanitizeKeepPromptText(rec.text)
|
||||
if (!text) return null
|
||||
const id = String(rec.id || '').trim() || crypto.randomUUID()
|
||||
return {
|
||||
id,
|
||||
label: sanitizeKeepPromptLabel(rec.label, text),
|
||||
text
|
||||
}
|
||||
}
|
||||
|
||||
export function normalizeKeepPromptList(raw: unknown): KeepPrompt[] {
|
||||
if (!Array.isArray(raw)) return []
|
||||
const seen = new Set<string>()
|
||||
const out: KeepPrompt[] = []
|
||||
for (const entry of raw) {
|
||||
if (out.length >= KEEP_PROMPT_MAX) break
|
||||
const item = normalizeItem(entry)
|
||||
if (!item || seen.has(item.id)) continue
|
||||
seen.add(item.id)
|
||||
out.push(item)
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
export function normalizeKeepPrompts(raw: unknown): KeepPromptLists {
|
||||
if (!raw || typeof raw !== 'object' || Array.isArray(raw)) return emptyKeepPrompts()
|
||||
const rec = raw as Record<string, unknown>
|
||||
return {
|
||||
video: normalizeKeepPromptList(rec.video),
|
||||
image: normalizeKeepPromptList(rec.image)
|
||||
}
|
||||
}
|
||||
|
||||
export function parseKeepPromptKind(raw: unknown): KeepPromptKind | '' {
|
||||
return raw === 'video' || raw === 'image' ? raw : ''
|
||||
}
|
||||
|
||||
export function insertKeepSnippet(text: string, snippet: string) {
|
||||
const src = String(text || '')
|
||||
const token = sanitizeKeepPromptText(snippet)
|
||||
if (!token) return src
|
||||
if (src.includes(token)) return src
|
||||
if (!src.trim()) return token
|
||||
const needsBreak = !/\n$/.test(src)
|
||||
return needsBreak ? `${src.trimEnd()}\n${token}` : `${src}${token}`
|
||||
}
|
||||
Reference in New Issue
Block a user