Repository navigation
Conversation
- Replace temp file based osascript execution with stdin pipe via spawn(),
eliminating fs write/delete overhead on every JXA invocation.
- Rewrite listInboxTasks() to use the `inbox` global object directly
instead of getPerspectiveTasks('Inbox'), removing the requirement for
an open OmniFocus window.
- Optimize getInboxCount() to count tasks in-process without serializing
every task object through JSON.
- Remove unused imports: writeFile, unlink, tmpdir, join, promisify.
When stdout is a TTY (interactive terminal), commands now display results as formatted tables instead of raw JSON. Pipe or redirect output retains JSON for machine consumption. Use --json/-j to force JSON output in a terminal. Supported table formats: - task list/view/search/inbox list: flag, name, project, tags, due, added - project list/view: name, status, folder, remaining/total tasks, tags - tag list/view: name, task count, remaining, status, parent, activity - folder list/view: hierarchical name, status, project counts - perspective list: name - stats commands: key-value format - inbox count: plain text "Count: N" Behavior: - TTY → table (default), --json forces JSON - Pipe/redirect → JSON (always), backward compatible - --compact → JSON (single line), unchanged
Add `of task complete` (alias `done`) and update `of task delete` to accept multiple task IDs/names in a single invocation. Both execute in a single JXA call, avoiding per-task process fork overhead. Examples: of task complete id1 id2 id3 of task done "task name A" "task name B" of task delete id1 id2 id3 of task rm "task name A" "task name B" This enables efficient bulk cleanup — completing or deleting 10 tasks takes ~650ms (one osascript call) instead of ~6.5s (ten calls).
44 new tests covering: - Type guards (isTask, isProject, isTag, isFolder, isPerspective, isRecord) - Table utilities (pad, relativeDate, shortDate, renderTable) - Table formatters (formatTaskTable, formatProjectTable, formatTagTable, formatFolderTable, formatPerspectiveTable, formatKeyValue) Exported pure functions from output.ts to enable direct testing. Total test count: 15 (display) + 44 (output) = 59.
This was referenced Oct 7, 2026
stephendolan
added a commit
that referenced
this pull request
Oct 7, 2026
…ed (#48) executeJXA wrote every script to $TMPDIR/omnifocus-<Date.now()>.js. Calls in the same millisecond, which the MCP server produces whenever a client makes parallel tool calls, shared that file: one call ran the other's script, or failed with osascript error -43 after a sibling call deleted it. Two parallel update_task calls could apply one update twice, skip the other, and report success for both. Scripts now go to `osascript -l JavaScript -` over stdin. execFile keeps UTF-8-safe decoding, the timeout, and maxBuffer. A no-op stdin error listener keeps an early osascript exit from crashing the process with EPIPE; the exit status still reports the failure. Adapted from #16. Co-authored-by: ruohan.chen <crhan123@gmail.com> Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
stephendolan
added a commit
that referenced
this pull request
Oct 7, 2026
`inbox list` and `inbox count` went through getPerspectiveTasks('Inbox'),
which fails without an open window and switches the user's front window
to the Inbox perspective on every call. They now traverse the `inbox`
collection with inbox.apply, which includes subtasks, and keep incomplete,
non-dropped tasks, matching `task list`'s default filter. The CLI, MCP,
and README descriptions say "remaining" so callers know results no longer
follow the window's view settings.
Adapted from #16, which iterated `inbox` directly and so skipped subtasks.
Co-authored-by: ruohan.chen <crhan123@gmail.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
|
Thanks for digging into this. Two pieces of your first commit landed in main with you as co-author, so I'm closing this one:
I'm passing on the rest:
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Commit 1: refactor — stdin pipe and direct inbox access
executeJXA()usesspawn()to pipe scripts via stdin instead of writing/reading/deleting temp files. Simplifies code, removes 5 unused imports.listInboxTasks()andgetInboxCount()use theinboxglobal object directly instead ofgetPerspectiveTasks('Inbox'). Inbox commands now work headlessly (no OmniFocus window needed).Commit 2: feat — human-readable table output
--json/-jflag forces JSON in terminal--compact/-cunchanged (minified JSON)Commit 3: feat — batch complete and delete
of task complete id1 id2 id3— mark multiple tasks completed in a single JXA callof task delete id1 id2 id3— delete multiple tasks in a single JXA callof task done,of task rmWhat was investigated but not done
Custom perspective without window: Omni Automation does not expose perspective filter rules as a queryable API. The
archivedFilterRulesproperty is inaccessible, andfileWrapperis a serialization format, not a query interface. Custom perspectives still require an open window to retrieve tasks.Test plan
of inbox count/of inbox listwork without an open windowof task list,of project list,of tag list,of folder listdisplay tables in TTYof perspective list,of tag stats,of task statsdisplay formatted outputof task list | jqoutputs JSON (pipe detection works)of --json task listforces JSON in TTYof task complete "taskA" "taskB"batch-completes in one callof task delete "taskA" "taskB"batch-deletes in one callof task delete "taskA"still worksbun run test— 15/15 passingbun run lint— 0 warnings, 0 errors