@stephendolan/omnifocus-cli 2.2.1 → 2.3.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/dist/cli.js CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env bun
2
2
 
3
3
  // src/cli.ts
4
- import { Command as Command8 } from "commander";
4
+ import { Command as Command9 } from "commander";
5
5
 
6
6
  // src/lib/output.ts
7
7
  var globalOutputOptions = {};
@@ -997,21 +997,21 @@ function createTaskCommand() {
997
997
  command.description("Manage OmniFocus tasks");
998
998
  command.command("list").alias("ls").description("List tasks").option("-f, --flagged", "Show only flagged tasks").option("-p, --project <name>", "Filter by project").option("-t, --tag <name>", "Filter by tag").option("-c, --completed", "Include completed tasks").action(
999
999
  withErrorHandling(async (options) => {
1000
- const of = new OmniFocus();
1000
+ const of2 = new OmniFocus();
1001
1001
  const filters = {
1002
1002
  includeCompleted: options.completed,
1003
1003
  ...options.flagged && { flagged: true },
1004
1004
  ...options.project && { project: options.project },
1005
1005
  ...options.tag && { tag: options.tag }
1006
1006
  };
1007
- const tasks = await of.listTasks(filters);
1007
+ const tasks = await of2.listTasks(filters);
1008
1008
  outputJson(tasks);
1009
1009
  })
1010
1010
  );
1011
1011
  command.command("create <name>").description("Create a new task").option("-p, --project <name>", "Assign to project").option("--note <text>", "Add note").option("-t, --tag <tags...>", "Add tags").option("-d, --due <date>", "Set due date").option("-D, --defer <date>", "Set defer date").option("-f, --flagged", "Flag the task").option("-e, --estimate <minutes>", "Estimated time in minutes", parseInt).action(
1012
1012
  withErrorHandling(async (name, options) => {
1013
- const of = new OmniFocus();
1014
- const task = await of.createTask({
1013
+ const of2 = new OmniFocus();
1014
+ const task = await of2.createTask({
1015
1015
  name,
1016
1016
  note: options.note,
1017
1017
  project: options.project,
@@ -1026,7 +1026,7 @@ function createTaskCommand() {
1026
1026
  );
1027
1027
  command.command("update <idOrName>").description("Update an existing task").option("-n, --name <name>", "New name").option("--note <text>", "New note").option("-p, --project <name>", "Move to project").option("-t, --tag <tags...>", "Replace tags").option("-d, --due <date>", "Set due date").option("-D, --defer <date>", "Set defer date").option("-f, --flag", "Flag the task").option("-F, --unflag", "Unflag the task").option("-c, --complete", "Mark as completed").option("-C, --incomplete", "Mark as incomplete").option("-e, --estimate <minutes>", "Estimated time in minutes", parseInt).action(
1028
1028
  withErrorHandling(async (idOrName, options) => {
1029
- const of = new OmniFocus();
1029
+ const of2 = new OmniFocus();
1030
1030
  const updates = {
1031
1031
  ...options.name && { name: options.name },
1032
1032
  ...options.note !== void 0 && { note: options.note },
@@ -1044,28 +1044,28 @@ function createTaskCommand() {
1044
1044
  ...options.incomplete && { completed: false },
1045
1045
  ...options.estimate !== void 0 && { estimatedMinutes: options.estimate }
1046
1046
  };
1047
- const task = await of.updateTask(idOrName, updates);
1047
+ const task = await of2.updateTask(idOrName, updates);
1048
1048
  outputJson(task);
1049
1049
  })
1050
1050
  );
1051
1051
  command.command("delete <idOrName>").alias("rm").description("Delete a task").action(
1052
1052
  withErrorHandling(async (idOrName) => {
1053
- const of = new OmniFocus();
1054
- await of.deleteTask(idOrName);
1053
+ const of2 = new OmniFocus();
1054
+ await of2.deleteTask(idOrName);
1055
1055
  outputJson({ message: "Task deleted successfully" });
1056
1056
  })
1057
1057
  );
1058
1058
  command.command("view <idOrName>").description("View task details").action(
1059
1059
  withErrorHandling(async (idOrName) => {
1060
- const of = new OmniFocus();
1061
- const task = await of.getTask(idOrName);
1060
+ const of2 = new OmniFocus();
1061
+ const task = await of2.getTask(idOrName);
1062
1062
  outputJson(task);
1063
1063
  })
1064
1064
  );
1065
1065
  command.command("stats").description("Show task statistics").action(
1066
1066
  withErrorHandling(async () => {
1067
- const of = new OmniFocus();
1068
- const stats = await of.getTaskStats();
1067
+ const of2 = new OmniFocus();
1068
+ const stats = await of2.getTaskStats();
1069
1069
  outputJson(stats);
1070
1070
  })
1071
1071
  );
@@ -1079,20 +1079,20 @@ function createProjectCommand() {
1079
1079
  command.description("Manage OmniFocus projects");
1080
1080
  command.command("list").alias("ls").description("List projects").option("-f, --folder <name>", "Filter by folder").option("-s, --status <status>", "Filter by status (active, on hold, dropped)").option("-d, --dropped", "Include dropped projects").action(
1081
1081
  withErrorHandling(async (options) => {
1082
- const of = new OmniFocus();
1082
+ const of2 = new OmniFocus();
1083
1083
  const filters = {
1084
1084
  includeDropped: options.dropped,
1085
1085
  ...options.folder && { folder: options.folder },
1086
1086
  ...options.status && { status: options.status }
1087
1087
  };
1088
- const projects = await of.listProjects(filters);
1088
+ const projects = await of2.listProjects(filters);
1089
1089
  outputJson(projects);
1090
1090
  })
1091
1091
  );
1092
1092
  command.command("create <name>").description("Create a new project").option("-f, --folder <name>", "Assign to folder").option("--note <text>", "Add note").option("-t, --tag <tags...>", "Add tags").option("-s, --sequential", "Make it a sequential project").option("--status <status>", "Set status (active, on hold, dropped)").action(
1093
1093
  withErrorHandling(async (name, options) => {
1094
- const of = new OmniFocus();
1095
- const project = await of.createProject({
1094
+ const of2 = new OmniFocus();
1095
+ const project = await of2.createProject({
1096
1096
  name,
1097
1097
  note: options.note,
1098
1098
  folder: options.folder,
@@ -1105,7 +1105,7 @@ function createProjectCommand() {
1105
1105
  );
1106
1106
  command.command("update <idOrName>").description("Update an existing project").option("-n, --name <name>", "Rename project").option("--note <text>", "New note").option("-f, --folder <name>", "Move to folder").option("-t, --tag <tags...>", "Replace tags").option("-s, --sequential", "Make it sequential").option("-p, --parallel", "Make it parallel").option("--status <status>", "Set status (active, on hold, dropped)").action(
1107
1107
  withErrorHandling(async (idOrName, options) => {
1108
- const of = new OmniFocus();
1108
+ const of2 = new OmniFocus();
1109
1109
  const updates = {
1110
1110
  ...options.name && { name: options.name },
1111
1111
  ...options.note !== void 0 && { note: options.note },
@@ -1115,28 +1115,28 @@ function createProjectCommand() {
1115
1115
  ...options.parallel && { sequential: false },
1116
1116
  ...options.status && { status: options.status }
1117
1117
  };
1118
- const project = await of.updateProject(idOrName, updates);
1118
+ const project = await of2.updateProject(idOrName, updates);
1119
1119
  outputJson(project);
1120
1120
  })
1121
1121
  );
1122
1122
  command.command("delete <idOrName>").alias("rm").description("Delete a project").action(
1123
1123
  withErrorHandling(async (idOrName) => {
1124
- const of = new OmniFocus();
1125
- await of.deleteProject(idOrName);
1124
+ const of2 = new OmniFocus();
1125
+ await of2.deleteProject(idOrName);
1126
1126
  outputJson({ message: "Project deleted successfully" });
1127
1127
  })
1128
1128
  );
1129
1129
  command.command("view <idOrName>").description("View project details").action(
1130
1130
  withErrorHandling(async (idOrName) => {
1131
- const of = new OmniFocus();
1132
- const project = await of.getProject(idOrName);
1131
+ const of2 = new OmniFocus();
1132
+ const project = await of2.getProject(idOrName);
1133
1133
  outputJson(project);
1134
1134
  })
1135
1135
  );
1136
1136
  command.command("stats").description("Show project statistics").action(
1137
1137
  withErrorHandling(async () => {
1138
- const of = new OmniFocus();
1139
- const stats = await of.getProjectStats();
1138
+ const of2 = new OmniFocus();
1139
+ const stats = await of2.getProjectStats();
1140
1140
  outputJson(stats);
1141
1141
  })
1142
1142
  );
@@ -1150,22 +1150,22 @@ function createInboxCommand() {
1150
1150
  command.description("Manage OmniFocus inbox");
1151
1151
  command.command("list").alias("ls").description("List inbox tasks").action(
1152
1152
  withErrorHandling(async () => {
1153
- const of = new OmniFocus();
1154
- const tasks = await of.listInboxTasks();
1153
+ const of2 = new OmniFocus();
1154
+ const tasks = await of2.listInboxTasks();
1155
1155
  outputJson(tasks);
1156
1156
  })
1157
1157
  );
1158
1158
  command.command("count").description("Get inbox count").action(
1159
1159
  withErrorHandling(async () => {
1160
- const of = new OmniFocus();
1161
- const count = await of.getInboxCount();
1160
+ const of2 = new OmniFocus();
1161
+ const count = await of2.getInboxCount();
1162
1162
  outputJson({ count });
1163
1163
  })
1164
1164
  );
1165
1165
  command.command("add <name>").description("Add a task to inbox").option("--note <text>", "Add note").option("-t, --tag <tags...>", "Add tags").option("-d, --due <date>", "Set due date").option("-D, --defer <date>", "Set defer date").option("-f, --flagged", "Flag the task").option("-e, --estimate <minutes>", "Estimated time in minutes", parseInt).action(
1166
1166
  withErrorHandling(async (name, options) => {
1167
- const of = new OmniFocus();
1168
- const task = await of.createTask({
1167
+ const of2 = new OmniFocus();
1168
+ const task = await of2.createTask({
1169
1169
  name,
1170
1170
  note: options.note,
1171
1171
  tags: options.tag,
@@ -1188,8 +1188,8 @@ function createSearchCommand() {
1188
1188
  command.argument("<query>", "Search query");
1189
1189
  command.action(
1190
1190
  withErrorHandling(async (query) => {
1191
- const of = new OmniFocus();
1192
- const tasks = await of.searchTasks(query);
1191
+ const of2 = new OmniFocus();
1192
+ const tasks = await of2.searchTasks(query);
1193
1193
  outputJson(tasks);
1194
1194
  })
1195
1195
  );
@@ -1203,15 +1203,15 @@ function createPerspectiveCommand() {
1203
1203
  command.description("Manage OmniFocus perspectives");
1204
1204
  command.command("list").alias("ls").description("List all perspectives").action(
1205
1205
  withErrorHandling(async () => {
1206
- const of = new OmniFocus();
1207
- const perspectives = await of.listPerspectives();
1206
+ const of2 = new OmniFocus();
1207
+ const perspectives = await of2.listPerspectives();
1208
1208
  outputJson(perspectives);
1209
1209
  })
1210
1210
  );
1211
1211
  command.command("view <name>").description("View tasks in a perspective").action(
1212
1212
  withErrorHandling(async (name) => {
1213
- const of = new OmniFocus();
1214
- const tasks = await of.getPerspectiveTasks(name);
1213
+ const of2 = new OmniFocus();
1214
+ const tasks = await of2.getPerspectiveTasks(name);
1215
1215
  outputJson(tasks);
1216
1216
  })
1217
1217
  );
@@ -1225,8 +1225,8 @@ function createTagCommand() {
1225
1225
  command.description("Manage and analyze OmniFocus tags");
1226
1226
  command.command("list").alias("ls").description("List tags with usage information").option("-u, --unused-days <days>", "Show tags unused for N days", parseInt).option("-s, --sort <field>", "Sort by: name, usage, activity (default: name)", "name").option("-a, --active-only", "Only count active (incomplete) tasks").action(
1227
1227
  withErrorHandling(async (options) => {
1228
- const of = new OmniFocus();
1229
- const tags = await of.listTags({
1228
+ const of2 = new OmniFocus();
1229
+ const tags = await of2.listTags({
1230
1230
  unusedDays: options.unusedDays,
1231
1231
  sortBy: options.sort,
1232
1232
  activeOnly: options.activeOnly
@@ -1236,8 +1236,8 @@ function createTagCommand() {
1236
1236
  );
1237
1237
  command.command("create <name>").description("Create a new tag").option("-p, --parent <name>", "Create as child of parent tag").option("-s, --status <status>", "Set status (active, on hold, dropped)").action(
1238
1238
  withErrorHandling(async (name, options) => {
1239
- const of = new OmniFocus();
1240
- const tag = await of.createTag({
1239
+ const of2 = new OmniFocus();
1240
+ const tag = await of2.createTag({
1241
1241
  name,
1242
1242
  parent: options.parent,
1243
1243
  status: options.status
@@ -1247,33 +1247,33 @@ function createTagCommand() {
1247
1247
  );
1248
1248
  command.command("view <idOrName>").description("View tag details").action(
1249
1249
  withErrorHandling(async (idOrName) => {
1250
- const of = new OmniFocus();
1251
- const tag = await of.getTag(idOrName);
1250
+ const of2 = new OmniFocus();
1251
+ const tag = await of2.getTag(idOrName);
1252
1252
  outputJson(tag);
1253
1253
  })
1254
1254
  );
1255
1255
  command.command("update <idOrName>").description("Update an existing tag").option("-n, --name <name>", "Rename tag").option("-s, --status <status>", "Set status (active, on hold, dropped)").action(
1256
1256
  withErrorHandling(async (idOrName, options) => {
1257
- const of = new OmniFocus();
1257
+ const of2 = new OmniFocus();
1258
1258
  const updates = {
1259
1259
  ...options.name && { name: options.name },
1260
1260
  ...options.status && { status: options.status }
1261
1261
  };
1262
- const tag = await of.updateTag(idOrName, updates);
1262
+ const tag = await of2.updateTag(idOrName, updates);
1263
1263
  outputJson(tag);
1264
1264
  })
1265
1265
  );
1266
1266
  command.command("delete <idOrName>").alias("rm").description("Delete a tag").action(
1267
1267
  withErrorHandling(async (idOrName) => {
1268
- const of = new OmniFocus();
1269
- await of.deleteTag(idOrName);
1268
+ const of2 = new OmniFocus();
1269
+ await of2.deleteTag(idOrName);
1270
1270
  outputJson({ message: "Tag deleted successfully" });
1271
1271
  })
1272
1272
  );
1273
1273
  command.command("stats").description("Show tag usage statistics").action(
1274
1274
  withErrorHandling(async () => {
1275
- const of = new OmniFocus();
1276
- const stats = await of.getTagStats();
1275
+ const of2 = new OmniFocus();
1276
+ const stats = await of2.getTagStats();
1277
1277
  outputJson(stats);
1278
1278
  })
1279
1279
  );
@@ -1287,25 +1287,273 @@ function createFolderCommand() {
1287
1287
  command.description("View OmniFocus folder hierarchy");
1288
1288
  command.command("list").alias("ls").description("List top-level folders with nested children").option("-d, --dropped", "Include dropped folders").action(
1289
1289
  withErrorHandling(async (options) => {
1290
- const of = new OmniFocus();
1291
- const folders = await of.listFolders({ includeDropped: options.dropped });
1290
+ const of2 = new OmniFocus();
1291
+ const folders = await of2.listFolders({ includeDropped: options.dropped });
1292
1292
  outputJson(folders);
1293
1293
  })
1294
1294
  );
1295
1295
  command.command("view <idOrName>").description("View folder details and children").option("-d, --dropped", "Include dropped child folders").action(
1296
1296
  withErrorHandling(async (idOrName, options) => {
1297
- const of = new OmniFocus();
1297
+ const of2 = new OmniFocus();
1298
1298
  const filters = { includeDropped: options.dropped };
1299
- const folder = await of.getFolder(idOrName, filters);
1299
+ const folder = await of2.getFolder(idOrName, filters);
1300
1300
  outputJson(folder);
1301
1301
  })
1302
1302
  );
1303
1303
  return command;
1304
1304
  }
1305
1305
 
1306
+ // src/commands/mcp.ts
1307
+ import { Command as Command8 } from "commander";
1308
+
1309
+ // src/mcp/server.ts
1310
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
1311
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
1312
+ import { z } from "zod";
1313
+ var server = new McpServer({
1314
+ name: "omnifocus",
1315
+ version: "1.0.0"
1316
+ });
1317
+ var of = new OmniFocus();
1318
+ function jsonResponse(data) {
1319
+ return { content: [{ type: "text", text: JSON.stringify(data, null, 2) }] };
1320
+ }
1321
+ server.tool(
1322
+ "list_tasks",
1323
+ "List tasks with optional filtering",
1324
+ {
1325
+ includeCompleted: z.boolean().optional().describe("Include completed tasks"),
1326
+ includeDropped: z.boolean().optional().describe("Include dropped tasks"),
1327
+ flagged: z.boolean().optional().describe("Only show flagged tasks"),
1328
+ project: z.string().optional().describe("Filter by project name"),
1329
+ tag: z.string().optional().describe("Filter by tag name")
1330
+ },
1331
+ async (filters) => jsonResponse(await of.listTasks(filters))
1332
+ );
1333
+ server.tool(
1334
+ "get_task",
1335
+ "Get a specific task by ID or name",
1336
+ { idOrName: z.string().describe("Task ID or name") },
1337
+ async ({ idOrName }) => jsonResponse(await of.getTask(idOrName))
1338
+ );
1339
+ server.tool(
1340
+ "create_task",
1341
+ "Create a new task",
1342
+ {
1343
+ name: z.string().describe("Task name"),
1344
+ note: z.string().optional().describe("Task note"),
1345
+ project: z.string().optional().describe("Project to add task to"),
1346
+ tags: z.array(z.string()).optional().describe("Tags to assign"),
1347
+ defer: z.string().optional().describe("Defer date (ISO 8601)"),
1348
+ due: z.string().optional().describe("Due date (ISO 8601)"),
1349
+ flagged: z.boolean().optional().describe("Flag the task"),
1350
+ estimatedMinutes: z.number().optional().describe("Estimated duration in minutes")
1351
+ },
1352
+ async (options) => jsonResponse(await of.createTask(options))
1353
+ );
1354
+ server.tool(
1355
+ "update_task",
1356
+ "Update an existing task",
1357
+ {
1358
+ idOrName: z.string().describe("Task ID or name"),
1359
+ name: z.string().optional().describe("New task name"),
1360
+ note: z.string().optional().describe("New task note"),
1361
+ project: z.string().optional().describe("Move to project"),
1362
+ tags: z.array(z.string()).optional().describe("Replace tags"),
1363
+ defer: z.string().optional().describe("New defer date (ISO 8601)"),
1364
+ due: z.string().optional().describe("New due date (ISO 8601)"),
1365
+ flagged: z.boolean().optional().describe("Flag/unflag the task"),
1366
+ estimatedMinutes: z.number().optional().describe("New estimated duration"),
1367
+ completed: z.boolean().optional().describe("Mark complete/incomplete")
1368
+ },
1369
+ async ({ idOrName, ...options }) => jsonResponse(await of.updateTask(idOrName, options))
1370
+ );
1371
+ server.tool(
1372
+ "delete_task",
1373
+ "Delete a task",
1374
+ { idOrName: z.string().describe("Task ID or name") },
1375
+ async ({ idOrName }) => {
1376
+ await of.deleteTask(idOrName);
1377
+ return jsonResponse({ deleted: true });
1378
+ }
1379
+ );
1380
+ server.tool(
1381
+ "search_tasks",
1382
+ "Search tasks by name or note content",
1383
+ { query: z.string().describe("Search query") },
1384
+ async ({ query }) => jsonResponse(await of.searchTasks(query))
1385
+ );
1386
+ server.tool(
1387
+ "get_task_stats",
1388
+ "Get task statistics",
1389
+ {},
1390
+ async () => jsonResponse(await of.getTaskStats())
1391
+ );
1392
+ server.tool(
1393
+ "list_inbox",
1394
+ "List all inbox tasks",
1395
+ {},
1396
+ async () => jsonResponse(await of.listInboxTasks())
1397
+ );
1398
+ server.tool(
1399
+ "get_inbox_count",
1400
+ "Get the number of inbox tasks",
1401
+ {},
1402
+ async () => jsonResponse({ count: await of.getInboxCount() })
1403
+ );
1404
+ server.tool(
1405
+ "list_projects",
1406
+ "List projects with optional filtering",
1407
+ {
1408
+ includeDropped: z.boolean().optional().describe("Include dropped projects"),
1409
+ status: z.enum(["active", "on hold", "dropped"]).optional().describe("Filter by status"),
1410
+ folder: z.string().optional().describe("Filter by folder name")
1411
+ },
1412
+ async (filters) => jsonResponse(await of.listProjects(filters))
1413
+ );
1414
+ server.tool(
1415
+ "get_project",
1416
+ "Get a specific project by ID or name",
1417
+ { idOrName: z.string().describe("Project ID or name") },
1418
+ async ({ idOrName }) => jsonResponse(await of.getProject(idOrName))
1419
+ );
1420
+ server.tool(
1421
+ "create_project",
1422
+ "Create a new project",
1423
+ {
1424
+ name: z.string().describe("Project name"),
1425
+ note: z.string().optional().describe("Project note"),
1426
+ folder: z.string().optional().describe("Folder to create project in"),
1427
+ sequential: z.boolean().optional().describe("Sequential project (tasks must be done in order)"),
1428
+ tags: z.array(z.string()).optional().describe("Tags to assign"),
1429
+ status: z.enum(["active", "on hold", "dropped"]).optional().describe("Initial status")
1430
+ },
1431
+ async (options) => jsonResponse(await of.createProject(options))
1432
+ );
1433
+ server.tool(
1434
+ "update_project",
1435
+ "Update an existing project",
1436
+ {
1437
+ idOrName: z.string().describe("Project ID or name"),
1438
+ name: z.string().optional().describe("New project name"),
1439
+ note: z.string().optional().describe("New project note"),
1440
+ folder: z.string().optional().describe("Move to folder"),
1441
+ sequential: z.boolean().optional().describe("Set sequential/parallel"),
1442
+ tags: z.array(z.string()).optional().describe("Replace tags"),
1443
+ status: z.enum(["active", "on hold", "dropped"]).optional().describe("New status")
1444
+ },
1445
+ async ({ idOrName, ...options }) => jsonResponse(await of.updateProject(idOrName, options))
1446
+ );
1447
+ server.tool(
1448
+ "delete_project",
1449
+ "Delete a project",
1450
+ { idOrName: z.string().describe("Project ID or name") },
1451
+ async ({ idOrName }) => {
1452
+ await of.deleteProject(idOrName);
1453
+ return jsonResponse({ deleted: true });
1454
+ }
1455
+ );
1456
+ server.tool(
1457
+ "get_project_stats",
1458
+ "Get project statistics",
1459
+ {},
1460
+ async () => jsonResponse(await of.getProjectStats())
1461
+ );
1462
+ server.tool(
1463
+ "list_perspectives",
1464
+ "List all available perspectives",
1465
+ {},
1466
+ async () => jsonResponse(await of.listPerspectives())
1467
+ );
1468
+ server.tool(
1469
+ "get_perspective_tasks",
1470
+ "Get tasks from a specific perspective",
1471
+ { name: z.string().describe("Perspective name (e.g., Inbox, Flagged, or custom perspective)") },
1472
+ async ({ name }) => jsonResponse(await of.getPerspectiveTasks(name))
1473
+ );
1474
+ server.tool(
1475
+ "list_tags",
1476
+ "List all tags with optional filtering and sorting",
1477
+ {
1478
+ unusedDays: z.number().optional().describe("Only show tags unused for this many days"),
1479
+ sortBy: z.enum(["name", "usage", "activity"]).optional().describe("Sort order"),
1480
+ activeOnly: z.boolean().optional().describe("Only count active tasks")
1481
+ },
1482
+ async (options) => jsonResponse(await of.listTags(options))
1483
+ );
1484
+ server.tool(
1485
+ "get_tag",
1486
+ "Get a specific tag by ID or name",
1487
+ { idOrName: z.string().describe('Tag ID, name, or path (e.g., "Parent/Child")') },
1488
+ async ({ idOrName }) => jsonResponse(await of.getTag(idOrName))
1489
+ );
1490
+ server.tool(
1491
+ "create_tag",
1492
+ "Create a new tag",
1493
+ {
1494
+ name: z.string().describe("Tag name"),
1495
+ parent: z.string().optional().describe("Parent tag name or path"),
1496
+ status: z.enum(["active", "on hold", "dropped"]).optional().describe("Initial status")
1497
+ },
1498
+ async (options) => jsonResponse(await of.createTag(options))
1499
+ );
1500
+ server.tool(
1501
+ "update_tag",
1502
+ "Update an existing tag",
1503
+ {
1504
+ idOrName: z.string().describe("Tag ID, name, or path"),
1505
+ name: z.string().optional().describe("New tag name"),
1506
+ status: z.enum(["active", "on hold", "dropped"]).optional().describe("New status")
1507
+ },
1508
+ async ({ idOrName, ...options }) => jsonResponse(await of.updateTag(idOrName, options))
1509
+ );
1510
+ server.tool(
1511
+ "delete_tag",
1512
+ "Delete a tag",
1513
+ { idOrName: z.string().describe("Tag ID, name, or path") },
1514
+ async ({ idOrName }) => {
1515
+ await of.deleteTag(idOrName);
1516
+ return jsonResponse({ deleted: true });
1517
+ }
1518
+ );
1519
+ server.tool(
1520
+ "get_tag_stats",
1521
+ "Get tag statistics",
1522
+ {},
1523
+ async () => jsonResponse(await of.getTagStats())
1524
+ );
1525
+ server.tool(
1526
+ "list_folders",
1527
+ "List all folders",
1528
+ { includeDropped: z.boolean().optional().describe("Include dropped folders") },
1529
+ async (filters) => jsonResponse(await of.listFolders(filters))
1530
+ );
1531
+ server.tool(
1532
+ "get_folder",
1533
+ "Get a specific folder by ID or name",
1534
+ {
1535
+ idOrName: z.string().describe("Folder ID or name"),
1536
+ includeDropped: z.boolean().optional().describe("Include dropped children")
1537
+ },
1538
+ async ({ idOrName, includeDropped }) => jsonResponse(await of.getFolder(idOrName, { includeDropped }))
1539
+ );
1540
+ async function runMcpServer() {
1541
+ const transport = new StdioServerTransport();
1542
+ await server.connect(transport);
1543
+ }
1544
+
1545
+ // src/commands/mcp.ts
1546
+ function createMcpCommand() {
1547
+ const cmd = new Command8("mcp").description("Run OmniFocus MCP server");
1548
+ cmd.action(async () => {
1549
+ await runMcpServer();
1550
+ });
1551
+ return cmd;
1552
+ }
1553
+
1306
1554
  // src/cli.ts
1307
- var program = new Command8();
1308
- program.name("of").description("A command-line interface for OmniFocus on macOS").version("2.2.1").option("-c, --compact", "Minified JSON output (single line)").hook("preAction", (thisCommand) => {
1555
+ var program = new Command9();
1556
+ program.name("of").description("A command-line interface for OmniFocus on macOS").version("2.3.0").option("-c, --compact", "Minified JSON output (single line)").hook("preAction", (thisCommand) => {
1309
1557
  const options = thisCommand.opts();
1310
1558
  setOutputOptions({
1311
1559
  compact: options.compact
@@ -1318,6 +1566,7 @@ program.addCommand(createSearchCommand());
1318
1566
  program.addCommand(createPerspectiveCommand());
1319
1567
  program.addCommand(createTagCommand());
1320
1568
  program.addCommand(createFolderCommand());
1569
+ program.addCommand(createMcpCommand());
1321
1570
  program.parseAsync().catch(() => {
1322
1571
  process.exit(1);
1323
1572
  });
package/dist/cli.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/cli.ts","../src/lib/output.ts","../src/commands/task.ts","../src/lib/errors.ts","../src/lib/command-utils.ts","../src/lib/omnifocus.ts","../src/lib/dates.ts","../src/commands/project.ts","../src/commands/inbox.ts","../src/commands/search.ts","../src/commands/perspective.ts","../src/commands/tag.ts","../src/commands/folder.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createTaskCommand } from './commands/task.js';\nimport { createProjectCommand } from './commands/project.js';\nimport { createInboxCommand } from './commands/inbox.js';\nimport { createSearchCommand } from './commands/search.js';\nimport { createPerspectiveCommand } from './commands/perspective.js';\nimport { createTagCommand } from './commands/tag.js';\nimport { createFolderCommand } from './commands/folder.js';\n\nconst program = new Command();\n\nprogram\n .name('of')\n .description('A command-line interface for OmniFocus on macOS')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n });\n });\n\nprogram.addCommand(createTaskCommand());\nprogram.addCommand(createProjectCommand());\nprogram.addCommand(createInboxCommand());\nprogram.addCommand(createSearchCommand());\nprogram.addCommand(createPerspectiveCommand());\nprogram.addCommand(createTagCommand());\nprogram.addCommand(createFolderCommand());\n\nprogram.parseAsync().catch(() => {\n process.exit(1);\n});\n","export interface OutputOptions {\n compact?: boolean;\n}\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const mergedOptions = { ...globalOutputOptions, ...options };\n const jsonString = mergedOptions.compact ? JSON.stringify(data) : JSON.stringify(data, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\nimport type { TaskFilters, UpdateTaskOptions } from '../types.js';\n\nexport function createTaskCommand(): Command {\n const command = new Command('task');\n command.description('Manage OmniFocus tasks');\n\n command\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option('-f, --flagged', 'Show only flagged tasks')\n .option('-p, --project <name>', 'Filter by project')\n .option('-t, --tag <name>', 'Filter by tag')\n .option('-c, --completed', 'Include completed tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: TaskFilters = {\n includeCompleted: options.completed,\n ...(options.flagged && { flagged: true }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tag: options.tag }),\n };\n const tasks = await of.listTasks(filters);\n outputJson(tasks);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new task')\n .option('-p, --project <name>', 'Assign to project')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n project: options.project,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing task')\n .option('-n, --name <name>', 'New name')\n .option('--note <text>', 'New note')\n .option('-p, --project <name>', 'Move to project')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flag', 'Flag the task')\n .option('-F, --unflag', 'Unflag the task')\n .option('-c, --complete', 'Mark as completed')\n .option('-C, --incomplete', 'Mark as incomplete')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTaskOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tags: options.tag }),\n ...(options.due !== undefined && {\n due: options.due ? parseDateTime(options.due) : null,\n }),\n ...(options.defer !== undefined && {\n defer: options.defer ? parseDateTime(options.defer) : null,\n }),\n ...(options.flag && { flagged: true }),\n ...(options.unflag && { flagged: false }),\n ...(options.complete && { completed: true }),\n ...(options.incomplete && { completed: false }),\n ...(options.estimate !== undefined && { estimatedMinutes: options.estimate }),\n };\n const task = await of.updateTask(idOrName, updates);\n outputJson(task);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a task')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTask(idOrName);\n outputJson({ message: 'Task deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View task details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const task = await of.getTask(idOrName);\n outputJson(task);\n })\n );\n\n command\n .command('stats')\n .description('Show task statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTaskStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { outputJson } from './output.js';\n\nexport class OmniFocusCliError extends Error {\n constructor(\n message: string,\n public statusCode: number = 500\n ) {\n super(message);\n this.name = 'OmniFocusCliError';\n }\n}\n\nexport function handleError(error: unknown): never {\n let name = 'unknown_error';\n let detail = 'An unknown error occurred';\n let statusCode = 500;\n\n if (error instanceof OmniFocusCliError) {\n name = 'cli_error';\n detail = error.message;\n statusCode = error.statusCode;\n } else if (error instanceof Error) {\n name = 'omnifocus_error';\n detail = error.message;\n\n if (detail.includes('not found')) {\n statusCode = 404;\n } else if (detail.includes('Multiple')) {\n statusCode = 400;\n }\n }\n\n outputJson({ error: { name, detail, statusCode } });\n process.exit(1);\n}\n","import { handleError } from './errors.js';\n\nexport function withErrorHandling<T extends unknown[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<void> {\n return async (...args: T) => {\n try {\n await fn(...args);\n } catch (error) {\n handleError(error);\n }\n };\n}\n","import { execFile } from 'child_process';\nimport { writeFile, unlink } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { promisify } from 'util';\nimport type {\n Task,\n Project,\n TaskFilters,\n ProjectFilters,\n CreateTaskOptions,\n UpdateTaskOptions,\n CreateProjectOptions,\n UpdateProjectOptions,\n Perspective,\n Tag,\n TagListOptions,\n TagStats,\n TaskStats,\n ProjectStats,\n CreateTagOptions,\n UpdateTagOptions,\n Folder,\n FolderFilters,\n} from '../types.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport class OmniFocus {\n private readonly PROJECT_STATUS_MAP = {\n active: 'Active',\n 'on hold': 'OnHold',\n dropped: 'Dropped',\n } as const;\n\n private readonly OMNI_HELPERS = `\n function serializeTask(task) {\n const containingProject = task.containingProject;\n const tagNames = task.tags.map(t => t.name);\n\n return {\n id: task.id.primaryKey,\n name: task.name,\n note: task.note || null,\n completed: task.completed,\n dropped: task.dropped,\n effectivelyActive: task.effectiveActive,\n flagged: task.flagged,\n project: containingProject ? containingProject.name : null,\n tags: tagNames,\n defer: task.deferDate ? task.deferDate.toISOString() : null,\n due: task.dueDate ? task.dueDate.toISOString() : null,\n estimatedMinutes: task.estimatedMinutes || null,\n completionDate: task.completionDate ? task.completionDate.toISOString() : null,\n added: task.added ? task.added.toISOString() : null,\n modified: task.modified ? task.modified.toISOString() : null\n };\n }\n\n function serializeProject(project) {\n const parentFolder = project.parentFolder;\n const allTasks = project.flattenedTasks;\n const remainingTasks = allTasks.filter(t => !t.completed);\n const tagNames = project.tags.map(t => t.name);\n\n return {\n id: project.id.primaryKey,\n name: project.name,\n note: project.note || null,\n status: projectStatusToString(project.status),\n folder: parentFolder ? parentFolder.name : null,\n sequential: project.sequential,\n taskCount: allTasks.length,\n remainingCount: remainingTasks.length,\n tags: tagNames\n };\n }\n\n function findTask(idOrName) {\n for (const task of flattenedTasks) {\n if (task.id.primaryKey === idOrName || task.name === idOrName) {\n return task;\n }\n }\n throw new Error(\"Task not found: \" + idOrName);\n }\n\n function findProject(idOrName) {\n for (const project of flattenedProjects) {\n if (project.id.primaryKey === idOrName || project.name === idOrName) {\n return project;\n }\n }\n throw new Error(\"Project not found: \" + idOrName);\n }\n\n function getTagPath(tag) {\n const parts = [tag.name];\n let current = tag.parent;\n while (current) {\n parts.unshift(current.name);\n current = current.parent;\n }\n return parts.join('/');\n }\n\n function findTag(idOrName) {\n for (const tag of flattenedTags) {\n if (tag.id.primaryKey === idOrName) {\n return tag;\n }\n }\n\n if (idOrName.includes('/')) {\n for (const tag of flattenedTags) {\n if (getTagPath(tag) === idOrName) {\n return tag;\n }\n }\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n const matches = flattenedTags.filter(tag => tag.name === idOrName);\n\n if (matches.length === 0) {\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n if (matches.length > 1) {\n const paths = matches.map(getTagPath);\n throw new Error(\"Multiple tags found with name '\" + idOrName + \"'. Please use full path:\\\\n \" + paths.join('\\\\n ') + \"\\\\nOr use tag ID: \" + matches.map(t => t.id.primaryKey).join(', '));\n }\n\n return matches[0];\n }\n\n function findByName(collection, name, typeName) {\n for (const item of collection) {\n if (item.name === name) {\n return item;\n }\n }\n throw new Error(typeName + \" not found: \" + name);\n }\n\n function assignTags(target, tagNames) {\n for (const tagName of tagNames) {\n const tag = findTag(tagName);\n target.addTag(tag);\n }\n }\n\n function replaceTagsOn(target, tagNames) {\n target.clearTags();\n assignTags(target, tagNames);\n }\n\n function statusToString(status, StatusEnum) {\n if (status === StatusEnum.Active) return 'active';\n if (status === StatusEnum.OnHold) return 'on hold';\n if (status === StatusEnum.Dropped) return 'dropped';\n if (status === StatusEnum.Done) return 'done';\n return 'dropped';\n }\n\n function stringToStatus(str, StatusEnum) {\n if (str === 'active') return StatusEnum.Active;\n if (str === 'on hold') return StatusEnum.OnHold;\n return StatusEnum.Dropped;\n }\n\n const projectStatusToString = (status) => statusToString(status, Project.Status);\n const tagStatusToString = (status) => statusToString(status, Tag.Status);\n const folderStatusToString = (status) => {\n if (status === Folder.Status.Active) return 'active';\n return 'dropped';\n };\n const stringToProjectStatus = (str) => stringToStatus(str, Project.Status);\n const stringToTagStatus = (str) => stringToStatus(str, Tag.Status);\n\n function serializeFolder(folder, includeDropped = false) {\n let childFolders = folder.folders;\n if (!includeDropped) {\n childFolders = childFolders.filter(c => c.effectiveActive);\n }\n\n return {\n id: folder.id.primaryKey,\n name: folder.name,\n status: folderStatusToString(folder.status),\n effectivelyActive: folder.effectiveActive,\n parent: folder.parent ? folder.parent.name : null,\n projectCount: folder.projects.length,\n remainingProjectCount: folder.projects.filter(p => p.effectiveActive).length,\n folderCount: folder.folders.length,\n children: childFolders.map(child => serializeFolder(child, includeDropped))\n };\n }\n\n function computeTopItems(items, keyFn, topN = 5) {\n return items\n .sort((a, b) => b[keyFn] - a[keyFn])\n .slice(0, topN)\n .map(item => ({ name: item.name, [keyFn]: item[keyFn] }));\n }\n\n function computeAverage(total, count) {\n return count > 0 ? Math.round((total / count) * 10) / 10 : 0;\n }\n\n function serializeTag(tag, activeOnly = false) {\n const tasks = tag.tasks;\n const remainingTasks = tag.remainingTasks;\n const includedTasks = activeOnly ? remainingTasks : tasks;\n\n const dates = [];\n if (tag.added) dates.push(tag.added);\n if (tag.modified) dates.push(tag.modified);\n\n for (const task of includedTasks) {\n if (task.added) dates.push(task.added);\n if (task.modified) dates.push(task.modified);\n if (!activeOnly && task.completionDate) dates.push(task.completionDate);\n if (!activeOnly && task.effectiveCompletionDate) dates.push(task.effectiveCompletionDate);\n }\n\n const lastActivity = dates.length > 0\n ? dates.reduce((latest, current) => current > latest ? current : latest)\n : null;\n\n return {\n id: tag.id.primaryKey,\n name: tag.name,\n taskCount: includedTasks.length,\n remainingTaskCount: remainingTasks.length,\n added: tag.added ? tag.added.toISOString() : null,\n modified: tag.modified ? tag.modified.toISOString() : null,\n lastActivity: lastActivity ? lastActivity.toISOString() : null,\n active: tag.active,\n status: tagStatusToString(tag.status),\n parent: tag.parent ? tag.parent.name : null,\n children: tag.children.map(c => c.name),\n allowsNextAction: tag.allowsNextAction\n };\n }\n `;\n\n private async executeJXA(script: string, timeoutMs = 30000): Promise<string> {\n const tmpFile = join(tmpdir(), `omnifocus-${Date.now()}.js`);\n\n try {\n await writeFile(tmpFile, script, 'utf-8');\n\n const { stdout } = await execFileAsync('osascript', ['-l', 'JavaScript', tmpFile], {\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024,\n });\n\n return stdout.trim();\n } finally {\n try {\n await unlink(tmpFile);\n } catch {\n /* ignore cleanup errors */\n }\n }\n }\n\n private escapeString(str: string): string {\n return str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n }\n\n private wrapOmniScript(omniScript: string): string {\n return `\n const app = Application('OmniFocus');\n app.includeStandardAdditions = true;\n const result = app.evaluateJavascript(${JSON.stringify(omniScript.trim())});\n result;\n `.trim();\n }\n\n private buildTaskFilters(filters: TaskFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeCompleted) {\n conditions.push('if (task.completed) continue;');\n }\n if (!filters.includeDropped) {\n conditions.push('if (!task.effectiveActive) continue;');\n }\n if (filters.flagged) {\n conditions.push('if (!task.flagged) continue;');\n conditions.push('if (task.taskStatus !== Task.Status.Available) continue;');\n }\n if (filters.project) {\n conditions.push(`\n if (!task.containingProject || task.containingProject.name !== \"${this.escapeString(filters.project)}\") {\n continue;\n }\n `);\n }\n if (filters.tag) {\n conditions.push(`\n if (!task.tags.some(t => t.name === \"${this.escapeString(filters.tag)}\")) {\n continue;\n }\n `);\n }\n\n return conditions.join('\\n ');\n }\n\n private buildProjectFilters(filters: ProjectFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeDropped) {\n conditions.push(\n 'if (project.status === Project.Status.Dropped || project.status === Project.Status.Done) continue;'\n );\n conditions.push(\n 'if (project.parentFolder && !project.parentFolder.effectiveActive) continue;'\n );\n }\n if (filters.status) {\n const statusCheck = this.PROJECT_STATUS_MAP[filters.status];\n conditions.push(`if (project.status !== Project.Status.${statusCheck}) continue;`);\n }\n if (filters.folder) {\n conditions.push(\n `if (!project.parentFolder || project.parentFolder.name !== \"${this.escapeString(filters.folder)}\") continue;`\n );\n }\n\n return conditions.join('\\n ');\n }\n\n private buildTaskUpdates(options: UpdateTaskOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`task.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`task.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.flagged !== undefined) {\n updates.push(`task.flagged = ${options.flagged};`);\n }\n if (options.completed !== undefined) {\n updates.push(options.completed ? 'task.markComplete();' : 'task.markIncomplete();');\n }\n if (options.estimatedMinutes !== undefined) {\n updates.push(`task.estimatedMinutes = ${options.estimatedMinutes};`);\n }\n if (options.defer !== undefined) {\n updates.push(\n options.defer\n ? `task.deferDate = new Date(${JSON.stringify(options.defer)});`\n : 'task.deferDate = null;'\n );\n }\n if (options.due !== undefined) {\n updates.push(\n options.due\n ? `task.dueDate = new Date(${JSON.stringify(options.due)});`\n : 'task.dueDate = null;'\n );\n }\n if (options.project !== undefined && options.project) {\n updates.push(`\n const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n moveTasks([task], targetProject);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(task, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildTagUpdates(options: UpdateTagOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`tag.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.status !== undefined) {\n updates.push(`tag.status = stringToTagStatus(\"${options.status}\");`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildProjectUpdates(options: UpdateProjectOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`project.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`project.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.sequential !== undefined) {\n updates.push(`project.sequential = ${options.sequential};`);\n }\n if (options.status !== undefined) {\n updates.push(`project.status = stringToProjectStatus(\"${options.status}\");`);\n }\n if (options.folder !== undefined && options.folder) {\n updates.push(`\n const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n moveProjects([project], targetFolder);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(project, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n async listTasks(filters: TaskFilters = {}): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const task of flattenedTasks) {\n ${this.buildTaskFilters(filters)}\n results.push(serializeTask(task));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTask(options: CreateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.project\n ? `const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n const task = new Task(\"${this.escapeString(options.name)}\", targetProject);`\n : `const task = new Task(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `task.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.flagged ? 'task.flagged = true;' : ''}\n ${options.estimatedMinutes ? `task.estimatedMinutes = ${options.estimatedMinutes};` : ''}\n ${options.defer ? `task.deferDate = new Date(${JSON.stringify(options.defer)});` : ''}\n ${options.due ? `task.dueDate = new Date(${JSON.stringify(options.due)});` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(task, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTask(idOrName: string, options: UpdateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n ${this.buildTaskUpdates(options)}\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTask(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTask(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listProjects(filters: ProjectFilters = {}): Promise<Project[]> {\n const filterCode = this.buildProjectFilters(filters);\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const project of flattenedProjects) {\n ${filterCode}\n results.push(serializeProject(project));\n }\n return JSON.stringify(results);\n })();\n `;\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createProject(options: CreateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.folder\n ? `const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n const project = new Project(\"${this.escapeString(options.name)}\", targetFolder);`\n : `const project = new Project(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `project.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.sequential !== undefined ? `project.sequential = ${options.sequential};` : ''}\n ${options.status ? `project.status = stringToProjectStatus(\"${options.status}\");` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(project, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateProject(idOrName: string, options: UpdateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n ${this.buildProjectUpdates(options)}\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteProject(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findProject(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listInboxTasks(): Promise<Task[]> {\n return this.getPerspectiveTasks('Inbox');\n }\n\n async getInboxCount(): Promise<number> {\n const tasks = await this.getPerspectiveTasks('Inbox');\n return tasks.length;\n }\n\n async searchTasks(query: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const searchQuery = \"${this.escapeString(query)}\".toLowerCase();\n\n for (const task of flattenedTasks) {\n if (task.completed) continue;\n if (!task.effectiveActive) continue;\n\n const name = task.name.toLowerCase();\n const note = (task.note || '').toLowerCase();\n\n if (name.includes(searchQuery) || note.includes(searchQuery)) {\n results.push(serializeTask(task));\n }\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTask(idOrName: string): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProject(idOrName: string): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listPerspectives(): Promise<Perspective[]> {\n const omniScript = `\n (() => {\n const results = [];\n\n const builtInNames = ['Inbox', 'Flagged', 'Forecast', 'Projects', 'Tags', 'Nearby', 'Review'];\n for (const name of builtInNames) {\n results.push({ id: name, name: name });\n }\n\n const customPerspectives = Perspective.Custom.all;\n for (const perspective of customPerspectives) {\n results.push({ id: perspective.name, name: perspective.name });\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getPerspectiveTasks(perspectiveName: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const doc = document;\n const windows = doc.windows;\n\n if (windows.length === 0) {\n throw new Error(\"No OmniFocus window is open. Please open an OmniFocus window and try again.\");\n }\n\n const win = windows[0];\n const perspectiveName = \"${this.escapeString(perspectiveName)}\";\n\n const builtInPerspectives = {\n 'inbox': Perspective.BuiltIn.Inbox,\n 'flagged': Perspective.BuiltIn.Flagged,\n 'forecast': Perspective.BuiltIn.Forecast,\n 'projects': Perspective.BuiltIn.Projects,\n 'tags': Perspective.BuiltIn.Tags,\n 'nearby': Perspective.BuiltIn.Nearby,\n 'review': Perspective.BuiltIn.Review\n };\n\n const lowerName = perspectiveName.toLowerCase();\n if (builtInPerspectives[lowerName]) {\n win.perspective = builtInPerspectives[lowerName];\n } else {\n const customPerspective = Perspective.Custom.byName(perspectiveName);\n if (customPerspective) {\n win.perspective = customPerspective;\n } else {\n throw new Error(\"Perspective not found: \" + perspectiveName);\n }\n }\n\n const content = win.content;\n if (!content) {\n throw new Error(\"No content available in window\");\n }\n\n const tasks = [];\n content.rootNode.apply(node => {\n const obj = node.object;\n if (obj instanceof Task) {\n tasks.push(serializeTask(obj));\n }\n });\n\n return JSON.stringify(tasks);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript), 60000);\n return JSON.parse(output);\n }\n\n async listTags(options: TagListOptions = {}): Promise<Tag[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const now = new Date();\n const activeOnly = ${!!options.activeOnly};\n\n for (const tag of flattenedTags) {\n const serialized = serializeTag(tag, activeOnly);\n results.push(serialized);\n }\n\n ${\n options.unusedDays\n ? `\n const cutoffDate = new Date(now.getTime() - (${options.unusedDays} * 24 * 60 * 60 * 1000));\n const filtered = results.filter(tag => {\n if (!tag.lastActivity) return true;\n return new Date(tag.lastActivity) < cutoffDate;\n });\n return JSON.stringify(filtered);\n `\n : 'return JSON.stringify(results);'\n }\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n const tags = JSON.parse(output);\n\n return this.sortTags(tags, options.sortBy);\n }\n\n private sortTags(tags: Tag[], sortBy: string = 'name'): Tag[] {\n const sortFns: Record<string, (a: Tag, b: Tag) => number> = {\n usage: (a, b) => b.taskCount - a.taskCount,\n activity: (a, b) => {\n if (!a.lastActivity && !b.lastActivity) return 0;\n if (!a.lastActivity) return 1;\n if (!b.lastActivity) return -1;\n return new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime();\n },\n name: (a, b) => a.name.localeCompare(b.name),\n };\n\n return tags.sort(sortFns[sortBy] || sortFns.name);\n }\n\n async getTagStats(): Promise<TagStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTags = [];\n for (const tag of flattenedTags) {\n allTags.push(serializeTag(tag));\n }\n\n const activeTags = allTags.filter(t => t.active);\n const tagsWithTasks = allTags.filter(t => t.taskCount > 0);\n const unusedTags = allTags.filter(t => t.taskCount === 0);\n\n const totalTasks = tagsWithTasks.reduce((sum, t) => sum + t.taskCount, 0);\n const avgTasksPerTag = computeAverage(totalTasks, tagsWithTasks.length);\n\n const mostUsedTags = computeTopItems(allTags, 'taskCount');\n const leastUsedTags = computeTopItems(\n tagsWithTasks.map(t => ({ ...t, taskCount: -t.taskCount })),\n 'taskCount'\n ).map(t => ({ name: t.name, taskCount: -t.taskCount }));\n\n const now = new Date();\n const thirtyDaysAgo = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n const staleTags = allTags\n .filter(t => t.lastActivity && new Date(t.lastActivity) < thirtyDaysAgo)\n .map(t => ({\n name: t.name,\n daysSinceActivity: Math.floor((now - new Date(t.lastActivity)) / (24 * 60 * 60 * 1000))\n }))\n .sort((a, b) => b.daysSinceActivity - a.daysSinceActivity);\n\n return JSON.stringify({\n totalTags: allTags.length,\n activeTags: activeTags.length,\n tagsWithTasks: tagsWithTasks.length,\n unusedTags: unusedTags.length,\n avgTasksPerTag,\n mostUsedTags,\n leastUsedTags,\n staleTags\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTag(options: CreateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.parent\n ? `const parentTag = findTag(\"${this.escapeString(options.parent)}\");\n const tag = new Tag(\"${this.escapeString(options.name)}\", parentTag);`\n : `const tag = new Tag(\"${this.escapeString(options.name)}\", tags.beginning);`\n }\n\n ${options.status ? `tag.status = stringToTagStatus(\"${options.status}\");` : ''}\n\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTag(idOrName: string): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTag(idOrName: string, options: UpdateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n ${this.buildTagUpdates(options)}\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTag(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTag(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async getTaskStats(): Promise<TaskStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTasks = Array.from(flattenedTasks);\n const now = new Date();\n\n const activeTasks = allTasks.filter(t => !t.completed && t.effectiveActive);\n const completedTasks = allTasks.filter(t => t.completed);\n const flaggedTasks = activeTasks.filter(t => t.flagged);\n const overdueActiveTasks = activeTasks.filter(t => t.dueDate && t.dueDate < now);\n\n const tasksWithEstimates = allTasks.filter(t => t.estimatedMinutes && t.estimatedMinutes > 0);\n const totalEstimatedMinutes = tasksWithEstimates.reduce((sum, t) => sum + (t.estimatedMinutes || 0), 0);\n const avgEstimatedMinutes = tasksWithEstimates.length > 0\n ? Math.round(totalEstimatedMinutes / tasksWithEstimates.length)\n : null;\n\n const totalNonDropped = allTasks.filter(t => t.effectiveActive || t.completed).length;\n const completionRate = totalNonDropped > 0\n ? Math.round((completedTasks.length / totalNonDropped) * 100)\n : 0;\n\n const projectCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n const projectName = task.containingProject ? task.containingProject.name : 'Inbox';\n projectCounts[projectName] = (projectCounts[projectName] || 0) + 1;\n }\n const tasksByProject = computeTopItems(\n Object.entries(projectCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n const tagCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n for (const tag of task.tags) {\n tagCounts[tag.name] = (tagCounts[tag.name] || 0) + 1;\n }\n }\n const tasksByTag = computeTopItems(\n Object.entries(tagCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n return JSON.stringify({\n totalTasks: allTasks.length,\n activeTasks: activeTasks.length,\n completedTasks: completedTasks.length,\n flaggedTasks: flaggedTasks.length,\n overdueActiveTasks: overdueActiveTasks.length,\n avgEstimatedMinutes,\n tasksWithEstimates: tasksWithEstimates.length,\n completionRate,\n tasksByProject,\n tasksByTag\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProjectStats(): Promise<ProjectStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allProjects = Array.from(flattenedProjects);\n\n function isProjectEffectivelyActive(p) {\n if (p.status === Project.Status.Dropped || p.status === Project.Status.Done) return false;\n if (p.parentFolder && !p.parentFolder.effectiveActive) return false;\n return true;\n }\n\n const effectivelyActiveProjects = allProjects.filter(isProjectEffectivelyActive);\n const activeProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.Active);\n const onHoldProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.OnHold);\n const droppedProjects = allProjects.filter(p => p.status === Project.Status.Dropped);\n const doneProjects = allProjects.filter(p => p.status === Project.Status.Done);\n const sequentialProjects = effectivelyActiveProjects.filter(p => p.sequential);\n const parallelProjects = effectivelyActiveProjects.filter(p => !p.sequential);\n\n const totalTasks = effectivelyActiveProjects.reduce((sum, p) => sum + p.flattenedTasks.length, 0);\n const totalRemaining = effectivelyActiveProjects.reduce((sum, p) => {\n return sum + p.flattenedTasks.filter(t => !t.completed).length;\n }, 0);\n\n const avgTasksPerProject = computeAverage(totalTasks, effectivelyActiveProjects.length);\n const avgRemainingPerProject = computeAverage(totalRemaining, effectivelyActiveProjects.length);\n\n const completionRates = effectivelyActiveProjects\n .filter(p => p.flattenedTasks.length > 0)\n .map(p => {\n const total = p.flattenedTasks.length;\n const completed = p.flattenedTasks.filter(t => t.completed).length;\n return (completed / total) * 100;\n });\n\n const avgCompletionRate = completionRates.length > 0\n ? Math.round(completionRates.reduce((sum, rate) => sum + rate, 0) / completionRates.length)\n : 0;\n\n const projectsWithMostTasks = computeTopItems(\n effectivelyActiveProjects.map(p => ({ name: p.name, taskCount: p.flattenedTasks.length })),\n 'taskCount'\n );\n\n const projectsWithMostRemaining = computeTopItems(\n effectivelyActiveProjects\n .map(p => ({ name: p.name, remainingCount: p.flattenedTasks.filter(t => !t.completed).length }))\n .filter(p => p.remainingCount > 0),\n 'remainingCount'\n );\n\n return JSON.stringify({\n totalProjects: allProjects.length,\n activeProjects: activeProjects.length,\n onHoldProjects: onHoldProjects.length,\n droppedProjects: droppedProjects.length,\n doneProjects: doneProjects.length,\n sequentialProjects: sequentialProjects.length,\n parallelProjects: parallelProjects.length,\n avgTasksPerProject,\n avgRemainingPerProject,\n avgCompletionRate,\n projectsWithMostTasks,\n projectsWithMostRemaining\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listFolders(filters: FolderFilters = {}): Promise<Folder[]> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n const results = [];\n for (const folder of folders) {\n if (!includeDropped && !folder.effectiveActive) continue;\n results.push(serializeFolder(folder, includeDropped));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getFolder(idOrName: string, filters: FolderFilters = {}): Promise<Folder> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n\n function findFolder(idOrName) {\n for (const folder of flattenedFolders) {\n if (folder.id.primaryKey === idOrName || folder.name === idOrName) {\n return folder;\n }\n }\n throw new Error(\"Folder not found: \" + idOrName);\n }\n\n const folder = findFolder(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeFolder(folder, includeDropped));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n}\n","import dayjs from 'dayjs';\nimport { OmniFocusCliError } from './errors.js';\n\nexport function parseDateTime(input: string): string {\n const d = dayjs(input);\n if (!d.isValid()) {\n throw new OmniFocusCliError(`Invalid date: ${input}`, 400);\n }\n return d.toISOString();\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { ProjectFilters, UpdateProjectOptions } from '../types.js';\n\nexport function createProjectCommand(): Command {\n const command = new Command('project');\n command.description('Manage OmniFocus projects');\n\n command\n .command('list')\n .alias('ls')\n .description('List projects')\n .option('-f, --folder <name>', 'Filter by folder')\n .option('-s, --status <status>', 'Filter by status (active, on hold, dropped)')\n .option('-d, --dropped', 'Include dropped projects')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: ProjectFilters = {\n includeDropped: options.dropped,\n ...(options.folder && { folder: options.folder }),\n ...(options.status && { status: options.status }),\n };\n const projects = await of.listProjects(filters);\n outputJson(projects);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new project')\n .option('-f, --folder <name>', 'Assign to folder')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-s, --sequential', 'Make it a sequential project')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const project = await of.createProject({\n name,\n note: options.note,\n folder: options.folder,\n tags: options.tag,\n sequential: options.sequential,\n status: options.status,\n });\n outputJson(project);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing project')\n .option('-n, --name <name>', 'Rename project')\n .option('--note <text>', 'New note')\n .option('-f, --folder <name>', 'Move to folder')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-s, --sequential', 'Make it sequential')\n .option('-p, --parallel', 'Make it parallel')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateProjectOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.folder && { folder: options.folder }),\n ...(options.tag && { tags: options.tag }),\n ...(options.sequential && { sequential: true }),\n ...(options.parallel && { sequential: false }),\n ...(options.status && { status: options.status }),\n };\n const project = await of.updateProject(idOrName, updates);\n outputJson(project);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a project')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteProject(idOrName);\n outputJson({ message: 'Project deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View project details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const project = await of.getProject(idOrName);\n outputJson(project);\n })\n );\n\n command\n .command('stats')\n .description('Show project statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getProjectStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\n\nexport function createInboxCommand(): Command {\n const command = new Command('inbox');\n command.description('Manage OmniFocus inbox');\n\n command\n .command('list')\n .alias('ls')\n .description('List inbox tasks')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const tasks = await of.listInboxTasks();\n outputJson(tasks);\n })\n );\n\n command\n .command('count')\n .description('Get inbox count')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const count = await of.getInboxCount();\n outputJson({ count });\n })\n );\n\n command\n .command('add <name>')\n .description('Add a task to inbox')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createSearchCommand(): Command {\n const command = new Command('search');\n command.description('Search tasks by name or note');\n command.argument('<query>', 'Search query');\n\n command.action(\n withErrorHandling(async (query) => {\n const of = new OmniFocus();\n const tasks = await of.searchTasks(query);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createPerspectiveCommand(): Command {\n const command = new Command('perspective');\n command.description('Manage OmniFocus perspectives');\n\n command\n .command('list')\n .alias('ls')\n .description('List all perspectives')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const perspectives = await of.listPerspectives();\n outputJson(perspectives);\n })\n );\n\n command\n .command('view <name>')\n .description('View tasks in a perspective')\n .action(\n withErrorHandling(async (name) => {\n const of = new OmniFocus();\n const tasks = await of.getPerspectiveTasks(name);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { UpdateTagOptions } from '../types.js';\n\nexport function createTagCommand(): Command {\n const command = new Command('tag');\n command.description('Manage and analyze OmniFocus tags');\n\n command\n .command('list')\n .alias('ls')\n .description('List tags with usage information')\n .option('-u, --unused-days <days>', 'Show tags unused for N days', parseInt)\n .option('-s, --sort <field>', 'Sort by: name, usage, activity (default: name)', 'name')\n .option('-a, --active-only', 'Only count active (incomplete) tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const tags = await of.listTags({\n unusedDays: options.unusedDays,\n sortBy: options.sort,\n activeOnly: options.activeOnly,\n });\n outputJson(tags);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new tag')\n .option('-p, --parent <name>', 'Create as child of parent tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const tag = await of.createTag({\n name,\n parent: options.parent,\n status: options.status,\n });\n outputJson(tag);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View tag details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const tag = await of.getTag(idOrName);\n outputJson(tag);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing tag')\n .option('-n, --name <name>', 'Rename tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTagOptions = {\n ...(options.name && { name: options.name }),\n ...(options.status && { status: options.status }),\n };\n const tag = await of.updateTag(idOrName, updates);\n outputJson(tag);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a tag')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTag(idOrName);\n outputJson({ message: 'Tag deleted successfully' });\n })\n );\n\n command\n .command('stats')\n .description('Show tag usage statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTagStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { FolderFilters } from '../types.js';\n\nexport function createFolderCommand(): Command {\n const command = new Command('folder');\n command.description('View OmniFocus folder hierarchy');\n\n command\n .command('list')\n .alias('ls')\n .description('List top-level folders with nested children')\n .option('-d, --dropped', 'Include dropped folders')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const folders = await of.listFolders({ includeDropped: options.dropped });\n outputJson(folders);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View folder details and children')\n .option('-d, --dropped', 'Include dropped child folders')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const filters: FolderFilters = { includeDropped: options.dropped };\n const folder = await of.getFolder(idOrName, filters);\n outputJson(folder);\n })\n );\n\n return command;\n}\n"],"mappings":"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","names":["Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command","Command"]}
1
+ {"version":3,"sources":["../src/cli.ts","../src/lib/output.ts","../src/commands/task.ts","../src/lib/errors.ts","../src/lib/command-utils.ts","../src/lib/omnifocus.ts","../src/lib/dates.ts","../src/commands/project.ts","../src/commands/inbox.ts","../src/commands/search.ts","../src/commands/perspective.ts","../src/commands/tag.ts","../src/commands/folder.ts","../src/commands/mcp.ts","../src/mcp/server.ts"],"sourcesContent":["#!/usr/bin/env bun\n\nimport { Command } from 'commander';\nimport { setOutputOptions } from './lib/output.js';\nimport { createTaskCommand } from './commands/task.js';\nimport { createProjectCommand } from './commands/project.js';\nimport { createInboxCommand } from './commands/inbox.js';\nimport { createSearchCommand } from './commands/search.js';\nimport { createPerspectiveCommand } from './commands/perspective.js';\nimport { createTagCommand } from './commands/tag.js';\nimport { createFolderCommand } from './commands/folder.js';\nimport { createMcpCommand } from './commands/mcp.js';\n\nconst program = new Command();\n\nprogram\n .name('of')\n .description('A command-line interface for OmniFocus on macOS')\n .version(__VERSION__)\n .option('-c, --compact', 'Minified JSON output (single line)')\n .hook('preAction', (thisCommand) => {\n const options = thisCommand.opts();\n setOutputOptions({\n compact: options.compact,\n });\n });\n\nprogram.addCommand(createTaskCommand());\nprogram.addCommand(createProjectCommand());\nprogram.addCommand(createInboxCommand());\nprogram.addCommand(createSearchCommand());\nprogram.addCommand(createPerspectiveCommand());\nprogram.addCommand(createTagCommand());\nprogram.addCommand(createFolderCommand());\nprogram.addCommand(createMcpCommand());\n\nprogram.parseAsync().catch(() => {\n process.exit(1);\n});\n","export interface OutputOptions {\n compact?: boolean;\n}\n\nlet globalOutputOptions: OutputOptions = {};\n\nexport function setOutputOptions(options: OutputOptions): void {\n globalOutputOptions = options;\n}\n\nexport function outputJson(data: unknown, options: OutputOptions = {}): void {\n const mergedOptions = { ...globalOutputOptions, ...options };\n const jsonString = mergedOptions.compact ? JSON.stringify(data) : JSON.stringify(data, null, 2);\n\n console.log(jsonString);\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\nimport type { TaskFilters, UpdateTaskOptions } from '../types.js';\n\nexport function createTaskCommand(): Command {\n const command = new Command('task');\n command.description('Manage OmniFocus tasks');\n\n command\n .command('list')\n .alias('ls')\n .description('List tasks')\n .option('-f, --flagged', 'Show only flagged tasks')\n .option('-p, --project <name>', 'Filter by project')\n .option('-t, --tag <name>', 'Filter by tag')\n .option('-c, --completed', 'Include completed tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: TaskFilters = {\n includeCompleted: options.completed,\n ...(options.flagged && { flagged: true }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tag: options.tag }),\n };\n const tasks = await of.listTasks(filters);\n outputJson(tasks);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new task')\n .option('-p, --project <name>', 'Assign to project')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n project: options.project,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing task')\n .option('-n, --name <name>', 'New name')\n .option('--note <text>', 'New note')\n .option('-p, --project <name>', 'Move to project')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flag', 'Flag the task')\n .option('-F, --unflag', 'Unflag the task')\n .option('-c, --complete', 'Mark as completed')\n .option('-C, --incomplete', 'Mark as incomplete')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTaskOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.project && { project: options.project }),\n ...(options.tag && { tags: options.tag }),\n ...(options.due !== undefined && {\n due: options.due ? parseDateTime(options.due) : null,\n }),\n ...(options.defer !== undefined && {\n defer: options.defer ? parseDateTime(options.defer) : null,\n }),\n ...(options.flag && { flagged: true }),\n ...(options.unflag && { flagged: false }),\n ...(options.complete && { completed: true }),\n ...(options.incomplete && { completed: false }),\n ...(options.estimate !== undefined && { estimatedMinutes: options.estimate }),\n };\n const task = await of.updateTask(idOrName, updates);\n outputJson(task);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a task')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTask(idOrName);\n outputJson({ message: 'Task deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View task details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const task = await of.getTask(idOrName);\n outputJson(task);\n })\n );\n\n command\n .command('stats')\n .description('Show task statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTaskStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { outputJson } from './output.js';\n\nexport class OmniFocusCliError extends Error {\n constructor(\n message: string,\n public statusCode: number = 500\n ) {\n super(message);\n this.name = 'OmniFocusCliError';\n }\n}\n\nexport function handleError(error: unknown): never {\n let name = 'unknown_error';\n let detail = 'An unknown error occurred';\n let statusCode = 500;\n\n if (error instanceof OmniFocusCliError) {\n name = 'cli_error';\n detail = error.message;\n statusCode = error.statusCode;\n } else if (error instanceof Error) {\n name = 'omnifocus_error';\n detail = error.message;\n\n if (detail.includes('not found')) {\n statusCode = 404;\n } else if (detail.includes('Multiple')) {\n statusCode = 400;\n }\n }\n\n outputJson({ error: { name, detail, statusCode } });\n process.exit(1);\n}\n","import { handleError } from './errors.js';\n\nexport function withErrorHandling<T extends unknown[], R>(\n fn: (...args: T) => Promise<R>\n): (...args: T) => Promise<void> {\n return async (...args: T) => {\n try {\n await fn(...args);\n } catch (error) {\n handleError(error);\n }\n };\n}\n","import { execFile } from 'child_process';\nimport { writeFile, unlink } from 'fs/promises';\nimport { tmpdir } from 'os';\nimport { join } from 'path';\nimport { promisify } from 'util';\nimport type {\n Task,\n Project,\n TaskFilters,\n ProjectFilters,\n CreateTaskOptions,\n UpdateTaskOptions,\n CreateProjectOptions,\n UpdateProjectOptions,\n Perspective,\n Tag,\n TagListOptions,\n TagStats,\n TaskStats,\n ProjectStats,\n CreateTagOptions,\n UpdateTagOptions,\n Folder,\n FolderFilters,\n} from '../types.js';\n\nconst execFileAsync = promisify(execFile);\n\nexport class OmniFocus {\n private readonly PROJECT_STATUS_MAP = {\n active: 'Active',\n 'on hold': 'OnHold',\n dropped: 'Dropped',\n } as const;\n\n private readonly OMNI_HELPERS = `\n function serializeTask(task) {\n const containingProject = task.containingProject;\n const tagNames = task.tags.map(t => t.name);\n\n return {\n id: task.id.primaryKey,\n name: task.name,\n note: task.note || null,\n completed: task.completed,\n dropped: task.dropped,\n effectivelyActive: task.effectiveActive,\n flagged: task.flagged,\n project: containingProject ? containingProject.name : null,\n tags: tagNames,\n defer: task.deferDate ? task.deferDate.toISOString() : null,\n due: task.dueDate ? task.dueDate.toISOString() : null,\n estimatedMinutes: task.estimatedMinutes || null,\n completionDate: task.completionDate ? task.completionDate.toISOString() : null,\n added: task.added ? task.added.toISOString() : null,\n modified: task.modified ? task.modified.toISOString() : null\n };\n }\n\n function serializeProject(project) {\n const parentFolder = project.parentFolder;\n const allTasks = project.flattenedTasks;\n const remainingTasks = allTasks.filter(t => !t.completed);\n const tagNames = project.tags.map(t => t.name);\n\n return {\n id: project.id.primaryKey,\n name: project.name,\n note: project.note || null,\n status: projectStatusToString(project.status),\n folder: parentFolder ? parentFolder.name : null,\n sequential: project.sequential,\n taskCount: allTasks.length,\n remainingCount: remainingTasks.length,\n tags: tagNames\n };\n }\n\n function findTask(idOrName) {\n for (const task of flattenedTasks) {\n if (task.id.primaryKey === idOrName || task.name === idOrName) {\n return task;\n }\n }\n throw new Error(\"Task not found: \" + idOrName);\n }\n\n function findProject(idOrName) {\n for (const project of flattenedProjects) {\n if (project.id.primaryKey === idOrName || project.name === idOrName) {\n return project;\n }\n }\n throw new Error(\"Project not found: \" + idOrName);\n }\n\n function getTagPath(tag) {\n const parts = [tag.name];\n let current = tag.parent;\n while (current) {\n parts.unshift(current.name);\n current = current.parent;\n }\n return parts.join('/');\n }\n\n function findTag(idOrName) {\n for (const tag of flattenedTags) {\n if (tag.id.primaryKey === idOrName) {\n return tag;\n }\n }\n\n if (idOrName.includes('/')) {\n for (const tag of flattenedTags) {\n if (getTagPath(tag) === idOrName) {\n return tag;\n }\n }\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n const matches = flattenedTags.filter(tag => tag.name === idOrName);\n\n if (matches.length === 0) {\n throw new Error(\"Tag not found: \" + idOrName);\n }\n\n if (matches.length > 1) {\n const paths = matches.map(getTagPath);\n throw new Error(\"Multiple tags found with name '\" + idOrName + \"'. Please use full path:\\\\n \" + paths.join('\\\\n ') + \"\\\\nOr use tag ID: \" + matches.map(t => t.id.primaryKey).join(', '));\n }\n\n return matches[0];\n }\n\n function findByName(collection, name, typeName) {\n for (const item of collection) {\n if (item.name === name) {\n return item;\n }\n }\n throw new Error(typeName + \" not found: \" + name);\n }\n\n function assignTags(target, tagNames) {\n for (const tagName of tagNames) {\n const tag = findTag(tagName);\n target.addTag(tag);\n }\n }\n\n function replaceTagsOn(target, tagNames) {\n target.clearTags();\n assignTags(target, tagNames);\n }\n\n function statusToString(status, StatusEnum) {\n if (status === StatusEnum.Active) return 'active';\n if (status === StatusEnum.OnHold) return 'on hold';\n if (status === StatusEnum.Dropped) return 'dropped';\n if (status === StatusEnum.Done) return 'done';\n return 'dropped';\n }\n\n function stringToStatus(str, StatusEnum) {\n if (str === 'active') return StatusEnum.Active;\n if (str === 'on hold') return StatusEnum.OnHold;\n return StatusEnum.Dropped;\n }\n\n const projectStatusToString = (status) => statusToString(status, Project.Status);\n const tagStatusToString = (status) => statusToString(status, Tag.Status);\n const folderStatusToString = (status) => {\n if (status === Folder.Status.Active) return 'active';\n return 'dropped';\n };\n const stringToProjectStatus = (str) => stringToStatus(str, Project.Status);\n const stringToTagStatus = (str) => stringToStatus(str, Tag.Status);\n\n function serializeFolder(folder, includeDropped = false) {\n let childFolders = folder.folders;\n if (!includeDropped) {\n childFolders = childFolders.filter(c => c.effectiveActive);\n }\n\n return {\n id: folder.id.primaryKey,\n name: folder.name,\n status: folderStatusToString(folder.status),\n effectivelyActive: folder.effectiveActive,\n parent: folder.parent ? folder.parent.name : null,\n projectCount: folder.projects.length,\n remainingProjectCount: folder.projects.filter(p => p.effectiveActive).length,\n folderCount: folder.folders.length,\n children: childFolders.map(child => serializeFolder(child, includeDropped))\n };\n }\n\n function computeTopItems(items, keyFn, topN = 5) {\n return items\n .sort((a, b) => b[keyFn] - a[keyFn])\n .slice(0, topN)\n .map(item => ({ name: item.name, [keyFn]: item[keyFn] }));\n }\n\n function computeAverage(total, count) {\n return count > 0 ? Math.round((total / count) * 10) / 10 : 0;\n }\n\n function serializeTag(tag, activeOnly = false) {\n const tasks = tag.tasks;\n const remainingTasks = tag.remainingTasks;\n const includedTasks = activeOnly ? remainingTasks : tasks;\n\n const dates = [];\n if (tag.added) dates.push(tag.added);\n if (tag.modified) dates.push(tag.modified);\n\n for (const task of includedTasks) {\n if (task.added) dates.push(task.added);\n if (task.modified) dates.push(task.modified);\n if (!activeOnly && task.completionDate) dates.push(task.completionDate);\n if (!activeOnly && task.effectiveCompletionDate) dates.push(task.effectiveCompletionDate);\n }\n\n const lastActivity = dates.length > 0\n ? dates.reduce((latest, current) => current > latest ? current : latest)\n : null;\n\n return {\n id: tag.id.primaryKey,\n name: tag.name,\n taskCount: includedTasks.length,\n remainingTaskCount: remainingTasks.length,\n added: tag.added ? tag.added.toISOString() : null,\n modified: tag.modified ? tag.modified.toISOString() : null,\n lastActivity: lastActivity ? lastActivity.toISOString() : null,\n active: tag.active,\n status: tagStatusToString(tag.status),\n parent: tag.parent ? tag.parent.name : null,\n children: tag.children.map(c => c.name),\n allowsNextAction: tag.allowsNextAction\n };\n }\n `;\n\n private async executeJXA(script: string, timeoutMs = 30000): Promise<string> {\n const tmpFile = join(tmpdir(), `omnifocus-${Date.now()}.js`);\n\n try {\n await writeFile(tmpFile, script, 'utf-8');\n\n const { stdout } = await execFileAsync('osascript', ['-l', 'JavaScript', tmpFile], {\n timeout: timeoutMs,\n maxBuffer: 10 * 1024 * 1024,\n });\n\n return stdout.trim();\n } finally {\n try {\n await unlink(tmpFile);\n } catch {\n /* ignore cleanup errors */\n }\n }\n }\n\n private escapeString(str: string): string {\n return str\n .replace(/\\\\/g, '\\\\\\\\')\n .replace(/\"/g, '\\\\\"')\n .replace(/\\n/g, '\\\\n')\n .replace(/\\r/g, '\\\\r')\n .replace(/\\t/g, '\\\\t');\n }\n\n private wrapOmniScript(omniScript: string): string {\n return `\n const app = Application('OmniFocus');\n app.includeStandardAdditions = true;\n const result = app.evaluateJavascript(${JSON.stringify(omniScript.trim())});\n result;\n `.trim();\n }\n\n private buildTaskFilters(filters: TaskFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeCompleted) {\n conditions.push('if (task.completed) continue;');\n }\n if (!filters.includeDropped) {\n conditions.push('if (!task.effectiveActive) continue;');\n }\n if (filters.flagged) {\n conditions.push('if (!task.flagged) continue;');\n conditions.push('if (task.taskStatus !== Task.Status.Available) continue;');\n }\n if (filters.project) {\n conditions.push(`\n if (!task.containingProject || task.containingProject.name !== \"${this.escapeString(filters.project)}\") {\n continue;\n }\n `);\n }\n if (filters.tag) {\n conditions.push(`\n if (!task.tags.some(t => t.name === \"${this.escapeString(filters.tag)}\")) {\n continue;\n }\n `);\n }\n\n return conditions.join('\\n ');\n }\n\n private buildProjectFilters(filters: ProjectFilters): string {\n const conditions: string[] = [];\n\n if (!filters.includeDropped) {\n conditions.push(\n 'if (project.status === Project.Status.Dropped || project.status === Project.Status.Done) continue;'\n );\n conditions.push(\n 'if (project.parentFolder && !project.parentFolder.effectiveActive) continue;'\n );\n }\n if (filters.status) {\n const statusCheck = this.PROJECT_STATUS_MAP[filters.status];\n conditions.push(`if (project.status !== Project.Status.${statusCheck}) continue;`);\n }\n if (filters.folder) {\n conditions.push(\n `if (!project.parentFolder || project.parentFolder.name !== \"${this.escapeString(filters.folder)}\") continue;`\n );\n }\n\n return conditions.join('\\n ');\n }\n\n private buildTaskUpdates(options: UpdateTaskOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`task.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`task.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.flagged !== undefined) {\n updates.push(`task.flagged = ${options.flagged};`);\n }\n if (options.completed !== undefined) {\n updates.push(options.completed ? 'task.markComplete();' : 'task.markIncomplete();');\n }\n if (options.estimatedMinutes !== undefined) {\n updates.push(`task.estimatedMinutes = ${options.estimatedMinutes};`);\n }\n if (options.defer !== undefined) {\n updates.push(\n options.defer\n ? `task.deferDate = new Date(${JSON.stringify(options.defer)});`\n : 'task.deferDate = null;'\n );\n }\n if (options.due !== undefined) {\n updates.push(\n options.due\n ? `task.dueDate = new Date(${JSON.stringify(options.due)});`\n : 'task.dueDate = null;'\n );\n }\n if (options.project !== undefined && options.project) {\n updates.push(`\n const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n moveTasks([task], targetProject);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(task, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildTagUpdates(options: UpdateTagOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`tag.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.status !== undefined) {\n updates.push(`tag.status = stringToTagStatus(\"${options.status}\");`);\n }\n\n return updates.join('\\n ');\n }\n\n private buildProjectUpdates(options: UpdateProjectOptions): string {\n const updates: string[] = [];\n\n if (options.name !== undefined) {\n updates.push(`project.name = \"${this.escapeString(options.name)}\";`);\n }\n if (options.note !== undefined) {\n updates.push(`project.note = \"${this.escapeString(options.note)}\";`);\n }\n if (options.sequential !== undefined) {\n updates.push(`project.sequential = ${options.sequential};`);\n }\n if (options.status !== undefined) {\n updates.push(`project.status = stringToProjectStatus(\"${options.status}\");`);\n }\n if (options.folder !== undefined && options.folder) {\n updates.push(`\n const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n moveProjects([project], targetFolder);\n `);\n }\n if (options.tags !== undefined) {\n updates.push(`replaceTagsOn(project, ${JSON.stringify(options.tags)});`);\n }\n\n return updates.join('\\n ');\n }\n\n async listTasks(filters: TaskFilters = {}): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const task of flattenedTasks) {\n ${this.buildTaskFilters(filters)}\n results.push(serializeTask(task));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTask(options: CreateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.project\n ? `const targetProject = findByName(flattenedProjects, \"${this.escapeString(options.project)}\", \"Project\");\n const task = new Task(\"${this.escapeString(options.name)}\", targetProject);`\n : `const task = new Task(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `task.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.flagged ? 'task.flagged = true;' : ''}\n ${options.estimatedMinutes ? `task.estimatedMinutes = ${options.estimatedMinutes};` : ''}\n ${options.defer ? `task.deferDate = new Date(${JSON.stringify(options.defer)});` : ''}\n ${options.due ? `task.dueDate = new Date(${JSON.stringify(options.due)});` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(task, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTask(idOrName: string, options: UpdateTaskOptions): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n ${this.buildTaskUpdates(options)}\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTask(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTask(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listProjects(filters: ProjectFilters = {}): Promise<Project[]> {\n const filterCode = this.buildProjectFilters(filters);\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n for (const project of flattenedProjects) {\n ${filterCode}\n results.push(serializeProject(project));\n }\n return JSON.stringify(results);\n })();\n `;\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createProject(options: CreateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.folder\n ? `const targetFolder = findByName(flattenedFolders, \"${this.escapeString(options.folder)}\", \"Folder\");\n const project = new Project(\"${this.escapeString(options.name)}\", targetFolder);`\n : `const project = new Project(\"${this.escapeString(options.name)}\");`\n }\n\n ${options.note ? `project.note = \"${this.escapeString(options.note)}\";` : ''}\n ${options.sequential !== undefined ? `project.sequential = ${options.sequential};` : ''}\n ${options.status ? `project.status = stringToProjectStatus(\"${options.status}\");` : ''}\n ${options.tags && options.tags.length > 0 ? `assignTags(project, ${JSON.stringify(options.tags)});` : ''}\n\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateProject(idOrName: string, options: UpdateProjectOptions): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n ${this.buildProjectUpdates(options)}\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteProject(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findProject(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async listInboxTasks(): Promise<Task[]> {\n return this.getPerspectiveTasks('Inbox');\n }\n\n async getInboxCount(): Promise<number> {\n const tasks = await this.getPerspectiveTasks('Inbox');\n return tasks.length;\n }\n\n async searchTasks(query: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const searchQuery = \"${this.escapeString(query)}\".toLowerCase();\n\n for (const task of flattenedTasks) {\n if (task.completed) continue;\n if (!task.effectiveActive) continue;\n\n const name = task.name.toLowerCase();\n const note = (task.note || '').toLowerCase();\n\n if (name.includes(searchQuery) || note.includes(searchQuery)) {\n results.push(serializeTask(task));\n }\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTask(idOrName: string): Promise<Task> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const task = findTask(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTask(task));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProject(idOrName: string): Promise<Project> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const project = findProject(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeProject(project));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listPerspectives(): Promise<Perspective[]> {\n const omniScript = `\n (() => {\n const results = [];\n\n const builtInNames = ['Inbox', 'Flagged', 'Forecast', 'Projects', 'Tags', 'Nearby', 'Review'];\n for (const name of builtInNames) {\n results.push({ id: name, name: name });\n }\n\n const customPerspectives = Perspective.Custom.all;\n for (const perspective of customPerspectives) {\n results.push({ id: perspective.name, name: perspective.name });\n }\n\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getPerspectiveTasks(perspectiveName: string): Promise<Task[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const doc = document;\n const windows = doc.windows;\n\n if (windows.length === 0) {\n throw new Error(\"No OmniFocus window is open. Please open an OmniFocus window and try again.\");\n }\n\n const win = windows[0];\n const perspectiveName = \"${this.escapeString(perspectiveName)}\";\n\n const builtInPerspectives = {\n 'inbox': Perspective.BuiltIn.Inbox,\n 'flagged': Perspective.BuiltIn.Flagged,\n 'forecast': Perspective.BuiltIn.Forecast,\n 'projects': Perspective.BuiltIn.Projects,\n 'tags': Perspective.BuiltIn.Tags,\n 'nearby': Perspective.BuiltIn.Nearby,\n 'review': Perspective.BuiltIn.Review\n };\n\n const lowerName = perspectiveName.toLowerCase();\n if (builtInPerspectives[lowerName]) {\n win.perspective = builtInPerspectives[lowerName];\n } else {\n const customPerspective = Perspective.Custom.byName(perspectiveName);\n if (customPerspective) {\n win.perspective = customPerspective;\n } else {\n throw new Error(\"Perspective not found: \" + perspectiveName);\n }\n }\n\n const content = win.content;\n if (!content) {\n throw new Error(\"No content available in window\");\n }\n\n const tasks = [];\n content.rootNode.apply(node => {\n const obj = node.object;\n if (obj instanceof Task) {\n tasks.push(serializeTask(obj));\n }\n });\n\n return JSON.stringify(tasks);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript), 60000);\n return JSON.parse(output);\n }\n\n async listTags(options: TagListOptions = {}): Promise<Tag[]> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const results = [];\n const now = new Date();\n const activeOnly = ${!!options.activeOnly};\n\n for (const tag of flattenedTags) {\n const serialized = serializeTag(tag, activeOnly);\n results.push(serialized);\n }\n\n ${\n options.unusedDays\n ? `\n const cutoffDate = new Date(now.getTime() - (${options.unusedDays} * 24 * 60 * 60 * 1000));\n const filtered = results.filter(tag => {\n if (!tag.lastActivity) return true;\n return new Date(tag.lastActivity) < cutoffDate;\n });\n return JSON.stringify(filtered);\n `\n : 'return JSON.stringify(results);'\n }\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n const tags = JSON.parse(output);\n\n return this.sortTags(tags, options.sortBy);\n }\n\n private sortTags(tags: Tag[], sortBy: string = 'name'): Tag[] {\n const sortFns: Record<string, (a: Tag, b: Tag) => number> = {\n usage: (a, b) => b.taskCount - a.taskCount,\n activity: (a, b) => {\n if (!a.lastActivity && !b.lastActivity) return 0;\n if (!a.lastActivity) return 1;\n if (!b.lastActivity) return -1;\n return new Date(b.lastActivity).getTime() - new Date(a.lastActivity).getTime();\n },\n name: (a, b) => a.name.localeCompare(b.name),\n };\n\n return tags.sort(sortFns[sortBy] || sortFns.name);\n }\n\n async getTagStats(): Promise<TagStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTags = [];\n for (const tag of flattenedTags) {\n allTags.push(serializeTag(tag));\n }\n\n const activeTags = allTags.filter(t => t.active);\n const tagsWithTasks = allTags.filter(t => t.taskCount > 0);\n const unusedTags = allTags.filter(t => t.taskCount === 0);\n\n const totalTasks = tagsWithTasks.reduce((sum, t) => sum + t.taskCount, 0);\n const avgTasksPerTag = computeAverage(totalTasks, tagsWithTasks.length);\n\n const mostUsedTags = computeTopItems(allTags, 'taskCount');\n const leastUsedTags = computeTopItems(\n tagsWithTasks.map(t => ({ ...t, taskCount: -t.taskCount })),\n 'taskCount'\n ).map(t => ({ name: t.name, taskCount: -t.taskCount }));\n\n const now = new Date();\n const thirtyDaysAgo = new Date(now.getTime() - (30 * 24 * 60 * 60 * 1000));\n const staleTags = allTags\n .filter(t => t.lastActivity && new Date(t.lastActivity) < thirtyDaysAgo)\n .map(t => ({\n name: t.name,\n daysSinceActivity: Math.floor((now - new Date(t.lastActivity)) / (24 * 60 * 60 * 1000))\n }))\n .sort((a, b) => b.daysSinceActivity - a.daysSinceActivity);\n\n return JSON.stringify({\n totalTags: allTags.length,\n activeTags: activeTags.length,\n tagsWithTasks: tagsWithTasks.length,\n unusedTags: unusedTags.length,\n avgTasksPerTag,\n mostUsedTags,\n leastUsedTags,\n staleTags\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async createTag(options: CreateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n ${\n options.parent\n ? `const parentTag = findTag(\"${this.escapeString(options.parent)}\");\n const tag = new Tag(\"${this.escapeString(options.name)}\", parentTag);`\n : `const tag = new Tag(\"${this.escapeString(options.name)}\", tags.beginning);`\n }\n\n ${options.status ? `tag.status = stringToTagStatus(\"${options.status}\");` : ''}\n\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getTag(idOrName: string): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async updateTag(idOrName: string, options: UpdateTagOptions): Promise<Tag> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const tag = findTag(\"${this.escapeString(idOrName)}\");\n ${this.buildTagUpdates(options)}\n return JSON.stringify(serializeTag(tag));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async deleteTag(idOrName: string): Promise<void> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n deleteObject(findTag(\"${this.escapeString(idOrName)}\"));\n })();\n `;\n\n await this.executeJXA(this.wrapOmniScript(omniScript));\n }\n\n async getTaskStats(): Promise<TaskStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allTasks = Array.from(flattenedTasks);\n const now = new Date();\n\n const activeTasks = allTasks.filter(t => !t.completed && t.effectiveActive);\n const completedTasks = allTasks.filter(t => t.completed);\n const flaggedTasks = activeTasks.filter(t => t.flagged);\n const overdueActiveTasks = activeTasks.filter(t => t.dueDate && t.dueDate < now);\n\n const tasksWithEstimates = allTasks.filter(t => t.estimatedMinutes && t.estimatedMinutes > 0);\n const totalEstimatedMinutes = tasksWithEstimates.reduce((sum, t) => sum + (t.estimatedMinutes || 0), 0);\n const avgEstimatedMinutes = tasksWithEstimates.length > 0\n ? Math.round(totalEstimatedMinutes / tasksWithEstimates.length)\n : null;\n\n const totalNonDropped = allTasks.filter(t => t.effectiveActive || t.completed).length;\n const completionRate = totalNonDropped > 0\n ? Math.round((completedTasks.length / totalNonDropped) * 100)\n : 0;\n\n const projectCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n const projectName = task.containingProject ? task.containingProject.name : 'Inbox';\n projectCounts[projectName] = (projectCounts[projectName] || 0) + 1;\n }\n const tasksByProject = computeTopItems(\n Object.entries(projectCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n const tagCounts = {};\n for (const task of allTasks) {\n if (!task.effectiveActive && !task.completed) continue;\n for (const tag of task.tags) {\n tagCounts[tag.name] = (tagCounts[tag.name] || 0) + 1;\n }\n }\n const tasksByTag = computeTopItems(\n Object.entries(tagCounts).map(([name, count]) => ({ name, taskCount: count })),\n 'taskCount'\n );\n\n return JSON.stringify({\n totalTasks: allTasks.length,\n activeTasks: activeTasks.length,\n completedTasks: completedTasks.length,\n flaggedTasks: flaggedTasks.length,\n overdueActiveTasks: overdueActiveTasks.length,\n avgEstimatedMinutes,\n tasksWithEstimates: tasksWithEstimates.length,\n completionRate,\n tasksByProject,\n tasksByTag\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getProjectStats(): Promise<ProjectStats> {\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const allProjects = Array.from(flattenedProjects);\n\n function isProjectEffectivelyActive(p) {\n if (p.status === Project.Status.Dropped || p.status === Project.Status.Done) return false;\n if (p.parentFolder && !p.parentFolder.effectiveActive) return false;\n return true;\n }\n\n const effectivelyActiveProjects = allProjects.filter(isProjectEffectivelyActive);\n const activeProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.Active);\n const onHoldProjects = effectivelyActiveProjects.filter(p => p.status === Project.Status.OnHold);\n const droppedProjects = allProjects.filter(p => p.status === Project.Status.Dropped);\n const doneProjects = allProjects.filter(p => p.status === Project.Status.Done);\n const sequentialProjects = effectivelyActiveProjects.filter(p => p.sequential);\n const parallelProjects = effectivelyActiveProjects.filter(p => !p.sequential);\n\n const totalTasks = effectivelyActiveProjects.reduce((sum, p) => sum + p.flattenedTasks.length, 0);\n const totalRemaining = effectivelyActiveProjects.reduce((sum, p) => {\n return sum + p.flattenedTasks.filter(t => !t.completed).length;\n }, 0);\n\n const avgTasksPerProject = computeAverage(totalTasks, effectivelyActiveProjects.length);\n const avgRemainingPerProject = computeAverage(totalRemaining, effectivelyActiveProjects.length);\n\n const completionRates = effectivelyActiveProjects\n .filter(p => p.flattenedTasks.length > 0)\n .map(p => {\n const total = p.flattenedTasks.length;\n const completed = p.flattenedTasks.filter(t => t.completed).length;\n return (completed / total) * 100;\n });\n\n const avgCompletionRate = completionRates.length > 0\n ? Math.round(completionRates.reduce((sum, rate) => sum + rate, 0) / completionRates.length)\n : 0;\n\n const projectsWithMostTasks = computeTopItems(\n effectivelyActiveProjects.map(p => ({ name: p.name, taskCount: p.flattenedTasks.length })),\n 'taskCount'\n );\n\n const projectsWithMostRemaining = computeTopItems(\n effectivelyActiveProjects\n .map(p => ({ name: p.name, remainingCount: p.flattenedTasks.filter(t => !t.completed).length }))\n .filter(p => p.remainingCount > 0),\n 'remainingCount'\n );\n\n return JSON.stringify({\n totalProjects: allProjects.length,\n activeProjects: activeProjects.length,\n onHoldProjects: onHoldProjects.length,\n droppedProjects: droppedProjects.length,\n doneProjects: doneProjects.length,\n sequentialProjects: sequentialProjects.length,\n parallelProjects: parallelProjects.length,\n avgTasksPerProject,\n avgRemainingPerProject,\n avgCompletionRate,\n projectsWithMostTasks,\n projectsWithMostRemaining\n });\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async listFolders(filters: FolderFilters = {}): Promise<Folder[]> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n const results = [];\n for (const folder of folders) {\n if (!includeDropped && !folder.effectiveActive) continue;\n results.push(serializeFolder(folder, includeDropped));\n }\n return JSON.stringify(results);\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n\n async getFolder(idOrName: string, filters: FolderFilters = {}): Promise<Folder> {\n const includeDropped = filters.includeDropped ?? false;\n const omniScript = `\n ${this.OMNI_HELPERS}\n (() => {\n const includeDropped = ${includeDropped};\n\n function findFolder(idOrName) {\n for (const folder of flattenedFolders) {\n if (folder.id.primaryKey === idOrName || folder.name === idOrName) {\n return folder;\n }\n }\n throw new Error(\"Folder not found: \" + idOrName);\n }\n\n const folder = findFolder(\"${this.escapeString(idOrName)}\");\n return JSON.stringify(serializeFolder(folder, includeDropped));\n })();\n `;\n\n const output = await this.executeJXA(this.wrapOmniScript(omniScript));\n return JSON.parse(output);\n }\n}\n","import dayjs from 'dayjs';\nimport { OmniFocusCliError } from './errors.js';\n\nexport function parseDateTime(input: string): string {\n const d = dayjs(input);\n if (!d.isValid()) {\n throw new OmniFocusCliError(`Invalid date: ${input}`, 400);\n }\n return d.toISOString();\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { ProjectFilters, UpdateProjectOptions } from '../types.js';\n\nexport function createProjectCommand(): Command {\n const command = new Command('project');\n command.description('Manage OmniFocus projects');\n\n command\n .command('list')\n .alias('ls')\n .description('List projects')\n .option('-f, --folder <name>', 'Filter by folder')\n .option('-s, --status <status>', 'Filter by status (active, on hold, dropped)')\n .option('-d, --dropped', 'Include dropped projects')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const filters: ProjectFilters = {\n includeDropped: options.dropped,\n ...(options.folder && { folder: options.folder }),\n ...(options.status && { status: options.status }),\n };\n const projects = await of.listProjects(filters);\n outputJson(projects);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new project')\n .option('-f, --folder <name>', 'Assign to folder')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-s, --sequential', 'Make it a sequential project')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const project = await of.createProject({\n name,\n note: options.note,\n folder: options.folder,\n tags: options.tag,\n sequential: options.sequential,\n status: options.status,\n });\n outputJson(project);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing project')\n .option('-n, --name <name>', 'Rename project')\n .option('--note <text>', 'New note')\n .option('-f, --folder <name>', 'Move to folder')\n .option('-t, --tag <tags...>', 'Replace tags')\n .option('-s, --sequential', 'Make it sequential')\n .option('-p, --parallel', 'Make it parallel')\n .option('--status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateProjectOptions = {\n ...(options.name && { name: options.name }),\n ...(options.note !== undefined && { note: options.note }),\n ...(options.folder && { folder: options.folder }),\n ...(options.tag && { tags: options.tag }),\n ...(options.sequential && { sequential: true }),\n ...(options.parallel && { sequential: false }),\n ...(options.status && { status: options.status }),\n };\n const project = await of.updateProject(idOrName, updates);\n outputJson(project);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a project')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteProject(idOrName);\n outputJson({ message: 'Project deleted successfully' });\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View project details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const project = await of.getProject(idOrName);\n outputJson(project);\n })\n );\n\n command\n .command('stats')\n .description('Show project statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getProjectStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport { parseDateTime } from '../lib/dates.js';\n\nexport function createInboxCommand(): Command {\n const command = new Command('inbox');\n command.description('Manage OmniFocus inbox');\n\n command\n .command('list')\n .alias('ls')\n .description('List inbox tasks')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const tasks = await of.listInboxTasks();\n outputJson(tasks);\n })\n );\n\n command\n .command('count')\n .description('Get inbox count')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const count = await of.getInboxCount();\n outputJson({ count });\n })\n );\n\n command\n .command('add <name>')\n .description('Add a task to inbox')\n .option('--note <text>', 'Add note')\n .option('-t, --tag <tags...>', 'Add tags')\n .option('-d, --due <date>', 'Set due date')\n .option('-D, --defer <date>', 'Set defer date')\n .option('-f, --flagged', 'Flag the task')\n .option('-e, --estimate <minutes>', 'Estimated time in minutes', parseInt)\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const task = await of.createTask({\n name,\n note: options.note,\n tags: options.tag,\n due: options.due ? parseDateTime(options.due) : undefined,\n defer: options.defer ? parseDateTime(options.defer) : undefined,\n flagged: options.flagged,\n estimatedMinutes: options.estimate,\n });\n outputJson(task);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createSearchCommand(): Command {\n const command = new Command('search');\n command.description('Search tasks by name or note');\n command.argument('<query>', 'Search query');\n\n command.action(\n withErrorHandling(async (query) => {\n const of = new OmniFocus();\n const tasks = await of.searchTasks(query);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nexport function createPerspectiveCommand(): Command {\n const command = new Command('perspective');\n command.description('Manage OmniFocus perspectives');\n\n command\n .command('list')\n .alias('ls')\n .description('List all perspectives')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const perspectives = await of.listPerspectives();\n outputJson(perspectives);\n })\n );\n\n command\n .command('view <name>')\n .description('View tasks in a perspective')\n .action(\n withErrorHandling(async (name) => {\n const of = new OmniFocus();\n const tasks = await of.getPerspectiveTasks(name);\n outputJson(tasks);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { UpdateTagOptions } from '../types.js';\n\nexport function createTagCommand(): Command {\n const command = new Command('tag');\n command.description('Manage and analyze OmniFocus tags');\n\n command\n .command('list')\n .alias('ls')\n .description('List tags with usage information')\n .option('-u, --unused-days <days>', 'Show tags unused for N days', parseInt)\n .option('-s, --sort <field>', 'Sort by: name, usage, activity (default: name)', 'name')\n .option('-a, --active-only', 'Only count active (incomplete) tasks')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const tags = await of.listTags({\n unusedDays: options.unusedDays,\n sortBy: options.sort,\n activeOnly: options.activeOnly,\n });\n outputJson(tags);\n })\n );\n\n command\n .command('create <name>')\n .description('Create a new tag')\n .option('-p, --parent <name>', 'Create as child of parent tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (name, options) => {\n const of = new OmniFocus();\n const tag = await of.createTag({\n name,\n parent: options.parent,\n status: options.status,\n });\n outputJson(tag);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View tag details')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n const tag = await of.getTag(idOrName);\n outputJson(tag);\n })\n );\n\n command\n .command('update <idOrName>')\n .description('Update an existing tag')\n .option('-n, --name <name>', 'Rename tag')\n .option('-s, --status <status>', 'Set status (active, on hold, dropped)')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const updates: UpdateTagOptions = {\n ...(options.name && { name: options.name }),\n ...(options.status && { status: options.status }),\n };\n const tag = await of.updateTag(idOrName, updates);\n outputJson(tag);\n })\n );\n\n command\n .command('delete <idOrName>')\n .alias('rm')\n .description('Delete a tag')\n .action(\n withErrorHandling(async (idOrName) => {\n const of = new OmniFocus();\n await of.deleteTag(idOrName);\n outputJson({ message: 'Tag deleted successfully' });\n })\n );\n\n command\n .command('stats')\n .description('Show tag usage statistics')\n .action(\n withErrorHandling(async () => {\n const of = new OmniFocus();\n const stats = await of.getTagStats();\n outputJson(stats);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { outputJson } from '../lib/output.js';\nimport { withErrorHandling } from '../lib/command-utils.js';\nimport { OmniFocus } from '../lib/omnifocus.js';\nimport type { FolderFilters } from '../types.js';\n\nexport function createFolderCommand(): Command {\n const command = new Command('folder');\n command.description('View OmniFocus folder hierarchy');\n\n command\n .command('list')\n .alias('ls')\n .description('List top-level folders with nested children')\n .option('-d, --dropped', 'Include dropped folders')\n .action(\n withErrorHandling(async (options) => {\n const of = new OmniFocus();\n const folders = await of.listFolders({ includeDropped: options.dropped });\n outputJson(folders);\n })\n );\n\n command\n .command('view <idOrName>')\n .description('View folder details and children')\n .option('-d, --dropped', 'Include dropped child folders')\n .action(\n withErrorHandling(async (idOrName, options) => {\n const of = new OmniFocus();\n const filters: FolderFilters = { includeDropped: options.dropped };\n const folder = await of.getFolder(idOrName, filters);\n outputJson(folder);\n })\n );\n\n return command;\n}\n","import { Command } from 'commander';\nimport { runMcpServer } from '../mcp/server.js';\n\nexport function createMcpCommand(): Command {\n const cmd = new Command('mcp').description('Run OmniFocus MCP server');\n\n cmd.action(async () => {\n await runMcpServer();\n });\n\n return cmd;\n}\n","import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';\nimport { z } from 'zod';\nimport { OmniFocus } from '../lib/omnifocus.js';\n\nconst server = new McpServer({\n name: 'omnifocus',\n version: '1.0.0',\n});\n\nconst of = new OmniFocus();\n\nfunction jsonResponse(data: unknown) {\n return { content: [{ type: 'text' as const, text: JSON.stringify(data, null, 2) }] };\n}\n\nserver.tool(\n 'list_tasks',\n 'List tasks with optional filtering',\n {\n includeCompleted: z.boolean().optional().describe('Include completed tasks'),\n includeDropped: z.boolean().optional().describe('Include dropped tasks'),\n flagged: z.boolean().optional().describe('Only show flagged tasks'),\n project: z.string().optional().describe('Filter by project name'),\n tag: z.string().optional().describe('Filter by tag name'),\n },\n async (filters) => jsonResponse(await of.listTasks(filters))\n);\n\nserver.tool(\n 'get_task',\n 'Get a specific task by ID or name',\n { idOrName: z.string().describe('Task ID or name') },\n async ({ idOrName }) => jsonResponse(await of.getTask(idOrName))\n);\n\nserver.tool(\n 'create_task',\n 'Create a new task',\n {\n name: z.string().describe('Task name'),\n note: z.string().optional().describe('Task note'),\n project: z.string().optional().describe('Project to add task to'),\n tags: z.array(z.string()).optional().describe('Tags to assign'),\n defer: z.string().optional().describe('Defer date (ISO 8601)'),\n due: z.string().optional().describe('Due date (ISO 8601)'),\n flagged: z.boolean().optional().describe('Flag the task'),\n estimatedMinutes: z.number().optional().describe('Estimated duration in minutes'),\n },\n async (options) => jsonResponse(await of.createTask(options))\n);\n\nserver.tool(\n 'update_task',\n 'Update an existing task',\n {\n idOrName: z.string().describe('Task ID or name'),\n name: z.string().optional().describe('New task name'),\n note: z.string().optional().describe('New task note'),\n project: z.string().optional().describe('Move to project'),\n tags: z.array(z.string()).optional().describe('Replace tags'),\n defer: z.string().optional().describe('New defer date (ISO 8601)'),\n due: z.string().optional().describe('New due date (ISO 8601)'),\n flagged: z.boolean().optional().describe('Flag/unflag the task'),\n estimatedMinutes: z.number().optional().describe('New estimated duration'),\n completed: z.boolean().optional().describe('Mark complete/incomplete'),\n },\n async ({ idOrName, ...options }) => jsonResponse(await of.updateTask(idOrName, options))\n);\n\nserver.tool(\n 'delete_task',\n 'Delete a task',\n { idOrName: z.string().describe('Task ID or name') },\n async ({ idOrName }) => {\n await of.deleteTask(idOrName);\n return jsonResponse({ deleted: true });\n }\n);\n\nserver.tool(\n 'search_tasks',\n 'Search tasks by name or note content',\n { query: z.string().describe('Search query') },\n async ({ query }) => jsonResponse(await of.searchTasks(query))\n);\n\nserver.tool(\n 'get_task_stats',\n 'Get task statistics',\n {},\n async () => jsonResponse(await of.getTaskStats())\n);\n\nserver.tool(\n 'list_inbox',\n 'List all inbox tasks',\n {},\n async () => jsonResponse(await of.listInboxTasks())\n);\n\nserver.tool(\n 'get_inbox_count',\n 'Get the number of inbox tasks',\n {},\n async () => jsonResponse({ count: await of.getInboxCount() })\n);\n\nserver.tool(\n 'list_projects',\n 'List projects with optional filtering',\n {\n includeDropped: z.boolean().optional().describe('Include dropped projects'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('Filter by status'),\n folder: z.string().optional().describe('Filter by folder name'),\n },\n async (filters) => jsonResponse(await of.listProjects(filters))\n);\n\nserver.tool(\n 'get_project',\n 'Get a specific project by ID or name',\n { idOrName: z.string().describe('Project ID or name') },\n async ({ idOrName }) => jsonResponse(await of.getProject(idOrName))\n);\n\nserver.tool(\n 'create_project',\n 'Create a new project',\n {\n name: z.string().describe('Project name'),\n note: z.string().optional().describe('Project note'),\n folder: z.string().optional().describe('Folder to create project in'),\n sequential: z.boolean().optional().describe('Sequential project (tasks must be done in order)'),\n tags: z.array(z.string()).optional().describe('Tags to assign'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('Initial status'),\n },\n async (options) => jsonResponse(await of.createProject(options))\n);\n\nserver.tool(\n 'update_project',\n 'Update an existing project',\n {\n idOrName: z.string().describe('Project ID or name'),\n name: z.string().optional().describe('New project name'),\n note: z.string().optional().describe('New project note'),\n folder: z.string().optional().describe('Move to folder'),\n sequential: z.boolean().optional().describe('Set sequential/parallel'),\n tags: z.array(z.string()).optional().describe('Replace tags'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('New status'),\n },\n async ({ idOrName, ...options }) => jsonResponse(await of.updateProject(idOrName, options))\n);\n\nserver.tool(\n 'delete_project',\n 'Delete a project',\n { idOrName: z.string().describe('Project ID or name') },\n async ({ idOrName }) => {\n await of.deleteProject(idOrName);\n return jsonResponse({ deleted: true });\n }\n);\n\nserver.tool(\n 'get_project_stats',\n 'Get project statistics',\n {},\n async () => jsonResponse(await of.getProjectStats())\n);\n\nserver.tool(\n 'list_perspectives',\n 'List all available perspectives',\n {},\n async () => jsonResponse(await of.listPerspectives())\n);\n\nserver.tool(\n 'get_perspective_tasks',\n 'Get tasks from a specific perspective',\n { name: z.string().describe('Perspective name (e.g., Inbox, Flagged, or custom perspective)') },\n async ({ name }) => jsonResponse(await of.getPerspectiveTasks(name))\n);\n\nserver.tool(\n 'list_tags',\n 'List all tags with optional filtering and sorting',\n {\n unusedDays: z.number().optional().describe('Only show tags unused for this many days'),\n sortBy: z.enum(['name', 'usage', 'activity']).optional().describe('Sort order'),\n activeOnly: z.boolean().optional().describe('Only count active tasks'),\n },\n async (options) => jsonResponse(await of.listTags(options))\n);\n\nserver.tool(\n 'get_tag',\n 'Get a specific tag by ID or name',\n { idOrName: z.string().describe('Tag ID, name, or path (e.g., \"Parent/Child\")') },\n async ({ idOrName }) => jsonResponse(await of.getTag(idOrName))\n);\n\nserver.tool(\n 'create_tag',\n 'Create a new tag',\n {\n name: z.string().describe('Tag name'),\n parent: z.string().optional().describe('Parent tag name or path'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('Initial status'),\n },\n async (options) => jsonResponse(await of.createTag(options))\n);\n\nserver.tool(\n 'update_tag',\n 'Update an existing tag',\n {\n idOrName: z.string().describe('Tag ID, name, or path'),\n name: z.string().optional().describe('New tag name'),\n status: z.enum(['active', 'on hold', 'dropped']).optional().describe('New status'),\n },\n async ({ idOrName, ...options }) => jsonResponse(await of.updateTag(idOrName, options))\n);\n\nserver.tool(\n 'delete_tag',\n 'Delete a tag',\n { idOrName: z.string().describe('Tag ID, name, or path') },\n async ({ idOrName }) => {\n await of.deleteTag(idOrName);\n return jsonResponse({ deleted: true });\n }\n);\n\nserver.tool(\n 'get_tag_stats',\n 'Get tag statistics',\n {},\n async () => jsonResponse(await of.getTagStats())\n);\n\nserver.tool(\n 'list_folders',\n 'List all folders',\n { includeDropped: z.boolean().optional().describe('Include dropped folders') },\n async (filters) => jsonResponse(await of.listFolders(filters))\n);\n\nserver.tool(\n 'get_folder',\n 'Get a specific folder by ID or name',\n {\n idOrName: z.string().describe('Folder ID or name'),\n includeDropped: z.boolean().optional().describe('Include dropped children'),\n },\n async ({ idOrName, includeDropped }) => jsonResponse(await of.getFolder(idOrName, { includeDropped }))\n);\n\nexport async function runMcpServer() {\n const transport = new StdioServerTransport();\n await server.connect(transport);\n}\n"],"mappings":"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","names":["Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","of","Command","Command","Command"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stephendolan/omnifocus-cli",
3
- "version": "2.2.1",
3
+ "version": "2.3.0",
4
4
  "description": "A command-line interface for OmniFocus on macOS",
5
5
  "main": "dist/cli.js",
6
6
  "type": "module",
@@ -48,8 +48,10 @@
48
48
  "bun": ">=1.0.0"
49
49
  },
50
50
  "dependencies": {
51
+ "@modelcontextprotocol/sdk": "^1.12.0",
51
52
  "commander": "^12.1.0",
52
- "dayjs": "^1.11.19"
53
+ "dayjs": "^1.11.19",
54
+ "zod": "^3.24.0"
53
55
  },
54
56
  "devDependencies": {
55
57
  "@biomejs/biome": "^1.9.4",