UNPKG

omnifocus-mcp-enhanced

Version:

🚀 NEW: Native Custom Perspective Access! Enhanced MCP server with OmniFocus custom perspective support, hierarchical task display, AI-optimized tool selection, and comprehensive task management

220 lines (189 loc) 6.85 kB
// JXA兼容的透视访问 - 基于验证过的逻辑但用JXA语法 (() => { try { // 参数会被自动注入 let perspectiveName = null; let hideCompleted = true; let limit = 0; // 0表示无限制 console.log(`JXA方式获取透视: ${perspectiveName}`); // 使用JXA方式访问OmniFocus const app = Application('OmniFocus'); const doc = app.defaultDocument; // Helper functions function formatDate(date) { if (!date) return null; return date.toISOString(); } // 1. 查找透视 - 使用JXA方式 let targetPerspective = null; // 尝试在自定义透视中查找 try { const customPerspectives = doc.customPerspectives; // 先尝试byName方法 try { targetPerspective = customPerspectives.byName(perspectiveName); if (targetPerspective && targetPerspective.name() === perspectiveName) { console.log(`通过byName找到透视: ${perspectiveName}`); } else { targetPerspective = null; } } catch (byNameError) { console.log(`byName方法失败: ${byNameError.message}`); targetPerspective = null; } // 如果byName失败,尝试遍历 if (!targetPerspective) { // 使用验证过的逻辑:不直接遍历,而是使用索引访问 for (let i = 0; i < 50; i++) { // 限制搜索范围 try { const perspective = customPerspectives[i]; if (perspective && perspective.name() === perspectiveName) { targetPerspective = perspective; console.log(`通过索引${i}找到透视: ${perspectiveName}`); break; } } catch (indexError) { // 索引超出范围,停止搜索 break; } } } } catch (customError) { console.log(`自定义透视访问失败: ${customError.message}`); } // 如果还没找到,尝试内置透视 if (!targetPerspective) { try { const builtInPerspectives = doc.builtInPerspectives; for (let i = 0; i < 20; i++) { try { const perspective = builtInPerspectives[i]; if (perspective && perspective.name() === perspectiveName) { targetPerspective = perspective; console.log(`在内置透视中找到: ${perspectiveName}`); break; } } catch (builtInIndexError) { break; } } } catch (builtInError) { console.log(`内置透视访问失败: ${builtInError.message}`); } } if (!targetPerspective) { return JSON.stringify({ success: false, error: `透视 "${perspectiveName}" 未找到` }); } console.log(`成功找到透视: ${perspectiveName}`); // 2. 切换到透视 - 关键:使用正确的方法 const windows = doc.windows; if (windows.length === 0) { return JSON.stringify({ success: false, error: "没有可用窗口" }); } const window = windows[0]; console.log("使用第一个窗口"); // 切换透视 window.perspective = targetPerspective; console.log(`已切换到透视: ${perspectiveName}`); // 3. 获取透视内容 - 使用验证过的方法 const tasks = []; try { const content = window.content; if (!content || !content.rootNode) { return JSON.stringify({ success: false, error: "无法获取窗口内容" }); } const rootNode = content.rootNode; console.log("获取根节点成功"); // 获取所有后代节点 const allNodes = rootNode.descendantNodes; console.log(`总节点数: ${allNodes.length}`); // 遍历所有节点,寻找任务 for (let i = 0; i < allNodes.length; i++) { try { const node = allNodes[i]; const obj = node.object(); if (obj && obj.class && obj.class() === 'task') { const completed = obj.completed(); const dropped = obj.dropped(); // 应用hideCompleted筛选 if (hideCompleted && (completed || dropped)) { continue; } const taskData = { id: obj.id(), name: obj.name(), note: obj.note() || "", completed: completed, dropped: dropped, flagged: obj.flagged(), dueDate: obj.dueDate() ? formatDate(obj.dueDate()) : null, deferDate: obj.deferDate() ? formatDate(obj.deferDate()) : null, completedDate: obj.completionDate() ? formatDate(obj.completionDate()) : null, estimatedMinutes: obj.estimatedMinutes() || 0, projectName: null, tags: [], containingProjectInfo: null, parentTaskInfo: null }; // 尝试获取项目信息 try { if (obj.containingProject && obj.containingProject()) { const project = obj.containingProject(); taskData.projectName = project.name(); taskData.containingProjectInfo = { name: project.name(), id: project.id(), status: "active status" }; } } catch (projError) { // 忽略项目信息获取错误 } tasks.push(taskData); // 应用限制 if (limit > 0 && tasks.length >= limit) { break; } } } catch (nodeError) { // 忽略单个节点错误,继续处理其他节点 } } } catch (contentError) { console.log(`获取内容失败: ${contentError.message}`); return JSON.stringify({ success: false, error: `获取透视内容失败: ${contentError.message}` }); } const result = { success: true, perspectiveInfo: { name: perspectiveName, rulesCount: 1, aggregation: "perspective_native" }, tasks: tasks, isReal: true, apiVersion: "JXA兼容的透视访问" }; console.log(`JXA方式获取透视 "${perspectiveName}" 返回 ${tasks.length} 个任务`); return JSON.stringify(result); } catch (error) { console.log(`JXA透视访问失败: ${error.message}`); return JSON.stringify({ success: false, error: `JXA透视访问失败: ${error.message}`, apiVersion: "JXA兼容的透视访问" }); } })();