@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,76 @@
1
+ import { spawn } from "child_process";
2
+ import { loadSnippet } from "./snippetLoader.js";
3
+ import { buildJxaScript } from "./jxaShim.js";
4
+ import { parseResultLine, ExecutionError } from "./resultProtocol.js";
5
+ const DEFAULT_TIMEOUT_MS = 30_000;
6
+ /**
7
+ * Execute an OmniJS snippet inside OmniFocus via the JXA bridge.
8
+ *
9
+ * @param name - Snippet filename (without .js extension) under src/snippets/
10
+ * @param args - Arguments to inject. Embedded as a JSON literal; safe for
11
+ * all unicode, apostrophes, quotes, etc. (Design Decision 2).
12
+ * @param opts - Optional timeout override (default 30s)
13
+ * @returns The `data` field from the success envelope
14
+ * @throws ExecutionError if the snippet throws inside OmniJS
15
+ * @throws Error on timeout, process errors, or protocol violations
16
+ */
17
+ export async function runSnippet(name, args, opts = {}) {
18
+ const timeoutMs = opts.timeoutMs ?? DEFAULT_TIMEOUT_MS;
19
+ // Load and inject args — the only interpolation allowed (Decision 2)
20
+ const template = loadSnippet(name);
21
+ const snippet = template.replace("__ARGS__", JSON.stringify(args));
22
+ // Wrap snippet in JXA shim
23
+ const jxaScript = buildJxaScript(snippet);
24
+ return new Promise((resolve, reject) => {
25
+ const MAX_OUTPUT_BYTES = 10 * 1024 * 1024; // 10 MB
26
+ const ac = new AbortController();
27
+ const timer = setTimeout(() => {
28
+ ac.abort();
29
+ child.kill("SIGKILL");
30
+ reject(new Error(`Snippet "${name}" timed out after ${timeoutMs}ms`));
31
+ }, timeoutMs);
32
+ const child = spawn("osascript", ["-l", "JavaScript"], {
33
+ signal: ac.signal,
34
+ });
35
+ let stdout = "";
36
+ let stderr = "";
37
+ child.stdout.on("data", (chunk) => {
38
+ stdout += chunk.toString();
39
+ if (stdout.length > MAX_OUTPUT_BYTES) {
40
+ child.kill("SIGKILL");
41
+ clearTimeout(timer);
42
+ reject(new Error(`Snippet "${name}" exceeded maximum output size`));
43
+ }
44
+ });
45
+ child.stderr.on("data", (chunk) => {
46
+ stderr += chunk.toString();
47
+ });
48
+ child.on("error", (err) => {
49
+ clearTimeout(timer);
50
+ if (err.code === "ABORT_ERR")
51
+ return; // handled by timer
52
+ reject(err);
53
+ });
54
+ child.on("close", (code) => {
55
+ clearTimeout(timer);
56
+ try {
57
+ const envelope = parseResultLine(stdout);
58
+ if (envelope.ok) {
59
+ resolve(envelope.data);
60
+ }
61
+ else {
62
+ reject(new ExecutionError(envelope.error));
63
+ }
64
+ }
65
+ catch (parseErr) {
66
+ const hint = stdout.slice(0, 200) || stderr.slice(0, 200);
67
+ reject(new Error(`Failed to parse bridge output for snippet "${name}" (exit ${code})` +
68
+ (hint ? `: ${hint}` : "")));
69
+ }
70
+ });
71
+ // Write JXA script to stdin
72
+ child.stdin.write(jxaScript);
73
+ child.stdin.end();
74
+ });
75
+ }
76
+ //# sourceMappingURL=bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bridge.js","sourceRoot":"","sources":["../../src/runtime/bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ export { runSnippet, type RunOptions } from "./bridge.js";
2
+ export { loadSnippet, clearSnippetCache } from "./snippetLoader.js";
3
+ export { parseResultLine, ExecutionError, type ResultEnvelope } from "./resultProtocol.js";
4
+ export { buildJxaScript } from "./jxaShim.js";
5
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,KAAK,UAAU,EAAE,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAE,KAAK,cAAc,EAAE,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,5 @@
1
+ export { runSnippet } from "./bridge.js";
2
+ export { loadSnippet, clearSnippetCache } from "./snippetLoader.js";
3
+ export { parseResultLine, ExecutionError } from "./resultProtocol.js";
4
+ export { buildJxaScript } from "./jxaShim.js";
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/runtime/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAmB,MAAM,aAAa,CAAC;AAC1D,OAAO,EAAE,WAAW,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AACpE,OAAO,EAAE,eAAe,EAAE,cAAc,EAAuB,MAAM,qBAAqB,CAAC;AAC3F,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC"}
@@ -0,0 +1,21 @@
1
+ /**
2
+ * JXA wrapper template. The `__SNIPPET__` placeholder is replaced with the
3
+ * OmniJS snippet to execute. The resulting script is passed to
4
+ * `osascript -l JavaScript` via stdin.
5
+ *
6
+ * This shim:
7
+ * - Calls Application('OmniFocus').evaluateJavascript() with the snippet
8
+ * - Wraps in try/catch
9
+ * - Prints exactly one line of JSON: {ok, data} | {ok: false, error: {...}}
10
+ *
11
+ * The JXA scripting dictionary is used ONLY for evaluateJavascript.
12
+ * No other scripting-dictionary domain methods are invoked here.
13
+ */
14
+ export declare const JXA_SHIM_TEMPLATE = "\n(function() {\n var snippet = __SNIPPET__;\n var app = Application('OmniFocus');\n app.includeStandardAdditions = true;\n try {\n var result = app.evaluateJavascript(snippet);\n // result is already a JSON string produced by the snippet\n $.NSFileHandle.fileHandleWithStandardOutput.writeData(\n $.NSString.alloc.initWithString(result + '\\n')\n .dataUsingEncoding($.NSUTF8StringEncoding)\n );\n } catch(e) {\n var errName = e.name || 'Error';\n var errMsg = e.message || String(e);\n // OmniJS wraps thrown errors; the original name is embedded in the message\n // as \"SomeName: original message\". Recover it when the name is generic.\n var nameMatch = errMsg.match(/^([A-Z]\\w*Error): ([\\s\\S]*)$/);\n if (nameMatch) { errName = nameMatch[1]; errMsg = nameMatch[2]; }\n var err = JSON.stringify({\n ok: false,\n error: {\n name: errName,\n message: errMsg\n }\n });\n $.NSFileHandle.fileHandleWithStandardOutput.writeData(\n $.NSString.alloc.initWithString(err + '\\n')\n .dataUsingEncoding($.NSUTF8StringEncoding)\n );\n }\n})();\n";
15
+ /**
16
+ * Build the complete JXA script to pass to osascript.
17
+ * The snippet is embedded as a JS string literal via JSON.stringify,
18
+ * so it is safe to contain any characters including quotes, backslashes, etc.
19
+ */
20
+ export declare function buildJxaScript(snippet: string): string;
21
+ //# sourceMappingURL=jxaShim.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jxaShim.d.ts","sourceRoot":"","sources":["../../src/runtime/jxaShim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,iBAAiB,ynCAgC7B,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,cAAc,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEtD"}
@@ -0,0 +1,55 @@
1
+ /**
2
+ * JXA wrapper template. The `__SNIPPET__` placeholder is replaced with the
3
+ * OmniJS snippet to execute. The resulting script is passed to
4
+ * `osascript -l JavaScript` via stdin.
5
+ *
6
+ * This shim:
7
+ * - Calls Application('OmniFocus').evaluateJavascript() with the snippet
8
+ * - Wraps in try/catch
9
+ * - Prints exactly one line of JSON: {ok, data} | {ok: false, error: {...}}
10
+ *
11
+ * The JXA scripting dictionary is used ONLY for evaluateJavascript.
12
+ * No other scripting-dictionary domain methods are invoked here.
13
+ */
14
+ export const JXA_SHIM_TEMPLATE = `
15
+ (function() {
16
+ var snippet = __SNIPPET__;
17
+ var app = Application('OmniFocus');
18
+ app.includeStandardAdditions = true;
19
+ try {
20
+ var result = app.evaluateJavascript(snippet);
21
+ // result is already a JSON string produced by the snippet
22
+ $.NSFileHandle.fileHandleWithStandardOutput.writeData(
23
+ $.NSString.alloc.initWithString(result + '\\n')
24
+ .dataUsingEncoding($.NSUTF8StringEncoding)
25
+ );
26
+ } catch(e) {
27
+ var errName = e.name || 'Error';
28
+ var errMsg = e.message || String(e);
29
+ // OmniJS wraps thrown errors; the original name is embedded in the message
30
+ // as "SomeName: original message". Recover it when the name is generic.
31
+ var nameMatch = errMsg.match(/^([A-Z]\\w*Error): ([\\s\\S]*)$/);
32
+ if (nameMatch) { errName = nameMatch[1]; errMsg = nameMatch[2]; }
33
+ var err = JSON.stringify({
34
+ ok: false,
35
+ error: {
36
+ name: errName,
37
+ message: errMsg
38
+ }
39
+ });
40
+ $.NSFileHandle.fileHandleWithStandardOutput.writeData(
41
+ $.NSString.alloc.initWithString(err + '\\n')
42
+ .dataUsingEncoding($.NSUTF8StringEncoding)
43
+ );
44
+ }
45
+ })();
46
+ `;
47
+ /**
48
+ * Build the complete JXA script to pass to osascript.
49
+ * The snippet is embedded as a JS string literal via JSON.stringify,
50
+ * so it is safe to contain any characters including quotes, backslashes, etc.
51
+ */
52
+ export function buildJxaScript(snippet) {
53
+ return JXA_SHIM_TEMPLATE.replace("__SNIPPET__", JSON.stringify(snippet));
54
+ }
55
+ //# sourceMappingURL=jxaShim.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"jxaShim.js","sourceRoot":"","sources":["../../src/runtime/jxaShim.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,MAAM,iBAAiB,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAgChC,CAAC;AAEF;;;;GAIG;AACH,MAAM,UAAU,cAAc,CAAC,OAAe;IAC5C,OAAO,iBAAiB,CAAC,OAAO,CAAC,aAAa,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC;AAC3E,CAAC"}
@@ -0,0 +1,66 @@
1
+ import { z } from "zod";
2
+ declare const ErrorDetail: z.ZodObject<{
3
+ name: z.ZodString;
4
+ message: z.ZodString;
5
+ stack: z.ZodOptional<z.ZodString>;
6
+ }, "strip", z.ZodTypeAny, {
7
+ name: string;
8
+ message: string;
9
+ stack?: string | undefined;
10
+ }, {
11
+ name: string;
12
+ message: string;
13
+ stack?: string | undefined;
14
+ }>;
15
+ declare const Envelope: z.ZodDiscriminatedUnion<"ok", [z.ZodObject<{
16
+ ok: z.ZodLiteral<true>;
17
+ data: z.ZodUnknown;
18
+ }, "strip", z.ZodTypeAny, {
19
+ ok: true;
20
+ data?: unknown;
21
+ }, {
22
+ ok: true;
23
+ data?: unknown;
24
+ }>, z.ZodObject<{
25
+ ok: z.ZodLiteral<false>;
26
+ error: z.ZodObject<{
27
+ name: z.ZodString;
28
+ message: z.ZodString;
29
+ stack: z.ZodOptional<z.ZodString>;
30
+ }, "strip", z.ZodTypeAny, {
31
+ name: string;
32
+ message: string;
33
+ stack?: string | undefined;
34
+ }, {
35
+ name: string;
36
+ message: string;
37
+ stack?: string | undefined;
38
+ }>;
39
+ }, "strip", z.ZodTypeAny, {
40
+ ok: false;
41
+ error: {
42
+ name: string;
43
+ message: string;
44
+ stack?: string | undefined;
45
+ };
46
+ }, {
47
+ ok: false;
48
+ error: {
49
+ name: string;
50
+ message: string;
51
+ stack?: string | undefined;
52
+ };
53
+ }>]>;
54
+ export type ResultEnvelope = z.infer<typeof Envelope>;
55
+ export declare class ExecutionError extends Error {
56
+ readonly errorName: string;
57
+ readonly remoteStack?: string;
58
+ constructor(detail: z.infer<typeof ErrorDetail>);
59
+ }
60
+ /**
61
+ * Scans stdout for the first JSON-parseable line and validates it as a result
62
+ * envelope. Ignores any preceding non-JSON chatter (e.g. osascript warnings).
63
+ */
64
+ export declare function parseResultLine(stdout: string): ResultEnvelope;
65
+ export {};
66
+ //# sourceMappingURL=resultProtocol.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resultProtocol.d.ts","sourceRoot":"","sources":["../../src/runtime/resultProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,QAAA,MAAM,WAAW;;;;;;;;;;;;EAIf,CAAC;AAYH,QAAA,MAAM,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;IAA+D,CAAC;AAE9E,MAAM,MAAM,cAAc,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,QAAQ,CAAC,CAAC;AAEtD,qBAAa,cAAe,SAAQ,KAAK;IACvC,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;gBAElB,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC;CAMhD;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,cAAc,CAuB9D"}
@@ -0,0 +1,52 @@
1
+ import { z } from "zod";
2
+ const ErrorDetail = z.object({
3
+ name: z.string(),
4
+ message: z.string(),
5
+ stack: z.string().optional(),
6
+ });
7
+ const SuccessEnvelope = z.object({
8
+ ok: z.literal(true),
9
+ data: z.unknown(),
10
+ });
11
+ const ErrorEnvelope = z.object({
12
+ ok: z.literal(false),
13
+ error: ErrorDetail,
14
+ });
15
+ const Envelope = z.discriminatedUnion("ok", [SuccessEnvelope, ErrorEnvelope]);
16
+ export class ExecutionError extends Error {
17
+ errorName;
18
+ remoteStack;
19
+ constructor(detail) {
20
+ super(detail.message);
21
+ this.name = "ExecutionError";
22
+ this.errorName = detail.name;
23
+ this.remoteStack = detail.stack;
24
+ }
25
+ }
26
+ /**
27
+ * Scans stdout for the first JSON-parseable line and validates it as a result
28
+ * envelope. Ignores any preceding non-JSON chatter (e.g. osascript warnings).
29
+ */
30
+ export function parseResultLine(stdout) {
31
+ const lines = stdout.split("\n");
32
+ for (const line of lines) {
33
+ const trimmed = line.trim();
34
+ if (!trimmed)
35
+ continue;
36
+ let parsed;
37
+ try {
38
+ parsed = JSON.parse(trimmed);
39
+ }
40
+ catch {
41
+ continue; // not JSON, skip
42
+ }
43
+ const result = Envelope.safeParse(parsed);
44
+ if (result.success) {
45
+ return result.data;
46
+ }
47
+ // Parsed as JSON but not a valid envelope — this is a protocol error
48
+ throw new Error(`Bridge returned JSON that is not a valid result envelope: ${trimmed}`);
49
+ }
50
+ throw new Error(`No valid JSON result envelope found in osascript output:\n${stdout}`);
51
+ }
52
+ //# sourceMappingURL=resultProtocol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resultProtocol.js","sourceRoot":"","sources":["../../src/runtime/resultProtocol.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,WAAW,GAAG,CAAC,CAAC,MAAM,CAAC;IAC3B,IAAI,EAAE,CAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,KAAK,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE;CAC7B,CAAC,CAAC;AAEH,MAAM,eAAe,GAAG,CAAC,CAAC,MAAM,CAAC;IAC/B,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,IAAI,CAAC;IACnB,IAAI,EAAE,CAAC,CAAC,OAAO,EAAE;CAClB,CAAC,CAAC;AAEH,MAAM,aAAa,GAAG,CAAC,CAAC,MAAM,CAAC;IAC7B,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC;IACpB,KAAK,EAAE,WAAW;CACnB,CAAC,CAAC;AAEH,MAAM,QAAQ,GAAG,CAAC,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC,CAAC;AAI9E,MAAM,OAAO,cAAe,SAAQ,KAAK;IAC9B,SAAS,CAAS;IAClB,WAAW,CAAU;IAE9B,YAAY,MAAmC;QAC7C,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACtB,IAAI,CAAC,IAAI,GAAG,gBAAgB,CAAC;QAC7B,IAAI,CAAC,SAAS,GAAG,MAAM,CAAC,IAAI,CAAC;QAC7B,IAAI,CAAC,WAAW,GAAG,MAAM,CAAC,KAAK,CAAC;IAClC,CAAC;CACF;AAED;;;GAGG;AACH,MAAM,UAAU,eAAe,CAAC,MAAc;IAC5C,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IACjC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QAC5B,IAAI,CAAC,OAAO;YAAE,SAAS;QACvB,IAAI,MAAe,CAAC;QACpB,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC;QAC/B,CAAC;QAAC,MAAM,CAAC;YACP,SAAS,CAAC,iBAAiB;QAC7B,CAAC;QACD,MAAM,MAAM,GAAG,QAAQ,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;QAC1C,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,MAAM,CAAC,IAAI,CAAC;QACrB,CAAC;QACD,qEAAqE;QACrE,MAAM,IAAI,KAAK,CACb,6DAA6D,OAAO,EAAE,CACvE,CAAC;IACJ,CAAC;IACD,MAAM,IAAI,KAAK,CACb,6DAA6D,MAAM,EAAE,CACtE,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ export declare function loadSnippet(name: string): string;
2
+ /** For testing: clear the in-memory cache. */
3
+ export declare function clearSnippetCache(): void;
4
+ //# sourceMappingURL=snippetLoader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snippetLoader.d.ts","sourceRoot":"","sources":["../../src/runtime/snippetLoader.ts"],"names":[],"mappings":"AA0CA,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CA+BhD;AAED,8CAA8C;AAC9C,wBAAgB,iBAAiB,IAAI,IAAI,CAExC"}
@@ -0,0 +1,68 @@
1
+ import { readFileSync } from "fs";
2
+ import { join, dirname } from "path";
3
+ import { fileURLToPath } from "url";
4
+ const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ const SNIPPETS_DIR = join(__dirname, "..", "snippets");
6
+ // Allowlist of valid snippet names. Adding a new snippet requires an explicit
7
+ // entry here, which prevents path-traversal attacks if a snippet name ever
8
+ // reaches this loader from a dynamic source.
9
+ const ALLOWED_SNIPPETS = new Set([
10
+ "get_folder",
11
+ "get_project",
12
+ "get_tag",
13
+ "get_task",
14
+ "list_folders",
15
+ "list_projects",
16
+ "list_tags",
17
+ "list_tasks",
18
+ "resolve_name",
19
+ "create_task",
20
+ "edit_task",
21
+ "complete_task",
22
+ "drop_task",
23
+ "delete_task",
24
+ "create_project",
25
+ "edit_project",
26
+ "complete_project",
27
+ "drop_project",
28
+ "delete_project",
29
+ "create_folder",
30
+ "edit_folder",
31
+ "delete_folder",
32
+ "create_tag",
33
+ "edit_tag",
34
+ "delete_tag",
35
+ "move_task",
36
+ "move_project",
37
+ ]);
38
+ const cache = new Map();
39
+ export function loadSnippet(name) {
40
+ if (!ALLOWED_SNIPPETS.has(name)) {
41
+ throw new Error(`Unknown snippet: "${name}"`);
42
+ }
43
+ if (cache.has(name)) {
44
+ return cache.get(name);
45
+ }
46
+ const filePath = join(SNIPPETS_DIR, `${name}.js`);
47
+ let content;
48
+ try {
49
+ content = readFileSync(filePath, "utf-8");
50
+ }
51
+ catch {
52
+ throw new Error(`Snippet "${name}" could not be loaded`);
53
+ }
54
+ const matches = content.split("__ARGS__").length - 1;
55
+ if (matches === 0) {
56
+ throw new Error(`Snippet "${name}" contains no __ARGS__ placeholder. Every snippet must have exactly one.`);
57
+ }
58
+ if (matches > 1) {
59
+ throw new Error(`Snippet "${name}" contains ${matches} __ARGS__ placeholders. Exactly one is required.`);
60
+ }
61
+ cache.set(name, content);
62
+ return content;
63
+ }
64
+ /** For testing: clear the in-memory cache. */
65
+ export function clearSnippetCache() {
66
+ cache.clear();
67
+ }
68
+ //# sourceMappingURL=snippetLoader.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"snippetLoader.js","sourceRoot":"","sources":["../../src/runtime/snippetLoader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACrC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AAEpC,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAC1D,MAAM,YAAY,GAAG,IAAI,CAAC,SAAS,EAAE,IAAI,EAAE,UAAU,CAAC,CAAC;AAEvD,8EAA8E;AAC9E,2EAA2E;AAC3E,6CAA6C;AAC7C,MAAM,gBAAgB,GAAG,IAAI,GAAG,CAAC;IAC/B,YAAY;IACZ,aAAa;IACb,SAAS;IACT,UAAU;IACV,cAAc;IACd,eAAe;IACf,WAAW;IACX,YAAY;IACZ,cAAc;IACd,aAAa;IACb,WAAW;IACX,eAAe;IACf,WAAW;IACX,aAAa;IACb,gBAAgB;IAChB,cAAc;IACd,kBAAkB;IAClB,cAAc;IACd,gBAAgB;IAChB,eAAe;IACf,aAAa;IACb,eAAe;IACf,YAAY;IACZ,UAAU;IACV,YAAY;IACZ,WAAW;IACX,cAAc;CACf,CAAC,CAAC;AAEH,MAAM,KAAK,GAAG,IAAI,GAAG,EAAkB,CAAC;AAExC,MAAM,UAAU,WAAW,CAAC,IAAY;IACtC,IAAI,CAAC,gBAAgB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QAChC,MAAM,IAAI,KAAK,CAAC,qBAAqB,IAAI,GAAG,CAAC,CAAC;IAChD,CAAC;IAED,IAAI,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;QACpB,OAAO,KAAK,CAAC,GAAG,CAAC,IAAI,CAAE,CAAC;IAC1B,CAAC;IAED,MAAM,QAAQ,GAAG,IAAI,CAAC,YAAY,EAAE,GAAG,IAAI,KAAK,CAAC,CAAC;IAClD,IAAI,OAAe,CAAC;IACpB,IAAI,CAAC;QACH,OAAO,GAAG,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAAC,MAAM,CAAC;QACP,MAAM,IAAI,KAAK,CAAC,YAAY,IAAI,uBAAuB,CAAC,CAAC;IAC3D,CAAC;IAED,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;IACrD,IAAI,OAAO,KAAK,CAAC,EAAE,CAAC;QAClB,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,0EAA0E,CAC3F,CAAC;IACJ,CAAC;IACD,IAAI,OAAO,GAAG,CAAC,EAAE,CAAC;QAChB,MAAM,IAAI,KAAK,CACb,YAAY,IAAI,cAAc,OAAO,kDAAkD,CACxF,CAAC;IACJ,CAAC;IAED,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC;IACzB,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,8CAA8C;AAC9C,MAAM,UAAU,iBAAiB;IAC/B,KAAK,CAAC,KAAK,EAAE,CAAC;AAChB,CAAC"}
@@ -0,0 +1,9 @@
1
+ import { z } from "zod";
2
+ export declare const IdSchema: z.ZodString;
3
+ export declare const EntityType: z.ZodEnum<["task", "project", "folder", "tag", "perspective"]>;
4
+ export declare const ProjectType: z.ZodEnum<["parallel", "sequential", "singleActions"]>;
5
+ export declare const ProjectStatus: z.ZodEnum<["active", "onHold", "done", "dropped"]>;
6
+ export declare const TaskStatus: z.ZodEnum<["available", "incomplete", "completedByChildren", "complete", "dropped", "dueSoon", "overdue", "flagged", "blocked", "next"]>;
7
+ export declare const TagStatus: z.ZodEnum<["active", "onHold", "dropped"]>;
8
+ export declare const FolderStatus: z.ZodEnum<["active", "dropped"]>;
9
+ //# sourceMappingURL=enums.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.d.ts","sourceRoot":"","sources":["../../src/schemas/enums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,eAAO,MAAM,QAAQ,aAAqD,CAAC;AAE3E,eAAO,MAAM,UAAU,gEAMrB,CAAC;AAEH,eAAO,MAAM,WAAW,wDAAsD,CAAC;AAE/E,eAAO,MAAM,aAAa,oDAAkD,CAAC;AAE7E,eAAO,MAAM,UAAU,0IAWrB,CAAC;AAEH,eAAO,MAAM,SAAS,4CAA0C,CAAC;AAEjE,eAAO,MAAM,YAAY,kCAAgC,CAAC"}
@@ -0,0 +1,26 @@
1
+ import { z } from "zod";
2
+ export const IdSchema = z.string().min(1, "ID must be a non-empty string");
3
+ export const EntityType = z.enum([
4
+ "task",
5
+ "project",
6
+ "folder",
7
+ "tag",
8
+ "perspective",
9
+ ]);
10
+ export const ProjectType = z.enum(["parallel", "sequential", "singleActions"]);
11
+ export const ProjectStatus = z.enum(["active", "onHold", "done", "dropped"]);
12
+ export const TaskStatus = z.enum([
13
+ "available",
14
+ "incomplete",
15
+ "completedByChildren",
16
+ "complete",
17
+ "dropped",
18
+ "dueSoon",
19
+ "overdue",
20
+ "flagged",
21
+ "blocked",
22
+ "next",
23
+ ]);
24
+ export const TagStatus = z.enum(["active", "onHold", "dropped"]);
25
+ export const FolderStatus = z.enum(["active", "dropped"]);
26
+ //# sourceMappingURL=enums.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"enums.js","sourceRoot":"","sources":["../../src/schemas/enums.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,CAAC,EAAE,+BAA+B,CAAC,CAAC;AAE3E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC;IAC/B,MAAM;IACN,SAAS;IACT,QAAQ;IACR,KAAK;IACL,aAAa;CACd,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,WAAW,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,YAAY,EAAE,eAAe,CAAC,CAAC,CAAC;AAE/E,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC;AAE7E,MAAM,CAAC,MAAM,UAAU,GAAG,CAAC,CAAC,IAAI,CAAC;IAC/B,WAAW;IACX,YAAY;IACZ,qBAAqB;IACrB,UAAU;IACV,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,SAAS;IACT,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC;AAEjE,MAAM,CAAC,MAAM,YAAY,GAAG,CAAC,CAAC,IAAI,CAAC,CAAC,QAAQ,EAAE,SAAS,CAAC,CAAC,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { IdSchema, EntityType, ProjectType, ProjectStatus, TaskStatus, TagStatus, FolderStatus, } from "./enums.js";
2
+ export { RepetitionRuleInput, RepetitionRuleDetail, TaskSummary, ListTasksFilter, TaskDetail, CreateTaskInput, EditTaskInput, MoveTaskInput, ReviewIntervalInput, CreateProjectInput, EditProjectInput, MoveProjectInput, ListProjectsFilter, ProjectSummary, ProjectDetail, ListFoldersFilter, CreateFolderInput, EditFolderInput, FolderSummary, FolderDetail, ListTagsFilter, CreateTagInput, EditTagInput, TagSummary, TagDetail, ResolveCandidate, } from "./shapes.js";
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,UAAU,EACV,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,EACZ,UAAU,EACV,SAAS,EACT,gBAAgB,GACjB,MAAM,aAAa,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { IdSchema, EntityType, ProjectType, ProjectStatus, TaskStatus, TagStatus, FolderStatus, } from "./enums.js";
2
+ export { RepetitionRuleInput, RepetitionRuleDetail, TaskSummary, ListTasksFilter, TaskDetail, CreateTaskInput, EditTaskInput, MoveTaskInput, ReviewIntervalInput, CreateProjectInput, EditProjectInput, MoveProjectInput, ListProjectsFilter, ProjectSummary, ProjectDetail, ListFoldersFilter, CreateFolderInput, EditFolderInput, FolderSummary, FolderDetail, ListTagsFilter, CreateTagInput, EditTagInput, TagSummary, TagDetail, ResolveCandidate, } from "./shapes.js";
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/schemas/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,QAAQ,EACR,UAAU,EACV,WAAW,EACX,aAAa,EACb,UAAU,EACV,SAAS,EACT,YAAY,GACb,MAAM,YAAY,CAAC;AAEpB,OAAO,EACL,mBAAmB,EACnB,oBAAoB,EACpB,WAAW,EACX,eAAe,EACf,UAAU,EACV,eAAe,EACf,aAAa,EACb,aAAa,EACb,mBAAmB,EACnB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,kBAAkB,EAClB,cAAc,EACd,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,eAAe,EACf,aAAa,EACb,YAAY,EACZ,cAAc,EACd,cAAc,EACd,YAAY,EACZ,UAAU,EACV,SAAS,EACT,gBAAgB,GACjB,MAAM,aAAa,CAAC"}