Files
hack/tools/scripts/llm-key-hunter/results/_cache/content/aprilming_maiknote.json
T

1 line
56 KiB
JSON
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
{"repo": "aprilming/maiknote", "files": {"src/stores/assistantsStore.ts": {"89114e543bd4a1da0786820b37bc5bb96c226e42": {"t": 1785746031.7333798, "n": 7277, "h": "c25efa96aa9e5cae", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n searchEnabled: boolean\n createdAt: number // timestamp in milliseconds\n}\n\nexport interface AiConfig {\n url: string\n key: string\n model: string\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '优化内容',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-2',\n name: '提取任务',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-3',\n name: '优化提示词',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n searchEnabled: true,\n },\n]\n\nexport const defaultAiConfig: AiConfig = {\n url: 'https://api.deepseek.com/chat/completions',\n key: '',\n model: 'deepseek-v4-flash',\n}\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n const aiUrl = ref(defaultAiConfig.url)\n const aiKey = ref(defaultAiConfig.key)\n const aiModel = ref(defaultAiConfig.model)\n const aiConfigExists = ref(false)\n const baiduSearchKey = ref('')\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = (parsed.assistants || []).map((a: Record<string, unknown>) => ({\n ...a,\n searchEnabled: a.searchEnabled === true,\n })) as Assistant[]\n\n // Load AI config from iCloud\n if (parsed.aiConfig) {\n aiUrl.value = parsed.aiConfig.url || defaultAiConfig.url\n aiKey.value = parsed.aiConfig.key || defaultAiConfig.key\n aiModel.value = parsed.aiConfig.model || defaultAiConfig.model\n aiConfigExists.value = true\n }\n\n // Load Baidu search key from iCloud\n if (parsed.baiduSearchKey) {\n baiduSearchKey.value = parsed.baiduSearchKey\n }\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants and AI config to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify({\n version: 1,\n assistants: assistants.value,\n aiConfig: { url: aiUrl.value, key: aiKey.value, model: aiModel.value },\n baiduSearchKey: baiduSearchKey.value,\n }, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string, searchEnabled = false): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n searchEnabled,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt' | 'searchEnabled'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n /**\n * Update AI config (url, key, model) and persist to iCloud\n */\n async function updateAiConfig(url: string, key: string, model: string): Promise<void> {\n aiUrl.value = url\n aiKey.value = key\n aiModel.value = model\n await saveAssistants()\n }\n\n async function updateBaiduSearchKey(key: string): Promise<void> {\n baiduSearchKey.value = key\n await saveAssistants()\n }\n\n return {\n assistants,\n isLoaded,\n aiConfigExists,\n aiUrl,\n aiKey,\n aiModel,\n baiduSearchKey,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n updateAiConfig,\n updateBaiduSearchKey,\n }\n})\n"}, "e4e0def3f082380c62335f83eec641534dc827b8": {"t": 1785759032.3592613, "n": 7277, "h": "c25efa96aa9e5cae", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n searchEnabled: boolean\n createdAt: number // timestamp in milliseconds\n}\n\nexport interface AiConfig {\n url: string\n key: string\n model: string\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '优化内容',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-2',\n name: '提取任务',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-3',\n name: '优化提示词',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n searchEnabled: true,\n },\n]\n\nexport const defaultAiConfig: AiConfig = {\n url: 'https://api.deepseek.com/chat/completions',\n key: '',\n model: 'deepseek-v4-flash',\n}\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n const aiUrl = ref(defaultAiConfig.url)\n const aiKey = ref(defaultAiConfig.key)\n const aiModel = ref(defaultAiConfig.model)\n const aiConfigExists = ref(false)\n const baiduSearchKey = ref('')\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = (parsed.assistants || []).map((a: Record<string, unknown>) => ({\n ...a,\n searchEnabled: a.searchEnabled === true,\n })) as Assistant[]\n\n // Load AI config from iCloud\n if (parsed.aiConfig) {\n aiUrl.value = parsed.aiConfig.url || defaultAiConfig.url\n aiKey.value = parsed.aiConfig.key || defaultAiConfig.key\n aiModel.value = parsed.aiConfig.model || defaultAiConfig.model\n aiConfigExists.value = true\n }\n\n // Load Baidu search key from iCloud\n if (parsed.baiduSearchKey) {\n baiduSearchKey.value = parsed.baiduSearchKey\n }\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants and AI config to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify({\n version: 1,\n assistants: assistants.value,\n aiConfig: { url: aiUrl.value, key: aiKey.value, model: aiModel.value },\n baiduSearchKey: baiduSearchKey.value,\n }, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string, searchEnabled = false): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n searchEnabled,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt' | 'searchEnabled'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n /**\n * Update AI config (url, key, model) and persist to iCloud\n */\n async function updateAiConfig(url: string, key: string, model: string): Promise<void> {\n aiUrl.value = url\n aiKey.value = key\n aiModel.value = model\n await saveAssistants()\n }\n\n async function updateBaiduSearchKey(key: string): Promise<void> {\n baiduSearchKey.value = key\n await saveAssistants()\n }\n\n return {\n assistants,\n isLoaded,\n aiConfigExists,\n aiUrl,\n aiKey,\n aiModel,\n baiduSearchKey,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n updateAiConfig,\n updateBaiduSearchKey,\n }\n})\n"}, "1a583602b2aa814d0420b71d3c95c3bd59e58708": {"t": 1785759035.2492504, "n": 7273, "h": "10a05a5dcd0e5100", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n searchEnabled: boolean\n createdAt: number // timestamp in milliseconds\n}\n\nexport interface AiConfig {\n url: string\n key: string\n model: string\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '优化内容',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-2',\n name: '提取任务',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-3',\n name: '优化提示词',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n searchEnabled: true,\n },\n]\n\nexport const defaultAiConfig: AiConfig = {\n url: 'https://api.deepseek.com/chat/completions',\n key: '',\n model: 'deepseek-chat',\n}\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n const aiUrl = ref(defaultAiConfig.url)\n const aiKey = ref(defaultAiConfig.key)\n const aiModel = ref(defaultAiConfig.model)\n const aiConfigExists = ref(false)\n const baiduSearchKey = ref('')\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = (parsed.assistants || []).map((a: Record<string, unknown>) => ({\n ...a,\n searchEnabled: a.searchEnabled === true,\n })) as Assistant[]\n\n // Load AI config from iCloud\n if (parsed.aiConfig) {\n aiUrl.value = parsed.aiConfig.url || defaultAiConfig.url\n aiKey.value = parsed.aiConfig.key || defaultAiConfig.key\n aiModel.value = parsed.aiConfig.model || defaultAiConfig.model\n aiConfigExists.value = true\n }\n\n // Load Baidu search key from iCloud\n if (parsed.baiduSearchKey) {\n baiduSearchKey.value = parsed.baiduSearchKey\n }\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants and AI config to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify({\n version: 1,\n assistants: assistants.value,\n aiConfig: { url: aiUrl.value, key: aiKey.value, model: aiModel.value },\n baiduSearchKey: baiduSearchKey.value,\n }, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string, searchEnabled = false): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n searchEnabled,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt' | 'searchEnabled'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n /**\n * Update AI config (url, key, model) and persist to iCloud\n */\n async function updateAiConfig(url: string, key: string, model: string): Promise<void> {\n aiUrl.value = url\n aiKey.value = key\n aiModel.value = model\n await saveAssistants()\n }\n\n async function updateBaiduSearchKey(key: string): Promise<void> {\n baiduSearchKey.value = key\n await saveAssistants()\n }\n\n return {\n assistants,\n isLoaded,\n aiConfigExists,\n aiUrl,\n aiKey,\n aiModel,\n baiduSearchKey,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n updateAiConfig,\n updateBaiduSearchKey,\n }\n})\n"}, "5a5f2cb595ed65a6f7b50c44345e752ce1ce1b67": {"t": 1785759037.4990118, "n": 6869, "h": "07212cb2a5768235", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n searchEnabled: boolean\n createdAt: number // timestamp in milliseconds\n}\n\nexport interface AiConfig {\n url: string\n key: string\n model: string\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '优化内容',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-2',\n name: '提取任务',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n searchEnabled: true,\n },\n {\n id: 'template-3',\n name: '优化提示词',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n searchEnabled: true,\n },\n]\n\nexport const defaultAiConfig: AiConfig = {\n url: 'https://api.deepseek.com/chat/completions',\n key: '',\n model: 'deepseek-chat',\n}\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n const aiUrl = ref(defaultAiConfig.url)\n const aiKey = ref(defaultAiConfig.key)\n const aiModel = ref(defaultAiConfig.model)\n const aiConfigExists = ref(false)\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = (parsed.assistants || []).map((a: Record<string, unknown>) => ({\n ...a,\n searchEnabled: a.searchEnabled === true,\n })) as Assistant[]\n\n // Load AI config from iCloud\n if (parsed.aiConfig) {\n aiUrl.value = parsed.aiConfig.url || defaultAiConfig.url\n aiKey.value = parsed.aiConfig.key || defaultAiConfig.key\n aiModel.value = parsed.aiConfig.model || defaultAiConfig.model\n aiConfigExists.value = true\n }\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants and AI config to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify({\n version: 1,\n assistants: assistants.value,\n aiConfig: { url: aiUrl.value, key: aiKey.value, model: aiModel.value },\n }, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string, searchEnabled = false): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n searchEnabled,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt' | 'searchEnabled'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n /**\n * Update AI config (url, key, model) and persist to iCloud\n */\n async function updateAiConfig(url: string, key: string, model: string): Promise<void> {\n aiUrl.value = url\n aiKey.value = key\n aiModel.value = model\n await saveAssistants()\n }\n\n return {\n assistants,\n isLoaded,\n aiConfigExists,\n aiUrl,\n aiKey,\n aiModel,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n updateAiConfig,\n }\n})\n"}, "f9681b307be973d9246a6fc16a35af2fca111574": {"t": 1785759038.81763, "n": 6572, "h": "ac17767d7c4ca3ce", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n createdAt: number // timestamp in milliseconds\n}\n\nexport interface AiConfig {\n url: string\n key: string\n model: string\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '优化内容',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n },\n {\n id: 'template-2',\n name: '提取任务',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n },\n {\n id: 'template-3',\n name: '优化提示词',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n },\n]\n\nexport const defaultAiConfig: AiConfig = {\n url: 'https://api.deepseek.com/chat/completions',\n key: '',\n model: 'deepseek-chat',\n}\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n const aiUrl = ref(defaultAiConfig.url)\n const aiKey = ref(defaultAiConfig.key)\n const aiModel = ref(defaultAiConfig.model)\n const aiConfigExists = ref(false)\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = parsed.assistants || []\n\n // Load AI config from iCloud\n if (parsed.aiConfig) {\n aiUrl.value = parsed.aiConfig.url || defaultAiConfig.url\n aiKey.value = parsed.aiConfig.key || defaultAiConfig.key\n aiModel.value = parsed.aiConfig.model || defaultAiConfig.model\n aiConfigExists.value = true\n }\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants and AI config to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify({\n version: 1,\n assistants: assistants.value,\n aiConfig: { url: aiUrl.value, key: aiKey.value, model: aiModel.value },\n }, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n /**\n * Update AI config (url, key, model) and persist to iCloud\n */\n async function updateAiConfig(url: string, key: string, model: string): Promise<void> {\n aiUrl.value = url\n aiKey.value = key\n aiModel.value = model\n await saveAssistants()\n }\n\n return {\n assistants,\n isLoaded,\n aiConfigExists,\n aiUrl,\n aiKey,\n aiModel,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n updateAiConfig,\n }\n})\n"}, "d7293c476cfef3d0088d3af28f71b053ffb930c9": {"t": 1785759040.1348577, "n": 5416, "h": "b2bf30db67b58153", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n createdAt: number // timestamp in milliseconds\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '优化内容',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n },\n {\n id: 'template-2',\n name: '提取任务',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n },\n {\n id: 'template-3',\n name: '优化提示词',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n },\n]\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = parsed.assistants || []\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify({ version: 1, assistants: assistants.value }, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n return {\n assistants,\n isLoaded,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n }\n})\n"}, "e2ee5f47ba76bb9feedeb18d50a7bd51fe959ee3": {"t": 1785759041.6421704, "n": 5387, "h": "5b2bb0f607b6d8ad", "c": "import { defineStore } from 'pinia'\nimport { ref } from 'vue'\nimport { invoke } from '@tauri-apps/api/core'\nimport { useFileSystem } from '@/composables/useFileSystem'\n\n// Assistant interface\nexport interface Assistant {\n id: string\n name: string\n prompt: string\n createdAt: number // timestamp in milliseconds\n}\n\n// Default template assistants - using string literals to avoid Pinia initialization issues\nexport const defaultAssistants: Assistant[] = [\n {\n id: 'template-1',\n name: '一号助手',\n prompt: '你是一个笔记优化助手,严格按照以下规则优化笔记内容,直接输出结果,不附加任何说明。\\n' +\n '输出格式\\n' +\n '返回纯字符串,不使用 ``` 代码块包裹\\n' +\n '内容处理规则\\n' +\n '删除信息来源(如\"来源:\"\"转自:\"等)\\n' +\n '删除所有 tag 标签(如 #标签)\\n' +\n '标题处理:全文仅保留一个 H2 标题;若无标题则在顶部生成一个;若已有标题则不新增\\n' +\n '链接处理:保留核心内容中的 URL;若为裸链接可转为 Markdown 格式;禁止修改链接本身;无链接时禁止生成链接\\n' +\n '禁止输出\"注:\"\"备注:\"\"注意:\"等注释性内容\\n' +\n '禁止输出\"已优化\"\"优化笔记\"\"以下是\"等无关话语',\n createdAt: 0,\n },\n {\n id: 'template-2',\n name: '二号助手',\n prompt: '从以下文本中提取待办事项,按如下格式输出:\\n' +\n '第一部分:笔记摘要\\n' +\n '用 h1–h3 标题概括笔记主题,标题 10 字以内\\n' +\n '标题下方正文仅保留日期、时间及关键信息,无则省略\\n' +\n '可适当添加表情 🎯\\n' +\n '第二部分:任务列表\\n' +\n '每条任务以 - [ ] 开头,保留时间、日期等关键信息\\n' +\n '不使用有序或无序列表,只用 - [ ] 格式\\n' +\n '特殊情况\\n' +\n '若无法提取到任务,则对笔记进行格式优化后输出\\n' +\n '不要输出任何引导语(如\"以下是……\")',\n createdAt: 0,\n },\n {\n id: 'template-3',\n name: '三号助手',\n prompt: '你是一个提示词优化专家,用户会给你一段提示词,你需要对其进行优化并直接输出结果。\\n' +\n '优化原则\\n' +\n '保留用户的原始意图,不改变核心需求\\n' +\n '补全缺失的约束条件(格式、边界情况、禁止行为等)\\n' +\n '消除歧义表达,改为明确、可执行的指令\\n' +\n '合并重复或冲突的规则\\n' +\n '结构清晰,分块呈现\\n' +\n '输出格式\\n' +\n '直接输出优化后的提示词,不加任何说明\\n' +\n '不使用 ``` 包裹\\n' +\n '不输出\"以下是优化后的提示词\"等引导语\\n' +\n '特殊情况\\n' +\n '若用户的提示词过于简单,主动补全合理的默认规则\\n' +\n '若存在矛盾规则,以最后出现的为准并合并',\n createdAt: 0,\n },\n]\n\nexport const useAssistantsStore = defineStore('assistants', () => {\n // State\n const assistants = ref<Assistant[]>([])\n const isLoaded = ref(false)\n\n // File system operations\n const { getICloudPath } = useFileSystem()\n\n /**\n * Generate a unique ID using crypto.randomUUID()\n */\n function generateId(): string {\n return crypto.randomUUID()\n }\n\n /**\n * Load assistants from iCloud file\n */\n async function loadAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = await invoke<string>('read_assistants', { basePath: path })\n\n if (content) {\n const parsed = JSON.parse(content)\n assistants.value = parsed.assistants || []\n }\n\n isLoaded.value = true\n } catch (e) {\n // If file doesn't exist or read fails, use default assistants\n console.error('Failed to load assistants, using defaults:', e)\n assistants.value = [...defaultAssistants]\n isLoaded.value = true\n }\n }\n\n /**\n * Save assistants to iCloud file\n */\n async function saveAssistants(): Promise<void> {\n try {\n const path = await getICloudPath()\n const content = JSON.stringify(assistants.value, null, 2)\n await invoke('write_assistants', { basePath: path, content })\n } catch (e) {\n console.error('Failed to save assistants:', e)\n }\n }\n\n /**\n * Add a new assistant\n */\n async function addAssistant(name: string, prompt: string): Promise<Assistant> {\n const newAssistant: Assistant = {\n id: generateId(),\n name,\n prompt,\n createdAt: Date.now(),\n }\n\n assistants.value.push(newAssistant)\n await saveAssistants()\n return newAssistant\n }\n\n /**\n * Update an existing assistant\n */\n async function updateAssistant(id: string, updates: Partial<Pick<Assistant, 'name' | 'prompt'>>): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value[index] = {\n ...assistants.value[index],\n ...updates,\n }\n\n await saveAssistants()\n return true\n }\n\n /**\n * Delete an assistant\n */\n async function deleteAssistant(id: string): Promise<boolean> {\n const index = assistants.value.findIndex(a => a.id === id)\n if (index === -1) {\n return false\n }\n\n assistants.value.splice(index, 1)\n await saveAssistants()\n return true\n }\n\n /**\n * Get assistant by ID\n */\n function getAssistantById(id: string): Assistant | undefined {\n return assistants.value.find(a => a.id === id)\n }\n\n /**\n * Check if an assistant with the same prompt already exists\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(a => a.prompt === prompt && a.id !== excludeId)\n }\n\n /**\n * Check if an assistant with the same prompt already exists (excluding template assistants)\n * @param prompt The prompt to check\n * @param excludeId Optional ID to exclude from check (for updates)\n */\n function hasUserPrompt(prompt: string, excludeId?: string): boolean {\n return assistants.value.some(\n a => a.prompt === prompt && a.id !== excludeId && !a.id.startsWith('template-')\n )\n }\n\n return {\n assistants,\n isLoaded,\n loadAssistants,\n saveAssistants,\n addAssistant,\n updateAssistant,\n deleteAssistant,\n getAssistantById,\n hasPrompt,\n hasUserPrompt,\n }\n})\n"}}}}