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
172 lines (147 loc) • 5.33 kB
JavaScript
// 真正的透视访问 - 使用 OmniFocus 4.2+ 正确的 API
(() => {
try {
// 参数会被自动注入
let perspectiveName = null;
let hideCompleted = true;
let limit = 100;
console.log(`获取真正的透视: ${perspectiveName}`);
const doc = Document.makeDefault();
// Helper functions
function formatDate(date) {
if (!date) return null;
return date.toISOString();
}
function getTaskStatus(status) {
const taskStatusMap = {
[Task.Status.Available]: "Available",
[Task.Status.Blocked]: "Blocked",
[Task.Status.Completed]: "Completed",
[Task.Status.Dropped]: "Dropped",
[Task.Status.DueSoon]: "DueSoon",
[Task.Status.Next]: "Next",
[Task.Status.Overdue]: "Overdue"
};
return taskStatusMap[status] || "Unknown";
}
// 1. 查找透视
let targetPerspective = null;
// 查找自定义透视
const customPerspectives = doc.customPerspectives;
for (let perspective of customPerspectives) {
if (perspective.name === perspectiveName) {
targetPerspective = perspective;
break;
}
}
if (!targetPerspective) {
return JSON.stringify({
success: false,
error: `透视 "${perspectiveName}" 未找到`
});
}
console.log(`找到透视: ${perspectiveName}`);
// 2. 获取透视信息
let perspectiveInfo = {
name: targetPerspective.name,
rulesCount: 0,
aggregation: "unknown"
};
// 尝试获取 archivedFilterRules (正确的属性访问,不是方法调用)
try {
if (targetPerspective.archivedFilterRules) {
perspectiveInfo.rulesCount = targetPerspective.archivedFilterRules.length;
}
if (targetPerspective.archivedTopLevelFilterAggregation) {
perspectiveInfo.aggregation = targetPerspective.archivedTopLevelFilterAggregation;
}
console.log(`透视规则数量: ${perspectiveInfo.rulesCount}`);
console.log(`聚合方式: ${perspectiveInfo.aggregation}`);
} catch (e) {
console.log(`获取透视规则失败: ${e.message}`);
}
// 3. 创建窗口并设置透视
let window = doc.windows[0];
if (!window) {
// 如果没有窗口,创建一个
window = doc.makeNewWindow();
}
// 设置透视
window.perspective = targetPerspective;
console.log(`已切换到透视: ${perspectiveName}`);
// 4. 从窗口内容获取已筛选的任务
const tasks = [];
const content = window.content;
if (content && content.rootNode) {
const rootNode = content.rootNode;
// 获取所有后代节点中的任务
function collectTasks(node) {
try {
const obj = node.object;
if (obj && obj instanceof Task) {
const taskStatus = getTaskStatus(obj.taskStatus);
// 应用 hideCompleted 筛选
if (hideCompleted && (taskStatus === "Completed" || taskStatus === "Dropped")) {
return;
}
const taskData = {
id: obj.id.primaryKey,
name: obj.name,
note: obj.note || "",
completed: taskStatus === "Completed",
dropped: taskStatus === "Dropped",
flagged: obj.flagged,
dueDate: formatDate(obj.dueDate),
deferDate: formatDate(obj.deferDate),
completedDate: formatDate(obj.completionDate),
estimatedMinutes: obj.estimatedMinutes || 0,
projectName: obj.containingProject ? obj.containingProject.name : null,
tags: obj.tags.map(tag => ({
id: tag.id.primaryKey,
name: tag.name
})),
containingProjectInfo: obj.containingProject ? {
name: obj.containingProject.name,
id: obj.containingProject.id.primaryKey,
status: "active status"
} : null,
parentTaskInfo: null
};
tasks.push(taskData);
// 应用限制
if (limit > 0 && tasks.length >= limit) {
return false; // 停止收集
}
}
} catch (e) {
console.log(`处理节点时出错: ${e.message}`);
}
// 递归处理子节点
if (node.children) {
for (let child of node.children) {
if (collectTasks(child) === false) {
return false; // 传播停止信号
}
}
}
}
collectTasks(rootNode);
}
const result = {
success: true,
perspectiveInfo: perspectiveInfo,
tasks: tasks,
isReal: true,
apiVersion: "OmniFocus 4.2+ archivedFilterRules"
};
console.log(`真正的透视 "${perspectiveName}" 返回 ${tasks.length} 个任务`);
return JSON.stringify(result);
} catch (error) {
console.error(`真正的透视访问失败: ${error}`);
return JSON.stringify({
success: false,
error: `真正的透视访问失败: ${error}`,
apiVersion: "OmniFocus 4.2+ archivedFilterRules"
});
}
})();