@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.
- package/README.md +80 -0
- package/api-report/ofocus-sdk.api.md +564 -0
- package/dist/.tsbuildinfo +1 -0
- package/dist/applescript.d.ts +30 -0
- package/dist/applescript.d.ts.map +1 -0
- package/dist/applescript.js +142 -0
- package/dist/applescript.js.map +1 -0
- package/dist/commands/batch.d.ts +23 -0
- package/dist/commands/batch.d.ts.map +1 -0
- package/dist/commands/batch.js +324 -0
- package/dist/commands/batch.js.map +1 -0
- package/dist/commands/complete.d.ts +14 -0
- package/dist/commands/complete.d.ts.map +1 -0
- package/dist/commands/complete.js +37 -0
- package/dist/commands/complete.js.map +1 -0
- package/dist/commands/create-project.d.ts +6 -0
- package/dist/commands/create-project.d.ts.map +1 -0
- package/dist/commands/create-project.js +124 -0
- package/dist/commands/create-project.js.map +1 -0
- package/dist/commands/drop.d.ts +26 -0
- package/dist/commands/drop.d.ts.map +1 -0
- package/dist/commands/drop.js +62 -0
- package/dist/commands/drop.js.map +1 -0
- package/dist/commands/folders.d.ts +10 -0
- package/dist/commands/folders.d.ts.map +1 -0
- package/dist/commands/folders.js +150 -0
- package/dist/commands/folders.js.map +1 -0
- package/dist/commands/inbox.d.ts +6 -0
- package/dist/commands/inbox.d.ts.map +1 -0
- package/dist/commands/inbox.js +124 -0
- package/dist/commands/inbox.js.map +1 -0
- package/dist/commands/perspectives.d.ts +20 -0
- package/dist/commands/perspectives.d.ts.map +1 -0
- package/dist/commands/perspectives.js +166 -0
- package/dist/commands/perspectives.js.map +1 -0
- package/dist/commands/projects.d.ts +6 -0
- package/dist/commands/projects.d.ts.map +1 -0
- package/dist/commands/projects.js +113 -0
- package/dist/commands/projects.js.map +1 -0
- package/dist/commands/repetition.d.ts +17 -0
- package/dist/commands/repetition.d.ts.map +1 -0
- package/dist/commands/repetition.js +59 -0
- package/dist/commands/repetition.js.map +1 -0
- package/dist/commands/review.d.ts +10 -0
- package/dist/commands/review.d.ts.map +1 -0
- package/dist/commands/review.js +132 -0
- package/dist/commands/review.js.map +1 -0
- package/dist/commands/search.d.ts +6 -0
- package/dist/commands/search.d.ts.map +1 -0
- package/dist/commands/search.js +150 -0
- package/dist/commands/search.js.map +1 -0
- package/dist/commands/subtasks.d.ts +14 -0
- package/dist/commands/subtasks.d.ts.map +1 -0
- package/dist/commands/subtasks.js +370 -0
- package/dist/commands/subtasks.js.map +1 -0
- package/dist/commands/tags-crud.d.ts +22 -0
- package/dist/commands/tags-crud.d.ts.map +1 -0
- package/dist/commands/tags-crud.js +187 -0
- package/dist/commands/tags-crud.js.map +1 -0
- package/dist/commands/tags.d.ts +6 -0
- package/dist/commands/tags.d.ts.map +1 -0
- package/dist/commands/tags.js +61 -0
- package/dist/commands/tags.js.map +1 -0
- package/dist/commands/tasks.d.ts +6 -0
- package/dist/commands/tasks.d.ts.map +1 -0
- package/dist/commands/tasks.js +160 -0
- package/dist/commands/tasks.js.map +1 -0
- package/dist/commands/update.d.ts +6 -0
- package/dist/commands/update.d.ts.map +1 -0
- package/dist/commands/update.js +179 -0
- package/dist/commands/update.js.map +1 -0
- package/dist/errors.d.ts +38 -0
- package/dist/errors.d.ts.map +1 -0
- package/dist/errors.js +77 -0
- package/dist/errors.js.map +1 -0
- package/dist/escape.d.ts +6 -0
- package/dist/escape.d.ts.map +1 -0
- package/dist/escape.js +8 -0
- package/dist/escape.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/ofocus-sdk.d.ts +608 -0
- package/dist/result.d.ts +15 -0
- package/dist/result.d.ts.map +1 -0
- package/dist/result.js +29 -0
- package/dist/result.js.map +1 -0
- package/dist/types.d.ts +228 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/validation.d.ts +57 -0
- package/dist/validation.d.ts.map +1 -0
- package/dist/validation.js +172 -0
- package/dist/validation.js.map +1 -0
- package/docs/index.md +30 -0
- package/docs/sdk.addtoinbox.md +68 -0
- package/docs/sdk.applescriptresult.data.md +11 -0
- package/docs/sdk.applescriptresult.error.md +11 -0
- package/docs/sdk.applescriptresult.md +92 -0
- package/docs/sdk.applescriptresult.success.md +11 -0
- package/docs/sdk.clierror.code.md +11 -0
- package/docs/sdk.clierror.details.md +11 -0
- package/docs/sdk.clierror.md +92 -0
- package/docs/sdk.clierror.message.md +11 -0
- package/docs/sdk.clioutput.data.md +11 -0
- package/docs/sdk.clioutput.error.md +11 -0
- package/docs/sdk.clioutput.md +90 -0
- package/docs/sdk.clioutput.success.md +11 -0
- package/docs/sdk.commandinfo.description.md +11 -0
- package/docs/sdk.commandinfo.md +90 -0
- package/docs/sdk.commandinfo.name.md +11 -0
- package/docs/sdk.commandinfo.usage.md +11 -0
- package/docs/sdk.completeresult.completed.md +11 -0
- package/docs/sdk.completeresult.md +90 -0
- package/docs/sdk.completeresult.taskid.md +11 -0
- package/docs/sdk.completeresult.taskname.md +11 -0
- package/docs/sdk.completetask.md +52 -0
- package/docs/sdk.createerror.md +82 -0
- package/docs/sdk.errorcode.md +24 -0
- package/docs/sdk.escapeapplescript.md +52 -0
- package/docs/sdk.failure.md +52 -0
- package/docs/sdk.failuremessage.md +52 -0
- package/docs/sdk.inboxoptions.defer.md +11 -0
- package/docs/sdk.inboxoptions.due.md +11 -0
- package/docs/sdk.inboxoptions.flag.md +11 -0
- package/docs/sdk.inboxoptions.md +134 -0
- package/docs/sdk.inboxoptions.note.md +11 -0
- package/docs/sdk.inboxoptions.tags.md +11 -0
- package/docs/sdk.jsonhelpers.md +13 -0
- package/docs/sdk.md +471 -0
- package/docs/sdk.ofperspective.id.md +11 -0
- package/docs/sdk.ofperspective.md +73 -0
- package/docs/sdk.ofperspective.name.md +11 -0
- package/docs/sdk.ofproject.folderid.md +11 -0
- package/docs/sdk.ofproject.foldername.md +11 -0
- package/docs/sdk.ofproject.id.md +11 -0
- package/docs/sdk.ofproject.md +192 -0
- package/docs/sdk.ofproject.name.md +11 -0
- package/docs/sdk.ofproject.note.md +11 -0
- package/docs/sdk.ofproject.remainingtaskcount.md +11 -0
- package/docs/sdk.ofproject.sequential.md +11 -0
- package/docs/sdk.ofproject.status.md +11 -0
- package/docs/sdk.ofproject.taskcount.md +11 -0
- package/docs/sdk.oftag.availabletaskcount.md +11 -0
- package/docs/sdk.oftag.id.md +11 -0
- package/docs/sdk.oftag.md +124 -0
- package/docs/sdk.oftag.name.md +11 -0
- package/docs/sdk.oftag.parentid.md +11 -0
- package/docs/sdk.oftag.parentname.md +11 -0
- package/docs/sdk.oftask.completed.md +11 -0
- package/docs/sdk.oftask.completiondate.md +11 -0
- package/docs/sdk.oftask.deferdate.md +11 -0
- package/docs/sdk.oftask.duedate.md +11 -0
- package/docs/sdk.oftask.flagged.md +11 -0
- package/docs/sdk.oftask.id.md +11 -0
- package/docs/sdk.oftask.md +226 -0
- package/docs/sdk.oftask.name.md +11 -0
- package/docs/sdk.oftask.note.md +11 -0
- package/docs/sdk.oftask.projectid.md +11 -0
- package/docs/sdk.oftask.projectname.md +11 -0
- package/docs/sdk.oftask.tags.md +11 -0
- package/docs/sdk.omnifocusscript.md +52 -0
- package/docs/sdk.omnifocusscriptwithhelpers.md +52 -0
- package/docs/sdk.parseapplescripterror.md +52 -0
- package/docs/sdk.projectqueryoptions.folder.md +11 -0
- package/docs/sdk.projectqueryoptions.md +96 -0
- package/docs/sdk.projectqueryoptions.sequential.md +11 -0
- package/docs/sdk.projectqueryoptions.status.md +11 -0
- package/docs/sdk.queryprojects.md +54 -0
- package/docs/sdk.querytags.md +54 -0
- package/docs/sdk.querytasks.md +54 -0
- package/docs/sdk.runapplescript.md +52 -0
- package/docs/sdk.runapplescriptfile.md +68 -0
- package/docs/sdk.success.md +52 -0
- package/docs/sdk.tagqueryoptions.md +58 -0
- package/docs/sdk.tagqueryoptions.parent.md +11 -0
- package/docs/sdk.taskqueryoptions.available.md +11 -0
- package/docs/sdk.taskqueryoptions.completed.md +11 -0
- package/docs/sdk.taskqueryoptions.dueafter.md +11 -0
- package/docs/sdk.taskqueryoptions.duebefore.md +11 -0
- package/docs/sdk.taskqueryoptions.flagged.md +11 -0
- package/docs/sdk.taskqueryoptions.md +172 -0
- package/docs/sdk.taskqueryoptions.project.md +11 -0
- package/docs/sdk.taskqueryoptions.tag.md +11 -0
- package/docs/sdk.taskupdateoptions.defer.md +11 -0
- package/docs/sdk.taskupdateoptions.due.md +11 -0
- package/docs/sdk.taskupdateoptions.flag.md +11 -0
- package/docs/sdk.taskupdateoptions.md +172 -0
- package/docs/sdk.taskupdateoptions.note.md +11 -0
- package/docs/sdk.taskupdateoptions.project.md +11 -0
- package/docs/sdk.taskupdateoptions.tags.md +11 -0
- package/docs/sdk.taskupdateoptions.title.md +11 -0
- package/docs/sdk.updatetask.md +66 -0
- package/docs/sdk.validatedatestring.md +54 -0
- package/docs/sdk.validateid.md +66 -0
- package/docs/sdk.validateprojectname.md +52 -0
- package/docs/sdk.validatetags.md +52 -0
- 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 @@
|
|
|
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"}
|