@ofocus/sdk 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 (200) hide show
  1. package/README.md +80 -0
  2. package/api-report/ofocus-sdk.api.md +564 -0
  3. package/dist/.tsbuildinfo +1 -0
  4. package/dist/applescript.d.ts +30 -0
  5. package/dist/applescript.d.ts.map +1 -0
  6. package/dist/applescript.js +142 -0
  7. package/dist/applescript.js.map +1 -0
  8. package/dist/commands/batch.d.ts +23 -0
  9. package/dist/commands/batch.d.ts.map +1 -0
  10. package/dist/commands/batch.js +324 -0
  11. package/dist/commands/batch.js.map +1 -0
  12. package/dist/commands/complete.d.ts +14 -0
  13. package/dist/commands/complete.d.ts.map +1 -0
  14. package/dist/commands/complete.js +37 -0
  15. package/dist/commands/complete.js.map +1 -0
  16. package/dist/commands/create-project.d.ts +6 -0
  17. package/dist/commands/create-project.d.ts.map +1 -0
  18. package/dist/commands/create-project.js +124 -0
  19. package/dist/commands/create-project.js.map +1 -0
  20. package/dist/commands/drop.d.ts +26 -0
  21. package/dist/commands/drop.d.ts.map +1 -0
  22. package/dist/commands/drop.js +62 -0
  23. package/dist/commands/drop.js.map +1 -0
  24. package/dist/commands/folders.d.ts +10 -0
  25. package/dist/commands/folders.d.ts.map +1 -0
  26. package/dist/commands/folders.js +150 -0
  27. package/dist/commands/folders.js.map +1 -0
  28. package/dist/commands/inbox.d.ts +6 -0
  29. package/dist/commands/inbox.d.ts.map +1 -0
  30. package/dist/commands/inbox.js +124 -0
  31. package/dist/commands/inbox.js.map +1 -0
  32. package/dist/commands/perspectives.d.ts +20 -0
  33. package/dist/commands/perspectives.d.ts.map +1 -0
  34. package/dist/commands/perspectives.js +166 -0
  35. package/dist/commands/perspectives.js.map +1 -0
  36. package/dist/commands/projects.d.ts +6 -0
  37. package/dist/commands/projects.d.ts.map +1 -0
  38. package/dist/commands/projects.js +113 -0
  39. package/dist/commands/projects.js.map +1 -0
  40. package/dist/commands/repetition.d.ts +17 -0
  41. package/dist/commands/repetition.d.ts.map +1 -0
  42. package/dist/commands/repetition.js +59 -0
  43. package/dist/commands/repetition.js.map +1 -0
  44. package/dist/commands/review.d.ts +10 -0
  45. package/dist/commands/review.d.ts.map +1 -0
  46. package/dist/commands/review.js +132 -0
  47. package/dist/commands/review.js.map +1 -0
  48. package/dist/commands/search.d.ts +6 -0
  49. package/dist/commands/search.d.ts.map +1 -0
  50. package/dist/commands/search.js +150 -0
  51. package/dist/commands/search.js.map +1 -0
  52. package/dist/commands/subtasks.d.ts +14 -0
  53. package/dist/commands/subtasks.d.ts.map +1 -0
  54. package/dist/commands/subtasks.js +370 -0
  55. package/dist/commands/subtasks.js.map +1 -0
  56. package/dist/commands/tags-crud.d.ts +22 -0
  57. package/dist/commands/tags-crud.d.ts.map +1 -0
  58. package/dist/commands/tags-crud.js +187 -0
  59. package/dist/commands/tags-crud.js.map +1 -0
  60. package/dist/commands/tags.d.ts +6 -0
  61. package/dist/commands/tags.d.ts.map +1 -0
  62. package/dist/commands/tags.js +61 -0
  63. package/dist/commands/tags.js.map +1 -0
  64. package/dist/commands/tasks.d.ts +6 -0
  65. package/dist/commands/tasks.d.ts.map +1 -0
  66. package/dist/commands/tasks.js +160 -0
  67. package/dist/commands/tasks.js.map +1 -0
  68. package/dist/commands/update.d.ts +6 -0
  69. package/dist/commands/update.d.ts.map +1 -0
  70. package/dist/commands/update.js +179 -0
  71. package/dist/commands/update.js.map +1 -0
  72. package/dist/errors.d.ts +38 -0
  73. package/dist/errors.d.ts.map +1 -0
  74. package/dist/errors.js +77 -0
  75. package/dist/errors.js.map +1 -0
  76. package/dist/escape.d.ts +6 -0
  77. package/dist/escape.d.ts.map +1 -0
  78. package/dist/escape.js +8 -0
  79. package/dist/escape.js.map +1 -0
  80. package/dist/index.d.ts +30 -0
  81. package/dist/index.d.ts.map +1 -0
  82. package/dist/index.js +36 -0
  83. package/dist/index.js.map +1 -0
  84. package/dist/ofocus-sdk.d.ts +608 -0
  85. package/dist/result.d.ts +15 -0
  86. package/dist/result.d.ts.map +1 -0
  87. package/dist/result.js +29 -0
  88. package/dist/result.js.map +1 -0
  89. package/dist/types.d.ts +228 -0
  90. package/dist/types.d.ts.map +1 -0
  91. package/dist/types.js +2 -0
  92. package/dist/types.js.map +1 -0
  93. package/dist/validation.d.ts +57 -0
  94. package/dist/validation.d.ts.map +1 -0
  95. package/dist/validation.js +172 -0
  96. package/dist/validation.js.map +1 -0
  97. package/docs/index.md +30 -0
  98. package/docs/sdk.addtoinbox.md +68 -0
  99. package/docs/sdk.applescriptresult.data.md +11 -0
  100. package/docs/sdk.applescriptresult.error.md +11 -0
  101. package/docs/sdk.applescriptresult.md +92 -0
  102. package/docs/sdk.applescriptresult.success.md +11 -0
  103. package/docs/sdk.clierror.code.md +11 -0
  104. package/docs/sdk.clierror.details.md +11 -0
  105. package/docs/sdk.clierror.md +92 -0
  106. package/docs/sdk.clierror.message.md +11 -0
  107. package/docs/sdk.clioutput.data.md +11 -0
  108. package/docs/sdk.clioutput.error.md +11 -0
  109. package/docs/sdk.clioutput.md +90 -0
  110. package/docs/sdk.clioutput.success.md +11 -0
  111. package/docs/sdk.commandinfo.description.md +11 -0
  112. package/docs/sdk.commandinfo.md +90 -0
  113. package/docs/sdk.commandinfo.name.md +11 -0
  114. package/docs/sdk.commandinfo.usage.md +11 -0
  115. package/docs/sdk.completeresult.completed.md +11 -0
  116. package/docs/sdk.completeresult.md +90 -0
  117. package/docs/sdk.completeresult.taskid.md +11 -0
  118. package/docs/sdk.completeresult.taskname.md +11 -0
  119. package/docs/sdk.completetask.md +52 -0
  120. package/docs/sdk.createerror.md +82 -0
  121. package/docs/sdk.errorcode.md +24 -0
  122. package/docs/sdk.escapeapplescript.md +52 -0
  123. package/docs/sdk.failure.md +52 -0
  124. package/docs/sdk.failuremessage.md +52 -0
  125. package/docs/sdk.inboxoptions.defer.md +11 -0
  126. package/docs/sdk.inboxoptions.due.md +11 -0
  127. package/docs/sdk.inboxoptions.flag.md +11 -0
  128. package/docs/sdk.inboxoptions.md +134 -0
  129. package/docs/sdk.inboxoptions.note.md +11 -0
  130. package/docs/sdk.inboxoptions.tags.md +11 -0
  131. package/docs/sdk.jsonhelpers.md +13 -0
  132. package/docs/sdk.md +471 -0
  133. package/docs/sdk.ofperspective.id.md +11 -0
  134. package/docs/sdk.ofperspective.md +73 -0
  135. package/docs/sdk.ofperspective.name.md +11 -0
  136. package/docs/sdk.ofproject.folderid.md +11 -0
  137. package/docs/sdk.ofproject.foldername.md +11 -0
  138. package/docs/sdk.ofproject.id.md +11 -0
  139. package/docs/sdk.ofproject.md +192 -0
  140. package/docs/sdk.ofproject.name.md +11 -0
  141. package/docs/sdk.ofproject.note.md +11 -0
  142. package/docs/sdk.ofproject.remainingtaskcount.md +11 -0
  143. package/docs/sdk.ofproject.sequential.md +11 -0
  144. package/docs/sdk.ofproject.status.md +11 -0
  145. package/docs/sdk.ofproject.taskcount.md +11 -0
  146. package/docs/sdk.oftag.availabletaskcount.md +11 -0
  147. package/docs/sdk.oftag.id.md +11 -0
  148. package/docs/sdk.oftag.md +124 -0
  149. package/docs/sdk.oftag.name.md +11 -0
  150. package/docs/sdk.oftag.parentid.md +11 -0
  151. package/docs/sdk.oftag.parentname.md +11 -0
  152. package/docs/sdk.oftask.completed.md +11 -0
  153. package/docs/sdk.oftask.completiondate.md +11 -0
  154. package/docs/sdk.oftask.deferdate.md +11 -0
  155. package/docs/sdk.oftask.duedate.md +11 -0
  156. package/docs/sdk.oftask.flagged.md +11 -0
  157. package/docs/sdk.oftask.id.md +11 -0
  158. package/docs/sdk.oftask.md +226 -0
  159. package/docs/sdk.oftask.name.md +11 -0
  160. package/docs/sdk.oftask.note.md +11 -0
  161. package/docs/sdk.oftask.projectid.md +11 -0
  162. package/docs/sdk.oftask.projectname.md +11 -0
  163. package/docs/sdk.oftask.tags.md +11 -0
  164. package/docs/sdk.omnifocusscript.md +52 -0
  165. package/docs/sdk.omnifocusscriptwithhelpers.md +52 -0
  166. package/docs/sdk.parseapplescripterror.md +52 -0
  167. package/docs/sdk.projectqueryoptions.folder.md +11 -0
  168. package/docs/sdk.projectqueryoptions.md +96 -0
  169. package/docs/sdk.projectqueryoptions.sequential.md +11 -0
  170. package/docs/sdk.projectqueryoptions.status.md +11 -0
  171. package/docs/sdk.queryprojects.md +54 -0
  172. package/docs/sdk.querytags.md +54 -0
  173. package/docs/sdk.querytasks.md +54 -0
  174. package/docs/sdk.runapplescript.md +52 -0
  175. package/docs/sdk.runapplescriptfile.md +68 -0
  176. package/docs/sdk.success.md +52 -0
  177. package/docs/sdk.tagqueryoptions.md +58 -0
  178. package/docs/sdk.tagqueryoptions.parent.md +11 -0
  179. package/docs/sdk.taskqueryoptions.available.md +11 -0
  180. package/docs/sdk.taskqueryoptions.completed.md +11 -0
  181. package/docs/sdk.taskqueryoptions.dueafter.md +11 -0
  182. package/docs/sdk.taskqueryoptions.duebefore.md +11 -0
  183. package/docs/sdk.taskqueryoptions.flagged.md +11 -0
  184. package/docs/sdk.taskqueryoptions.md +172 -0
  185. package/docs/sdk.taskqueryoptions.project.md +11 -0
  186. package/docs/sdk.taskqueryoptions.tag.md +11 -0
  187. package/docs/sdk.taskupdateoptions.defer.md +11 -0
  188. package/docs/sdk.taskupdateoptions.due.md +11 -0
  189. package/docs/sdk.taskupdateoptions.flag.md +11 -0
  190. package/docs/sdk.taskupdateoptions.md +172 -0
  191. package/docs/sdk.taskupdateoptions.note.md +11 -0
  192. package/docs/sdk.taskupdateoptions.project.md +11 -0
  193. package/docs/sdk.taskupdateoptions.tags.md +11 -0
  194. package/docs/sdk.taskupdateoptions.title.md +11 -0
  195. package/docs/sdk.updatetask.md +66 -0
  196. package/docs/sdk.validatedatestring.md +54 -0
  197. package/docs/sdk.validateid.md +66 -0
  198. package/docs/sdk.validateprojectname.md +52 -0
  199. package/docs/sdk.validatetags.md +52 -0
  200. package/package.json +51 -0
@@ -0,0 +1,150 @@
1
+ import { success, failure } from "../result.js";
2
+ import { ErrorCode, createError } from "../errors.js";
3
+ import { validateFolderName, validateId } from "../validation.js";
4
+ import { escapeAppleScript } from "../escape.js";
5
+ import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
6
+ /**
7
+ * Create a new folder in OmniFocus.
8
+ */
9
+ export async function createFolder(name, options = {}) {
10
+ // Validate folder name (required for create)
11
+ if (!name || name.trim() === "") {
12
+ return failure(createError(ErrorCode.VALIDATION_ERROR, "Folder name cannot be empty"));
13
+ }
14
+ const nameError = validateFolderName(name);
15
+ if (nameError)
16
+ return failure(nameError);
17
+ // Validate optional inputs
18
+ if (options.parentFolderId !== undefined) {
19
+ const parentIdError = validateId(options.parentFolderId, "project");
20
+ if (parentIdError)
21
+ return failure(parentIdError);
22
+ }
23
+ const parentNameError = validateFolderName(options.parentFolderName);
24
+ if (parentNameError)
25
+ return failure(parentNameError);
26
+ // Build script based on whether we're placing in a parent folder
27
+ let findParent = "";
28
+ let makeFolder = "";
29
+ if (options.parentFolderId) {
30
+ findParent = `set parentFolder to first flattened folder whose id is "${escapeAppleScript(options.parentFolderId)}"`;
31
+ makeFolder = `set newFolder to make new folder at end of folders of parentFolder with properties {name:"${escapeAppleScript(name)}"}`;
32
+ }
33
+ else if (options.parentFolderName) {
34
+ findParent = `set parentFolder to first flattened folder whose name is "${escapeAppleScript(options.parentFolderName)}"`;
35
+ makeFolder = `set newFolder to make new folder at end of folders of parentFolder with properties {name:"${escapeAppleScript(name)}"}`;
36
+ }
37
+ else {
38
+ findParent = "";
39
+ makeFolder = `set newFolder to make new folder with properties {name:"${escapeAppleScript(name)}"}`;
40
+ }
41
+ const script = `
42
+ ${findParent}
43
+ ${makeFolder}
44
+
45
+ -- Return the created folder info
46
+ set folderId to id of newFolder
47
+ set folderName to name of newFolder
48
+
49
+ set parentId to ""
50
+ set parentName to ""
51
+ try
52
+ set p to container of newFolder
53
+ if class of p is folder then
54
+ set parentId to id of p
55
+ set parentName to name of p
56
+ end if
57
+ end try
58
+
59
+ set projCount to count of projects of newFolder
60
+ set subFolderCount to count of folders of newFolder
61
+
62
+ return "{" & ¬
63
+ "\\"id\\": \\"" & folderId & "\\"," & ¬
64
+ "\\"name\\": \\"" & (my escapeJson(folderName)) & "\\"," & ¬
65
+ "\\"parentId\\": " & (my jsonString(parentId)) & "," & ¬
66
+ "\\"parentName\\": " & (my jsonString(parentName)) & "," & ¬
67
+ "\\"projectCount\\": " & projCount & "," & ¬
68
+ "\\"folderCount\\": " & subFolderCount & ¬
69
+ "}"
70
+ `;
71
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
72
+ if (!result.success) {
73
+ return failure(result.error ??
74
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to create folder"));
75
+ }
76
+ if (result.data === undefined) {
77
+ return failure(createError(ErrorCode.UNKNOWN_ERROR, "No folder data returned"));
78
+ }
79
+ return success(result.data);
80
+ }
81
+ /**
82
+ * Query folders from OmniFocus with optional filters.
83
+ */
84
+ export async function queryFolders(options = {}) {
85
+ // Validate parent filter
86
+ const parentError = validateFolderName(options.parent);
87
+ if (parentError)
88
+ return failure(parentError);
89
+ const script = `
90
+ set output to "["
91
+ set isFirst to true
92
+
93
+ set allFolders to flattened folders
94
+
95
+ repeat with f in allFolders
96
+ set shouldInclude to true
97
+
98
+ ${options.parent ? `-- Filter by parent folder` : ""}
99
+ ${options.parent ? `try` : ""}
100
+ ${options.parent ? ` set c to container of f` : ""}
101
+ ${options.parent ? ` if class of c is folder then` : ""}
102
+ ${options.parent ? ` if name of c is not "${escapeAppleScript(options.parent)}" then set shouldInclude to false` : ""}
103
+ ${options.parent ? ` else` : ""}
104
+ ${options.parent ? ` set shouldInclude to false` : ""}
105
+ ${options.parent ? ` end if` : ""}
106
+ ${options.parent ? `on error` : ""}
107
+ ${options.parent ? ` set shouldInclude to false` : ""}
108
+ ${options.parent ? `end try` : ""}
109
+
110
+ if shouldInclude then
111
+ if not isFirst then set output to output & ","
112
+ set isFirst to false
113
+
114
+ set folderId to id of f
115
+ set folderName to name of f
116
+
117
+ set parentId to ""
118
+ set parentName to ""
119
+ try
120
+ set p to container of f
121
+ if class of p is folder then
122
+ set parentId to id of p
123
+ set parentName to name of p
124
+ end if
125
+ end try
126
+
127
+ set projCount to count of projects of f
128
+ set subFolderCount to count of folders of f
129
+
130
+ set output to output & "{" & ¬
131
+ "\\"id\\": \\"" & folderId & "\\"," & ¬
132
+ "\\"name\\": \\"" & (my escapeJson(folderName)) & "\\"," & ¬
133
+ "\\"parentId\\": " & (my jsonString(parentId)) & "," & ¬
134
+ "\\"parentName\\": " & (my jsonString(parentName)) & "," & ¬
135
+ "\\"projectCount\\": " & projCount & "," & ¬
136
+ "\\"folderCount\\": " & subFolderCount & ¬
137
+ "}"
138
+ end if
139
+ end repeat
140
+
141
+ return output & "]"
142
+ `;
143
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
144
+ if (!result.success) {
145
+ return failure(result.error ??
146
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to query folders"));
147
+ }
148
+ return success(result.data ?? []);
149
+ }
150
+ //# sourceMappingURL=folders.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"folders.js","sourceRoot":"","sources":["../../src/commands/folders.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ import type { CliOutput, InboxOptions, OFTask } from "../types.js";
2
+ /**
3
+ * Add a task to the OmniFocus inbox.
4
+ */
5
+ export declare function addToInbox(title: string, options?: InboxOptions): Promise<CliOutput<OFTask>>;
6
+ //# sourceMappingURL=inbox.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAgBnE;;GAEG;AACH,wBAAsB,UAAU,CAC9B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAmI5B"}
@@ -0,0 +1,124 @@
1
+ import { success, failure } from "../result.js";
2
+ import { ErrorCode, createError } from "../errors.js";
3
+ import { validateDateString, validateTags, validateEstimatedMinutes, validateRepetitionRule, } from "../validation.js";
4
+ import { escapeAppleScript } from "../escape.js";
5
+ import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
6
+ import { buildRepetitionRuleScript } from "./repetition.js";
7
+ /**
8
+ * Add a task to the OmniFocus inbox.
9
+ */
10
+ export async function addToInbox(title, options = {}) {
11
+ // Validate inputs
12
+ if (options.due !== undefined) {
13
+ const dueError = validateDateString(options.due);
14
+ if (dueError)
15
+ return failure(dueError);
16
+ }
17
+ if (options.defer !== undefined) {
18
+ const deferError = validateDateString(options.defer);
19
+ if (deferError)
20
+ return failure(deferError);
21
+ }
22
+ const tagsError = validateTags(options.tags);
23
+ if (tagsError)
24
+ return failure(tagsError);
25
+ const estimateError = validateEstimatedMinutes(options.estimatedMinutes);
26
+ if (estimateError)
27
+ return failure(estimateError);
28
+ const repeatError = validateRepetitionRule(options.repeat);
29
+ if (repeatError)
30
+ return failure(repeatError);
31
+ const properties = [`name:"${escapeAppleScript(title)}"`];
32
+ if (options.note !== undefined) {
33
+ properties.push(`note:"${escapeAppleScript(options.note)}"`);
34
+ }
35
+ if (options.flag === true) {
36
+ properties.push("flagged:true");
37
+ }
38
+ if (options.due !== undefined) {
39
+ properties.push(`due date:date "${options.due}"`);
40
+ }
41
+ if (options.defer !== undefined) {
42
+ properties.push(`defer date:date "${options.defer}"`);
43
+ }
44
+ if (options.estimatedMinutes !== undefined) {
45
+ properties.push(`estimated minutes:${String(options.estimatedMinutes)}`);
46
+ }
47
+ // Build repetition rule script if provided
48
+ const repetitionScript = options.repeat
49
+ ? buildRepetitionRuleScript("newTask", options.repeat)
50
+ : "";
51
+ // Build the AppleScript
52
+ let script = `
53
+ set newTask to make new inbox task with properties {${properties.join(", ")}}
54
+ `;
55
+ // Handle tags separately (requires looking them up)
56
+ if (options.tags && options.tags.length > 0) {
57
+ for (const tagName of options.tags) {
58
+ script += `
59
+ try
60
+ set theTag to first flattened tag whose name is "${escapeAppleScript(tagName)}"
61
+ add theTag to tags of newTask
62
+ end try
63
+ `;
64
+ }
65
+ }
66
+ // Add repetition rule if provided
67
+ if (repetitionScript) {
68
+ script += repetitionScript;
69
+ }
70
+ // Return the created task info
71
+ script += `
72
+ set taskId to id of newTask
73
+ set taskName to name of newTask
74
+ set taskNote to note of newTask
75
+ set taskFlagged to flagged of newTask
76
+ set taskCompleted to completed of newTask
77
+
78
+ set dueStr to ""
79
+ try
80
+ set dueStr to (due date of newTask) as string
81
+ end try
82
+
83
+ set deferStr to ""
84
+ try
85
+ set deferStr to (defer date of newTask) as string
86
+ end try
87
+
88
+ set tagNames to {}
89
+ repeat with t in tags of newTask
90
+ set end of tagNames to name of t
91
+ end repeat
92
+
93
+ set estMinutes to 0
94
+ try
95
+ set estMinutes to estimated minutes of newTask
96
+ if estMinutes is missing value then set estMinutes to 0
97
+ end try
98
+
99
+ return "{" & ¬
100
+ "\\"id\\": \\"" & taskId & "\\"," & ¬
101
+ "\\"name\\": \\"" & taskName & "\\"," & ¬
102
+ "\\"note\\": " & (my jsonString(taskNote)) & "," & ¬
103
+ "\\"flagged\\": " & taskFlagged & "," & ¬
104
+ "\\"completed\\": " & taskCompleted & "," & ¬
105
+ "\\"dueDate\\": " & (my jsonString(dueStr)) & "," & ¬
106
+ "\\"deferDate\\": " & (my jsonString(deferStr)) & "," & ¬
107
+ "\\"completionDate\\": null," & ¬
108
+ "\\"projectId\\": null," & ¬
109
+ "\\"projectName\\": null," & ¬
110
+ "\\"tags\\": " & (my jsonArray(tagNames)) & "," & ¬
111
+ "\\"estimatedMinutes\\": " & estMinutes & ¬
112
+ "}"
113
+ `;
114
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
115
+ if (!result.success) {
116
+ return failure(result.error ??
117
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to add task to inbox"));
118
+ }
119
+ if (result.data === undefined) {
120
+ return failure(createError(ErrorCode.UNKNOWN_ERROR, "No task data returned"));
121
+ }
122
+ return success(result.data);
123
+ }
124
+ //# sourceMappingURL=inbox.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/commands/inbox.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,20 @@
1
+ import type { CliOutput, OFPerspective, OFTask } from "../types.js";
2
+ /**
3
+ * Options for querying a perspective.
4
+ */
5
+ export interface PerspectiveQueryOptions {
6
+ limit?: number | undefined;
7
+ }
8
+ /**
9
+ * List all perspectives in OmniFocus.
10
+ */
11
+ export declare function listPerspectives(): Promise<CliOutput<OFPerspective[]>>;
12
+ /**
13
+ * Query tasks from a specific perspective in OmniFocus.
14
+ *
15
+ * Note: This function retrieves tasks based on the perspective's filtering rules.
16
+ * Some perspectives may require UI interaction in OmniFocus to be properly evaluated.
17
+ * Built-in perspectives like "Flagged", "Forecast", and "Projects" work best.
18
+ */
19
+ export declare function queryPerspective(name: string, options?: PerspectiveQueryOptions): Promise<CliOutput<OFTask[]>>;
20
+ //# sourceMappingURL=perspectives.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perspectives.d.ts","sourceRoot":"","sources":["../../src/commands/perspectives.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAUpE;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAED;;GAEG;AACH,wBAAsB,gBAAgB,IAAI,OAAO,CAAC,SAAS,CAAC,aAAa,EAAE,CAAC,CAAC,CAmC5E;AAED;;;;;;GAMG;AACH,wBAAsB,gBAAgB,CACpC,IAAI,EAAE,MAAM,EACZ,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAwI9B"}
@@ -0,0 +1,166 @@
1
+ import { success, failure } from "../result.js";
2
+ import { ErrorCode, createError } from "../errors.js";
3
+ import { validateSearchQuery } from "../validation.js";
4
+ import { escapeAppleScript } from "../escape.js";
5
+ import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
6
+ /**
7
+ * List all perspectives in OmniFocus.
8
+ */
9
+ export async function listPerspectives() {
10
+ const script = `
11
+ set output to "["
12
+ set isFirst to true
13
+
14
+ set allPerspectives to perspectives
15
+
16
+ repeat with p in allPerspectives
17
+ if not isFirst then set output to output & ","
18
+ set isFirst to false
19
+
20
+ set perspId to id of p
21
+ set perspName to name of p
22
+
23
+ set output to output & "{" & ¬
24
+ "\\"id\\": \\"" & perspId & "\\"," & ¬
25
+ "\\"name\\": \\"" & (my escapeJson(perspName)) & "\\"" & ¬
26
+ "}"
27
+ end repeat
28
+
29
+ return output & "]"
30
+ `;
31
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
32
+ if (!result.success) {
33
+ return failure(result.error ??
34
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to list perspectives"));
35
+ }
36
+ return success(result.data ?? []);
37
+ }
38
+ /**
39
+ * Query tasks from a specific perspective in OmniFocus.
40
+ *
41
+ * Note: This function retrieves tasks based on the perspective's filtering rules.
42
+ * Some perspectives may require UI interaction in OmniFocus to be properly evaluated.
43
+ * Built-in perspectives like "Flagged", "Forecast", and "Projects" work best.
44
+ */
45
+ export async function queryPerspective(name, options = {}) {
46
+ // Validate perspective name
47
+ const nameError = validateSearchQuery(name);
48
+ if (nameError) {
49
+ return failure(createError(ErrorCode.VALIDATION_ERROR, "Perspective name cannot be empty"));
50
+ }
51
+ const limit = options.limit ?? 100;
52
+ // Note: OmniFocus's AppleScript support for perspectives is limited.
53
+ // We can check if a perspective exists but getting its filtered tasks
54
+ // programmatically is difficult. We'll get all tasks and note that
55
+ // this is a limitation.
56
+ //
57
+ // For built-in perspectives, we can implement specific logic:
58
+ // - Flagged: flagged tasks
59
+ // - Inbox: inbox tasks
60
+ // - Projects: all project tasks
61
+ // - Forecast: tasks with due dates
62
+ const escapedName = escapeAppleScript(name);
63
+ const script = `
64
+ -- First verify the perspective exists
65
+ set perspExists to false
66
+ try
67
+ set thePerspective to perspective "${escapedName}"
68
+ set perspExists to true
69
+ end try
70
+
71
+ if not perspExists then
72
+ error "Perspective not found: ${escapedName}"
73
+ end if
74
+
75
+ -- Handle known built-in perspectives
76
+ set perspNameLower to "${escapedName.toLowerCase()}"
77
+ set output to "["
78
+ set isFirst to true
79
+ set matchCount to 0
80
+ set maxResults to ${String(limit)}
81
+
82
+ if perspNameLower is "flagged" then
83
+ set taskList to (flattened tasks where flagged is true and completed is false)
84
+ else if perspNameLower is "inbox" then
85
+ set taskList to inbox tasks
86
+ else if perspNameLower is "forecast" then
87
+ set taskList to (flattened tasks where due date is not missing value and completed is false)
88
+ else
89
+ -- For custom perspectives, return all available tasks as a fallback
90
+ -- This is a limitation of OmniFocus's AppleScript API
91
+ set taskList to (flattened tasks where completed is false)
92
+ end if
93
+
94
+ repeat with t in taskList
95
+ if matchCount >= maxResults then exit repeat
96
+ set matchCount to matchCount + 1
97
+
98
+ if not isFirst then set output to output & ","
99
+ set isFirst to false
100
+
101
+ set taskId to id of t
102
+ set taskName to name of t
103
+ set taskNote to note of t
104
+ set taskFlagged to flagged of t
105
+ set taskCompleted to completed of t
106
+
107
+ set dueStr to ""
108
+ try
109
+ set dueStr to (due date of t) as string
110
+ end try
111
+
112
+ set deferStr to ""
113
+ try
114
+ set deferStr to (defer date of t) as string
115
+ end try
116
+
117
+ set completionStr to ""
118
+ try
119
+ set completionStr to (completion date of t) as string
120
+ end try
121
+
122
+ set projId to ""
123
+ set projName to ""
124
+ try
125
+ set proj to containing project of t
126
+ set projId to id of proj
127
+ set projName to name of proj
128
+ end try
129
+
130
+ set tagNames to {}
131
+ repeat with tg in tags of t
132
+ set end of tagNames to name of tg
133
+ end repeat
134
+
135
+ set estMinutes to 0
136
+ try
137
+ set estMinutes to estimated minutes of t
138
+ if estMinutes is missing value then set estMinutes to 0
139
+ end try
140
+
141
+ set output to output & "{" & ¬
142
+ "\\"id\\": \\"" & taskId & "\\"," & ¬
143
+ "\\"name\\": \\"" & (my escapeJson(taskName)) & "\\"," & ¬
144
+ "\\"note\\": " & (my jsonString(taskNote)) & "," & ¬
145
+ "\\"flagged\\": " & taskFlagged & "," & ¬
146
+ "\\"completed\\": " & taskCompleted & "," & ¬
147
+ "\\"dueDate\\": " & (my jsonString(dueStr)) & "," & ¬
148
+ "\\"deferDate\\": " & (my jsonString(deferStr)) & "," & ¬
149
+ "\\"completionDate\\": " & (my jsonString(completionStr)) & "," & ¬
150
+ "\\"projectId\\": " & (my jsonString(projId)) & "," & ¬
151
+ "\\"projectName\\": " & (my jsonString(projName)) & "," & ¬
152
+ "\\"tags\\": " & (my jsonArray(tagNames)) & "," & ¬
153
+ "\\"estimatedMinutes\\": " & estMinutes & ¬
154
+ "}"
155
+ end repeat
156
+
157
+ return output & "]"
158
+ `;
159
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
160
+ if (!result.success) {
161
+ return failure(result.error ??
162
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to query perspective"));
163
+ }
164
+ return success(result.data ?? []);
165
+ }
166
+ //# sourceMappingURL=perspectives.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"perspectives.js","sourceRoot":"","sources":["../../src/commands/perspectives.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,cAAc,CAAC;AACtD,OAAO,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAS3B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB;IACpC,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;GAoBd,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,0BAA0B,CAAC,MAAM,CAAC,CACnC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,OAAO,CACZ,MAAM,CAAC,KAAK;YACV,WAAW,CAAC,SAAS,CAAC,aAAa,EAAE,6BAA6B,CAAC,CACtE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,gBAAgB,CACpC,IAAY,EACZ,UAAmC,EAAE;IAErC,4BAA4B;IAC5B,MAAM,SAAS,GAAG,mBAAmB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,SAAS,EAAE,CAAC;QACd,OAAO,OAAO,CACZ,WAAW,CACT,SAAS,CAAC,gBAAgB,EAC1B,kCAAkC,CACnC,CACF,CAAC;IACJ,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC;IAEnC,qEAAqE;IACrE,sEAAsE;IACtE,mEAAmE;IACnE,wBAAwB;IACxB,EAAE;IACF,8DAA8D;IAC9D,2BAA2B;IAC3B,uBAAuB;IACvB,gCAAgC;IAChC,mCAAmC;IAEnC,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE5C,MAAM,MAAM,GAAG;;;;2CAI0B,WAAW;;;;;sCAKhB,WAAW;;;;6BAIpB,WAAW,CAAC,WAAW,EAAE;;;;wBAI9B,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8ElC,CAAC;IAEF,MAAM,MAAM,GAAG,MAAM,cAAc,CACjC,0BAA0B,CAAC,MAAM,CAAC,CACnC,CAAC;IAEF,IAAI,CAAC,MAAM,CAAC,OAAO,EAAE,CAAC;QACpB,OAAO,OAAO,CACZ,MAAM,CAAC,KAAK;YACV,WAAW,CAAC,SAAS,CAAC,aAAa,EAAE,6BAA6B,CAAC,CACtE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { CliOutput, ProjectQueryOptions, OFProject } from "../types.js";
2
+ /**
3
+ * Query projects from OmniFocus with optional filters.
4
+ */
5
+ export declare function queryProjects(options?: ProjectQueryOptions): Promise<CliOutput<OFProject[]>>;
6
+ //# sourceMappingURL=projects.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.d.ts","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,mBAAmB,EACnB,SAAS,EACV,MAAM,aAAa,CAAC;AASrB;;GAEG;AACH,wBAAsB,aAAa,CACjC,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAmHjC"}
@@ -0,0 +1,113 @@
1
+ import { success, failure } from "../result.js";
2
+ import { ErrorCode, createError } from "../errors.js";
3
+ import { escapeAppleScript } from "../escape.js";
4
+ import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
5
+ /**
6
+ * Query projects from OmniFocus with optional filters.
7
+ */
8
+ export async function queryProjects(options = {}) {
9
+ // Build filter conditions for properties that work in where clauses
10
+ const conditions = [];
11
+ if (options.sequential === true) {
12
+ conditions.push("sequential is true");
13
+ }
14
+ else if (options.sequential === false) {
15
+ conditions.push("sequential is false");
16
+ }
17
+ const whereClause = conditions.length > 0 ? `where ${conditions.join(" and ")}` : "";
18
+ // Map status option to AppleScript status value
19
+ let statusFilter = "";
20
+ if (options.status !== undefined) {
21
+ switch (options.status) {
22
+ case "active":
23
+ statusFilter = "active status";
24
+ break;
25
+ case "on-hold":
26
+ statusFilter = "on hold";
27
+ break;
28
+ case "completed":
29
+ statusFilter = "done";
30
+ break;
31
+ case "dropped":
32
+ statusFilter = "dropped";
33
+ break;
34
+ }
35
+ }
36
+ const script = `
37
+ set output to "["
38
+ set isFirst to true
39
+
40
+ set allProjects to flattened projects ${whereClause}
41
+
42
+ repeat with p in allProjects
43
+ set shouldInclude to true
44
+
45
+ -- Safely determine project status (OmniFocus has issues with direct status comparisons)
46
+ set projStatus to "active"
47
+ try
48
+ set theStatus to status of p
49
+ if theStatus is on hold then
50
+ set projStatus to "on-hold"
51
+ else if theStatus is done then
52
+ set projStatus to "completed"
53
+ else if theStatus is dropped then
54
+ set projStatus to "dropped"
55
+ end if
56
+ end try
57
+
58
+ ${statusFilter === "active status" ? `if projStatus is not "active" then set shouldInclude to false` : ""}
59
+ ${statusFilter === "on hold" ? `if projStatus is not "on-hold" then set shouldInclude to false` : ""}
60
+ ${statusFilter === "done" ? `if projStatus is not "completed" then set shouldInclude to false` : ""}
61
+ ${statusFilter === "dropped" ? `if projStatus is not "dropped" then set shouldInclude to false` : ""}
62
+
63
+ ${options.folder ? `-- Filter by folder` : ""}
64
+ ${options.folder ? `try` : ""}
65
+ ${options.folder ? ` if name of folder of p is not "${escapeAppleScript(options.folder)}" then set shouldInclude to false` : ""}
66
+ ${options.folder ? `on error` : ""}
67
+ ${options.folder ? ` set shouldInclude to false` : ""}
68
+ ${options.folder ? `end try` : ""}
69
+
70
+ if shouldInclude then
71
+ if not isFirst then set output to output & ","
72
+ set isFirst to false
73
+
74
+ set projId to id of p
75
+ set projName to name of p
76
+ set projNote to note of p
77
+ set projSeq to sequential of p
78
+
79
+ set folderId to ""
80
+ set folderName to ""
81
+ try
82
+ set f to folder of p
83
+ set folderId to id of f
84
+ set folderName to name of f
85
+ end try
86
+
87
+ set taskCount to count of tasks of p
88
+ set remainingCount to count of (tasks of p where completed is false)
89
+
90
+ set output to output & "{" & ¬
91
+ "\\"id\\": \\"" & projId & "\\"," & ¬
92
+ "\\"name\\": \\"" & (my escapeJson(projName)) & "\\"," & ¬
93
+ "\\"note\\": " & (my jsonString(projNote)) & "," & ¬
94
+ "\\"status\\": \\"" & projStatus & "\\"," & ¬
95
+ "\\"sequential\\": " & projSeq & "," & ¬
96
+ "\\"folderId\\": " & (my jsonString(folderId)) & "," & ¬
97
+ "\\"folderName\\": " & (my jsonString(folderName)) & "," & ¬
98
+ "\\"taskCount\\": " & taskCount & "," & ¬
99
+ "\\"remainingTaskCount\\": " & remainingCount & ¬
100
+ "}"
101
+ end if
102
+ end repeat
103
+
104
+ return output & "]"
105
+ `;
106
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
107
+ if (!result.success) {
108
+ return failure(result.error ??
109
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to query projects"));
110
+ }
111
+ return success(result.data ?? []);
112
+ }
113
+ //# sourceMappingURL=projects.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"projects.js","sourceRoot":"","sources":["../../src/commands/projects.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ import type { RepetitionRule } from "../types.js";
2
+ /**
3
+ * Build iCalendar RRULE string from a RepetitionRule.
4
+ */
5
+ export declare function buildRRule(rule: RepetitionRule): string;
6
+ /**
7
+ * Build AppleScript to set a repetition rule on a task.
8
+ * @param taskVar - The AppleScript variable name for the task
9
+ * @param rule - The repetition rule to apply
10
+ */
11
+ export declare function buildRepetitionRuleScript(taskVar: string, rule: RepetitionRule): string;
12
+ /**
13
+ * Build AppleScript to clear a repetition rule from a task.
14
+ * @param taskVar - The AppleScript variable name for the task
15
+ */
16
+ export declare function buildClearRepetitionScript(taskVar: string): string;
17
+ //# sourceMappingURL=repetition.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repetition.d.ts","sourceRoot":"","sources":["../../src/commands/repetition.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAC;AAElD;;GAEG;AACH,wBAAgB,UAAU,CAAC,IAAI,EAAE,cAAc,GAAG,MAAM,CAsCvD;AAED;;;;GAIG;AACH,wBAAgB,yBAAyB,CACvC,OAAO,EAAE,MAAM,EACf,IAAI,EAAE,cAAc,GACnB,MAAM,CAQR;AAED;;;GAGG;AACH,wBAAgB,0BAA0B,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAIlE"}