@stephendolan/omnifocus-cli 2.1.0 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/lib/output.ts","../src/commands/task.ts","../src/lib/errors.ts","../src/lib/command-utils.ts","../src/lib/omnifocus.ts","../src/lib/dates.ts","../src/commands/project.ts","../src/commands/inbox.ts","../src/commands/search.ts","../src/commands/perspective.ts","../src/commands/tag.ts","../src/commands/folder.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createTaskCommand } from './commands/task.js';\nimport { createProjectCommand } from './commands/project.js';\nimport { createInboxCommand } from './commands/inbox.js';\nimport { createSearchCommand } from './commands/search.js';\nimport { createPerspectiveCommand } from './commands/perspective.js';\nimport { createTagCommand } from './commands/tag.js';\nimport { createFolderCommand } from './commands/folder.js';\n\nconst program = new Command();\n\nprogram\n .name('of')\n .description('A command-line interface for OmniFocus on macOS')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n });\n });\n\nprogram.addCommand(createTaskCommand());\nprogram.addCommand(createProjectCommand());\nprogram.addCommand(createInboxCommand());\nprogram.addCommand(createSearchCommand());\nprogram.addCommand(createPerspectiveCommand());\nprogram.addCommand(createTagCommand());\nprogram.addCommand(createFolderCommand());\n\nprogram.parseAsync().catch(() => {\n process.exit(1);\n});\n","export interface OutputOptions {\n compact?: boolean;\n}\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const mergedOptions = { ...globalOutputOptions, ...options };\n const jsonString = mergedOptions.compact ? JSON.stringify(data) : JSON.stringify(data, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\nimport type { TaskFilters, UpdateTaskOptions } from '../types.js';\n\nexport function createTaskCommand(): Command {\n const command = new Command('task');\n command.description('Manage OmniFocus tasks');\n\n command\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option('-f, --flagged', 'Show only flagged tasks')\n .option('-p, --project <name>', 'Filter by project')\n .option('-t, --tag <name>', 'Filter by tag')\n .option('-c, --completed', 'Include completed tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: TaskFilters = {\n includeCompleted: options.completed,\n ...(options.flagged && { flagged: true }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tag: options.tag }),\n };\n const tasks = await of.listTasks(filters);\n outputJson(tasks);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new task')\n .option('-p, --project <name>', 'Assign to project')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n project: options.project,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing task')\n .option('-n, --name <name>', 'New name')\n .option('--note <text>', 'New note')\n .option('-p, --project <name>', 'Move to project')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flag', 'Flag the task')\n .option('-F, --unflag', 'Unflag the task')\n .option('-c, --complete', 'Mark as completed')\n .option('-C, --incomplete', 'Mark as incomplete')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTaskOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tags: options.tag }),\n ...(options.due !== undefined && {\n due: options.due ? parseDateTime(options.due) : null,\n }),\n ...(options.defer !== undefined && {\n defer: options.defer ? parseDateTime(options.defer) : null,\n }),\n ...(options.flag && { flagged: true }),\n ...(options.unflag && { flagged: false }),\n ...(options.complete && { completed: true }),\n ...(options.incomplete && { completed: false }),\n ...(options.estimate !== undefined && { estimatedMinutes: options.estimate }),\n };\n const task = await of.updateTask(idOrName, updates);\n outputJson(task);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a task')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTask(idOrName);\n outputJson({ message: 'Task deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View task details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const task = await of.getTask(idOrName);\n outputJson(task);\n })\n );\n\n command\n .command('stats')\n .description('Show task statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTaskStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { outputJson } from './output.js';\n\nexport class OmniFocusCliError extends Error {\n constructor(\n message: string,\n public statusCode: number = 500\n ) {\n super(message);\n this.name = 'OmniFocusCliError';\n }\n}\n\nexport function handleError(error: unknown): never {\n let name = 'unknown_error';\n let detail = 'An unknown error occurred';\n let statusCode = 500;\n\n if (error instanceof OmniFocusCliError) {\n name = 'cli_error';\n detail = error.message;\n statusCode = error.statusCode;\n } else if (error instanceof Error) {\n name = 'omnifocus_error';\n detail = error.message;\n\n if (detail.includes('not found')) {\n statusCode = 404;\n } else if (detail.includes('Multiple')) {\n statusCode = 400;\n }\n }\n\n outputJson({ error: { name, detail, statusCode } });\n process.exit(1);\n}\n","import { handleError } from './errors.js';\n\nexport function withErrorHandling<T extends unknown[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<void> {\n return async (...args: T) => {\n try {\n await fn(...args);\n } catch (error) {\n handleError(error);\n }\n };\n}\n","import { execFile } from 'child_process';\nimport { writeFile, unlink } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { promisify } from 'util';\nimport type {\n Task,\n Project,\n TaskFilters,\n ProjectFilters,\n CreateTaskOptions,\n UpdateTaskOptions,\n CreateProjectOptions,\n UpdateProjectOptions,\n Perspective,\n Tag,\n TagListOptions,\n TagStats,\n TaskStats,\n ProjectStats,\n CreateTagOptions,\n UpdateTagOptions,\n Folder,\n FolderFilters,\n} from '../types.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport class OmniFocus {\n private readonly PROJECT_STATUS_MAP = {\n active: 'Active',\n 'on hold': 'OnHold',\n dropped: 'Dropped',\n } as const;\n\n private readonly OMNI_HELPERS = `\n function serializeTask(task) {\n const containingProject = task.containingProject;\n const tagNames = task.tags.map(t => t.name);\n\n return {\n id: task.id.primaryKey,\n name: task.name,\n note: task.note || null,\n completed: task.completed,\n dropped: task.dropped,\n effectivelyActive: task.effectiveActive,\n flagged: task.flagged,\n project: containingProject ? containingProject.name : null,\n tags: tagNames,\n defer: task.deferDate ? task.deferDate.toISOString() : null,\n due: task.dueDate ? task.dueDate.toISOString() : null,\n estimatedMinutes: task.estimatedMinutes || null,\n completionDate: task.completionDate ? task.completionDate.toISOString() : null,\n added: task.added ? task.added.toISOString() : null,\n modified: task.modified ? task.modified.toISOString() : null\n };\n }\n\n function serializeProject(project) {\n const parentFolder = project.parentFolder;\n const allTasks = project.flattenedTasks;\n const remainingTasks = allTasks.filter(t => !t.completed);\n const tagNames = project.tags.map(t => t.name);\n\n return {\n id: project.id.primaryKey,\n name: project.name,\n note: project.note || null,\n status: projectStatusToString(project.status),\n folder: parentFolder ? parentFolder.name : null,\n sequential: project.sequential,\n taskCount: allTasks.length,\n remainingCount: remainingTasks.length,\n tags: tagNames\n };\n }\n\n function findTask(idOrName) {\n for (const task of flattenedTasks) {\n if (task.id.primaryKey === idOrName || task.name === idOrName) {\n return task;\n }\n }\n throw new Error(\"Task not found: \" + idOrName);\n }\n\n function findProject(idOrName) {\n for (const project of flattenedProjects) {\n if (project.id.primaryKey === idOrName || project.name === idOrName) {\n return project;\n }\n }\n throw new Error(\"Project not found: \" + idOrName);\n }\n\n function getTagPath(tag) {\n const parts = [tag.name];\n let current = tag.parent;\n while (current) {\n parts.unshift(current.name);\n current = current.parent;\n }\n return parts.join('/');\n }\n\n function findTag(idOrName) {\n for (const tag of flattenedTags) {\n if (tag.id.primaryKey === idOrName) {\n return tag;\n }\n }\n\n if (idOrName.includes('/')) {\n for (const tag of flattenedTags) {\n if (getTagPath(tag) === idOrName) {\n return tag;\n }\n }\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n const matches = flattenedTags.filter(tag => tag.name === idOrName);\n\n if (matches.length === 0) {\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n if (matches.length > 1) {\n const paths = matches.map(getTagPath);\n throw new Error(\"Multiple tags found with name '\" + idOrName + \"'. Please use full path:\\\\n \" + paths.join('\\\\n ') + \"\\\\nOr use tag ID: \" + matches.map(t => t.id.primaryKey).join(', '));\n }\n\n return matches[0];\n }\n\n function findByName(collection, name, typeName) {\n for (const item of collection) {\n if (item.name === name) {\n return item;\n }\n }\n throw new Error(typeName + \" not found: \" + name);\n }\n\n function assignTags(target, tagNames) {\n for (const tagName of tagNames) {\n const tag = findTag(tagName);\n target.addTag(tag);\n }\n }\n\n function replaceTagsOn(target, tagNames) {\n target.clearTags();\n assignTags(target, tagNames);\n }\n\n function statusToString(status, StatusEnum) {\n if (status === StatusEnum.Active) return 'active';\n if (status === StatusEnum.OnHold) return 'on hold';\n if (status === StatusEnum.Dropped) return 'dropped';\n if (status === StatusEnum.Done) return 'done';\n return 'dropped';\n }\n\n function stringToStatus(str, StatusEnum) {\n if (str === 'active') return StatusEnum.Active;\n if (str === 'on hold') return StatusEnum.OnHold;\n return StatusEnum.Dropped;\n }\n\n const projectStatusToString = (status) => statusToString(status, Project.Status);\n const tagStatusToString = (status) => statusToString(status, Tag.Status);\n const folderStatusToString = (status) => {\n if (status === Folder.Status.Active) return 'active';\n return 'dropped';\n };\n const stringToProjectStatus = (str) => stringToStatus(str, Project.Status);\n const stringToTagStatus = (str) => stringToStatus(str, Tag.Status);\n\n function serializeFolder(folder, includeDropped = false) {\n let childFolders = folder.folders;\n if (!includeDropped) {\n childFolders = childFolders.filter(c => c.effectiveActive);\n }\n\n return {\n id: folder.id.primaryKey,\n name: folder.name,\n status: folderStatusToString(folder.status),\n effectivelyActive: folder.effectiveActive,\n parent: folder.parent ? folder.parent.name : null,\n projectCount: folder.projects.length,\n remainingProjectCount: folder.projects.filter(p => p.effectiveActive).length,\n folderCount: folder.folders.length,\n children: childFolders.map(child => serializeFolder(child, includeDropped))\n };\n }\n\n function computeTopItems(items, keyFn, topN = 5) {\n return items\n .sort((a, b) => b[keyFn] - a[keyFn])\n .slice(0, topN)\n .map(item => ({ name: item.name, [keyFn]: item[keyFn] }));\n }\n\n function computeAverage(total, count) {\n return count > 0 ? Math.round((total / count) * 10) / 10 : 0;\n }\n\n function serializeTag(tag, activeOnly = false) {\n const tasks = tag.tasks;\n const remainingTasks = tag.remainingTasks;\n const includedTasks = activeOnly ? remainingTasks : tasks;\n\n const dates = [];\n if (tag.added) dates.push(tag.added);\n if (tag.modified) dates.push(tag.modified);\n\n for (const task of includedTasks) {\n if (task.added) dates.push(task.added);\n if (task.modified) dates.push(task.modified);\n if (!activeOnly && task.completionDate) dates.push(task.completionDate);\n if (!activeOnly && task.effectiveCompletionDate) dates.push(task.effectiveCompletionDate);\n }\n\n const lastActivity = dates.length > 0\n ? dates.reduce((latest, current) => current > latest ? current : latest)\n : null;\n\n return {\n id: tag.id.primaryKey,\n name: tag.name,\n taskCount: includedTasks.length,\n remainingTaskCount: remainingTasks.length,\n added: tag.added ? tag.added.toISOString() : null,\n modified: tag.modified ? tag.modified.toISOString() : null,\n lastActivity: lastActivity ? lastActivity.toISOString() : null,\n active: tag.active,\n status: tagStatusToString(tag.status),\n parent: tag.parent ? tag.parent.name : null,\n children: tag.children.map(c => c.name),\n allowsNextAction: tag.allowsNextAction\n };\n }\n `;\n\n private async executeJXA(script: string, timeoutMs = 30000): Promise<string> {\n const tmpFile = join(tmpdir(), `omnifocus-${Date.now()}.js`);\n\n try {\n await writeFile(tmpFile, script, 'utf-8');\n\n const { stdout } = await execFileAsync('osascript', ['-l', 'JavaScript', tmpFile], {\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024,\n });\n\n return stdout.trim();\n } finally {\n try {\n await unlink(tmpFile);\n } catch {\n /* ignore cleanup errors */\n }\n }\n }\n\n private escapeString(str: string): string {\n return str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n }\n\n private wrapOmniScript(omniScript: string): string {\n return `\n const app = Application('OmniFocus');\n app.includeStandardAdditions = true;\n const result = app.evaluateJavascript(${JSON.stringify(omniScript.trim())});\n result;\n `.trim();\n }\n\n private buildTaskFilters(filters: TaskFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeCompleted) {\n conditions.push('if (task.completed) continue;');\n }\n if (!filters.includeDropped) {\n conditions.push('if (!task.effectiveActive) continue;');\n }\n if (filters.flagged) {\n conditions.push('if (!task.flagged) continue;');\n conditions.push('if (task.taskStatus !== Task.Status.Available) continue;');\n }\n if (filters.project) {\n conditions.push(`\n if (!task.containingProject || task.containingProject.name !== \"${this.escapeString(filters.project)}\") {\n continue;\n }\n `);\n }\n if (filters.tag) {\n conditions.push(`\n if (!task.tags.some(t => t.name === \"${this.escapeString(filters.tag)}\")) {\n continue;\n }\n `);\n }\n\n return conditions.join('\\n ');\n }\n\n private buildProjectFilters(filters: ProjectFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeDropped) {\n conditions.push(\n 'if (project.status === Project.Status.Dropped || project.status === Project.Status.Done) continue;'\n );\n conditions.push(\n 'if (project.parentFolder && !project.parentFolder.effectiveActive) continue;'\n );\n }\n if (filters.status) {\n const statusCheck = this.PROJECT_STATUS_MAP[filters.status];\n conditions.push(`if (project.status !== Project.Status.${statusCheck}) continue;`);\n }\n if (filters.folder) {\n conditions.push(\n `if (!project.parentFolder || project.parentFolder.name !== \"${this.escapeString(filters.folder)}\") continue;`\n );\n }\n\n return conditions.join('\\n ');\n }\n\n private buildTaskUpdates(options: UpdateTaskOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`task.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`task.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.flagged !== undefined) {\n updates.push(`task.flagged = ${options.flagged};`);\n }\n if (options.completed !== undefined) {\n updates.push(`task.completed = ${options.completed};`);\n }\n if (options.estimatedMinutes !== undefined) {\n updates.push(`task.estimatedMinutes = ${options.estimatedMinutes};`);\n }\n if (options.defer !== undefined) {\n updates.push(\n options.defer\n ? `task.deferDate = new Date(${JSON.stringify(options.defer)});`\n : 'task.deferDate = null;'\n );\n }\n if (options.due !== undefined) {\n updates.push(\n options.due\n ? `task.dueDate = new Date(${JSON.stringify(options.due)});`\n : 'task.dueDate = null;'\n );\n }\n if (options.project !== undefined && options.project) {\n updates.push(`\n const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n moveTasks([task], targetProject);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(task, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildTagUpdates(options: UpdateTagOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`tag.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.status !== undefined) {\n updates.push(`tag.status = stringToTagStatus(\"${options.status}\");`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildProjectUpdates(options: UpdateProjectOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`project.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`project.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.sequential !== undefined) {\n updates.push(`project.sequential = ${options.sequential};`);\n }\n if (options.status !== undefined) {\n updates.push(`project.status = stringToProjectStatus(\"${options.status}\");`);\n }\n if (options.folder !== undefined && options.folder) {\n updates.push(`\n const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n moveProjects([project], targetFolder);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(project, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n async listTasks(filters: TaskFilters = {}): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const task of flattenedTasks) {\n ${this.buildTaskFilters(filters)}\n results.push(serializeTask(task));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTask(options: CreateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.project\n ? `const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n const task = new Task(\"${this.escapeString(options.name)}\", targetProject);`\n : `const task = new Task(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `task.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.flagged ? 'task.flagged = true;' : ''}\n ${options.estimatedMinutes ? `task.estimatedMinutes = ${options.estimatedMinutes};` : ''}\n ${options.defer ? `task.deferDate = new Date(${JSON.stringify(options.defer)});` : ''}\n ${options.due ? `task.dueDate = new Date(${JSON.stringify(options.due)});` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(task, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTask(idOrName: string, options: UpdateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n ${this.buildTaskUpdates(options)}\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTask(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTask(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listProjects(filters: ProjectFilters = {}): Promise<Project[]> {\n const filterCode = this.buildProjectFilters(filters);\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const project of flattenedProjects) {\n ${filterCode}\n results.push(serializeProject(project));\n }\n return JSON.stringify(results);\n })();\n `;\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createProject(options: CreateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.folder\n ? `const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n const project = new Project(\"${this.escapeString(options.name)}\", targetFolder);`\n : `const project = new Project(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `project.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.sequential !== undefined ? `project.sequential = ${options.sequential};` : ''}\n ${options.status ? `project.status = stringToProjectStatus(\"${options.status}\");` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(project, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateProject(idOrName: string, options: UpdateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n ${this.buildProjectUpdates(options)}\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteProject(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findProject(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listInboxTasks(): Promise<Task[]> {\n return this.getPerspectiveTasks('Inbox');\n }\n\n async getInboxCount(): Promise<number> {\n const tasks = await this.getPerspectiveTasks('Inbox');\n return tasks.length;\n }\n\n async searchTasks(query: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const searchQuery = \"${this.escapeString(query)}\".toLowerCase();\n\n for (const task of flattenedTasks) {\n if (task.completed) continue;\n if (!task.effectiveActive) continue;\n\n const name = task.name.toLowerCase();\n const note = (task.note || '').toLowerCase();\n\n if (name.includes(searchQuery) || note.includes(searchQuery)) {\n results.push(serializeTask(task));\n }\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTask(idOrName: string): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProject(idOrName: string): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listPerspectives(): Promise<Perspective[]> {\n const omniScript = `\n (() => {\n const results = [];\n\n const builtInNames = ['Inbox', 'Flagged', 'Forecast', 'Projects', 'Tags', 'Nearby', 'Review'];\n for (const name of builtInNames) {\n results.push({ id: name, name: name });\n }\n\n const customPerspectives = Perspective.Custom.all;\n for (const perspective of customPerspectives) {\n results.push({ id: perspective.name, name: perspective.name });\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getPerspectiveTasks(perspectiveName: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const doc = document;\n const windows = doc.windows;\n\n if (windows.length === 0) {\n throw new Error(\"No OmniFocus window is open. Please open an OmniFocus window and try again.\");\n }\n\n const win = windows[0];\n const perspectiveName = \"${this.escapeString(perspectiveName)}\";\n\n const builtInPerspectives = {\n 'inbox': Perspective.BuiltIn.Inbox,\n 'flagged': Perspective.BuiltIn.Flagged,\n 'forecast': Perspective.BuiltIn.Forecast,\n 'projects': Perspective.BuiltIn.Projects,\n 'tags': Perspective.BuiltIn.Tags,\n 'nearby': Perspective.BuiltIn.Nearby,\n 'review': Perspective.BuiltIn.Review\n };\n\n const lowerName = perspectiveName.toLowerCase();\n if (builtInPerspectives[lowerName]) {\n win.perspective = builtInPerspectives[lowerName];\n } else {\n const customPerspective = Perspective.Custom.byName(perspectiveName);\n if (customPerspective) {\n win.perspective = customPerspective;\n } else {\n throw new Error(\"Perspective not found: \" + perspectiveName);\n }\n }\n\n const content = win.content;\n if (!content) {\n throw new Error(\"No content available in window\");\n }\n\n const tasks = [];\n content.rootNode.apply(node => {\n const obj = node.object;\n if (obj instanceof Task) {\n tasks.push(serializeTask(obj));\n }\n });\n\n return JSON.stringify(tasks);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript), 60000);\n return JSON.parse(output);\n }\n\n async listTags(options: TagListOptions = {}): Promise<Tag[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const now = new Date();\n const activeOnly = ${!!options.activeOnly};\n\n for (const tag of flattenedTags) {\n const serialized = serializeTag(tag, activeOnly);\n results.push(serialized);\n }\n\n ${\n options.unusedDays\n ? `\n const cutoffDate = new Date(now.getTime() - (${options.unusedDays} * 24 * 60 * 60 * 1000));\n const filtered = results.filter(tag => {\n if (!tag.lastActivity) return true;\n return new Date(tag.lastActivity) < cutoffDate;\n });\n return JSON.stringify(filtered);\n `\n : 'return JSON.stringify(results);'\n }\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n const tags = JSON.parse(output);\n\n return this.sortTags(tags, options.sortBy);\n }\n\n private sortTags(tags: Tag[], sortBy: string = 'name'): Tag[] {\n const sortFns: Record<string, (a: Tag, b: Tag) => number> = {\n usage: (a, b) => b.taskCount - a.taskCount,\n activity: (a, b) => {\n if (!a.lastActivity && !b.lastActivity) return 0;\n if (!a.lastActivity) return 1;\n if (!b.lastActivity) return -1;\n return new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime();\n },\n name: (a, b) => a.name.localeCompare(b.name),\n };\n\n return tags.sort(sortFns[sortBy] || sortFns.name);\n }\n\n async getTagStats(): Promise<TagStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTags = [];\n for (const tag of flattenedTags) {\n allTags.push(serializeTag(tag));\n }\n\n const activeTags = allTags.filter(t => t.active);\n const tagsWithTasks = allTags.filter(t => t.taskCount > 0);\n const unusedTags = allTags.filter(t => t.taskCount === 0);\n\n const totalTasks = tagsWithTasks.reduce((sum, t) => sum + t.taskCount, 0);\n const avgTasksPerTag = computeAverage(totalTasks, tagsWithTasks.length);\n\n const mostUsedTags = computeTopItems(allTags, 'taskCount');\n const leastUsedTags = computeTopItems(\n tagsWithTasks.map(t => ({ ...t, taskCount: -t.taskCount })),\n 'taskCount'\n ).map(t => ({ name: t.name, taskCount: -t.taskCount }));\n\n const now = new Date();\n const thirtyDaysAgo = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n const staleTags = allTags\n .filter(t => t.lastActivity && new Date(t.lastActivity) < thirtyDaysAgo)\n .map(t => ({\n name: t.name,\n daysSinceActivity: Math.floor((now - new Date(t.lastActivity)) / (24 * 60 * 60 * 1000))\n }))\n .sort((a, b) => b.daysSinceActivity - a.daysSinceActivity);\n\n return JSON.stringify({\n totalTags: allTags.length,\n activeTags: activeTags.length,\n tagsWithTasks: tagsWithTasks.length,\n unusedTags: unusedTags.length,\n avgTasksPerTag,\n mostUsedTags,\n leastUsedTags,\n staleTags\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTag(options: CreateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.parent\n ? `const parentTag = findTag(\"${this.escapeString(options.parent)}\");\n const tag = new Tag(\"${this.escapeString(options.name)}\", parentTag);`\n : `const tag = new Tag(\"${this.escapeString(options.name)}\", tags.beginning);`\n }\n\n ${options.status ? `tag.status = stringToTagStatus(\"${options.status}\");` : ''}\n\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTag(idOrName: string): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTag(idOrName: string, options: UpdateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n ${this.buildTagUpdates(options)}\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTag(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTag(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async getTaskStats(): Promise<TaskStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTasks = Array.from(flattenedTasks);\n const now = new Date();\n\n const activeTasks = allTasks.filter(t => !t.completed && t.effectiveActive);\n const completedTasks = allTasks.filter(t => t.completed);\n const flaggedTasks = activeTasks.filter(t => t.flagged);\n const overdueActiveTasks = activeTasks.filter(t => t.dueDate && t.dueDate < now);\n\n const tasksWithEstimates = allTasks.filter(t => t.estimatedMinutes && t.estimatedMinutes > 0);\n const totalEstimatedMinutes = tasksWithEstimates.reduce((sum, t) => sum + (t.estimatedMinutes || 0), 0);\n const avgEstimatedMinutes = tasksWithEstimates.length > 0\n ? Math.round(totalEstimatedMinutes / tasksWithEstimates.length)\n : null;\n\n const totalNonDropped = allTasks.filter(t => t.effectiveActive || t.completed).length;\n const completionRate = totalNonDropped > 0\n ? Math.round((completedTasks.length / totalNonDropped) * 100)\n : 0;\n\n const projectCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n const projectName = task.containingProject ? task.containingProject.name : 'Inbox';\n projectCounts[projectName] = (projectCounts[projectName] || 0) + 1;\n }\n const tasksByProject = computeTopItems(\n Object.entries(projectCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n const tagCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n for (const tag of task.tags) {\n tagCounts[tag.name] = (tagCounts[tag.name] || 0) + 1;\n }\n }\n const tasksByTag = computeTopItems(\n Object.entries(tagCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n return JSON.stringify({\n totalTasks: allTasks.length,\n activeTasks: activeTasks.length,\n completedTasks: completedTasks.length,\n flaggedTasks: flaggedTasks.length,\n overdueActiveTasks: overdueActiveTasks.length,\n avgEstimatedMinutes,\n tasksWithEstimates: tasksWithEstimates.length,\n completionRate,\n tasksByProject,\n tasksByTag\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProjectStats(): Promise<ProjectStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allProjects = Array.from(flattenedProjects);\n\n function isProjectEffectivelyActive(p) {\n if (p.status === Project.Status.Dropped || p.status === Project.Status.Done) return false;\n if (p.parentFolder && !p.parentFolder.effectiveActive) return false;\n return true;\n }\n\n const effectivelyActiveProjects = allProjects.filter(isProjectEffectivelyActive);\n const activeProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.Active);\n const onHoldProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.OnHold);\n const droppedProjects = allProjects.filter(p => p.status === Project.Status.Dropped);\n const doneProjects = allProjects.filter(p => p.status === Project.Status.Done);\n const sequentialProjects = effectivelyActiveProjects.filter(p => p.sequential);\n const parallelProjects = effectivelyActiveProjects.filter(p => !p.sequential);\n\n const totalTasks = effectivelyActiveProjects.reduce((sum, p) => sum + p.flattenedTasks.length, 0);\n const totalRemaining = effectivelyActiveProjects.reduce((sum, p) => {\n return sum + p.flattenedTasks.filter(t => !t.completed).length;\n }, 0);\n\n const avgTasksPerProject = computeAverage(totalTasks, effectivelyActiveProjects.length);\n const avgRemainingPerProject = computeAverage(totalRemaining, effectivelyActiveProjects.length);\n\n const completionRates = effectivelyActiveProjects\n .filter(p => p.flattenedTasks.length > 0)\n .map(p => {\n const total = p.flattenedTasks.length;\n const completed = p.flattenedTasks.filter(t => t.completed).length;\n return (completed / total) * 100;\n });\n\n const avgCompletionRate = completionRates.length > 0\n ? Math.round(completionRates.reduce((sum, rate) => sum + rate, 0) / completionRates.length)\n : 0;\n\n const projectsWithMostTasks = computeTopItems(\n effectivelyActiveProjects.map(p => ({ name: p.name, taskCount: p.flattenedTasks.length })),\n 'taskCount'\n );\n\n const projectsWithMostRemaining = computeTopItems(\n effectivelyActiveProjects\n .map(p => ({ name: p.name, remainingCount: p.flattenedTasks.filter(t => !t.completed).length }))\n .filter(p => p.remainingCount > 0),\n 'remainingCount'\n );\n\n return JSON.stringify({\n totalProjects: allProjects.length,\n activeProjects: activeProjects.length,\n onHoldProjects: onHoldProjects.length,\n droppedProjects: droppedProjects.length,\n doneProjects: doneProjects.length,\n sequentialProjects: sequentialProjects.length,\n parallelProjects: parallelProjects.length,\n avgTasksPerProject,\n avgRemainingPerProject,\n avgCompletionRate,\n projectsWithMostTasks,\n projectsWithMostRemaining\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listFolders(filters: FolderFilters = {}): Promise<Folder[]> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n const results = [];\n for (const folder of folders) {\n if (!includeDropped && !folder.effectiveActive) continue;\n results.push(serializeFolder(folder, includeDropped));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getFolder(idOrName: string, filters: FolderFilters = {}): Promise<Folder> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n\n function findFolder(idOrName) {\n for (const folder of flattenedFolders) {\n if (folder.id.primaryKey === idOrName || folder.name === idOrName) {\n return folder;\n }\n }\n throw new Error(\"Folder not found: \" + idOrName);\n }\n\n const folder = findFolder(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeFolder(folder, includeDropped));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n}\n","import dayjs from 'dayjs';\nimport { OmniFocusCliError } from './errors.js';\n\nexport function parseDateTime(input: string): string {\n const d = dayjs(input);\n if (!d.isValid()) {\n throw new OmniFocusCliError(`Invalid date: ${input}`, 400);\n }\n return d.toISOString();\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { ProjectFilters, UpdateProjectOptions } from '../types.js';\n\nexport function createProjectCommand(): Command {\n const command = new Command('project');\n command.description('Manage OmniFocus projects');\n\n command\n .command('list')\n .alias('ls')\n .description('List projects')\n .option('-f, --folder <name>', 'Filter by folder')\n .option('-s, --status <status>', 'Filter by status (active, on hold, dropped)')\n .option('-d, --dropped', 'Include dropped projects')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: ProjectFilters = {\n includeDropped: options.dropped,\n ...(options.folder && { folder: options.folder }),\n ...(options.status && { status: options.status }),\n };\n const projects = await of.listProjects(filters);\n outputJson(projects);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new project')\n .option('-f, --folder <name>', 'Assign to folder')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-s, --sequential', 'Make it a sequential project')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const project = await of.createProject({\n name,\n note: options.note,\n folder: options.folder,\n tags: options.tag,\n sequential: options.sequential,\n status: options.status,\n });\n outputJson(project);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing project')\n .option('-n, --name <name>', 'Rename project')\n .option('--note <text>', 'New note')\n .option('-f, --folder <name>', 'Move to folder')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-s, --sequential', 'Make it sequential')\n .option('-p, --parallel', 'Make it parallel')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateProjectOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.folder && { folder: options.folder }),\n ...(options.tag && { tags: options.tag }),\n ...(options.sequential && { sequential: true }),\n ...(options.parallel && { sequential: false }),\n ...(options.status && { status: options.status }),\n };\n const project = await of.updateProject(idOrName, updates);\n outputJson(project);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a project')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteProject(idOrName);\n outputJson({ message: 'Project deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View project details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const project = await of.getProject(idOrName);\n outputJson(project);\n })\n );\n\n command\n .command('stats')\n .description('Show project statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getProjectStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createInboxCommand(): Command {\n const command = new Command('inbox');\n command.description('Manage OmniFocus inbox');\n\n command\n .command('list')\n .alias('ls')\n .description('List inbox tasks')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const tasks = await of.listInboxTasks();\n outputJson(tasks);\n })\n );\n\n command\n .command('count')\n .description('Get inbox count')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const count = await of.getInboxCount();\n outputJson({ count });\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createSearchCommand(): Command {\n const command = new Command('search');\n command.description('Search tasks by name or note');\n command.argument('<query>', 'Search query');\n\n command.action(\n withErrorHandling(async (query) => {\n const of = new OmniFocus();\n const tasks = await of.searchTasks(query);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createPerspectiveCommand(): Command {\n const command = new Command('perspective');\n command.description('Manage OmniFocus perspectives');\n\n command\n .command('list')\n .alias('ls')\n .description('List all perspectives')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const perspectives = await of.listPerspectives();\n outputJson(perspectives);\n })\n );\n\n command\n .command('view <name>')\n .description('View tasks in a perspective')\n .action(\n withErrorHandling(async (name) => {\n const of = new OmniFocus();\n const tasks = await of.getPerspectiveTasks(name);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { UpdateTagOptions } from '../types.js';\n\nexport function createTagCommand(): Command {\n const command = new Command('tag');\n command.description('Manage and analyze OmniFocus tags');\n\n command\n .command('list')\n .alias('ls')\n .description('List tags with usage information')\n .option('-u, --unused-days <days>', 'Show tags unused for N days', parseInt)\n .option('-s, --sort <field>', 'Sort by: name, usage, activity (default: name)', 'name')\n .option('-a, --active-only', 'Only count active (incomplete) tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const tags = await of.listTags({\n unusedDays: options.unusedDays,\n sortBy: options.sort,\n activeOnly: options.activeOnly,\n });\n outputJson(tags);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new tag')\n .option('-p, --parent <name>', 'Create as child of parent tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const tag = await of.createTag({\n name,\n parent: options.parent,\n status: options.status,\n });\n outputJson(tag);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View tag details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const tag = await of.getTag(idOrName);\n outputJson(tag);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing tag')\n .option('-n, --name <name>', 'Rename tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTagOptions = {\n ...(options.name && { name: options.name }),\n ...(options.status && { status: options.status }),\n };\n const tag = await of.updateTag(idOrName, updates);\n outputJson(tag);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a tag')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTag(idOrName);\n outputJson({ message: 'Tag deleted successfully' });\n })\n );\n\n command\n .command('stats')\n .description('Show tag usage statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTagStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { FolderFilters } from '../types.js';\n\nexport function createFolderCommand(): Command {\n const command = new Command('folder');\n command.description('View OmniFocus folder hierarchy');\n\n command\n .command('list')\n .alias('ls')\n .description('List top-level folders with nested children')\n .option('-d, --dropped', 'Include dropped folders')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const folders = await of.listFolders({ includeDropped: options.dropped });\n outputJson(folders);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View folder details and children')\n .option('-d, --dropped', 'Include dropped child folders')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const filters: FolderFilters = { includeDropped: options.dropped };\n const folder = await of.getFolder(idOrName, filters);\n outputJson(folder);\n })\n );\n\n return command;\n}\n"],"mappings":"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","names":["Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/lib/output.ts","../src/commands/task.ts","../src/lib/errors.ts","../src/lib/command-utils.ts","../src/lib/omnifocus.ts","../src/lib/dates.ts","../src/commands/project.ts","../src/commands/inbox.ts","../src/commands/search.ts","../src/commands/perspective.ts","../src/commands/tag.ts","../src/commands/folder.ts","../src/commands/mcp.ts","../src/mcp/server.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createTaskCommand } from './commands/task.js';\nimport { createProjectCommand } from './commands/project.js';\nimport { createInboxCommand } from './commands/inbox.js';\nimport { createSearchCommand } from './commands/search.js';\nimport { createPerspectiveCommand } from './commands/perspective.js';\nimport { createTagCommand } from './commands/tag.js';\nimport { createFolderCommand } from './commands/folder.js';\nimport { createMcpCommand } from './commands/mcp.js';\n\nconst program = new Command();\n\nprogram\n .name('of')\n .description('A command-line interface for OmniFocus on macOS')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n });\n });\n\nprogram.addCommand(createTaskCommand());\nprogram.addCommand(createProjectCommand());\nprogram.addCommand(createInboxCommand());\nprogram.addCommand(createSearchCommand());\nprogram.addCommand(createPerspectiveCommand());\nprogram.addCommand(createTagCommand());\nprogram.addCommand(createFolderCommand());\nprogram.addCommand(createMcpCommand());\n\nprogram.parseAsync().catch(() => {\n process.exit(1);\n});\n","export interface OutputOptions {\n compact?: boolean;\n}\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const mergedOptions = { ...globalOutputOptions, ...options };\n const jsonString = mergedOptions.compact ? JSON.stringify(data) : JSON.stringify(data, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\nimport type { TaskFilters, UpdateTaskOptions } from '../types.js';\n\nexport function createTaskCommand(): Command {\n const command = new Command('task');\n command.description('Manage OmniFocus tasks');\n\n command\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option('-f, --flagged', 'Show only flagged tasks')\n .option('-p, --project <name>', 'Filter by project')\n .option('-t, --tag <name>', 'Filter by tag')\n .option('-c, --completed', 'Include completed tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: TaskFilters = {\n includeCompleted: options.completed,\n ...(options.flagged && { flagged: true }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tag: options.tag }),\n };\n const tasks = await of.listTasks(filters);\n outputJson(tasks);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new task')\n .option('-p, --project <name>', 'Assign to project')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n project: options.project,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing task')\n .option('-n, --name <name>', 'New name')\n .option('--note <text>', 'New note')\n .option('-p, --project <name>', 'Move to project')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flag', 'Flag the task')\n .option('-F, --unflag', 'Unflag the task')\n .option('-c, --complete', 'Mark as completed')\n .option('-C, --incomplete', 'Mark as incomplete')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTaskOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tags: options.tag }),\n ...(options.due !== undefined && {\n due: options.due ? parseDateTime(options.due) : null,\n }),\n ...(options.defer !== undefined && {\n defer: options.defer ? parseDateTime(options.defer) : null,\n }),\n ...(options.flag && { flagged: true }),\n ...(options.unflag && { flagged: false }),\n ...(options.complete && { completed: true }),\n ...(options.incomplete && { completed: false }),\n ...(options.estimate !== undefined && { estimatedMinutes: options.estimate }),\n };\n const task = await of.updateTask(idOrName, updates);\n outputJson(task);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a task')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTask(idOrName);\n outputJson({ message: 'Task deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View task details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const task = await of.getTask(idOrName);\n outputJson(task);\n })\n );\n\n command\n .command('stats')\n .description('Show task statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTaskStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { outputJson } from './output.js';\n\nexport class OmniFocusCliError extends Error {\n constructor(\n message: string,\n public statusCode: number = 500\n ) {\n super(message);\n this.name = 'OmniFocusCliError';\n }\n}\n\nexport function handleError(error: unknown): never {\n let name = 'unknown_error';\n let detail = 'An unknown error occurred';\n let statusCode = 500;\n\n if (error instanceof OmniFocusCliError) {\n name = 'cli_error';\n detail = error.message;\n statusCode = error.statusCode;\n } else if (error instanceof Error) {\n name = 'omnifocus_error';\n detail = error.message;\n\n if (detail.includes('not found')) {\n statusCode = 404;\n } else if (detail.includes('Multiple')) {\n statusCode = 400;\n }\n }\n\n outputJson({ error: { name, detail, statusCode } });\n process.exit(1);\n}\n","import { handleError } from './errors.js';\n\nexport function withErrorHandling<T extends unknown[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<void> {\n return async (...args: T) => {\n try {\n await fn(...args);\n } catch (error) {\n handleError(error);\n }\n };\n}\n","import { execFile } from 'child_process';\nimport { writeFile, unlink } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { promisify } from 'util';\nimport type {\n Task,\n Project,\n TaskFilters,\n ProjectFilters,\n CreateTaskOptions,\n UpdateTaskOptions,\n CreateProjectOptions,\n UpdateProjectOptions,\n Perspective,\n Tag,\n TagListOptions,\n TagStats,\n TaskStats,\n ProjectStats,\n CreateTagOptions,\n UpdateTagOptions,\n Folder,\n FolderFilters,\n} from '../types.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport class OmniFocus {\n private readonly PROJECT_STATUS_MAP = {\n active: 'Active',\n 'on hold': 'OnHold',\n dropped: 'Dropped',\n } as const;\n\n private readonly OMNI_HELPERS = `\n function serializeTask(task) {\n const containingProject = task.containingProject;\n const tagNames = task.tags.map(t => t.name);\n\n return {\n id: task.id.primaryKey,\n name: task.name,\n note: task.note || null,\n completed: task.completed,\n dropped: task.dropped,\n effectivelyActive: task.effectiveActive,\n flagged: task.flagged,\n project: containingProject ? containingProject.name : null,\n tags: tagNames,\n defer: task.deferDate ? task.deferDate.toISOString() : null,\n due: task.dueDate ? task.dueDate.toISOString() : null,\n estimatedMinutes: task.estimatedMinutes || null,\n completionDate: task.completionDate ? task.completionDate.toISOString() : null,\n added: task.added ? task.added.toISOString() : null,\n modified: task.modified ? task.modified.toISOString() : null\n };\n }\n\n function serializeProject(project) {\n const parentFolder = project.parentFolder;\n const allTasks = project.flattenedTasks;\n const remainingTasks = allTasks.filter(t => !t.completed);\n const tagNames = project.tags.map(t => t.name);\n\n return {\n id: project.id.primaryKey,\n name: project.name,\n note: project.note || null,\n status: projectStatusToString(project.status),\n folder: parentFolder ? parentFolder.name : null,\n sequential: project.sequential,\n taskCount: allTasks.length,\n remainingCount: remainingTasks.length,\n tags: tagNames\n };\n }\n\n function findTask(idOrName) {\n for (const task of flattenedTasks) {\n if (task.id.primaryKey === idOrName || task.name === idOrName) {\n return task;\n }\n }\n throw new Error(\"Task not found: \" + idOrName);\n }\n\n function findProject(idOrName) {\n for (const project of flattenedProjects) {\n if (project.id.primaryKey === idOrName || project.name === idOrName) {\n return project;\n }\n }\n throw new Error(\"Project not found: \" + idOrName);\n }\n\n function getTagPath(tag) {\n const parts = [tag.name];\n let current = tag.parent;\n while (current) {\n parts.unshift(current.name);\n current = current.parent;\n }\n return parts.join('/');\n }\n\n function findTag(idOrName) {\n for (const tag of flattenedTags) {\n if (tag.id.primaryKey === idOrName) {\n return tag;\n }\n }\n\n if (idOrName.includes('/')) {\n for (const tag of flattenedTags) {\n if (getTagPath(tag) === idOrName) {\n return tag;\n }\n }\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n const matches = flattenedTags.filter(tag => tag.name === idOrName);\n\n if (matches.length === 0) {\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n if (matches.length > 1) {\n const paths = matches.map(getTagPath);\n throw new Error(\"Multiple tags found with name '\" + idOrName + \"'. Please use full path:\\\\n \" + paths.join('\\\\n ') + \"\\\\nOr use tag ID: \" + matches.map(t => t.id.primaryKey).join(', '));\n }\n\n return matches[0];\n }\n\n function findByName(collection, name, typeName) {\n for (const item of collection) {\n if (item.name === name) {\n return item;\n }\n }\n throw new Error(typeName + \" not found: \" + name);\n }\n\n function assignTags(target, tagNames) {\n for (const tagName of tagNames) {\n const tag = findTag(tagName);\n target.addTag(tag);\n }\n }\n\n function replaceTagsOn(target, tagNames) {\n target.clearTags();\n assignTags(target, tagNames);\n }\n\n function statusToString(status, StatusEnum) {\n if (status === StatusEnum.Active) return 'active';\n if (status === StatusEnum.OnHold) return 'on hold';\n if (status === StatusEnum.Dropped) return 'dropped';\n if (status === StatusEnum.Done) return 'done';\n return 'dropped';\n }\n\n function stringToStatus(str, StatusEnum) {\n if (str === 'active') return StatusEnum.Active;\n if (str === 'on hold') return StatusEnum.OnHold;\n return StatusEnum.Dropped;\n }\n\n const projectStatusToString = (status) => statusToString(status, Project.Status);\n const tagStatusToString = (status) => statusToString(status, Tag.Status);\n const folderStatusToString = (status) => {\n if (status === Folder.Status.Active) return 'active';\n return 'dropped';\n };\n const stringToProjectStatus = (str) => stringToStatus(str, Project.Status);\n const stringToTagStatus = (str) => stringToStatus(str, Tag.Status);\n\n function serializeFolder(folder, includeDropped = false) {\n let childFolders = folder.folders;\n if (!includeDropped) {\n childFolders = childFolders.filter(c => c.effectiveActive);\n }\n\n return {\n id: folder.id.primaryKey,\n name: folder.name,\n status: folderStatusToString(folder.status),\n effectivelyActive: folder.effectiveActive,\n parent: folder.parent ? folder.parent.name : null,\n projectCount: folder.projects.length,\n remainingProjectCount: folder.projects.filter(p => p.effectiveActive).length,\n folderCount: folder.folders.length,\n children: childFolders.map(child => serializeFolder(child, includeDropped))\n };\n }\n\n function computeTopItems(items, keyFn, topN = 5) {\n return items\n .sort((a, b) => b[keyFn] - a[keyFn])\n .slice(0, topN)\n .map(item => ({ name: item.name, [keyFn]: item[keyFn] }));\n }\n\n function computeAverage(total, count) {\n return count > 0 ? Math.round((total / count) * 10) / 10 : 0;\n }\n\n function serializeTag(tag, activeOnly = false) {\n const tasks = tag.tasks;\n const remainingTasks = tag.remainingTasks;\n const includedTasks = activeOnly ? remainingTasks : tasks;\n\n const dates = [];\n if (tag.added) dates.push(tag.added);\n if (tag.modified) dates.push(tag.modified);\n\n for (const task of includedTasks) {\n if (task.added) dates.push(task.added);\n if (task.modified) dates.push(task.modified);\n if (!activeOnly && task.completionDate) dates.push(task.completionDate);\n if (!activeOnly && task.effectiveCompletionDate) dates.push(task.effectiveCompletionDate);\n }\n\n const lastActivity = dates.length > 0\n ? dates.reduce((latest, current) => current > latest ? current : latest)\n : null;\n\n return {\n id: tag.id.primaryKey,\n name: tag.name,\n taskCount: includedTasks.length,\n remainingTaskCount: remainingTasks.length,\n added: tag.added ? tag.added.toISOString() : null,\n modified: tag.modified ? tag.modified.toISOString() : null,\n lastActivity: lastActivity ? lastActivity.toISOString() : null,\n active: tag.active,\n status: tagStatusToString(tag.status),\n parent: tag.parent ? tag.parent.name : null,\n children: tag.children.map(c => c.name),\n allowsNextAction: tag.allowsNextAction\n };\n }\n `;\n\n private async executeJXA(script: string, timeoutMs = 30000): Promise<string> {\n const tmpFile = join(tmpdir(), `omnifocus-${Date.now()}.js`);\n\n try {\n await writeFile(tmpFile, script, 'utf-8');\n\n const { stdout } = await execFileAsync('osascript', ['-l', 'JavaScript', tmpFile], {\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024,\n });\n\n return stdout.trim();\n } finally {\n try {\n await unlink(tmpFile);\n } catch {\n /* ignore cleanup errors */\n }\n }\n }\n\n private escapeString(str: string): string {\n return str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n }\n\n private wrapOmniScript(omniScript: string): string {\n return `\n const app = Application('OmniFocus');\n app.includeStandardAdditions = true;\n const result = app.evaluateJavascript(${JSON.stringify(omniScript.trim())});\n result;\n `.trim();\n }\n\n private buildTaskFilters(filters: TaskFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeCompleted) {\n conditions.push('if (task.completed) continue;');\n }\n if (!filters.includeDropped) {\n conditions.push('if (!task.effectiveActive) continue;');\n }\n if (filters.flagged) {\n conditions.push('if (!task.flagged) continue;');\n conditions.push('if (task.taskStatus !== Task.Status.Available) continue;');\n }\n if (filters.project) {\n conditions.push(`\n if (!task.containingProject || task.containingProject.name !== \"${this.escapeString(filters.project)}\") {\n continue;\n }\n `);\n }\n if (filters.tag) {\n conditions.push(`\n if (!task.tags.some(t => t.name === \"${this.escapeString(filters.tag)}\")) {\n continue;\n }\n `);\n }\n\n return conditions.join('\\n ');\n }\n\n private buildProjectFilters(filters: ProjectFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeDropped) {\n conditions.push(\n 'if (project.status === Project.Status.Dropped || project.status === Project.Status.Done) continue;'\n );\n conditions.push(\n 'if (project.parentFolder && !project.parentFolder.effectiveActive) continue;'\n );\n }\n if (filters.status) {\n const statusCheck = this.PROJECT_STATUS_MAP[filters.status];\n conditions.push(`if (project.status !== Project.Status.${statusCheck}) continue;`);\n }\n if (filters.folder) {\n conditions.push(\n `if (!project.parentFolder || project.parentFolder.name !== \"${this.escapeString(filters.folder)}\") continue;`\n );\n }\n\n return conditions.join('\\n ');\n }\n\n private buildTaskUpdates(options: UpdateTaskOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`task.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`task.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.flagged !== undefined) {\n updates.push(`task.flagged = ${options.flagged};`);\n }\n if (options.completed !== undefined) {\n updates.push(options.completed ? 'task.markComplete();' : 'task.markIncomplete();');\n }\n if (options.estimatedMinutes !== undefined) {\n updates.push(`task.estimatedMinutes = ${options.estimatedMinutes};`);\n }\n if (options.defer !== undefined) {\n updates.push(\n options.defer\n ? `task.deferDate = new Date(${JSON.stringify(options.defer)});`\n : 'task.deferDate = null;'\n );\n }\n if (options.due !== undefined) {\n updates.push(\n options.due\n ? `task.dueDate = new Date(${JSON.stringify(options.due)});`\n : 'task.dueDate = null;'\n );\n }\n if (options.project !== undefined && options.project) {\n updates.push(`\n const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n moveTasks([task], targetProject);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(task, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildTagUpdates(options: UpdateTagOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`tag.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.status !== undefined) {\n updates.push(`tag.status = stringToTagStatus(\"${options.status}\");`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildProjectUpdates(options: UpdateProjectOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`project.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`project.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.sequential !== undefined) {\n updates.push(`project.sequential = ${options.sequential};`);\n }\n if (options.status !== undefined) {\n updates.push(`project.status = stringToProjectStatus(\"${options.status}\");`);\n }\n if (options.folder !== undefined && options.folder) {\n updates.push(`\n const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n moveProjects([project], targetFolder);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(project, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n async listTasks(filters: TaskFilters = {}): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const task of flattenedTasks) {\n ${this.buildTaskFilters(filters)}\n results.push(serializeTask(task));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTask(options: CreateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.project\n ? `const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n const task = new Task(\"${this.escapeString(options.name)}\", targetProject);`\n : `const task = new Task(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `task.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.flagged ? 'task.flagged = true;' : ''}\n ${options.estimatedMinutes ? `task.estimatedMinutes = ${options.estimatedMinutes};` : ''}\n ${options.defer ? `task.deferDate = new Date(${JSON.stringify(options.defer)});` : ''}\n ${options.due ? `task.dueDate = new Date(${JSON.stringify(options.due)});` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(task, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTask(idOrName: string, options: UpdateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n ${this.buildTaskUpdates(options)}\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTask(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTask(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listProjects(filters: ProjectFilters = {}): Promise<Project[]> {\n const filterCode = this.buildProjectFilters(filters);\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const project of flattenedProjects) {\n ${filterCode}\n results.push(serializeProject(project));\n }\n return JSON.stringify(results);\n })();\n `;\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createProject(options: CreateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.folder\n ? `const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n const project = new Project(\"${this.escapeString(options.name)}\", targetFolder);`\n : `const project = new Project(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `project.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.sequential !== undefined ? `project.sequential = ${options.sequential};` : ''}\n ${options.status ? `project.status = stringToProjectStatus(\"${options.status}\");` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(project, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateProject(idOrName: string, options: UpdateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n ${this.buildProjectUpdates(options)}\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteProject(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findProject(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listInboxTasks(): Promise<Task[]> {\n return this.getPerspectiveTasks('Inbox');\n }\n\n async getInboxCount(): Promise<number> {\n const tasks = await this.getPerspectiveTasks('Inbox');\n return tasks.length;\n }\n\n async searchTasks(query: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const searchQuery = \"${this.escapeString(query)}\".toLowerCase();\n\n for (const task of flattenedTasks) {\n if (task.completed) continue;\n if (!task.effectiveActive) continue;\n\n const name = task.name.toLowerCase();\n const note = (task.note || '').toLowerCase();\n\n if (name.includes(searchQuery) || note.includes(searchQuery)) {\n results.push(serializeTask(task));\n }\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTask(idOrName: string): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProject(idOrName: string): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listPerspectives(): Promise<Perspective[]> {\n const omniScript = `\n (() => {\n const results = [];\n\n const builtInNames = ['Inbox', 'Flagged', 'Forecast', 'Projects', 'Tags', 'Nearby', 'Review'];\n for (const name of builtInNames) {\n results.push({ id: name, name: name });\n }\n\n const customPerspectives = Perspective.Custom.all;\n for (const perspective of customPerspectives) {\n results.push({ id: perspective.name, name: perspective.name });\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getPerspectiveTasks(perspectiveName: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const doc = document;\n const windows = doc.windows;\n\n if (windows.length === 0) {\n throw new Error(\"No OmniFocus window is open. Please open an OmniFocus window and try again.\");\n }\n\n const win = windows[0];\n const perspectiveName = \"${this.escapeString(perspectiveName)}\";\n\n const builtInPerspectives = {\n 'inbox': Perspective.BuiltIn.Inbox,\n 'flagged': Perspective.BuiltIn.Flagged,\n 'forecast': Perspective.BuiltIn.Forecast,\n 'projects': Perspective.BuiltIn.Projects,\n 'tags': Perspective.BuiltIn.Tags,\n 'nearby': Perspective.BuiltIn.Nearby,\n 'review': Perspective.BuiltIn.Review\n };\n\n const lowerName = perspectiveName.toLowerCase();\n if (builtInPerspectives[lowerName]) {\n win.perspective = builtInPerspectives[lowerName];\n } else {\n const customPerspective = Perspective.Custom.byName(perspectiveName);\n if (customPerspective) {\n win.perspective = customPerspective;\n } else {\n throw new Error(\"Perspective not found: \" + perspectiveName);\n }\n }\n\n const content = win.content;\n if (!content) {\n throw new Error(\"No content available in window\");\n }\n\n const tasks = [];\n content.rootNode.apply(node => {\n const obj = node.object;\n if (obj instanceof Task) {\n tasks.push(serializeTask(obj));\n }\n });\n\n return JSON.stringify(tasks);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript), 60000);\n return JSON.parse(output);\n }\n\n async listTags(options: TagListOptions = {}): Promise<Tag[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const now = new Date();\n const activeOnly = ${!!options.activeOnly};\n\n for (const tag of flattenedTags) {\n const serialized = serializeTag(tag, activeOnly);\n results.push(serialized);\n }\n\n ${\n options.unusedDays\n ? `\n const cutoffDate = new Date(now.getTime() - (${options.unusedDays} * 24 * 60 * 60 * 1000));\n const filtered = results.filter(tag => {\n if (!tag.lastActivity) return true;\n return new Date(tag.lastActivity) < cutoffDate;\n });\n return JSON.stringify(filtered);\n `\n : 'return JSON.stringify(results);'\n }\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n const tags = JSON.parse(output);\n\n return this.sortTags(tags, options.sortBy);\n }\n\n private sortTags(tags: Tag[], sortBy: string = 'name'): Tag[] {\n const sortFns: Record<string, (a: Tag, b: Tag) => number> = {\n usage: (a, b) => b.taskCount - a.taskCount,\n activity: (a, b) => {\n if (!a.lastActivity && !b.lastActivity) return 0;\n if (!a.lastActivity) return 1;\n if (!b.lastActivity) return -1;\n return new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime();\n },\n name: (a, b) => a.name.localeCompare(b.name),\n };\n\n return tags.sort(sortFns[sortBy] || sortFns.name);\n }\n\n async getTagStats(): Promise<TagStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTags = [];\n for (const tag of flattenedTags) {\n allTags.push(serializeTag(tag));\n }\n\n const activeTags = allTags.filter(t => t.active);\n const tagsWithTasks = allTags.filter(t => t.taskCount > 0);\n const unusedTags = allTags.filter(t => t.taskCount === 0);\n\n const totalTasks = tagsWithTasks.reduce((sum, t) => sum + t.taskCount, 0);\n const avgTasksPerTag = computeAverage(totalTasks, tagsWithTasks.length);\n\n const mostUsedTags = computeTopItems(allTags, 'taskCount');\n const leastUsedTags = computeTopItems(\n tagsWithTasks.map(t => ({ ...t, taskCount: -t.taskCount })),\n 'taskCount'\n ).map(t => ({ name: t.name, taskCount: -t.taskCount }));\n\n const now = new Date();\n const thirtyDaysAgo = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n const staleTags = allTags\n .filter(t => t.lastActivity && new Date(t.lastActivity) < thirtyDaysAgo)\n .map(t => ({\n name: t.name,\n daysSinceActivity: Math.floor((now - new Date(t.lastActivity)) / (24 * 60 * 60 * 1000))\n }))\n .sort((a, b) => b.daysSinceActivity - a.daysSinceActivity);\n\n return JSON.stringify({\n totalTags: allTags.length,\n activeTags: activeTags.length,\n tagsWithTasks: tagsWithTasks.length,\n unusedTags: unusedTags.length,\n avgTasksPerTag,\n mostUsedTags,\n leastUsedTags,\n staleTags\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTag(options: CreateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.parent\n ? `const parentTag = findTag(\"${this.escapeString(options.parent)}\");\n const tag = new Tag(\"${this.escapeString(options.name)}\", parentTag);`\n : `const tag = new Tag(\"${this.escapeString(options.name)}\", tags.beginning);`\n }\n\n ${options.status ? `tag.status = stringToTagStatus(\"${options.status}\");` : ''}\n\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTag(idOrName: string): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTag(idOrName: string, options: UpdateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n ${this.buildTagUpdates(options)}\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTag(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTag(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async getTaskStats(): Promise<TaskStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTasks = Array.from(flattenedTasks);\n const now = new Date();\n\n const activeTasks = allTasks.filter(t => !t.completed && t.effectiveActive);\n const completedTasks = allTasks.filter(t => t.completed);\n const flaggedTasks = activeTasks.filter(t => t.flagged);\n const overdueActiveTasks = activeTasks.filter(t => t.dueDate && t.dueDate < now);\n\n const tasksWithEstimates = allTasks.filter(t => t.estimatedMinutes && t.estimatedMinutes > 0);\n const totalEstimatedMinutes = tasksWithEstimates.reduce((sum, t) => sum + (t.estimatedMinutes || 0), 0);\n const avgEstimatedMinutes = tasksWithEstimates.length > 0\n ? Math.round(totalEstimatedMinutes / tasksWithEstimates.length)\n : null;\n\n const totalNonDropped = allTasks.filter(t => t.effectiveActive || t.completed).length;\n const completionRate = totalNonDropped > 0\n ? Math.round((completedTasks.length / totalNonDropped) * 100)\n : 0;\n\n const projectCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n const projectName = task.containingProject ? task.containingProject.name : 'Inbox';\n projectCounts[projectName] = (projectCounts[projectName] || 0) + 1;\n }\n const tasksByProject = computeTopItems(\n Object.entries(projectCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n const tagCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n for (const tag of task.tags) {\n tagCounts[tag.name] = (tagCounts[tag.name] || 0) + 1;\n }\n }\n const tasksByTag = computeTopItems(\n Object.entries(tagCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n return JSON.stringify({\n totalTasks: allTasks.length,\n activeTasks: activeTasks.length,\n completedTasks: completedTasks.length,\n flaggedTasks: flaggedTasks.length,\n overdueActiveTasks: overdueActiveTasks.length,\n avgEstimatedMinutes,\n tasksWithEstimates: tasksWithEstimates.length,\n completionRate,\n tasksByProject,\n tasksByTag\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProjectStats(): Promise<ProjectStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allProjects = Array.from(flattenedProjects);\n\n function isProjectEffectivelyActive(p) {\n if (p.status === Project.Status.Dropped || p.status === Project.Status.Done) return false;\n if (p.parentFolder && !p.parentFolder.effectiveActive) return false;\n return true;\n }\n\n const effectivelyActiveProjects = allProjects.filter(isProjectEffectivelyActive);\n const activeProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.Active);\n const onHoldProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.OnHold);\n const droppedProjects = allProjects.filter(p => p.status === Project.Status.Dropped);\n const doneProjects = allProjects.filter(p => p.status === Project.Status.Done);\n const sequentialProjects = effectivelyActiveProjects.filter(p => p.sequential);\n const parallelProjects = effectivelyActiveProjects.filter(p => !p.sequential);\n\n const totalTasks = effectivelyActiveProjects.reduce((sum, p) => sum + p.flattenedTasks.length, 0);\n const totalRemaining = effectivelyActiveProjects.reduce((sum, p) => {\n return sum + p.flattenedTasks.filter(t => !t.completed).length;\n }, 0);\n\n const avgTasksPerProject = computeAverage(totalTasks, effectivelyActiveProjects.length);\n const avgRemainingPerProject = computeAverage(totalRemaining, effectivelyActiveProjects.length);\n\n const completionRates = effectivelyActiveProjects\n .filter(p => p.flattenedTasks.length > 0)\n .map(p => {\n const total = p.flattenedTasks.length;\n const completed = p.flattenedTasks.filter(t => t.completed).length;\n return (completed / total) * 100;\n });\n\n const avgCompletionRate = completionRates.length > 0\n ? Math.round(completionRates.reduce((sum, rate) => sum + rate, 0) / completionRates.length)\n : 0;\n\n const projectsWithMostTasks = computeTopItems(\n effectivelyActiveProjects.map(p => ({ name: p.name, taskCount: p.flattenedTasks.length })),\n 'taskCount'\n );\n\n const projectsWithMostRemaining = computeTopItems(\n effectivelyActiveProjects\n .map(p => ({ name: p.name, remainingCount: p.flattenedTasks.filter(t => !t.completed).length }))\n .filter(p => p.remainingCount > 0),\n 'remainingCount'\n );\n\n return JSON.stringify({\n totalProjects: allProjects.length,\n activeProjects: activeProjects.length,\n onHoldProjects: onHoldProjects.length,\n droppedProjects: droppedProjects.length,\n doneProjects: doneProjects.length,\n sequentialProjects: sequentialProjects.length,\n parallelProjects: parallelProjects.length,\n avgTasksPerProject,\n avgRemainingPerProject,\n avgCompletionRate,\n projectsWithMostTasks,\n projectsWithMostRemaining\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listFolders(filters: FolderFilters = {}): Promise<Folder[]> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n const results = [];\n for (const folder of folders) {\n if (!includeDropped && !folder.effectiveActive) continue;\n results.push(serializeFolder(folder, includeDropped));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getFolder(idOrName: string, filters: FolderFilters = {}): Promise<Folder> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n\n function findFolder(idOrName) {\n for (const folder of flattenedFolders) {\n if (folder.id.primaryKey === idOrName || folder.name === idOrName) {\n return folder;\n }\n }\n throw new Error(\"Folder not found: \" + idOrName);\n }\n\n const folder = findFolder(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeFolder(folder, includeDropped));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n}\n","import dayjs from 'dayjs';\nimport { OmniFocusCliError } from './errors.js';\n\nexport function parseDateTime(input: string): string {\n const d = dayjs(input);\n if (!d.isValid()) {\n throw new OmniFocusCliError(`Invalid date: ${input}`, 400);\n }\n return d.toISOString();\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { ProjectFilters, UpdateProjectOptions } from '../types.js';\n\nexport function createProjectCommand(): Command {\n const command = new Command('project');\n command.description('Manage OmniFocus projects');\n\n command\n .command('list')\n .alias('ls')\n .description('List projects')\n .option('-f, --folder <name>', 'Filter by folder')\n .option('-s, --status <status>', 'Filter by status (active, on hold, dropped)')\n .option('-d, --dropped', 'Include dropped projects')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: ProjectFilters = {\n includeDropped: options.dropped,\n ...(options.folder && { folder: options.folder }),\n ...(options.status && { status: options.status }),\n };\n const projects = await of.listProjects(filters);\n outputJson(projects);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new project')\n .option('-f, --folder <name>', 'Assign to folder')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-s, --sequential', 'Make it a sequential project')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const project = await of.createProject({\n name,\n note: options.note,\n folder: options.folder,\n tags: options.tag,\n sequential: options.sequential,\n status: options.status,\n });\n outputJson(project);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing project')\n .option('-n, --name <name>', 'Rename project')\n .option('--note <text>', 'New note')\n .option('-f, --folder <name>', 'Move to folder')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-s, --sequential', 'Make it sequential')\n .option('-p, --parallel', 'Make it parallel')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateProjectOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.folder && { folder: options.folder }),\n ...(options.tag && { tags: options.tag }),\n ...(options.sequential && { sequential: true }),\n ...(options.parallel && { sequential: false }),\n ...(options.status && { status: options.status }),\n };\n const project = await of.updateProject(idOrName, updates);\n outputJson(project);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a project')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteProject(idOrName);\n outputJson({ message: 'Project deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View project details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const project = await of.getProject(idOrName);\n outputJson(project);\n })\n );\n\n command\n .command('stats')\n .description('Show project statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getProjectStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\n\nexport function createInboxCommand(): Command {\n const command = new Command('inbox');\n command.description('Manage OmniFocus inbox');\n\n command\n .command('list')\n .alias('ls')\n .description('List inbox tasks')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const tasks = await of.listInboxTasks();\n outputJson(tasks);\n })\n );\n\n command\n .command('count')\n .description('Get inbox count')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const count = await of.getInboxCount();\n outputJson({ count });\n })\n );\n\n command\n .command('add <name>')\n .description('Add a task to inbox')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createSearchCommand(): Command {\n const command = new Command('search');\n command.description('Search tasks by name or note');\n command.argument('<query>', 'Search query');\n\n command.action(\n withErrorHandling(async (query) => {\n const of = new OmniFocus();\n const tasks = await of.searchTasks(query);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createPerspectiveCommand(): Command {\n const command = new Command('perspective');\n command.description('Manage OmniFocus perspectives');\n\n command\n .command('list')\n .alias('ls')\n .description('List all perspectives')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const perspectives = await of.listPerspectives();\n outputJson(perspectives);\n })\n );\n\n command\n .command('view <name>')\n .description('View tasks in a perspective')\n .action(\n withErrorHandling(async (name) => {\n const of = new OmniFocus();\n const tasks = await of.getPerspectiveTasks(name);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { UpdateTagOptions } from '../types.js';\n\nexport function createTagCommand(): Command {\n const command = new Command('tag');\n command.description('Manage and analyze OmniFocus tags');\n\n command\n .command('list')\n .alias('ls')\n .description('List tags with usage information')\n .option('-u, --unused-days <days>', 'Show tags unused for N days', parseInt)\n .option('-s, --sort <field>', 'Sort by: name, usage, activity (default: name)', 'name')\n .option('-a, --active-only', 'Only count active (incomplete) tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const tags = await of.listTags({\n unusedDays: options.unusedDays,\n sortBy: options.sort,\n activeOnly: options.activeOnly,\n });\n outputJson(tags);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new tag')\n .option('-p, --parent <name>', 'Create as child of parent tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const tag = await of.createTag({\n name,\n parent: options.parent,\n status: options.status,\n });\n outputJson(tag);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View tag details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const tag = await of.getTag(idOrName);\n outputJson(tag);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing tag')\n .option('-n, --name <name>', 'Rename tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTagOptions = {\n ...(options.name && { name: options.name }),\n ...(options.status && { status: options.status }),\n };\n const tag = await of.updateTag(idOrName, updates);\n outputJson(tag);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a tag')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTag(idOrName);\n outputJson({ message: 'Tag deleted successfully' });\n })\n );\n\n command\n .command('stats')\n .description('Show tag usage statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTagStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { FolderFilters } from '../types.js';\n\nexport function createFolderCommand(): Command {\n const command = new Command('folder');\n command.description('View OmniFocus folder hierarchy');\n\n command\n .command('list')\n .alias('ls')\n .description('List top-level folders with nested children')\n .option('-d, --dropped', 'Include dropped folders')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const folders = await of.listFolders({ includeDropped: options.dropped });\n outputJson(folders);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View folder details and children')\n .option('-d, --dropped', 'Include dropped child folders')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const filters: FolderFilters = { includeDropped: options.dropped };\n const folder = await of.getFolder(idOrName, filters);\n outputJson(folder);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { runMcpServer } from '../mcp/server.js';\n\nexport function createMcpCommand(): Command {\n const cmd = new Command('mcp').description('Run OmniFocus MCP server');\n\n cmd.action(async () => {\n await runMcpServer();\n });\n\n return cmd;\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nconst server = new McpServer({\n name: 'omnifocus',\n version: '1.0.0',\n});\n\nconst of = new OmniFocus();\n\nfunction jsonResponse(data: unknown) {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }] };\n}\n\nserver.tool(\n 'list_tasks',\n 'List tasks with optional filtering',\n {\n includeCompleted: z.boolean().optional().describe('Include completed tasks'),\n includeDropped: z.boolean().optional().describe('Include dropped tasks'),\n flagged: z.boolean().optional().describe('Only show flagged tasks'),\n project: z.string().optional().describe('Filter by project name'),\n tag: z.string().optional().describe('Filter by tag name'),\n },\n async (filters) => jsonResponse(await of.listTasks(filters))\n);\n\nserver.tool(\n 'get_task',\n 'Get a specific task by ID or name',\n { idOrName: z.string().describe('Task ID or name') },\n async ({ idOrName }) => jsonResponse(await of.getTask(idOrName))\n);\n\nserver.tool(\n 'create_task',\n 'Create a new task',\n {\n name: z.string().describe('Task name'),\n note: z.string().optional().describe('Task note'),\n project: z.string().optional().describe('Project to add task to'),\n tags: z.array(z.string()).optional().describe('Tags to assign'),\n defer: z.string().optional().describe('Defer date (ISO 8601)'),\n due: z.string().optional().describe('Due date (ISO 8601)'),\n flagged: z.boolean().optional().describe('Flag the task'),\n estimatedMinutes: z.number().optional().describe('Estimated duration in minutes'),\n },\n async (options) => jsonResponse(await of.createTask(options))\n);\n\nserver.tool(\n 'update_task',\n 'Update an existing task',\n {\n idOrName: z.string().describe('Task ID or name'),\n name: z.string().optional().describe('New task name'),\n note: z.string().optional().describe('New task note'),\n project: z.string().optional().describe('Move to project'),\n tags: z.array(z.string()).optional().describe('Replace tags'),\n defer: z.string().optional().describe('New defer date (ISO 8601)'),\n due: z.string().optional().describe('New due date (ISO 8601)'),\n flagged: z.boolean().optional().describe('Flag/unflag the task'),\n estimatedMinutes: z.number().optional().describe('New estimated duration'),\n completed: z.boolean().optional().describe('Mark complete/incomplete'),\n },\n async ({ idOrName, ...options }) => jsonResponse(await of.updateTask(idOrName, options))\n);\n\nserver.tool(\n 'delete_task',\n 'Delete a task',\n { idOrName: z.string().describe('Task ID or name') },\n async ({ idOrName }) => {\n await of.deleteTask(idOrName);\n return jsonResponse({ deleted: true });\n }\n);\n\nserver.tool(\n 'search_tasks',\n 'Search tasks by name or note content',\n { query: z.string().describe('Search query') },\n async ({ query }) => jsonResponse(await of.searchTasks(query))\n);\n\nserver.tool(\n 'get_task_stats',\n 'Get task statistics',\n {},\n async () => jsonResponse(await of.getTaskStats())\n);\n\nserver.tool(\n 'list_inbox',\n 'List all inbox tasks',\n {},\n async () => jsonResponse(await of.listInboxTasks())\n);\n\nserver.tool(\n 'get_inbox_count',\n 'Get the number of inbox tasks',\n {},\n async () => jsonResponse({ count: await of.getInboxCount() })\n);\n\nserver.tool(\n 'list_projects',\n 'List projects with optional filtering',\n {\n includeDropped: z.boolean().optional().describe('Include dropped projects'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('Filter by status'),\n folder: z.string().optional().describe('Filter by folder name'),\n },\n async (filters) => jsonResponse(await of.listProjects(filters))\n);\n\nserver.tool(\n 'get_project',\n 'Get a specific project by ID or name',\n { idOrName: z.string().describe('Project ID or name') },\n async ({ idOrName }) => jsonResponse(await of.getProject(idOrName))\n);\n\nserver.tool(\n 'create_project',\n 'Create a new project',\n {\n name: z.string().describe('Project name'),\n note: z.string().optional().describe('Project note'),\n folder: z.string().optional().describe('Folder to create project in'),\n sequential: z.boolean().optional().describe('Sequential project (tasks must be done in order)'),\n tags: z.array(z.string()).optional().describe('Tags to assign'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('Initial status'),\n },\n async (options) => jsonResponse(await of.createProject(options))\n);\n\nserver.tool(\n 'update_project',\n 'Update an existing project',\n {\n idOrName: z.string().describe('Project ID or name'),\n name: z.string().optional().describe('New project name'),\n note: z.string().optional().describe('New project note'),\n folder: z.string().optional().describe('Move to folder'),\n sequential: z.boolean().optional().describe('Set sequential/parallel'),\n tags: z.array(z.string()).optional().describe('Replace tags'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('New status'),\n },\n async ({ idOrName, ...options }) => jsonResponse(await of.updateProject(idOrName, options))\n);\n\nserver.tool(\n 'delete_project',\n 'Delete a project',\n { idOrName: z.string().describe('Project ID or name') },\n async ({ idOrName }) => {\n await of.deleteProject(idOrName);\n return jsonResponse({ deleted: true });\n }\n);\n\nserver.tool(\n 'get_project_stats',\n 'Get project statistics',\n {},\n async () => jsonResponse(await of.getProjectStats())\n);\n\nserver.tool(\n 'list_perspectives',\n 'List all available perspectives',\n {},\n async () => jsonResponse(await of.listPerspectives())\n);\n\nserver.tool(\n 'get_perspective_tasks',\n 'Get tasks from a specific perspective',\n { name: z.string().describe('Perspective name (e.g., Inbox, Flagged, or custom perspective)') },\n async ({ name }) => jsonResponse(await of.getPerspectiveTasks(name))\n);\n\nserver.tool(\n 'list_tags',\n 'List all tags with optional filtering and sorting',\n {\n unusedDays: z.number().optional().describe('Only show tags unused for this many days'),\n sortBy: z.enum(['name', 'usage', 'activity']).optional().describe('Sort order'),\n activeOnly: z.boolean().optional().describe('Only count active tasks'),\n },\n async (options) => jsonResponse(await of.listTags(options))\n);\n\nserver.tool(\n 'get_tag',\n 'Get a specific tag by ID or name',\n { idOrName: z.string().describe('Tag ID, name, or path (e.g., \"Parent/Child\")') },\n async ({ idOrName }) => jsonResponse(await of.getTag(idOrName))\n);\n\nserver.tool(\n 'create_tag',\n 'Create a new tag',\n {\n name: z.string().describe('Tag name'),\n parent: z.string().optional().describe('Parent tag name or path'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('Initial status'),\n },\n async (options) => jsonResponse(await of.createTag(options))\n);\n\nserver.tool(\n 'update_tag',\n 'Update an existing tag',\n {\n idOrName: z.string().describe('Tag ID, name, or path'),\n name: z.string().optional().describe('New tag name'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('New status'),\n },\n async ({ idOrName, ...options }) => jsonResponse(await of.updateTag(idOrName, options))\n);\n\nserver.tool(\n 'delete_tag',\n 'Delete a tag',\n { idOrName: z.string().describe('Tag ID, name, or path') },\n async ({ idOrName }) => {\n await of.deleteTag(idOrName);\n return jsonResponse({ deleted: true });\n }\n);\n\nserver.tool(\n 'get_tag_stats',\n 'Get tag statistics',\n {},\n async () => jsonResponse(await of.getTagStats())\n);\n\nserver.tool(\n 'list_folders',\n 'List all folders',\n { includeDropped: z.boolean().optional().describe('Include dropped folders') },\n async (filters) => jsonResponse(await of.listFolders(filters))\n);\n\nserver.tool(\n 'get_folder',\n 'Get a specific folder by ID or name',\n {\n idOrName: z.string().describe('Folder ID or name'),\n includeDropped: z.boolean().optional().describe('Include dropped children'),\n },\n async ({ idOrName, includeDropped }) => jsonResponse(await of.getFolder(idOrName, { includeDropped }))\n);\n\nexport async function runMcpServer() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"mappings":"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","names":["Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stephendolan/omnifocus-cli",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "description": "A command-line interface for OmniFocus on macOS",
5
5
  "main": "dist/cli.js",
6
6
  "type": "module",
@@ -48,8 +48,10 @@
48
48
  "bun": ">=1.0.0"
49
49
  },
50
50
  "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.12.0",
51
52
  "commander": "^12.1.0",
52
- "dayjs": "^1.11.19"
53
+ "dayjs": "^1.11.19",
54
+ "zod": "^3.24.0"
53
55
  },
54
56
  "devDependencies": {
55
57
  "@biomejs/biome": "^1.9.4",