@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,59 @@
1
+ /**
2
+ * Build iCalendar RRULE string from a RepetitionRule.
3
+ */
4
+ export function buildRRule(rule) {
5
+ const parts = [];
6
+ // Frequency
7
+ const freqMap = {
8
+ daily: "DAILY",
9
+ weekly: "WEEKLY",
10
+ monthly: "MONTHLY",
11
+ yearly: "YEARLY",
12
+ };
13
+ parts.push(`FREQ=${freqMap[rule.frequency]}`);
14
+ // Interval
15
+ if (rule.interval > 1) {
16
+ parts.push(`INTERVAL=${String(rule.interval)}`);
17
+ }
18
+ // Days of week (for weekly)
19
+ if (rule.daysOfWeek && rule.daysOfWeek.length > 0) {
20
+ const dayMap = {
21
+ 0: "SU",
22
+ 1: "MO",
23
+ 2: "TU",
24
+ 3: "WE",
25
+ 4: "TH",
26
+ 5: "FR",
27
+ 6: "SA",
28
+ };
29
+ const days = rule.daysOfWeek.map((d) => dayMap[d]).join(",");
30
+ parts.push(`BYDAY=${days}`);
31
+ }
32
+ // Day of month (for monthly)
33
+ if (rule.dayOfMonth !== undefined) {
34
+ parts.push(`BYMONTHDAY=${String(rule.dayOfMonth)}`);
35
+ }
36
+ return parts.join(";");
37
+ }
38
+ /**
39
+ * Build AppleScript to set a repetition rule on a task.
40
+ * @param taskVar - The AppleScript variable name for the task
41
+ * @param rule - The repetition rule to apply
42
+ */
43
+ export function buildRepetitionRuleScript(taskVar, rule) {
44
+ const rrule = buildRRule(rule);
45
+ const repetitionMethod = rule.repeatMethod === "due-again" ? "due again" : "defer another";
46
+ return `
47
+ set repetition rule of ${taskVar} to {repetition method:${repetitionMethod}, recurrence:"${rrule}"}
48
+ `;
49
+ }
50
+ /**
51
+ * Build AppleScript to clear a repetition rule from a task.
52
+ * @param taskVar - The AppleScript variable name for the task
53
+ */
54
+ export function buildClearRepetitionScript(taskVar) {
55
+ return `
56
+ set repetition rule of ${taskVar} to missing value
57
+ `;
58
+ }
59
+ //# sourceMappingURL=repetition.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"repetition.js","sourceRoot":"","sources":["../../src/commands/repetition.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,UAAU,UAAU,CAAC,IAAoB;IAC7C,MAAM,KAAK,GAAa,EAAE,CAAC;IAE3B,YAAY;IACZ,MAAM,OAAO,GAAG;QACd,KAAK,EAAE,OAAO;QACd,MAAM,EAAE,QAAQ;QAChB,OAAO,EAAE,SAAS;QAClB,MAAM,EAAE,QAAQ;KACR,CAAC;IACX,KAAK,CAAC,IAAI,CAAC,QAAQ,OAAO,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC;IAE9C,WAAW;IACX,IAAI,IAAI,CAAC,QAAQ,GAAG,CAAC,EAAE,CAAC;QACtB,KAAK,CAAC,IAAI,CAAC,YAAY,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC;IAClD,CAAC;IAED,4BAA4B;IAC5B,IAAI,IAAI,CAAC,UAAU,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAClD,MAAM,MAAM,GAA2B;YACrC,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;YACP,CAAC,EAAE,IAAI;SACR,CAAC;QACF,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAC7D,KAAK,CAAC,IAAI,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC;IAC9B,CAAC;IAED,6BAA6B;IAC7B,IAAI,IAAI,CAAC,UAAU,KAAK,SAAS,EAAE,CAAC;QAClC,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;IACtD,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,yBAAyB,CACvC,OAAe,EACf,IAAoB;IAEpB,MAAM,KAAK,GAAG,UAAU,CAAC,IAAI,CAAC,CAAC;IAC/B,MAAM,gBAAgB,GACpB,IAAI,CAAC,YAAY,KAAK,WAAW,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,eAAe,CAAC;IAEpE,OAAO;6BACoB,OAAO,0BAA0B,gBAAgB,iBAAiB,KAAK;GACjG,CAAC;AACJ,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,0BAA0B,CAAC,OAAe;IACxD,OAAO;6BACoB,OAAO;GACjC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,10 @@
1
+ import type { CliOutput, OFProject, ReviewResult } from "../types.js";
2
+ /**
3
+ * Mark a project as reviewed in OmniFocus.
4
+ */
5
+ export declare function reviewProject(projectId: string): Promise<CliOutput<ReviewResult>>;
6
+ /**
7
+ * Query projects that are due for review in OmniFocus.
8
+ */
9
+ export declare function queryProjectsForReview(): Promise<CliOutput<OFProject[]>>;
10
+ //# sourceMappingURL=review.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.d.ts","sourceRoot":"","sources":["../../src/commands/review.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAUtE;;GAEG;AACH,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,CAkDlC;AAED;;GAEG;AACH,wBAAsB,sBAAsB,IAAI,OAAO,CAAC,SAAS,CAAC,SAAS,EAAE,CAAC,CAAC,CAwF9E"}
@@ -0,0 +1,132 @@
1
+ import { success, failure } from "../result.js";
2
+ import { ErrorCode, createError } from "../errors.js";
3
+ import { validateId } from "../validation.js";
4
+ import { escapeAppleScript } from "../escape.js";
5
+ import { runAppleScript, omniFocusScriptWithHelpers, } from "../applescript.js";
6
+ /**
7
+ * Mark a project as reviewed in OmniFocus.
8
+ */
9
+ export async function reviewProject(projectId) {
10
+ // Validate project ID
11
+ const idError = validateId(projectId, "project");
12
+ if (idError)
13
+ return failure(idError);
14
+ const script = `
15
+ set theProject to first flattened project whose id is "${escapeAppleScript(projectId)}"
16
+
17
+ -- Mark as reviewed by setting last review date to now
18
+ set last review date of theProject to current date
19
+
20
+ set projId to id of theProject
21
+ set projName to name of theProject
22
+
23
+ set lastReviewStr to ""
24
+ try
25
+ set lastReviewStr to (last review date of theProject) as string
26
+ end try
27
+
28
+ set nextReviewStr to ""
29
+ try
30
+ set nextReviewStr to (next review date of theProject) as string
31
+ end try
32
+
33
+ return "{" & ¬
34
+ "\\"projectId\\": \\"" & projId & "\\"," & ¬
35
+ "\\"projectName\\": \\"" & (my escapeJson(projName)) & "\\"," & ¬
36
+ "\\"lastReviewed\\": " & (my jsonString(lastReviewStr)) & "," & ¬
37
+ "\\"nextReviewDate\\": " & (my jsonString(nextReviewStr)) & ¬
38
+ "}"
39
+ `;
40
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
41
+ if (!result.success) {
42
+ return failure(result.error ??
43
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to review project"));
44
+ }
45
+ if (result.data === undefined) {
46
+ return failure(createError(ErrorCode.UNKNOWN_ERROR, "No result returned"));
47
+ }
48
+ return success(result.data);
49
+ }
50
+ /**
51
+ * Query projects that are due for review in OmniFocus.
52
+ */
53
+ export async function queryProjectsForReview() {
54
+ const script = `
55
+ set output to "["
56
+ set isFirst to true
57
+ set currentDate to current date
58
+
59
+ set allProjects to flattened projects
60
+
61
+ repeat with p in allProjects
62
+ set shouldInclude to false
63
+
64
+ -- Check if project needs review (next review date is in the past or today)
65
+ try
66
+ set theStatus to status of p
67
+ if theStatus is not dropped and theStatus is not done then
68
+ set nextReview to next review date of p
69
+ if nextReview is not missing value then
70
+ if nextReview <= currentDate then
71
+ set shouldInclude to true
72
+ end if
73
+ end if
74
+ end if
75
+ end try
76
+
77
+ if shouldInclude then
78
+ if not isFirst then set output to output & ","
79
+ set isFirst to false
80
+
81
+ set projId to id of p
82
+ set projName to name of p
83
+ set projNote to note of p
84
+ set projSeq to sequential of p
85
+
86
+ set projStatus to "active"
87
+ try
88
+ set theStatus to status of p
89
+ if theStatus is on hold then
90
+ set projStatus to "on-hold"
91
+ else if theStatus is done then
92
+ set projStatus to "completed"
93
+ else if theStatus is dropped then
94
+ set projStatus to "dropped"
95
+ end if
96
+ end try
97
+
98
+ set folderId to ""
99
+ set folderName to ""
100
+ try
101
+ set f to folder of p
102
+ set folderId to id of f
103
+ set folderName to name of f
104
+ end try
105
+
106
+ set taskCount to count of tasks of p
107
+ set remainingCount to count of (tasks of p where completed is false)
108
+
109
+ set output to output & "{" & ¬
110
+ "\\"id\\": \\"" & projId & "\\"," & ¬
111
+ "\\"name\\": \\"" & (my escapeJson(projName)) & "\\"," & ¬
112
+ "\\"note\\": " & (my jsonString(projNote)) & "," & ¬
113
+ "\\"status\\": \\"" & projStatus & "\\"," & ¬
114
+ "\\"sequential\\": " & projSeq & "," & ¬
115
+ "\\"folderId\\": " & (my jsonString(folderId)) & "," & ¬
116
+ "\\"folderName\\": " & (my jsonString(folderName)) & "," & ¬
117
+ "\\"taskCount\\": " & taskCount & "," & ¬
118
+ "\\"remainingTaskCount\\": " & remainingCount & ¬
119
+ "}"
120
+ end if
121
+ end repeat
122
+
123
+ return output & "]"
124
+ `;
125
+ const result = await runAppleScript(omniFocusScriptWithHelpers(script));
126
+ if (!result.success) {
127
+ return failure(result.error ??
128
+ createError(ErrorCode.UNKNOWN_ERROR, "Failed to query projects for review"));
129
+ }
130
+ return success(result.data ?? []);
131
+ }
132
+ //# sourceMappingURL=review.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review.js","sourceRoot":"","sources":["../../src/commands/review.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,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EACL,cAAc,EACd,0BAA0B,GAC3B,MAAM,mBAAmB,CAAC;AAE3B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CACjC,SAAiB;IAEjB,sBAAsB;IACtB,MAAM,OAAO,GAAG,UAAU,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;IACjD,IAAI,OAAO;QAAE,OAAO,OAAO,CAAC,OAAO,CAAC,CAAC;IAErC,MAAM,MAAM,GAAG;6DAC4C,iBAAiB,CAAC,SAAS,CAAC;;;;;;;;;;;;;;;;;;;;;;;;GAwBtF,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,0BAA0B,CAAC,CACnE,CAAC;IACJ,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;QAC9B,OAAO,OAAO,CACZ,WAAW,CAAC,SAAS,CAAC,aAAa,EAAE,oBAAoB,CAAC,CAC3D,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC;AAED;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,sBAAsB;IAC1C,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAsEd,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,CACT,SAAS,CAAC,aAAa,EACvB,qCAAqC,CACtC,CACJ,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,6 @@
1
+ import type { CliOutput, SearchOptions, OFTask } from "../types.js";
2
+ /**
3
+ * Search tasks in OmniFocus.
4
+ */
5
+ export declare function searchTasks(query: string, options?: SearchOptions): Promise<CliOutput<OFTask[]>>;
6
+ //# sourceMappingURL=search.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.d.ts","sourceRoot":"","sources":["../../src/commands/search.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,aAAa,CAAC;AAUpE;;GAEG;AACH,wBAAsB,WAAW,CAC/B,KAAK,EAAE,MAAM,EACb,OAAO,GAAE,aAAkB,GAC1B,OAAO,CAAC,SAAS,CAAC,MAAM,EAAE,CAAC,CAAC,CAuJ9B"}
@@ -0,0 +1,150 @@
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
+ * Search tasks in OmniFocus.
8
+ */
9
+ export async function searchTasks(query, options = {}) {
10
+ // Validate search query
11
+ const queryError = validateSearchQuery(query);
12
+ if (queryError)
13
+ return failure(queryError);
14
+ const scope = options.scope ?? "both";
15
+ const limit = options.limit ?? 100;
16
+ const includeCompleted = options.includeCompleted ?? false;
17
+ // Build the search script
18
+ // OmniFocus doesn't have a built-in full-text search, so we do it manually
19
+ const escapedQuery = escapeAppleScript(query.toLowerCase());
20
+ // Build filter conditions based on scope
21
+ let searchCondition;
22
+ switch (scope) {
23
+ case "name":
24
+ searchCondition = `(my containsText(name of t, "${escapedQuery}"))`;
25
+ break;
26
+ case "note":
27
+ searchCondition = `(my containsText(note of t, "${escapedQuery}"))`;
28
+ break;
29
+ default:
30
+ // "both"
31
+ searchCondition = `(my containsText(name of t, "${escapedQuery}") or my containsText(note of t, "${escapedQuery}"))`;
32
+ break;
33
+ }
34
+ const completedFilter = includeCompleted
35
+ ? ""
36
+ : "if completed of t is true then set shouldInclude to false";
37
+ const script = `
38
+ -- Helper function to check if a string contains another string (case-insensitive)
39
+ on containsText(theText, searchText)
40
+ if theText is missing value then return false
41
+ set theTextLower to (my toLowerCase(theText as string))
42
+ return theTextLower contains searchText
43
+ end containsText
44
+
45
+ on toLowerCase(theText)
46
+ set lowercaseChars to "abcdefghijklmnopqrstuvwxyz"
47
+ set uppercaseChars to "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
48
+ set resultText to ""
49
+ repeat with c in theText
50
+ set charIndex to offset of c in uppercaseChars
51
+ if charIndex > 0 then
52
+ set resultText to resultText & (character charIndex of lowercaseChars)
53
+ else
54
+ set resultText to resultText & c
55
+ end if
56
+ end repeat
57
+ return resultText
58
+ end toLowerCase
59
+
60
+ set output to "["
61
+ set isFirst to true
62
+ set matchCount to 0
63
+ set maxResults to ${String(limit)}
64
+
65
+ set allTasks to flattened tasks
66
+
67
+ repeat with t in allTasks
68
+ if matchCount >= maxResults then exit repeat
69
+
70
+ set shouldInclude to false
71
+
72
+ try
73
+ if ${searchCondition} then set shouldInclude to true
74
+ end try
75
+
76
+ ${completedFilter}
77
+
78
+ if shouldInclude then
79
+ set matchCount to matchCount + 1
80
+
81
+ if not isFirst then set output to output & ","
82
+ set isFirst to false
83
+
84
+ set taskId to id of t
85
+ set taskName to name of t
86
+ set taskNote to note of t
87
+ set taskFlagged to flagged of t
88
+ set taskCompleted to completed of t
89
+
90
+ set dueStr to ""
91
+ try
92
+ set dueStr to (due date of t) as string
93
+ end try
94
+
95
+ set deferStr to ""
96
+ try
97
+ set deferStr to (defer date of t) as string
98
+ end try
99
+
100
+ set completionStr to ""
101
+ try
102
+ set completionStr to (completion date of t) as string
103
+ end try
104
+
105
+ set projId to ""
106
+ set projName to ""
107
+ try
108
+ set proj to containing project of t
109
+ set projId to id of proj
110
+ set projName to name of proj
111
+ end try
112
+
113
+ set tagNames to {}
114
+ repeat with tg in tags of t
115
+ set end of tagNames to name of tg
116
+ end repeat
117
+
118
+ set estMinutes to 0
119
+ try
120
+ set estMinutes to estimated minutes of t
121
+ if estMinutes is missing value then set estMinutes to 0
122
+ end try
123
+
124
+ set output to output & "{" & ¬
125
+ "\\"id\\": \\"" & taskId & "\\"," & ¬
126
+ "\\"name\\": \\"" & (my escapeJson(taskName)) & "\\"," & ¬
127
+ "\\"note\\": " & (my jsonString(taskNote)) & "," & ¬
128
+ "\\"flagged\\": " & taskFlagged & "," & ¬
129
+ "\\"completed\\": " & taskCompleted & "," & ¬
130
+ "\\"dueDate\\": " & (my jsonString(dueStr)) & "," & ¬
131
+ "\\"deferDate\\": " & (my jsonString(deferStr)) & "," & ¬
132
+ "\\"completionDate\\": " & (my jsonString(completionStr)) & "," & ¬
133
+ "\\"projectId\\": " & (my jsonString(projId)) & "," & ¬
134
+ "\\"projectName\\": " & (my jsonString(projName)) & "," & ¬
135
+ "\\"tags\\": " & (my jsonArray(tagNames)) & "," & ¬
136
+ "\\"estimatedMinutes\\": " & estMinutes & ¬
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 search tasks"));
147
+ }
148
+ return success(result.data ?? []);
149
+ }
150
+ //# sourceMappingURL=search.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search.js","sourceRoot":"","sources":["../../src/commands/search.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;AAE3B;;GAEG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAC/B,KAAa,EACb,UAAyB,EAAE;IAE3B,wBAAwB;IACxB,MAAM,UAAU,GAAG,mBAAmB,CAAC,KAAK,CAAC,CAAC;IAC9C,IAAI,UAAU;QAAE,OAAO,OAAO,CAAC,UAAU,CAAC,CAAC;IAE3C,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC;IACtC,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,GAAG,CAAC;IACnC,MAAM,gBAAgB,GAAG,OAAO,CAAC,gBAAgB,IAAI,KAAK,CAAC;IAE3D,0BAA0B;IAC1B,2EAA2E;IAC3E,MAAM,YAAY,GAAG,iBAAiB,CAAC,KAAK,CAAC,WAAW,EAAE,CAAC,CAAC;IAE5D,yCAAyC;IACzC,IAAI,eAAuB,CAAC;IAC5B,QAAQ,KAAK,EAAE,CAAC;QACd,KAAK,MAAM;YACT,eAAe,GAAG,gCAAgC,YAAY,KAAK,CAAC;YACpE,MAAM;QACR,KAAK,MAAM;YACT,eAAe,GAAG,gCAAgC,YAAY,KAAK,CAAC;YACpE,MAAM;QACR;YACE,SAAS;YACT,eAAe,GAAG,gCAAgC,YAAY,qCAAqC,YAAY,KAAK,CAAC;YACrH,MAAM;IACV,CAAC;IAED,MAAM,eAAe,GAAG,gBAAgB;QACtC,CAAC,CAAC,EAAE;QACJ,CAAC,CAAC,2DAA2D,CAAC;IAEhE,MAAM,MAAM,GAAG;;;;;;;;;;;;;;;;;;;;;;;;;;wBA0BO,MAAM,CAAC,KAAK,CAAC;;;;;;;;;;aAUxB,eAAe;;;QAGpB,eAAe;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkEpB,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,wBAAwB,CAAC,CACjE,CAAC;IACJ,CAAC;IAED,OAAO,OAAO,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,14 @@
1
+ import type { CliOutput, InboxOptions, SubtaskQueryOptions, OFTaskWithChildren } from "../types.js";
2
+ /**
3
+ * Create a subtask under a parent task in OmniFocus.
4
+ */
5
+ export declare function createSubtask(title: string, parentTaskId: string, options?: InboxOptions): Promise<CliOutput<OFTaskWithChildren>>;
6
+ /**
7
+ * Query subtasks of a parent task in OmniFocus.
8
+ */
9
+ export declare function querySubtasks(parentTaskId: string, options?: SubtaskQueryOptions): Promise<CliOutput<OFTaskWithChildren[]>>;
10
+ /**
11
+ * Move a task to become a subtask of another task.
12
+ */
13
+ export declare function moveTaskToParent(taskId: string, parentTaskId: string): Promise<CliOutput<OFTaskWithChildren>>;
14
+ //# sourceMappingURL=subtasks.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"subtasks.d.ts","sourceRoot":"","sources":["../../src/commands/subtasks.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,aAAa,CAAC;AAiBrB;;GAEG;AACH,wBAAsB,aAAa,CACjC,KAAK,EAAE,MAAM,EACb,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,YAAiB,GACzB,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CAoKxC;AAED;;GAEG;AACH,wBAAsB,aAAa,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,GAAE,mBAAwB,GAChC,OAAO,CAAC,SAAS,CAAC,kBAAkB,EAAE,CAAC,CAAC,CA0H1C;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CACpC,MAAM,EAAE,MAAM,EACd,YAAY,EAAE,MAAM,GACnB,OAAO,CAAC,SAAS,CAAC,kBAAkB,CAAC,CAAC,CA0GxC"}