@ofocus/sdk
v0.4.0
Published
OmniFocus SDK - Core library for interacting with OmniFocus
Readme
@ofocus/sdk
Core SDK for interacting with OmniFocus via AppleScript.
Installation
pnpm add @ofocus/sdkUsage
import {
addToInbox,
queryTasks,
queryProjects,
completeTask,
success,
failure,
} from "@ofocus/sdk";
// Add a task to the inbox
const result = await addToInbox("Buy groceries", {
note: "Milk, eggs, bread",
due: "tomorrow 5pm",
flag: true,
tags: ["errands"],
});
if (result.success) {
console.log("Created task:", result.data.id);
} else {
console.error("Error:", result.error.message);
}
// Query tasks
const tasks = await queryTasks({
flagged: true,
available: true,
});
// Complete a task
await completeTask("task-id-here");Querying Tasks
Use Filters First
Always prefer filtering to fetching everything. The SDK supports many filters:
// Get flagged tasks only
const flagged = await queryTasks({ flagged: true });
// Get tasks in a specific project
const projectTasks = await queryTasks({ project: "Project Name" });
// Get tasks with a specific tag
const tagged = await queryTasks({ tag: "urgent" });
// Get tasks due soon
const dueSoon = await queryTasks({ dueBefore: "2024-12-31" });
// Get available (actionable) tasks
const available = await queryTasks({ available: true });
// Combine filters
const urgentAvailable = await queryTasks({ flagged: true, available: true });Inbox vs Project Tasks
queryTasks() returns both inbox tasks and project tasks:
- Inbox tasks:
projectId === null(not assigned to any project) - Project tasks:
projectIdis set
const result = await queryTasks({ flagged: true });
if (result.success) {
const inboxTasks = result.data.items.filter((t) => t.projectId === null);
const projectTasks = result.data.items.filter((t) => t.projectId !== null);
}Pagination
All query functions return paginated results (default limit: 100 items):
// First page (default)
const page1 = await queryTasks({ flagged: true });
// Check if there are more results
if (page1.data.hasMore) {
const page2 = await queryTasks({ flagged: true, offset: 100 });
}
// Smaller pages for efficiency
const smallPage = await queryTasks({ limit: 20, offset: 0 });Result format:
interface PaginatedResult<T> {
items: T[]; // The items for this page
totalCount: number; // Total items matching the query (before pagination)
returnedCount: number; // Items in this page
hasMore: boolean; // Whether more items exist
offset: number; // The offset used
limit: number; // The limit used
}Note: Only increase the limit beyond 100 when you specifically need all matching items. For most agent tasks, filters and pagination are more efficient.
API
Commands
addToInbox(title, options?)- Add a task to the OmniFocus inboxqueryTasks(options?)- Query tasks with optional filtersqueryProjects(options?)- Query projects with optional filtersqueryTags(options?)- Query tags with optional filtersqueryFolders(options?)- Query folders with optional filterscompleteTask(taskId)- Mark a task as completeupdateTask(taskId, options)- Update task propertiesdeleteTask(taskId)- Permanently delete a taskdeleteProject(projectId)- Permanently delete a projectdeleteTag(tagId)- Permanently delete a tagdeleteFolder(folderId)- Permanently delete a folder
Result Helpers
success(data)- Create a successful resultfailure(error)- Create a failed resultfailureMessage(message)- Create a failed result with a string message
Error Handling
ErrorCode- Enum of error codes for semantic error handlingcreateError(code, message, details?)- Create a structured errorparseAppleScriptError(rawError)- Parse AppleScript errors
Utilities
escapeAppleScript(str)- Escape strings for AppleScriptvalidateId(id, type)- Validate OmniFocus IDsvalidateDateString(dateStr)- Validate date stringsvalidateTags(tags)- Validate tag namesvalidateProjectName(name)- Validate project names
License
MIT
