Add clickable keep-prompt snippets for video and image.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Towsty
2026-08-31 20:39:08 -05:00
co-authored by Cursor
parent 529598cef2
commit a3380870ad
7 changed files with 407 additions and 12 deletions
+85
View File
@@ -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}`
}