@scardis/omnifocus-mcp 0.1.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.
Files changed (387) hide show
  1. package/.claude/commands/opsx/apply.md +152 -0
  2. package/.claude/commands/opsx/archive.md +157 -0
  3. package/.claude/commands/opsx/bulk-archive.md +242 -0
  4. package/.claude/commands/opsx/continue.md +114 -0
  5. package/.claude/commands/opsx/explore.md +173 -0
  6. package/.claude/commands/opsx/ff.md +97 -0
  7. package/.claude/commands/opsx/new.md +69 -0
  8. package/.claude/commands/opsx/onboard.md +550 -0
  9. package/.claude/commands/opsx/propose.md +106 -0
  10. package/.claude/commands/opsx/sync.md +134 -0
  11. package/.claude/commands/opsx/verify.md +164 -0
  12. package/.claude/skills/openspec-apply-change/SKILL.md +156 -0
  13. package/.claude/skills/openspec-archive-change/SKILL.md +114 -0
  14. package/.claude/skills/openspec-bulk-archive-change/SKILL.md +246 -0
  15. package/.claude/skills/openspec-continue-change/SKILL.md +118 -0
  16. package/.claude/skills/openspec-explore/SKILL.md +288 -0
  17. package/.claude/skills/openspec-ff-change/SKILL.md +101 -0
  18. package/.claude/skills/openspec-new-change/SKILL.md +74 -0
  19. package/.claude/skills/openspec-onboard/SKILL.md +554 -0
  20. package/.claude/skills/openspec-propose/SKILL.md +110 -0
  21. package/.claude/skills/openspec-sync-specs/SKILL.md +138 -0
  22. package/.claude/skills/openspec-verify-change/SKILL.md +168 -0
  23. package/CONTRIBUTING.md +83 -0
  24. package/LICENSE +21 -0
  25. package/README.md +198 -0
  26. package/dist/runtime/bridge.d.ts +16 -0
  27. package/dist/runtime/bridge.d.ts.map +1 -0
  28. package/dist/runtime/bridge.js +76 -0
  29. package/dist/runtime/bridge.js.map +1 -0
  30. package/dist/runtime/index.d.ts +5 -0
  31. package/dist/runtime/index.d.ts.map +1 -0
  32. package/dist/runtime/index.js +5 -0
  33. package/dist/runtime/index.js.map +1 -0
  34. package/dist/runtime/jxaShim.d.ts +21 -0
  35. package/dist/runtime/jxaShim.d.ts.map +1 -0
  36. package/dist/runtime/jxaShim.js +55 -0
  37. package/dist/runtime/jxaShim.js.map +1 -0
  38. package/dist/runtime/resultProtocol.d.ts +66 -0
  39. package/dist/runtime/resultProtocol.d.ts.map +1 -0
  40. package/dist/runtime/resultProtocol.js +52 -0
  41. package/dist/runtime/resultProtocol.js.map +1 -0
  42. package/dist/runtime/snippetLoader.d.ts +4 -0
  43. package/dist/runtime/snippetLoader.d.ts.map +1 -0
  44. package/dist/runtime/snippetLoader.js +68 -0
  45. package/dist/runtime/snippetLoader.js.map +1 -0
  46. package/dist/schemas/enums.d.ts +9 -0
  47. package/dist/schemas/enums.d.ts.map +1 -0
  48. package/dist/schemas/enums.js +26 -0
  49. package/dist/schemas/enums.js.map +1 -0
  50. package/dist/schemas/index.d.ts +3 -0
  51. package/dist/schemas/index.d.ts.map +1 -0
  52. package/dist/schemas/index.js +3 -0
  53. package/dist/schemas/index.js.map +1 -0
  54. package/dist/schemas/shapes.d.ts +726 -0
  55. package/dist/schemas/shapes.d.ts.map +1 -0
  56. package/dist/schemas/shapes.js +221 -0
  57. package/dist/schemas/shapes.js.map +1 -0
  58. package/dist/server.d.ts +2 -0
  59. package/dist/server.d.ts.map +1 -0
  60. package/dist/server.js +50 -0
  61. package/dist/server.js.map +1 -0
  62. package/dist/tools/completeProject.d.ts +24 -0
  63. package/dist/tools/completeProject.d.ts.map +1 -0
  64. package/dist/tools/completeProject.js +17 -0
  65. package/dist/tools/completeProject.js.map +1 -0
  66. package/dist/tools/completeTask.d.ts +25 -0
  67. package/dist/tools/completeTask.d.ts.map +1 -0
  68. package/dist/tools/completeTask.js +17 -0
  69. package/dist/tools/completeTask.js.map +1 -0
  70. package/dist/tools/createFolder.d.ts +20 -0
  71. package/dist/tools/createFolder.d.ts.map +1 -0
  72. package/dist/tools/createFolder.js +13 -0
  73. package/dist/tools/createFolder.js.map +1 -0
  74. package/dist/tools/createProject.d.ts +59 -0
  75. package/dist/tools/createProject.d.ts.map +1 -0
  76. package/dist/tools/createProject.js +13 -0
  77. package/dist/tools/createProject.js.map +1 -0
  78. package/dist/tools/createTag.d.ts +20 -0
  79. package/dist/tools/createTag.d.ts.map +1 -0
  80. package/dist/tools/createTag.js +13 -0
  81. package/dist/tools/createTag.js.map +1 -0
  82. package/dist/tools/createTask.d.ts +116 -0
  83. package/dist/tools/createTask.d.ts.map +1 -0
  84. package/dist/tools/createTask.js +13 -0
  85. package/dist/tools/createTask.js.map +1 -0
  86. package/dist/tools/deleteFolder.d.ts +30 -0
  87. package/dist/tools/deleteFolder.d.ts.map +1 -0
  88. package/dist/tools/deleteFolder.js +18 -0
  89. package/dist/tools/deleteFolder.js.map +1 -0
  90. package/dist/tools/deleteProject.d.ts +30 -0
  91. package/dist/tools/deleteProject.d.ts.map +1 -0
  92. package/dist/tools/deleteProject.js +18 -0
  93. package/dist/tools/deleteProject.js.map +1 -0
  94. package/dist/tools/deleteTag.d.ts +30 -0
  95. package/dist/tools/deleteTag.d.ts.map +1 -0
  96. package/dist/tools/deleteTag.js +18 -0
  97. package/dist/tools/deleteTag.js.map +1 -0
  98. package/dist/tools/deleteTask.d.ts +31 -0
  99. package/dist/tools/deleteTask.d.ts.map +1 -0
  100. package/dist/tools/deleteTask.js +18 -0
  101. package/dist/tools/deleteTask.js.map +1 -0
  102. package/dist/tools/dropProject.d.ts +24 -0
  103. package/dist/tools/dropProject.d.ts.map +1 -0
  104. package/dist/tools/dropProject.js +17 -0
  105. package/dist/tools/dropProject.js.map +1 -0
  106. package/dist/tools/dropTask.d.ts +25 -0
  107. package/dist/tools/dropTask.d.ts.map +1 -0
  108. package/dist/tools/dropTask.js +17 -0
  109. package/dist/tools/dropTask.js.map +1 -0
  110. package/dist/tools/editFolder.d.ts +20 -0
  111. package/dist/tools/editFolder.d.ts.map +1 -0
  112. package/dist/tools/editFolder.js +13 -0
  113. package/dist/tools/editFolder.js.map +1 -0
  114. package/dist/tools/editProject.d.ts +59 -0
  115. package/dist/tools/editProject.d.ts.map +1 -0
  116. package/dist/tools/editProject.js +13 -0
  117. package/dist/tools/editProject.js.map +1 -0
  118. package/dist/tools/editTag.d.ts +31 -0
  119. package/dist/tools/editTag.d.ts.map +1 -0
  120. package/dist/tools/editTag.js +13 -0
  121. package/dist/tools/editTag.js.map +1 -0
  122. package/dist/tools/editTask.d.ts +79 -0
  123. package/dist/tools/editTask.d.ts.map +1 -0
  124. package/dist/tools/editTask.js +13 -0
  125. package/dist/tools/editTask.js.map +1 -0
  126. package/dist/tools/getFolder.d.ts +24 -0
  127. package/dist/tools/getFolder.d.ts.map +1 -0
  128. package/dist/tools/getFolder.js +17 -0
  129. package/dist/tools/getFolder.js.map +1 -0
  130. package/dist/tools/getProject.d.ts +24 -0
  131. package/dist/tools/getProject.d.ts.map +1 -0
  132. package/dist/tools/getProject.js +17 -0
  133. package/dist/tools/getProject.js.map +1 -0
  134. package/dist/tools/getTag.d.ts +24 -0
  135. package/dist/tools/getTag.d.ts.map +1 -0
  136. package/dist/tools/getTag.js +17 -0
  137. package/dist/tools/getTag.js.map +1 -0
  138. package/dist/tools/getTask.d.ts +24 -0
  139. package/dist/tools/getTask.d.ts.map +1 -0
  140. package/dist/tools/getTask.js +17 -0
  141. package/dist/tools/getTask.js.map +1 -0
  142. package/dist/tools/index.d.ts +732 -0
  143. package/dist/tools/index.d.ts.map +1 -0
  144. package/dist/tools/index.js +84 -0
  145. package/dist/tools/index.js.map +1 -0
  146. package/dist/tools/listFolders.d.ts +50 -0
  147. package/dist/tools/listFolders.d.ts.map +1 -0
  148. package/dist/tools/listFolders.js +21 -0
  149. package/dist/tools/listFolders.js.map +1 -0
  150. package/dist/tools/listProjects.d.ts +70 -0
  151. package/dist/tools/listProjects.d.ts.map +1 -0
  152. package/dist/tools/listProjects.js +21 -0
  153. package/dist/tools/listProjects.js.map +1 -0
  154. package/dist/tools/listTags.d.ts +50 -0
  155. package/dist/tools/listTags.d.ts.map +1 -0
  156. package/dist/tools/listTags.js +21 -0
  157. package/dist/tools/listTags.js.map +1 -0
  158. package/dist/tools/listTasks.d.ts +156 -0
  159. package/dist/tools/listTasks.d.ts.map +1 -0
  160. package/dist/tools/listTasks.js +36 -0
  161. package/dist/tools/listTasks.js.map +1 -0
  162. package/dist/tools/moveProject.d.ts +20 -0
  163. package/dist/tools/moveProject.d.ts.map +1 -0
  164. package/dist/tools/moveProject.js +13 -0
  165. package/dist/tools/moveProject.js.map +1 -0
  166. package/dist/tools/moveTask.d.ts +31 -0
  167. package/dist/tools/moveTask.d.ts.map +1 -0
  168. package/dist/tools/moveTask.js +13 -0
  169. package/dist/tools/moveTask.js.map +1 -0
  170. package/dist/tools/resolveName.d.ts +36 -0
  171. package/dist/tools/resolveName.d.ts.map +1 -0
  172. package/dist/tools/resolveName.js +26 -0
  173. package/dist/tools/resolveName.js.map +1 -0
  174. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/.openspec.yaml +2 -0
  175. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/design.md +162 -0
  176. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/proposal.md +49 -0
  177. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/attachments/spec.md +9 -0
  178. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/batch-operations/spec.md +9 -0
  179. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/database-inspection/spec.md +9 -0
  180. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/execution-runtime/spec.md +69 -0
  181. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/folder-management/spec.md +25 -0
  182. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/forecast/spec.md +9 -0
  183. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/identity-resolution/spec.md +45 -0
  184. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/perspective-management/spec.md +9 -0
  185. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/project-management/spec.md +25 -0
  186. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/recurrence/spec.md +9 -0
  187. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/settings/spec.md +9 -0
  188. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/tag-management/spec.md +25 -0
  189. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/task-management/spec.md +29 -0
  190. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/url-automation/spec.md +9 -0
  191. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/specs/window-state/spec.md +9 -0
  192. package/openspec/changes/archive/2026-04-09-bootstrap-omnifocus-mcp/tasks.md +84 -0
  193. package/openspec/changes/archive/2026-04-09-folder-crud/.openspec.yaml +2 -0
  194. package/openspec/changes/archive/2026-04-09-folder-crud/design.md +58 -0
  195. package/openspec/changes/archive/2026-04-09-folder-crud/proposal.md +28 -0
  196. package/openspec/changes/archive/2026-04-09-folder-crud/specs/folder-write/spec.md +45 -0
  197. package/openspec/changes/archive/2026-04-09-folder-crud/tasks.md +41 -0
  198. package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/.openspec.yaml +2 -0
  199. package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/design.md +38 -0
  200. package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/proposal.md +30 -0
  201. package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/specs/folder-management/spec.md +21 -0
  202. package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/specs/tag-management/spec.md +21 -0
  203. package/openspec/changes/archive/2026-04-09-folder-tag-list-filtering/tasks.md +35 -0
  204. package/openspec/changes/archive/2026-04-09-move-operations/.openspec.yaml +2 -0
  205. package/openspec/changes/archive/2026-04-09-move-operations/design.md +43 -0
  206. package/openspec/changes/archive/2026-04-09-move-operations/proposal.md +25 -0
  207. package/openspec/changes/archive/2026-04-09-move-operations/specs/move-operations/spec.md +41 -0
  208. package/openspec/changes/archive/2026-04-09-move-operations/tasks.md +40 -0
  209. package/openspec/changes/archive/2026-04-09-project-crud/.openspec.yaml +2 -0
  210. package/openspec/changes/archive/2026-04-09-project-crud/design.md +60 -0
  211. package/openspec/changes/archive/2026-04-09-project-crud/proposal.md +29 -0
  212. package/openspec/changes/archive/2026-04-09-project-crud/specs/project-write/spec.md +74 -0
  213. package/openspec/changes/archive/2026-04-09-project-crud/tasks.md +48 -0
  214. package/openspec/changes/archive/2026-04-09-project-filtering/.openspec.yaml +2 -0
  215. package/openspec/changes/archive/2026-04-09-project-filtering/design.md +52 -0
  216. package/openspec/changes/archive/2026-04-09-project-filtering/proposal.md +26 -0
  217. package/openspec/changes/archive/2026-04-09-project-filtering/specs/project-filtering/spec.md +66 -0
  218. package/openspec/changes/archive/2026-04-09-project-filtering/specs/project-management/spec.md +13 -0
  219. package/openspec/changes/archive/2026-04-09-project-filtering/tasks.md +41 -0
  220. package/openspec/changes/archive/2026-04-09-tag-crud/.openspec.yaml +2 -0
  221. package/openspec/changes/archive/2026-04-09-tag-crud/design.md +45 -0
  222. package/openspec/changes/archive/2026-04-09-tag-crud/proposal.md +28 -0
  223. package/openspec/changes/archive/2026-04-09-tag-crud/specs/tag-write/spec.md +49 -0
  224. package/openspec/changes/archive/2026-04-09-tag-crud/tasks.md +41 -0
  225. package/openspec/changes/archive/2026-04-09-task-crud/.openspec.yaml +2 -0
  226. package/openspec/changes/archive/2026-04-09-task-crud/design.md +62 -0
  227. package/openspec/changes/archive/2026-04-09-task-crud/proposal.md +29 -0
  228. package/openspec/changes/archive/2026-04-09-task-crud/specs/task-management/spec.md +17 -0
  229. package/openspec/changes/archive/2026-04-09-task-crud/specs/task-write/spec.md +89 -0
  230. package/openspec/changes/archive/2026-04-09-task-crud/tasks.md +55 -0
  231. package/openspec/changes/archive/2026-04-09-task-filtering/.openspec.yaml +2 -0
  232. package/openspec/changes/archive/2026-04-09-task-filtering/design.md +61 -0
  233. package/openspec/changes/archive/2026-04-09-task-filtering/proposal.md +26 -0
  234. package/openspec/changes/archive/2026-04-09-task-filtering/specs/task-filtering/spec.md +63 -0
  235. package/openspec/changes/archive/2026-04-09-task-filtering/specs/task-management/spec.md +17 -0
  236. package/openspec/changes/archive/2026-04-09-task-filtering/tasks.md +42 -0
  237. package/openspec/changes/archive/2026-04-10-planned-date/.openspec.yaml +2 -0
  238. package/openspec/changes/archive/2026-04-10-planned-date/design.md +27 -0
  239. package/openspec/changes/archive/2026-04-10-planned-date/proposal.md +29 -0
  240. package/openspec/changes/archive/2026-04-10-planned-date/specs/task-management/spec.md +29 -0
  241. package/openspec/changes/archive/2026-04-10-planned-date/specs/task-write/spec.md +69 -0
  242. package/openspec/changes/archive/2026-04-10-planned-date/tasks.md +26 -0
  243. package/openspec/changes/archive/2026-04-10-task-recurrence/.openspec.yaml +2 -0
  244. package/openspec/changes/archive/2026-04-10-task-recurrence/design.md +81 -0
  245. package/openspec/changes/archive/2026-04-10-task-recurrence/proposal.md +28 -0
  246. package/openspec/changes/archive/2026-04-10-task-recurrence/specs/recurrence/spec.md +47 -0
  247. package/openspec/changes/archive/2026-04-10-task-recurrence/specs/task-management/spec.md +25 -0
  248. package/openspec/changes/archive/2026-04-10-task-recurrence/specs/task-write/spec.md +61 -0
  249. package/openspec/changes/archive/2026-04-10-task-recurrence/tasks.md +39 -0
  250. package/openspec/config.yaml +20 -0
  251. package/openspec/specs/attachments/spec.md +15 -0
  252. package/openspec/specs/batch-operations/spec.md +15 -0
  253. package/openspec/specs/database-inspection/spec.md +15 -0
  254. package/openspec/specs/execution-runtime/spec.md +75 -0
  255. package/openspec/specs/folder-management/spec.md +39 -0
  256. package/openspec/specs/folder-write/spec.md +45 -0
  257. package/openspec/specs/forecast/spec.md +15 -0
  258. package/openspec/specs/identity-resolution/spec.md +51 -0
  259. package/openspec/specs/move-operations/spec.md +41 -0
  260. package/openspec/specs/perspective-management/spec.md +15 -0
  261. package/openspec/specs/project-filtering/spec.md +72 -0
  262. package/openspec/specs/project-management/spec.md +31 -0
  263. package/openspec/specs/project-write/spec.md +79 -0
  264. package/openspec/specs/recurrence/spec.md +51 -0
  265. package/openspec/specs/settings/spec.md +15 -0
  266. package/openspec/specs/tag-management/spec.md +39 -0
  267. package/openspec/specs/tag-write/spec.md +49 -0
  268. package/openspec/specs/task-filtering/spec.md +63 -0
  269. package/openspec/specs/task-management/spec.md +51 -0
  270. package/openspec/specs/task-write/spec.md +115 -0
  271. package/openspec/specs/url-automation/spec.md +15 -0
  272. package/openspec/specs/window-state/spec.md +15 -0
  273. package/package.json +32 -0
  274. package/scripts/cleanup-fixtures.ts +89 -0
  275. package/server.json +21 -0
  276. package/src/runtime/bridge.ts +97 -0
  277. package/src/runtime/index.ts +4 -0
  278. package/src/runtime/jxaShim.ts +55 -0
  279. package/src/runtime/resultProtocol.ts +62 -0
  280. package/src/runtime/snippetLoader.ts +79 -0
  281. package/src/schemas/enums.ts +32 -0
  282. package/src/schemas/index.ts +38 -0
  283. package/src/schemas/shapes.ts +267 -0
  284. package/src/server.ts +58 -0
  285. package/src/snippets/complete_project.js +73 -0
  286. package/src/snippets/complete_task.js +85 -0
  287. package/src/snippets/create_folder.js +52 -0
  288. package/src/snippets/create_project.js +107 -0
  289. package/src/snippets/create_tag.js +55 -0
  290. package/src/snippets/create_task.js +159 -0
  291. package/src/snippets/delete_folder.js +26 -0
  292. package/src/snippets/delete_project.js +20 -0
  293. package/src/snippets/delete_tag.js +20 -0
  294. package/src/snippets/delete_task.js +20 -0
  295. package/src/snippets/drop_project.js +73 -0
  296. package/src/snippets/drop_task.js +85 -0
  297. package/src/snippets/edit_folder.js +46 -0
  298. package/src/snippets/edit_project.js +106 -0
  299. package/src/snippets/edit_tag.js +56 -0
  300. package/src/snippets/edit_task.js +146 -0
  301. package/src/snippets/get_folder.js +48 -0
  302. package/src/snippets/get_project.js +77 -0
  303. package/src/snippets/get_tag.js +51 -0
  304. package/src/snippets/get_task.js +96 -0
  305. package/src/snippets/list_folders.js +50 -0
  306. package/src/snippets/list_projects.js +98 -0
  307. package/src/snippets/list_tags.js +54 -0
  308. package/src/snippets/list_tasks.js +127 -0
  309. package/src/snippets/move_project.js +79 -0
  310. package/src/snippets/move_task.js +113 -0
  311. package/src/snippets/resolve_name.js +83 -0
  312. package/src/tools/completeProject.ts +21 -0
  313. package/src/tools/completeTask.ts +23 -0
  314. package/src/tools/createFolder.ts +20 -0
  315. package/src/tools/createProject.ts +20 -0
  316. package/src/tools/createTag.ts +20 -0
  317. package/src/tools/createTask.ts +20 -0
  318. package/src/tools/deleteFolder.ts +24 -0
  319. package/src/tools/deleteProject.ts +24 -0
  320. package/src/tools/deleteTag.ts +24 -0
  321. package/src/tools/deleteTask.ts +26 -0
  322. package/src/tools/dropProject.ts +21 -0
  323. package/src/tools/dropTask.ts +23 -0
  324. package/src/tools/editFolder.ts +19 -0
  325. package/src/tools/editProject.ts +20 -0
  326. package/src/tools/editTag.ts +20 -0
  327. package/src/tools/editTask.ts +20 -0
  328. package/src/tools/getFolder.ts +24 -0
  329. package/src/tools/getProject.ts +24 -0
  330. package/src/tools/getTag.ts +24 -0
  331. package/src/tools/getTask.ts +24 -0
  332. package/src/tools/index.ts +85 -0
  333. package/src/tools/listFolders.ts +32 -0
  334. package/src/tools/listProjects.ts +32 -0
  335. package/src/tools/listTags.ts +32 -0
  336. package/src/tools/listTasks.ts +56 -0
  337. package/src/tools/moveProject.ts +20 -0
  338. package/src/tools/moveTask.ts +20 -0
  339. package/src/tools/resolveName.ts +37 -0
  340. package/test/integration/.gitkeep +0 -0
  341. package/test/integration/completeProject.int.test.ts +25 -0
  342. package/test/integration/completeTask.int.test.ts +30 -0
  343. package/test/integration/createFolder.int.test.ts +50 -0
  344. package/test/integration/createProject.int.test.ts +49 -0
  345. package/test/integration/createTag.int.test.ts +52 -0
  346. package/test/integration/createTask.int.test.ts +55 -0
  347. package/test/integration/deleteFolder.int.test.ts +64 -0
  348. package/test/integration/deleteProject.int.test.ts +31 -0
  349. package/test/integration/deleteTag.int.test.ts +61 -0
  350. package/test/integration/deleteTask.int.test.ts +36 -0
  351. package/test/integration/dropProject.int.test.ts +24 -0
  352. package/test/integration/dropTask.int.test.ts +29 -0
  353. package/test/integration/editFolder.int.test.ts +43 -0
  354. package/test/integration/editProject.int.test.ts +39 -0
  355. package/test/integration/editTag.int.test.ts +43 -0
  356. package/test/integration/editTask.int.test.ts +56 -0
  357. package/test/integration/fixtures.ts +219 -0
  358. package/test/integration/getTask.int.test.ts +64 -0
  359. package/test/integration/listFoldersFiltered.int.test.ts +98 -0
  360. package/test/integration/listProjects.int.test.ts +73 -0
  361. package/test/integration/listProjectsFiltered.int.test.ts +96 -0
  362. package/test/integration/listTagsFiltered.int.test.ts +54 -0
  363. package/test/integration/listTasksFiltered.int.test.ts +141 -0
  364. package/test/integration/moveProject.int.test.ts +57 -0
  365. package/test/integration/moveTask.int.test.ts +61 -0
  366. package/test/integration/plannedDate.int.test.ts +72 -0
  367. package/test/integration/preflight.ts +60 -0
  368. package/test/integration/resolveName.int.test.ts +86 -0
  369. package/test/integration/taskRecurrence.int.test.ts +106 -0
  370. package/test/unit/.gitkeep +0 -0
  371. package/test/unit/bridge.injection.test.ts +66 -0
  372. package/test/unit/resultProtocol.test.ts +71 -0
  373. package/test/unit/schemas.createFolder.test.ts +38 -0
  374. package/test/unit/schemas.createProject.test.ts +115 -0
  375. package/test/unit/schemas.createTask.test.ts +87 -0
  376. package/test/unit/schemas.editTag.test.ts +64 -0
  377. package/test/unit/schemas.folderTagFiltering.test.ts +42 -0
  378. package/test/unit/schemas.listProjects.test.ts +44 -0
  379. package/test/unit/schemas.moveOperations.test.ts +60 -0
  380. package/test/unit/schemas.recurrence.test.ts +120 -0
  381. package/test/unit/schemas.test.ts +126 -0
  382. package/test/unit/snippetLoader.test.ts +56 -0
  383. package/test/unit/tools.deleteTask.test.ts +19 -0
  384. package/test/unit/tools.listTasks.test.ts +126 -0
  385. package/tsconfig.json +19 -0
  386. package/vitest.config.ts +8 -0
  387. package/vitest.integration.config.ts +18 -0
@@ -0,0 +1,127 @@
1
+ /**
2
+ * list_tasks.js — List tasks within a specified scope with optional filtering
3
+ *
4
+ * PASTE-TO-CONSOLE:
5
+ * Replace ARGS_PLACEHOLDER with one of:
6
+ * { scope: { projectId: "your-project-id" } }
7
+ * { scope: { folderId: "your-folder-id" } }
8
+ * { scope: { inbox: true } }
9
+ * { scope: { all: true } }
10
+ * { scope: { all: true }, filter: { flagged: true } }
11
+ * { scope: { all: true }, filter: { status: ["overdue", "dueSoon"] } }
12
+ * { scope: { all: true }, filter: { dueBeforeDate: "2026-04-09T23:59:59Z" } }
13
+ * Example: const args = { scope: { inbox: true } };
14
+ */
15
+ (() => {
16
+ const args = __ARGS__;
17
+
18
+ function taskStatusString(task) {
19
+ try {
20
+ var s = task.taskStatus;
21
+ if (s === Task.Status.Available) return "available";
22
+ if (s === Task.Status.Blocked) return "blocked";
23
+ if (s === Task.Status.Completed) return "complete";
24
+ if (s === Task.Status.Dropped) return "dropped";
25
+ if (s === Task.Status.DueSoon) return "dueSoon";
26
+ if (s === Task.Status.Next) return "next";
27
+ if (s === Task.Status.Overdue) return "overdue";
28
+ return "incomplete";
29
+ } catch(_) { return "incomplete"; }
30
+ }
31
+
32
+ function containerInfo(task) {
33
+ if (!task.assignedContainer) return { containerId: null, containerType: null };
34
+ var c = task.assignedContainer;
35
+ if (c instanceof Project) {
36
+ return { containerId: c.id.primaryKey, containerType: "project" };
37
+ }
38
+ return { containerId: c.id.primaryKey, containerType: "task" };
39
+ }
40
+
41
+ function mapTask(task, overrideContainerType) {
42
+ var ci = containerInfo(task);
43
+ return {
44
+ id: task.id.primaryKey,
45
+ name: task.name,
46
+ status: taskStatusString(task),
47
+ flagged: task.flagged || false,
48
+ containerId: ci.containerId,
49
+ containerType: overrideContainerType || ci.containerType,
50
+ dueDate: task.dueDate ? task.dueDate.toISOString() : null,
51
+ tagIds: (task.tags || []).map(function(t) { return t.id.primaryKey; }),
52
+ };
53
+ }
54
+
55
+ // ── Scope resolution ────────────────────────────────────────────────────────
56
+
57
+ var scope = args.scope;
58
+ var tasks = [];
59
+
60
+ if (scope.projectId) {
61
+ var project = flattenedProjects.find(function(p) {
62
+ return p.id.primaryKey === scope.projectId;
63
+ });
64
+ if (!project) {
65
+ return JSON.stringify({ ok: false, error: { name: "NotFoundError", message: "Project not found: " + scope.projectId } });
66
+ }
67
+ tasks = project.flattenedTasks.map(function(t) { return mapTask(t, "project"); });
68
+ } else if (scope.folderId) {
69
+ var folder = flattenedFolders.find(function(f) {
70
+ return f.id.primaryKey === scope.folderId;
71
+ });
72
+ if (!folder) {
73
+ return JSON.stringify({ ok: false, error: { name: "NotFoundError", message: "Folder not found: " + scope.folderId } });
74
+ }
75
+ folder.flattenedProjects.forEach(function(p) {
76
+ p.flattenedTasks.forEach(function(t) { tasks.push(mapTask(t, "project")); });
77
+ });
78
+ } else if (scope.inbox) {
79
+ tasks = flattenedTasks
80
+ .filter(function(t) { return !t.containingProject && !t.parentTask; })
81
+ .map(function(t) { return mapTask(t, "inbox"); });
82
+ } else if (scope.all) {
83
+ tasks = flattenedTasks.map(function(t) { return mapTask(t, null); });
84
+ }
85
+
86
+ // ── Filtering ───────────────────────────────────────────────────────────────
87
+
88
+ var filter = args.filter || {};
89
+ var hasStatusFilter = Array.isArray(filter.status) && filter.status.length > 0;
90
+
91
+ // Default: exclude complete and dropped when no explicit status filter
92
+ if (!hasStatusFilter) {
93
+ tasks = tasks.filter(function(t) {
94
+ return t.status !== "complete" && t.status !== "dropped";
95
+ });
96
+ } else {
97
+ tasks = tasks.filter(function(t) {
98
+ return filter.status.indexOf(t.status) !== -1;
99
+ });
100
+ }
101
+
102
+ if (filter.flagged === true) {
103
+ tasks = tasks.filter(function(t) { return t.flagged === true; });
104
+ }
105
+
106
+ if (filter.tagId) {
107
+ tasks = tasks.filter(function(t) {
108
+ return t.tagIds.indexOf(filter.tagId) !== -1;
109
+ });
110
+ }
111
+
112
+ if (filter.dueBeforeDate) {
113
+ var cutoff = new Date(filter.dueBeforeDate);
114
+ tasks = tasks.filter(function(t) {
115
+ return t.dueDate !== null && new Date(t.dueDate) <= cutoff;
116
+ });
117
+ }
118
+
119
+ // ── Limit ───────────────────────────────────────────────────────────────────
120
+
121
+ var limit = (args.limit !== undefined && args.limit !== null) ? args.limit : 200;
122
+ if (tasks.length > limit) {
123
+ tasks = tasks.slice(0, limit);
124
+ }
125
+
126
+ return JSON.stringify({ ok: true, data: tasks });
127
+ })();
@@ -0,0 +1,79 @@
1
+ /**
2
+ * move_project.js — Move a project to a different folder or to the top level
3
+ *
4
+ * PASTE-TO-CONSOLE:
5
+ * Replace ARGS_PLACEHOLDER with one of:
6
+ * { id: "project-id", folderId: "folder-id" }
7
+ * { id: "project-id", folderId: null }
8
+ * Example: const args = { id: "jMBMptE7rJ1", folderId: null };
9
+ */
10
+ (() => {
11
+ const args = __ARGS__;
12
+
13
+ function NotFoundError(msg) { var e = new Error(msg); e.name = "NotFoundError"; return e; }
14
+
15
+ function projectStatusString(project) {
16
+ var s = project.status;
17
+ if (s === Project.Status.Active) return "active";
18
+ if (s === Project.Status.OnHold) return "onHold";
19
+ if (s === Project.Status.Done) return "done";
20
+ if (s === Project.Status.Dropped) return "dropped";
21
+ return "active";
22
+ }
23
+
24
+ function projectType(project) {
25
+ if (project.containsSingletonActions) return "singleActions";
26
+ if (project.sequential) return "sequential";
27
+ return "parallel";
28
+ }
29
+
30
+ function folderPath(project) {
31
+ var parts = [];
32
+ var container = project.parentFolder;
33
+ while (container) {
34
+ parts.unshift(container.name);
35
+ container = container.parent;
36
+ }
37
+ return parts.join(" \u25b8 ");
38
+ }
39
+
40
+ // ── Resolve project ────────────────────────────────────────────────────────
41
+
42
+ var project = flattenedProjects.find(function(p) {
43
+ return p.id.primaryKey === args.id;
44
+ });
45
+ if (!project) throw new NotFoundError("Project not found: " + args.id);
46
+
47
+ // ── Move ───────────────────────────────────────────────────────────────────
48
+
49
+ if (args.folderId !== null && args.folderId !== undefined) {
50
+ var folder = flattenedFolders.find(function(f) {
51
+ return f.id.primaryKey === args.folderId;
52
+ });
53
+ if (!folder) throw new NotFoundError("Folder not found: " + args.folderId);
54
+ moveSections([project], folder);
55
+ } else {
56
+ // moveSections requires a non-null position. To reach the root level, anchor
57
+ // to the first root-level folder's .before location (a root-level insertion point).
58
+ var rootFolder = flattenedFolders.find(function(f) { return !f.parent; });
59
+ if (!rootFolder) {
60
+ throw new Error("Cannot move project to top level: no root-level folders found to anchor position");
61
+ }
62
+ moveSections([project], rootFolder.before);
63
+ }
64
+
65
+ // ── Return updated summary ─────────────────────────────────────────────────
66
+
67
+ return JSON.stringify({
68
+ ok: true,
69
+ data: {
70
+ id: project.id.primaryKey,
71
+ name: project.name,
72
+ folderPath: folderPath(project),
73
+ folderId: project.parentFolder ? project.parentFolder.id.primaryKey : null,
74
+ status: projectStatusString(project),
75
+ type: projectType(project),
76
+ flagged: project.flagged || false,
77
+ },
78
+ });
79
+ })();
@@ -0,0 +1,113 @@
1
+ /**
2
+ * move_task.js — Move a task to a different project or make it a subtask
3
+ *
4
+ * PASTE-TO-CONSOLE:
5
+ * Replace ARGS_PLACEHOLDER with one of:
6
+ * { id: "task-id", projectId: "project-id" }
7
+ * { id: "task-id", parentTaskId: "parent-task-id" }
8
+ * Example: const args = { id: "jMBMptE7rJ1", projectId: "kABCdef123" };
9
+ */
10
+ (() => {
11
+ const args = __ARGS__;
12
+
13
+ function NotFoundError(msg) { var e = new Error(msg); e.name = "NotFoundError"; return e; }
14
+ function ValidationError(msg) { var e = new Error(msg); e.name = "ValidationError"; return e; }
15
+
16
+ function taskStatusString(task) {
17
+ try {
18
+ var s = task.taskStatus;
19
+ if (s === Task.Status.Available) return "available";
20
+ if (s === Task.Status.Blocked) return "blocked";
21
+ if (s === Task.Status.Completed) return "complete";
22
+ if (s === Task.Status.Dropped) return "dropped";
23
+ if (s === Task.Status.DueSoon) return "dueSoon";
24
+ if (s === Task.Status.Next) return "next";
25
+ if (s === Task.Status.Overdue) return "overdue";
26
+ return "incomplete";
27
+ } catch(_) { return "incomplete"; }
28
+ }
29
+
30
+ function containerInfo(task) {
31
+ // Use parentTask and containingProject rather than assignedContainer —
32
+ // assignedContainer reflects original placement and doesn't update after moveTasks.
33
+ if (task.parentTask) {
34
+ return { containerId: task.parentTask.id.primaryKey, containerType: "task" };
35
+ }
36
+ var proj = task.containingProject;
37
+ if (proj) {
38
+ return { containerId: proj.id.primaryKey, containerType: "project" };
39
+ }
40
+ return { containerId: null, containerType: "inbox" };
41
+ }
42
+
43
+ // ── Validate: exactly one destination ──────────────────────────────────────
44
+
45
+ var hasProject = args.projectId !== undefined && args.projectId !== null;
46
+ var hasParent = args.parentTaskId !== undefined && args.parentTaskId !== null;
47
+
48
+ if (hasProject && hasParent) {
49
+ throw new ValidationError("Exactly one of projectId or parentTaskId must be provided, not both");
50
+ }
51
+ if (!hasProject && !hasParent) {
52
+ throw new ValidationError("Exactly one of projectId or parentTaskId must be provided");
53
+ }
54
+
55
+ // ── Resolve task ───────────────────────────────────────────────────────────
56
+
57
+ var task = flattenedTasks.find(function(t) {
58
+ return t.id.primaryKey === args.id;
59
+ });
60
+ if (!task) throw new NotFoundError("Task not found: " + args.id);
61
+
62
+ // ── Move ───────────────────────────────────────────────────────────────────
63
+
64
+ if (hasProject) {
65
+ var project = flattenedProjects.find(function(p) {
66
+ return p.id.primaryKey === args.projectId;
67
+ });
68
+ if (!project) throw new NotFoundError("Project not found: " + args.projectId);
69
+ moveTasks([task], project);
70
+ } else {
71
+ var parentTask = flattenedTasks.find(function(t) {
72
+ return t.id.primaryKey === args.parentTaskId;
73
+ });
74
+ if (!parentTask) throw new NotFoundError("Parent task not found: " + args.parentTaskId);
75
+ moveTasks([task], parentTask.ending);
76
+ }
77
+
78
+ // ── Return updated summary ─────────────────────────────────────────────────
79
+
80
+ // Re-fetch after move.
81
+ var movedTask = flattenedTasks.find(function(t) { return t.id.primaryKey === args.id; }) || task;
82
+
83
+ // task.parentTask is unreliable after moveTasks (can return project root task).
84
+ // For the subtask case, verify from the parent side via flattenedTasks.
85
+ var ci;
86
+ if (hasParent) {
87
+ var parentTask2 = flattenedTasks.find(function(t) { return t.id.primaryKey === args.parentTaskId; });
88
+ var isSubtask = parentTask2 && (parentTask2.flattenedTasks || []).some(function(t) {
89
+ return t.id.primaryKey === args.id;
90
+ });
91
+ if (isSubtask) {
92
+ ci = { containerId: parentTask2.id.primaryKey, containerType: "task" };
93
+ } else {
94
+ ci = containerInfo(movedTask);
95
+ }
96
+ } else {
97
+ ci = containerInfo(movedTask);
98
+ }
99
+
100
+ return JSON.stringify({
101
+ ok: true,
102
+ data: {
103
+ id: movedTask.id.primaryKey,
104
+ name: movedTask.name,
105
+ status: taskStatusString(movedTask),
106
+ flagged: movedTask.flagged || false,
107
+ containerId: ci.containerId,
108
+ containerType: ci.containerType,
109
+ dueDate: movedTask.dueDate ? movedTask.dueDate.toISOString() : null,
110
+ tagIds: (movedTask.tags || []).map(function(t) { return t.id.primaryKey; }),
111
+ },
112
+ });
113
+ })();
@@ -0,0 +1,83 @@
1
+ /**
2
+ * resolve_name.js — Resolve entity name to ID candidates
3
+ *
4
+ * PASTE-TO-CONSOLE:
5
+ * Replace ARGS_PLACEHOLDER with: { type: "project", query: "My Project", scope: null }
6
+ * Example: const args = { type: "folder", query: "Work", scope: null };
7
+ *
8
+ * Returns ALL matches (never silently picks one).
9
+ * Returns empty array on no match (does not throw).
10
+ */
11
+ (() => {
12
+ const args = __ARGS__;
13
+
14
+ function buildPath(entity) {
15
+ const parts = [];
16
+ let current = entity;
17
+ while (current) {
18
+ parts.unshift(current.name);
19
+ current = current.parent;
20
+ }
21
+ return parts.join(" \u25b8 ");
22
+ }
23
+
24
+ // Projects use parentFolder (not .parent, which is the Task parent)
25
+ function buildProjectPath(project) {
26
+ const parts = [project.name];
27
+ let folder = project.parentFolder;
28
+ while (folder) {
29
+ parts.unshift(folder.name);
30
+ folder = folder.parent;
31
+ }
32
+ return parts.join(" \u25b8 ");
33
+ }
34
+
35
+ function inScope(path, scope) {
36
+ if (!scope) return true;
37
+ return path.startsWith(scope + " \u25b8 ") || path === scope;
38
+ }
39
+
40
+ function matchName(entity, query) {
41
+ return entity.name === query;
42
+ }
43
+
44
+ const type = args.type;
45
+ const query = args.query;
46
+ const scope = args.scope || null;
47
+
48
+ var candidates = [];
49
+
50
+ if (type === "project") {
51
+ flattenedProjects.forEach(function(p) {
52
+ if (!matchName(p, query)) return;
53
+ const path = buildProjectPath(p);
54
+ if (!inScope(path, scope)) return;
55
+ candidates.push({ id: p.id.primaryKey, name: p.name, path: path, type: "project" });
56
+ });
57
+ } else if (type === "folder") {
58
+ flattenedFolders.forEach(function(f) {
59
+ if (!matchName(f, query)) return;
60
+ const path = buildPath(f);
61
+ if (!inScope(path, scope)) return;
62
+ candidates.push({ id: f.id.primaryKey, name: f.name, path: path, type: "folder" });
63
+ });
64
+ } else if (type === "task") {
65
+ flattenedTasks.forEach(function(t) {
66
+ if (!matchName(t, query)) return;
67
+ // Build path as "Project ▸ Task" for disambiguation; fall back to task name for inbox tasks
68
+ var taskPath = t.containingProject
69
+ ? t.containingProject.name + " \u25b8 " + t.name
70
+ : t.name;
71
+ candidates.push({ id: t.id.primaryKey, name: t.name, path: taskPath, type: "task" });
72
+ });
73
+ } else if (type === "tag") {
74
+ flattenedTags.forEach(function(t) {
75
+ if (!matchName(t, query)) return;
76
+ const path = buildPath(t);
77
+ if (!inScope(path, scope)) return;
78
+ candidates.push({ id: t.id.primaryKey, name: t.name, path: path, type: "tag" });
79
+ });
80
+ }
81
+
82
+ return JSON.stringify({ ok: true, data: candidates });
83
+ })();
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema, ProjectDetail } from "../schemas/index.js";
4
+
5
+ const CompleteProjectInput = z.object({
6
+ id: IdSchema.describe("The project's id.primaryKey"),
7
+ });
8
+
9
+ export async function completeProjectHandler(
10
+ input: z.infer<typeof CompleteProjectInput>
11
+ ): Promise<z.infer<typeof ProjectDetail>> {
12
+ const raw = await runSnippet("complete_project", { id: input.id });
13
+ return ProjectDetail.parse(raw);
14
+ }
15
+
16
+ export const completeProjectTool = {
17
+ name: "complete_project",
18
+ description: "Mark a project as done (complete). Returns the updated project detail.",
19
+ inputSchema: CompleteProjectInput,
20
+ handler: completeProjectHandler,
21
+ } as const;
@@ -0,0 +1,23 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema, TaskDetail } from "../schemas/index.js";
4
+
5
+ const completeTaskSchema = z.object({
6
+ id: IdSchema.describe("The task's id.primaryKey"),
7
+ });
8
+
9
+ export type CompleteTaskInput = z.infer<typeof completeTaskSchema>;
10
+
11
+ export async function completeTaskHandler(
12
+ input: CompleteTaskInput
13
+ ): Promise<z.infer<typeof TaskDetail>> {
14
+ const raw = await runSnippet("complete_task", { id: input.id });
15
+ return TaskDetail.parse(raw);
16
+ }
17
+
18
+ export const completeTaskTool = {
19
+ name: "complete_task",
20
+ description: "Mark a task complete by its stable ID. Returns the updated task detail.",
21
+ inputSchema: completeTaskSchema,
22
+ handler: completeTaskHandler,
23
+ } as const;
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { CreateFolderInput, FolderDetail } from "../schemas/index.js";
4
+
5
+ export type CreateFolderInputType = z.infer<typeof CreateFolderInput>;
6
+
7
+ export async function createFolderHandler(
8
+ input: CreateFolderInputType
9
+ ): Promise<z.infer<typeof FolderDetail>> {
10
+ const raw = await runSnippet("create_folder", input);
11
+ return FolderDetail.parse(raw);
12
+ }
13
+
14
+ export const createFolderTool = {
15
+ name: "create_folder",
16
+ description:
17
+ "Create a new OmniFocus folder. Omit parentFolderId to create at the top level; provide parentFolderId to nest it inside an existing folder.",
18
+ inputSchema: CreateFolderInput,
19
+ handler: createFolderHandler,
20
+ } as const;
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { CreateProjectInput, ProjectDetail } from "../schemas/index.js";
4
+
5
+ export type CreateProjectInputType = z.infer<typeof CreateProjectInput>;
6
+
7
+ export async function createProjectHandler(
8
+ input: CreateProjectInputType
9
+ ): Promise<z.infer<typeof ProjectDetail>> {
10
+ const raw = await runSnippet("create_project", input);
11
+ return ProjectDetail.parse(raw);
12
+ }
13
+
14
+ export const createProjectTool = {
15
+ name: "create_project",
16
+ description:
17
+ "Create a new OmniFocus project. Omit folderId to create at the top level; provide folderId to place it inside a folder. Optionally set type (parallel/sequential/singleActions), status (active/onHold), review interval, and tags.",
18
+ inputSchema: CreateProjectInput,
19
+ handler: createProjectHandler,
20
+ } as const;
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { CreateTagInput, TagDetail } from "../schemas/index.js";
4
+
5
+ export type CreateTagInputType = z.infer<typeof CreateTagInput>;
6
+
7
+ export async function createTagHandler(
8
+ input: CreateTagInputType
9
+ ): Promise<z.infer<typeof TagDetail>> {
10
+ const raw = await runSnippet("create_tag", input);
11
+ return TagDetail.parse(raw);
12
+ }
13
+
14
+ export const createTagTool = {
15
+ name: "create_tag",
16
+ description:
17
+ "Create a new OmniFocus tag. Omit parentTagId to create at the top level; provide parentTagId to nest it under an existing tag.",
18
+ inputSchema: CreateTagInput,
19
+ handler: createTagHandler,
20
+ } as const;
@@ -0,0 +1,20 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { CreateTaskInput, TaskDetail } from "../schemas/index.js";
4
+
5
+ export type CreateTaskInputType = z.infer<typeof CreateTaskInput>;
6
+
7
+ export async function createTaskHandler(
8
+ input: CreateTaskInputType
9
+ ): Promise<z.infer<typeof TaskDetail>> {
10
+ const raw = await runSnippet("create_task", input);
11
+ return TaskDetail.parse(raw);
12
+ }
13
+
14
+ export const createTaskTool = {
15
+ name: "create_task",
16
+ description:
17
+ "Create a new task. Placement: omit projectId and parentTaskId for inbox; provide projectId to add to a project; provide parentTaskId to create a subtask. Providing both projectId and parentTaskId is an error.",
18
+ inputSchema: CreateTaskInput,
19
+ handler: createTaskHandler,
20
+ } as const;
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema } from "../schemas/index.js";
4
+
5
+ const DeleteFolderInput = z.object({
6
+ id: IdSchema.describe("The folder's id.primaryKey"),
7
+ });
8
+
9
+ const DeleteFolderResult = z.object({ id: z.string() });
10
+
11
+ export async function deleteFolderHandler(
12
+ input: z.infer<typeof DeleteFolderInput>
13
+ ): Promise<z.infer<typeof DeleteFolderResult>> {
14
+ const raw = await runSnippet("delete_folder", { id: input.id });
15
+ return DeleteFolderResult.parse(raw);
16
+ }
17
+
18
+ export const deleteFolderTool = {
19
+ name: "delete_folder",
20
+ description:
21
+ "Permanently and recursively delete an OmniFocus folder. THIS ACTION CANNOT BE UNDONE. The ENTIRE subtree is destroyed: all child folders, all projects within those folders, and all tasks within those projects. Before calling this tool you MUST ask the user to explicitly confirm they want to permanently delete the folder and all of its contents.",
22
+ inputSchema: DeleteFolderInput,
23
+ handler: deleteFolderHandler,
24
+ } as const;
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema } from "../schemas/index.js";
4
+
5
+ const DeleteProjectInput = z.object({
6
+ id: IdSchema.describe("The project's id.primaryKey"),
7
+ });
8
+
9
+ const DeleteProjectResult = z.object({ id: z.string() });
10
+
11
+ export async function deleteProjectHandler(
12
+ input: z.infer<typeof DeleteProjectInput>
13
+ ): Promise<z.infer<typeof DeleteProjectResult>> {
14
+ const raw = await runSnippet("delete_project", { id: input.id });
15
+ return DeleteProjectResult.parse(raw);
16
+ }
17
+
18
+ export const deleteProjectTool = {
19
+ name: "delete_project",
20
+ description:
21
+ "Permanently delete a project and ALL its tasks. THIS ACTION CANNOT BE UNDONE. Before calling this tool you MUST ask the user to explicitly confirm they want to permanently delete the project, and inform them that all tasks within the project will also be deleted.",
22
+ inputSchema: DeleteProjectInput,
23
+ handler: deleteProjectHandler,
24
+ } as const;
@@ -0,0 +1,24 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema } from "../schemas/index.js";
4
+
5
+ const DeleteTagInput = z.object({
6
+ id: IdSchema.describe("The tag's id.primaryKey"),
7
+ });
8
+
9
+ const DeleteTagResult = z.object({ id: z.string() });
10
+
11
+ export async function deleteTagHandler(
12
+ input: z.infer<typeof DeleteTagInput>
13
+ ): Promise<z.infer<typeof DeleteTagResult>> {
14
+ const raw = await runSnippet("delete_tag", { id: input.id });
15
+ return DeleteTagResult.parse(raw);
16
+ }
17
+
18
+ export const deleteTagTool = {
19
+ name: "delete_tag",
20
+ description:
21
+ "Permanently delete an OmniFocus tag. THIS ACTION CANNOT BE UNDONE. All child tags are also deleted, and all tasks/projects that held this tag have it removed automatically. Before calling this tool you MUST ask the user to explicitly confirm they want to permanently delete the tag and all its child tags.",
22
+ inputSchema: DeleteTagInput,
23
+ handler: deleteTagHandler,
24
+ } as const;
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema } from "../schemas/index.js";
4
+
5
+ const deleteTaskSchema = z.object({
6
+ id: IdSchema.describe("The task's id.primaryKey"),
7
+ });
8
+
9
+ export type DeleteTaskInput = z.infer<typeof deleteTaskSchema>;
10
+
11
+ const DeleteTaskResult = z.object({ id: IdSchema });
12
+
13
+ export async function deleteTaskHandler(
14
+ input: DeleteTaskInput
15
+ ): Promise<z.infer<typeof DeleteTaskResult>> {
16
+ const raw = await runSnippet("delete_task", { id: input.id });
17
+ return DeleteTaskResult.parse(raw);
18
+ }
19
+
20
+ export const deleteTaskTool = {
21
+ name: "delete_task",
22
+ description:
23
+ "Permanently delete a task and all its subtasks. THIS ACTION CANNOT BE UNDONE. Before calling this tool you MUST ask the user to explicitly confirm they want to permanently delete the task, and inform them that all subtasks will also be deleted.",
24
+ inputSchema: deleteTaskSchema,
25
+ handler: deleteTaskHandler,
26
+ } as const;
@@ -0,0 +1,21 @@
1
+ import { z } from "zod";
2
+ import { runSnippet } from "../runtime/index.js";
3
+ import { IdSchema, ProjectDetail } from "../schemas/index.js";
4
+
5
+ const DropProjectInput = z.object({
6
+ id: IdSchema.describe("The project's id.primaryKey"),
7
+ });
8
+
9
+ export async function dropProjectHandler(
10
+ input: z.infer<typeof DropProjectInput>
11
+ ): Promise<z.infer<typeof ProjectDetail>> {
12
+ const raw = await runSnippet("drop_project", { id: input.id });
13
+ return ProjectDetail.parse(raw);
14
+ }
15
+
16
+ export const dropProjectTool = {
17
+ name: "drop_project",
18
+ description: "Mark a project as dropped. Returns the updated project detail.",
19
+ inputSchema: DropProjectInput,
20
+ handler: dropProjectHandler,
21
+ } as const;