@stephendolan/omnifocus-cli 1.0.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 (47) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +321 -0
  3. package/dist/commands/inbox.d.ts +3 -0
  4. package/dist/commands/inbox.d.ts.map +1 -0
  5. package/dist/commands/inbox.js +31 -0
  6. package/dist/commands/inbox.js.map +1 -0
  7. package/dist/commands/perspective.d.ts +3 -0
  8. package/dist/commands/perspective.d.ts.map +1 -0
  9. package/dist/commands/perspective.js +23 -0
  10. package/dist/commands/perspective.js.map +1 -0
  11. package/dist/commands/project.d.ts +3 -0
  12. package/dist/commands/project.d.ts.map +1 -0
  13. package/dist/commands/project.js +58 -0
  14. package/dist/commands/project.js.map +1 -0
  15. package/dist/commands/search.d.ts +3 -0
  16. package/dist/commands/search.d.ts.map +1 -0
  17. package/dist/commands/search.js +14 -0
  18. package/dist/commands/search.js.map +1 -0
  19. package/dist/commands/task.d.ts +3 -0
  20. package/dist/commands/task.d.ts.map +1 -0
  21. package/dist/commands/task.js +96 -0
  22. package/dist/commands/task.js.map +1 -0
  23. package/dist/index.d.ts +3 -0
  24. package/dist/index.d.ts.map +1 -0
  25. package/dist/index.js +19 -0
  26. package/dist/index.js.map +1 -0
  27. package/dist/lib/command-utils.d.ts +4 -0
  28. package/dist/lib/command-utils.d.ts.map +1 -0
  29. package/dist/lib/command-utils.js +22 -0
  30. package/dist/lib/command-utils.js.map +1 -0
  31. package/dist/lib/display.d.ts +12 -0
  32. package/dist/lib/display.d.ts.map +1 -0
  33. package/dist/lib/display.js +168 -0
  34. package/dist/lib/display.js.map +1 -0
  35. package/dist/lib/filters.d.ts +14 -0
  36. package/dist/lib/filters.d.ts.map +1 -0
  37. package/dist/lib/filters.js +48 -0
  38. package/dist/lib/filters.js.map +1 -0
  39. package/dist/lib/omnifocus.d.ts +26 -0
  40. package/dist/lib/omnifocus.d.ts.map +1 -0
  41. package/dist/lib/omnifocus.js +457 -0
  42. package/dist/lib/omnifocus.js.map +1 -0
  43. package/dist/types.d.ts +70 -0
  44. package/dist/types.d.ts.map +1 -0
  45. package/dist/types.js +2 -0
  46. package/dist/types.js.map +1 -0
  47. package/package.json +41 -0
@@ -0,0 +1,457 @@
1
+ import { execFile } from 'child_process';
2
+ import { writeFile, unlink } from 'fs/promises';
3
+ import { tmpdir } from 'os';
4
+ import { join } from 'path';
5
+ import { promisify } from 'util';
6
+ const execFileAsync = promisify(execFile);
7
+ export class OmniFocus {
8
+ PROJECT_STATUS_MAP = {
9
+ 'active': 'Active',
10
+ 'on hold': 'OnHold',
11
+ 'dropped': 'Dropped'
12
+ };
13
+ OMNI_HELPERS = `
14
+ function serializeTask(task) {
15
+ const containingProject = task.containingProject;
16
+ const tagNames = task.tags.map(t => t.name);
17
+
18
+ return {
19
+ id: task.id.primaryKey,
20
+ name: task.name,
21
+ note: task.note || null,
22
+ completed: task.completed,
23
+ flagged: task.flagged,
24
+ project: containingProject ? containingProject.name : null,
25
+ tags: tagNames,
26
+ defer: task.deferDate ? task.deferDate.toISOString() : null,
27
+ due: task.dueDate ? task.dueDate.toISOString() : null,
28
+ estimatedMinutes: task.estimatedMinutes || null,
29
+ completionDate: task.completionDate ? task.completionDate.toISOString() : null
30
+ };
31
+ }
32
+
33
+ function serializeProject(project) {
34
+ const folder = project.folder;
35
+ const allTasks = project.flattenedTasks;
36
+ const remainingTasks = allTasks.filter(t => !t.completed);
37
+ const tagNames = project.tags.map(t => t.name);
38
+
39
+ return {
40
+ id: project.id.primaryKey,
41
+ name: project.name,
42
+ note: project.note || null,
43
+ status: projectStatusToString(project.status),
44
+ folder: folder ? folder.name : null,
45
+ sequential: project.sequential,
46
+ taskCount: allTasks.length,
47
+ remainingCount: remainingTasks.length,
48
+ tags: tagNames
49
+ };
50
+ }
51
+
52
+ function findTask(idOrName) {
53
+ for (const task of flattenedTasks) {
54
+ if (task.id.primaryKey === idOrName || task.name === idOrName) {
55
+ return task;
56
+ }
57
+ }
58
+ throw new Error("Task not found: " + idOrName);
59
+ }
60
+
61
+ function findProject(idOrName) {
62
+ for (const project of flattenedProjects) {
63
+ if (project.id.primaryKey === idOrName || project.name === idOrName) {
64
+ return project;
65
+ }
66
+ }
67
+ throw new Error("Project not found: " + idOrName);
68
+ }
69
+
70
+ function findByName(collection, name, typeName) {
71
+ for (const item of collection) {
72
+ if (item.name === name) {
73
+ return item;
74
+ }
75
+ }
76
+ throw new Error(typeName + " not found: " + name);
77
+ }
78
+
79
+ function assignTags(target, tagNames) {
80
+ for (const tagName of tagNames) {
81
+ const tag = findByName(flattenedTags, tagName, "Tag");
82
+ target.addTag(tag);
83
+ }
84
+ }
85
+
86
+ function replaceTagsOn(target, tagNames) {
87
+ target.clearTags();
88
+ assignTags(target, tagNames);
89
+ }
90
+
91
+ function projectStatusToString(status) {
92
+ if (status === Project.Status.Active) return 'active';
93
+ if (status === Project.Status.OnHold) return 'on hold';
94
+ return 'dropped';
95
+ }
96
+
97
+ function stringToProjectStatus(str) {
98
+ if (str === 'active') return Project.Status.Active;
99
+ if (str === 'on hold') return Project.Status.OnHold;
100
+ return Project.Status.Dropped;
101
+ }
102
+ `;
103
+ async executeJXA(script, timeoutMs = 30000) {
104
+ const tmpFile = join(tmpdir(), `omnifocus-${Date.now()}.js`);
105
+ try {
106
+ await writeFile(tmpFile, script, 'utf-8');
107
+ const { stdout, stderr } = await execFileAsync('osascript', ['-l', 'JavaScript', tmpFile], {
108
+ timeout: timeoutMs,
109
+ maxBuffer: 10 * 1024 * 1024,
110
+ });
111
+ if (stderr) {
112
+ console.error('JXA stderr:', stderr);
113
+ }
114
+ return stdout.trim();
115
+ }
116
+ finally {
117
+ try {
118
+ await unlink(tmpFile);
119
+ }
120
+ catch (error) {
121
+ // Temporary file cleanup is non-critical and safe to ignore
122
+ }
123
+ }
124
+ }
125
+ escapeString(str) {
126
+ return str
127
+ .replace(/\\/g, '\\\\')
128
+ .replace(/"/g, '\\"')
129
+ .replace(/\n/g, '\\n')
130
+ .replace(/\r/g, '\\r');
131
+ }
132
+ wrapOmniScript(omniScript) {
133
+ return `
134
+ const app = Application('OmniFocus');
135
+ app.includeStandardAdditions = true;
136
+ const result = app.evaluateJavascript(${JSON.stringify(omniScript.trim())});
137
+ result;
138
+ `.trim();
139
+ }
140
+ buildTaskFilters(filters) {
141
+ const conditions = [];
142
+ if (!filters.includeCompleted) {
143
+ conditions.push('if (task.completed) continue;');
144
+ }
145
+ if (!filters.includeDropped) {
146
+ conditions.push('if (task.dropped) continue;');
147
+ }
148
+ if (filters.flagged) {
149
+ conditions.push('if (!task.flagged) continue;');
150
+ conditions.push('if (task.taskStatus !== Task.Status.Available) continue;');
151
+ }
152
+ if (filters.project) {
153
+ conditions.push(`
154
+ if (!task.containingProject || task.containingProject.name !== "${this.escapeString(filters.project)}") {
155
+ continue;
156
+ }
157
+ `);
158
+ }
159
+ if (filters.tag) {
160
+ conditions.push(`
161
+ if (!task.tags.some(t => t.name === "${this.escapeString(filters.tag)}")) {
162
+ continue;
163
+ }
164
+ `);
165
+ }
166
+ return conditions.join('\n ');
167
+ }
168
+ buildProjectFilters(filters) {
169
+ const conditions = [];
170
+ if (!filters.includeDropped) {
171
+ conditions.push('if (project.status === Project.Status.Dropped) continue;');
172
+ }
173
+ if (filters.status) {
174
+ const statusCheck = this.PROJECT_STATUS_MAP[filters.status];
175
+ conditions.push(`if (project.status !== Project.Status.${statusCheck}) continue;`);
176
+ }
177
+ if (filters.folder) {
178
+ conditions.push(`
179
+ if (!project.folder || project.folder.name !== "${this.escapeString(filters.folder)}") {
180
+ continue;
181
+ }
182
+ `);
183
+ }
184
+ return conditions.join('\n ');
185
+ }
186
+ buildTaskUpdates(options) {
187
+ const updates = [];
188
+ if (options.name !== undefined) {
189
+ updates.push(`task.name = "${this.escapeString(options.name)}";`);
190
+ }
191
+ if (options.note !== undefined) {
192
+ updates.push(`task.note = "${this.escapeString(options.note)}";`);
193
+ }
194
+ if (options.flagged !== undefined) {
195
+ updates.push(`task.flagged = ${options.flagged};`);
196
+ }
197
+ if (options.completed !== undefined) {
198
+ updates.push(`task.completed = ${options.completed};`);
199
+ }
200
+ if (options.estimatedMinutes !== undefined) {
201
+ updates.push(`task.estimatedMinutes = ${options.estimatedMinutes};`);
202
+ }
203
+ if (options.defer !== undefined) {
204
+ updates.push(options.defer
205
+ ? `task.deferDate = new Date("${options.defer}");`
206
+ : 'task.deferDate = null;');
207
+ }
208
+ if (options.due !== undefined) {
209
+ updates.push(options.due
210
+ ? `task.dueDate = new Date("${options.due}");`
211
+ : 'task.dueDate = null;');
212
+ }
213
+ if (options.project !== undefined && options.project) {
214
+ updates.push(`
215
+ const targetProject = findByName(flattenedProjects, "${this.escapeString(options.project)}", "Project");
216
+ moveTasks([task], targetProject);
217
+ `);
218
+ }
219
+ if (options.tags !== undefined) {
220
+ updates.push(`replaceTagsOn(task, ${JSON.stringify(options.tags)});`);
221
+ }
222
+ return updates.join('\n ');
223
+ }
224
+ async listTasks(filters = {}) {
225
+ const omniScript = `
226
+ ${this.OMNI_HELPERS}
227
+ (() => {
228
+ const results = [];
229
+ for (const task of flattenedTasks) {
230
+ ${this.buildTaskFilters(filters)}
231
+ results.push(serializeTask(task));
232
+ }
233
+ return JSON.stringify(results);
234
+ })();
235
+ `;
236
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
237
+ return JSON.parse(output);
238
+ }
239
+ async createTask(options) {
240
+ const omniScript = `
241
+ ${this.OMNI_HELPERS}
242
+ (() => {
243
+ ${options.project
244
+ ? `const targetProject = findByName(flattenedProjects, "${this.escapeString(options.project)}", "Project");
245
+ const task = new Task("${this.escapeString(options.name)}", targetProject);`
246
+ : `const task = new Task("${this.escapeString(options.name)}", inbox);`}
247
+
248
+ ${options.note ? `task.note = "${this.escapeString(options.note)}";` : ''}
249
+ ${options.flagged ? 'task.flagged = true;' : ''}
250
+ ${options.estimatedMinutes ? `task.estimatedMinutes = ${options.estimatedMinutes};` : ''}
251
+ ${options.defer ? `task.deferDate = new Date("${options.defer}");` : ''}
252
+ ${options.due ? `task.dueDate = new Date("${options.due}");` : ''}
253
+ ${options.tags && options.tags.length > 0 ? `assignTags(task, ${JSON.stringify(options.tags)});` : ''}
254
+
255
+ return JSON.stringify(serializeTask(task));
256
+ })();
257
+ `;
258
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
259
+ return JSON.parse(output);
260
+ }
261
+ async updateTask(idOrName, options) {
262
+ const omniScript = `
263
+ ${this.OMNI_HELPERS}
264
+ (() => {
265
+ const task = findTask("${this.escapeString(idOrName)}");
266
+ ${this.buildTaskUpdates(options)}
267
+ return JSON.stringify(serializeTask(task));
268
+ })();
269
+ `;
270
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
271
+ return JSON.parse(output);
272
+ }
273
+ async deleteTask(idOrName) {
274
+ const omniScript = `
275
+ ${this.OMNI_HELPERS}
276
+ (() => {
277
+ deleteObject(findTask("${this.escapeString(idOrName)}"));
278
+ })();
279
+ `;
280
+ await this.executeJXA(this.wrapOmniScript(omniScript));
281
+ }
282
+ async listProjects(filters = {}) {
283
+ const omniScript = `
284
+ ${this.OMNI_HELPERS}
285
+ (() => {
286
+ const results = [];
287
+ for (const project of flattenedProjects) {
288
+ ${this.buildProjectFilters(filters)}
289
+ results.push(serializeProject(project));
290
+ }
291
+ return JSON.stringify(results);
292
+ })();
293
+ `;
294
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
295
+ return JSON.parse(output);
296
+ }
297
+ async createProject(options) {
298
+ const omniScript = `
299
+ ${this.OMNI_HELPERS}
300
+ (() => {
301
+ ${options.folder
302
+ ? `const targetFolder = findByName(flattenedFolders, "${this.escapeString(options.folder)}", "Folder");
303
+ const project = new Project("${this.escapeString(options.name)}", targetFolder);`
304
+ : `const project = new Project("${this.escapeString(options.name)}");`}
305
+
306
+ ${options.note ? `project.note = "${this.escapeString(options.note)}";` : ''}
307
+ ${options.sequential !== undefined ? `project.sequential = ${options.sequential};` : ''}
308
+ ${options.status ? `project.status = stringToProjectStatus("${options.status}");` : ''}
309
+ ${options.tags && options.tags.length > 0 ? `assignTags(project, ${JSON.stringify(options.tags)});` : ''}
310
+
311
+ return JSON.stringify(serializeProject(project));
312
+ })();
313
+ `;
314
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
315
+ return JSON.parse(output);
316
+ }
317
+ async deleteProject(idOrName) {
318
+ const omniScript = `
319
+ ${this.OMNI_HELPERS}
320
+ (() => {
321
+ deleteObject(findProject("${this.escapeString(idOrName)}"));
322
+ })();
323
+ `;
324
+ await this.executeJXA(this.wrapOmniScript(omniScript));
325
+ }
326
+ async listInboxTasks() {
327
+ return this.getPerspectiveTasks('Inbox');
328
+ }
329
+ async getInboxCount() {
330
+ const tasks = await this.getPerspectiveTasks('Inbox');
331
+ return tasks.length;
332
+ }
333
+ async searchTasks(query) {
334
+ const omniScript = `
335
+ ${this.OMNI_HELPERS}
336
+ (() => {
337
+ const results = [];
338
+ const searchQuery = "${this.escapeString(query)}".toLowerCase();
339
+
340
+ for (const task of flattenedTasks) {
341
+ if (task.completed) continue;
342
+ if (task.dropped) continue;
343
+
344
+ const name = task.name.toLowerCase();
345
+ const note = (task.note || '').toLowerCase();
346
+
347
+ if (name.includes(searchQuery) || note.includes(searchQuery)) {
348
+ results.push(serializeTask(task));
349
+ }
350
+ }
351
+
352
+ return JSON.stringify(results);
353
+ })();
354
+ `;
355
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
356
+ return JSON.parse(output);
357
+ }
358
+ async getTask(idOrName) {
359
+ const omniScript = `
360
+ ${this.OMNI_HELPERS}
361
+ (() => {
362
+ const task = findTask("${this.escapeString(idOrName)}");
363
+ return JSON.stringify(serializeTask(task));
364
+ })();
365
+ `;
366
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
367
+ return JSON.parse(output);
368
+ }
369
+ async getProject(idOrName) {
370
+ const omniScript = `
371
+ ${this.OMNI_HELPERS}
372
+ (() => {
373
+ const project = findProject("${this.escapeString(idOrName)}");
374
+ return JSON.stringify(serializeProject(project));
375
+ })();
376
+ `;
377
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
378
+ return JSON.parse(output);
379
+ }
380
+ async listPerspectives() {
381
+ const omniScript = `
382
+ (() => {
383
+ const results = [];
384
+
385
+ const builtInNames = ['Inbox', 'Flagged', 'Forecast', 'Projects', 'Tags', 'Nearby', 'Review'];
386
+ for (const name of builtInNames) {
387
+ results.push({ id: name, name: name });
388
+ }
389
+
390
+ const customPerspectives = Perspective.Custom.all;
391
+ for (const perspective of customPerspectives) {
392
+ results.push({ id: perspective.name, name: perspective.name });
393
+ }
394
+
395
+ return JSON.stringify(results);
396
+ })();
397
+ `;
398
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript));
399
+ return JSON.parse(output);
400
+ }
401
+ async getPerspectiveTasks(perspectiveName) {
402
+ const omniScript = `
403
+ ${this.OMNI_HELPERS}
404
+ (() => {
405
+ const doc = document;
406
+ const windows = doc.windows;
407
+
408
+ if (windows.length === 0) {
409
+ throw new Error("No OmniFocus window is open. Please open an OmniFocus window and try again.");
410
+ }
411
+
412
+ const win = windows[0];
413
+ const perspectiveName = "${this.escapeString(perspectiveName)}";
414
+
415
+ const builtInPerspectives = {
416
+ 'inbox': Perspective.BuiltIn.Inbox,
417
+ 'flagged': Perspective.BuiltIn.Flagged,
418
+ 'forecast': Perspective.BuiltIn.Forecast,
419
+ 'projects': Perspective.BuiltIn.Projects,
420
+ 'tags': Perspective.BuiltIn.Tags,
421
+ 'nearby': Perspective.BuiltIn.Nearby,
422
+ 'review': Perspective.BuiltIn.Review
423
+ };
424
+
425
+ const lowerName = perspectiveName.toLowerCase();
426
+ if (builtInPerspectives[lowerName]) {
427
+ win.perspective = builtInPerspectives[lowerName];
428
+ } else {
429
+ const customPerspective = Perspective.Custom.byName(perspectiveName);
430
+ if (customPerspective) {
431
+ win.perspective = customPerspective;
432
+ } else {
433
+ throw new Error("Perspective not found: " + perspectiveName);
434
+ }
435
+ }
436
+
437
+ const content = win.content;
438
+ if (!content) {
439
+ throw new Error("No content available in window");
440
+ }
441
+
442
+ const tasks = [];
443
+ content.rootNode.apply(node => {
444
+ const obj = node.object;
445
+ if (obj instanceof Task) {
446
+ tasks.push(serializeTask(obj));
447
+ }
448
+ });
449
+
450
+ return JSON.stringify(tasks);
451
+ })();
452
+ `;
453
+ const output = await this.executeJXA(this.wrapOmniScript(omniScript), 60000);
454
+ return JSON.parse(output);
455
+ }
456
+ }
457
+ //# sourceMappingURL=omnifocus.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"omnifocus.js","sourceRoot":"","sources":["../../src/lib/omnifocus.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,70 @@
1
+ export interface Task {
2
+ id: string;
3
+ name: string;
4
+ note: string | null;
5
+ completed: boolean;
6
+ flagged: boolean;
7
+ project: string | null;
8
+ tags: string[];
9
+ defer: string | null;
10
+ due: string | null;
11
+ estimatedMinutes: number | null;
12
+ completionDate: string | null;
13
+ }
14
+ export interface Project {
15
+ id: string;
16
+ name: string;
17
+ note: string | null;
18
+ status: 'active' | 'on hold' | 'dropped';
19
+ folder: string | null;
20
+ sequential: boolean;
21
+ taskCount: number;
22
+ remainingCount: number;
23
+ tags: string[];
24
+ }
25
+ export interface TaskFilters {
26
+ includeCompleted?: boolean;
27
+ includeDropped?: boolean;
28
+ flagged?: boolean;
29
+ project?: string;
30
+ tag?: string;
31
+ }
32
+ export interface ProjectFilters {
33
+ includeDropped?: boolean;
34
+ status?: 'active' | 'on hold' | 'dropped';
35
+ folder?: string;
36
+ }
37
+ export interface CreateTaskOptions {
38
+ name: string;
39
+ note?: string;
40
+ project?: string;
41
+ tags?: string[];
42
+ defer?: string;
43
+ due?: string;
44
+ flagged?: boolean;
45
+ estimatedMinutes?: number;
46
+ }
47
+ export interface UpdateTaskOptions {
48
+ name?: string;
49
+ note?: string;
50
+ project?: string;
51
+ tags?: string[];
52
+ defer?: string;
53
+ due?: string;
54
+ flagged?: boolean;
55
+ estimatedMinutes?: number;
56
+ completed?: boolean;
57
+ }
58
+ export interface CreateProjectOptions {
59
+ name: string;
60
+ note?: string;
61
+ folder?: string;
62
+ sequential?: boolean;
63
+ tags?: string[];
64
+ status?: 'active' | 'on hold' | 'dropped';
65
+ }
66
+ export interface Perspective {
67
+ id: string;
68
+ name: string;
69
+ }
70
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,IAAI;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;IACf,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,cAAc,EAAE,MAAM,GAAG,IAAI,CAAC;CAC/B;AAED,MAAM,WAAW,OAAO;IACtB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;IACpB,MAAM,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IACzC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,UAAU,EAAE,OAAO,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,IAAI,EAAE,MAAM,EAAE,CAAC;CAChB;AAED,MAAM,WAAW,WAAW;IAC1B,gBAAgB,CAAC,EAAE,OAAO,CAAC;IAC3B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AAED,MAAM,WAAW,cAAc;IAC7B,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;CAC3B;AAED,MAAM,WAAW,iBAAiB;IAChC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;IAChB,MAAM,CAAC,EAAE,QAAQ,GAAG,SAAS,GAAG,SAAS,CAAC;CAC3C;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;CACd"}
package/dist/types.js ADDED
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
package/package.json ADDED
@@ -0,0 +1,41 @@
1
+ {
2
+ "name": "@stephendolan/omnifocus-cli",
3
+ "version": "1.0.0",
4
+ "description": "A command-line interface for OmniFocus on macOS",
5
+ "main": "dist/index.js",
6
+ "type": "module",
7
+ "bin": {
8
+ "of": "./dist/index.js"
9
+ },
10
+ "scripts": {
11
+ "build": "tsc",
12
+ "dev": "tsc --watch",
13
+ "start": "node dist/index.js"
14
+ },
15
+ "keywords": [
16
+ "omnifocus",
17
+ "cli",
18
+ "productivity",
19
+ "gtd"
20
+ ],
21
+ "author": "Stephen Dolan <stephen@stephendolan.com>",
22
+ "license": "MIT",
23
+ "repository": {
24
+ "type": "git",
25
+ "url": "https://github.com/stephendolan/omnifocus-cli.git"
26
+ },
27
+ "homepage": "https://github.com/stephendolan/omnifocus-cli#readme",
28
+ "bugs": {
29
+ "url": "https://github.com/stephendolan/omnifocus-cli/issues"
30
+ },
31
+ "dependencies": {
32
+ "commander": "^12.1.0",
33
+ "chalk": "^5.3.0",
34
+ "ora": "^8.1.1",
35
+ "date-fns": "^4.1.0"
36
+ },
37
+ "devDependencies": {
38
+ "@types/node": "^22.10.2",
39
+ "typescript": "^5.7.2"
40
+ }
41
+ }