@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,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 @@
|
|
|
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"}
|