@mattheworiordan/remi 0.1.0 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +101 -136
- package/dist/cli/commands/add.js +9 -6
- package/dist/cli/commands/add.js.map +1 -1
- package/dist/cli/commands/complete.js +4 -2
- package/dist/cli/commands/complete.js.map +1 -1
- package/dist/cli/commands/create-section.js +4 -2
- package/dist/cli/commands/create-section.js.map +1 -1
- package/dist/cli/commands/delete-list.js +4 -2
- package/dist/cli/commands/delete-list.js.map +1 -1
- package/dist/cli/commands/delete-section.js +5 -2
- package/dist/cli/commands/delete-section.js.map +1 -1
- package/dist/cli/commands/delete.js +4 -3
- package/dist/cli/commands/delete.js.map +1 -1
- package/dist/cli/commands/demo.d.ts +3 -0
- package/dist/cli/commands/demo.js +134 -0
- package/dist/cli/commands/demo.js.map +1 -0
- package/dist/cli/commands/list.js +48 -2
- package/dist/cli/commands/list.js.map +1 -1
- package/dist/cli/commands/move.js +6 -4
- package/dist/cli/commands/move.js.map +1 -1
- package/dist/cli/commands/sections.js +4 -2
- package/dist/cli/commands/sections.js.map +1 -1
- package/dist/cli/commands/update.js +4 -2
- package/dist/cli/commands/update.js.map +1 -1
- package/dist/cli/index.js +234 -215
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/output.d.ts +2 -0
- package/dist/cli/output.js +33 -3
- package/dist/cli/output.js.map +1 -1
- package/dist/core/fuzzy.d.ts +16 -0
- package/dist/core/fuzzy.js +39 -0
- package/dist/core/fuzzy.js.map +1 -0
- package/dist/core/lookup.d.ts +1 -1
- package/dist/core/lookup.js +19 -9
- package/dist/core/lookup.js.map +1 -1
- package/dist/core/resolve.d.ts +13 -0
- package/dist/core/resolve.js +25 -0
- package/dist/core/resolve.js.map +1 -0
- package/dist/mcp/server.d.ts +23 -0
- package/dist/mcp/server.js +217 -0
- package/dist/mcp/server.js.map +1 -0
- package/package.json +2 -1
|
@@ -1,11 +1,57 @@
|
|
|
1
1
|
import { getReminders } from "../../core/eventkit.js";
|
|
2
|
+
import { getMemberships } from "../../core/membership.js";
|
|
3
|
+
import { listSections } from "../../core/reminderkit.js";
|
|
4
|
+
import { resolveListName } from "../../core/resolve.js";
|
|
2
5
|
import { outputReminders } from "../output.js";
|
|
3
6
|
export async function listCommand(name, opts) {
|
|
7
|
+
const listName = await resolveListName(name);
|
|
4
8
|
const filter = opts.includeCompleted ? "all" : "incomplete";
|
|
5
|
-
const reminders = await getReminders({ list:
|
|
6
|
-
|
|
9
|
+
const reminders = await getReminders({ list: listName, filter });
|
|
10
|
+
// Try to enrich reminders with section info
|
|
11
|
+
try {
|
|
12
|
+
const [sections, memberships] = await Promise.all([
|
|
13
|
+
listSections(listName),
|
|
14
|
+
getMemberships(listName),
|
|
15
|
+
]);
|
|
16
|
+
if (sections.length > 0) {
|
|
17
|
+
// Build lookup: memberID (dashed UUID) -> groupID
|
|
18
|
+
const memberToGroup = new Map(memberships.memberships.map((m) => [m.reminderID, m.sectionID]));
|
|
19
|
+
// Build groupID -> sectionName lookup from sections + memberships
|
|
20
|
+
const groupToSection = new Map();
|
|
21
|
+
// We need to map groupIDs to section names. Since we don't have
|
|
22
|
+
// section UUIDs from ReminderKit, use the database to match them.
|
|
23
|
+
// For now, use a simpler approach: query section identifiers via the DB
|
|
24
|
+
const { dbFindSection } = await import("../../core/reminderkit.js");
|
|
25
|
+
// Build the map by looking up each section's identifier
|
|
26
|
+
for (const section of sections) {
|
|
27
|
+
try {
|
|
28
|
+
const dbSection = await dbFindSection(section.displayName, listName);
|
|
29
|
+
// Convert hex identifier to dashed UUID
|
|
30
|
+
const hex = dbSection.identifier;
|
|
31
|
+
const uuid = `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
|
32
|
+
groupToSection.set(uuid, section.displayName);
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
// Skip if can't find in DB
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
// Assign section names to reminders
|
|
39
|
+
for (const r of reminders) {
|
|
40
|
+
const groupId = memberToGroup.get(r.id);
|
|
41
|
+
if (groupId) {
|
|
42
|
+
r.section = groupToSection.get(groupId);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
}
|
|
47
|
+
catch {
|
|
48
|
+
// Section enrichment failed (no FDA, no section-helper, etc.)
|
|
49
|
+
// Continue without section info — basic list still works
|
|
50
|
+
}
|
|
51
|
+
outputReminders(reminders, listName, {
|
|
7
52
|
context: "list",
|
|
8
53
|
sortByDate: true,
|
|
54
|
+
groupBySections: true,
|
|
9
55
|
});
|
|
10
56
|
}
|
|
11
57
|
//# sourceMappingURL=list.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAAE,eAAe,EAAE,MAAM,cAAc,CAAC;AAE/C,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,IAAY,EACZ,IAAsD;IAEtD,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,YAAY,CAAC;IAC5D,MAAM,SAAS,GAAG,MAAM,YAAY,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"list.js","sourceRoot":"","sources":["../../../src/cli/commands/list.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,11 +1,13 @@
|
|
|
1
1
|
import { assignToSection } from "../../core/membership.js";
|
|
2
|
+
import { resolveListName, resolveSectionName } from "../../core/resolve.js";
|
|
2
3
|
import { outputMessage } from "../output.js";
|
|
3
4
|
export async function moveCommand(list, title, opts) {
|
|
4
|
-
const
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
const listName = await resolveListName(list);
|
|
6
|
+
const sectionName = await resolveSectionName(listName, opts.toSection);
|
|
7
|
+
const { warning } = await assignToSection(listName, title, sectionName);
|
|
8
|
+
let msg = `Moved "${title}" to section "${sectionName}" in "${listName}"`;
|
|
9
|
+
if (warning)
|
|
7
10
|
msg += ` (note: ${warning})`;
|
|
8
|
-
}
|
|
9
11
|
outputMessage(msg);
|
|
10
12
|
}
|
|
11
13
|
//# sourceMappingURL=move.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../../src/cli/commands/move.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,IAAY,EACZ,KAAa,EACb,IAA2B;IAE3B,MAAM,
|
|
1
|
+
{"version":3,"file":"move.js","sourceRoot":"","sources":["../../../src/cli/commands/move.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC5E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,WAAW,CAChC,IAAY,EACZ,KAAa,EACb,IAA2B;IAE3B,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,WAAW,GAAG,MAAM,kBAAkB,CAAC,QAAQ,EAAE,IAAI,CAAC,SAAS,CAAC,CAAC;IACvE,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,eAAe,CAAC,QAAQ,EAAE,KAAK,EAAE,WAAW,CAAC,CAAC;IACxE,IAAI,GAAG,GAAG,UAAU,KAAK,iBAAiB,WAAW,SAAS,QAAQ,GAAG,CAAC;IAC1E,IAAI,OAAO;QAAE,GAAG,IAAI,WAAW,OAAO,GAAG,CAAC;IAC1C,aAAa,CAAC,GAAG,CAAC,CAAC;AACpB,CAAC"}
|
|
@@ -1,7 +1,9 @@
|
|
|
1
1
|
import { listSections } from "../../core/reminderkit.js";
|
|
2
|
+
import { resolveListName } from "../../core/resolve.js";
|
|
2
3
|
import { outputSections } from "../output.js";
|
|
3
4
|
export async function sectionsCommand(list) {
|
|
4
|
-
const
|
|
5
|
-
|
|
5
|
+
const listName = await resolveListName(list);
|
|
6
|
+
const sections = await listSections(listName);
|
|
7
|
+
outputSections(sections, listName);
|
|
6
8
|
}
|
|
7
9
|
//# sourceMappingURL=sections.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sections.js","sourceRoot":"","sources":["../../../src/cli/commands/sections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IACjD,MAAM,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"sections.js","sourceRoot":"","sources":["../../../src/cli/commands/sections.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AACzD,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAE9C,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY;IACjD,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IAC9C,cAAc,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;AACpC,CAAC"}
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
import { parseDate } from "../../core/dateparse.js";
|
|
2
2
|
import * as eventkit from "../../core/eventkit.js";
|
|
3
3
|
import { findReminderByTitle } from "../../core/lookup.js";
|
|
4
|
+
import { resolveListName } from "../../core/resolve.js";
|
|
4
5
|
import { outputMessage } from "../output.js";
|
|
5
6
|
export async function updateCommand(list, title, opts) {
|
|
6
|
-
const
|
|
7
|
+
const listName = await resolveListName(list);
|
|
8
|
+
const reminder = await findReminderByTitle(listName, title);
|
|
7
9
|
await eventkit.editReminder({
|
|
8
10
|
id: reminder.id,
|
|
9
11
|
title: opts.title,
|
|
@@ -12,6 +14,6 @@ export async function updateCommand(list, title, opts) {
|
|
|
12
14
|
notes: opts.notes,
|
|
13
15
|
priority: opts.priority,
|
|
14
16
|
});
|
|
15
|
-
outputMessage(`Updated "${reminder.title}" in "${
|
|
17
|
+
outputMessage(`Updated "${reminder.title}" in "${listName}"`);
|
|
16
18
|
}
|
|
17
19
|
//# sourceMappingURL=update.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,IAAY,EACZ,KAAa,EACb,IAA6F;IAE7F,MAAM,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"update.js","sourceRoot":"","sources":["../../../src/cli/commands/update.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,QAAQ,MAAM,wBAAwB,CAAC;AACnD,OAAO,EAAE,mBAAmB,EAAE,MAAM,sBAAsB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAE7C,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,IAAY,EACZ,KAAa,EACb,IAA6F;IAE7F,MAAM,QAAQ,GAAG,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;IAC7C,MAAM,QAAQ,GAAG,MAAM,mBAAmB,CAAC,QAAQ,EAAE,KAAK,CAAC,CAAC;IAC5D,MAAM,QAAQ,CAAC,YAAY,CAAC;QAC3B,EAAE,EAAE,QAAQ,CAAC,EAAE;QACf,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,GAAG,EAAE,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,SAAS,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS;QAC/C,QAAQ,EAAE,IAAI,CAAC,QAAQ;QACvB,KAAK,EAAE,IAAI,CAAC,KAAK;QACjB,QAAQ,EAAE,IAAI,CAAC,QAAQ;KACvB,CAAC,CAAC;IACH,aAAa,CAAC,YAAY,QAAQ,CAAC,KAAK,SAAS,QAAQ,GAAG,CAAC,CAAC;AAC/D,CAAC"}
|
package/dist/cli/index.js
CHANGED
|
@@ -1,185 +1,202 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
import
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
const
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
});
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
program
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
});
|
|
91
|
-
program
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
});
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
});
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
program
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
2
|
+
// If --mcp flag is present, start the MCP server instead of the CLI
|
|
3
|
+
if (process.argv.includes("--mcp")) {
|
|
4
|
+
await import("../mcp/server.js");
|
|
5
|
+
// MCP server runs until disconnected — don't proceed to CLI
|
|
6
|
+
}
|
|
7
|
+
else {
|
|
8
|
+
await runCli();
|
|
9
|
+
}
|
|
10
|
+
async function runCli() {
|
|
11
|
+
const { Command } = await import("commander");
|
|
12
|
+
const { RemiCommandError } = await import("../core/errors.js");
|
|
13
|
+
const { outputError, setJsonMode, setVerboseMode } = await import("./output.js");
|
|
14
|
+
const program = new Command();
|
|
15
|
+
program
|
|
16
|
+
.name("remi")
|
|
17
|
+
.description("Fast, reliable CLI for Apple Reminders with section support and iCloud sync")
|
|
18
|
+
.version("0.1.0")
|
|
19
|
+
.option("--json", "Output in JSON format for machine consumption")
|
|
20
|
+
.option("-v, --verbose", "Show additional details (notes preview, full dates)")
|
|
21
|
+
.hook("preAction", (thisCommand) => {
|
|
22
|
+
const opts = thisCommand.opts();
|
|
23
|
+
if (opts.json) {
|
|
24
|
+
setJsonMode(true);
|
|
25
|
+
}
|
|
26
|
+
if (opts.verbose) {
|
|
27
|
+
setVerboseMode(true);
|
|
28
|
+
}
|
|
29
|
+
});
|
|
30
|
+
// -- Daily drivers: queries --
|
|
31
|
+
program
|
|
32
|
+
.command("today")
|
|
33
|
+
.description("Show reminders due today")
|
|
34
|
+
.action(async () => {
|
|
35
|
+
const { todayCommand } = await import("./commands/today.js");
|
|
36
|
+
await todayCommand();
|
|
37
|
+
});
|
|
38
|
+
program
|
|
39
|
+
.command("upcoming")
|
|
40
|
+
.description("Show upcoming reminders")
|
|
41
|
+
.option("--days <n>", "Number of days to look ahead", "7")
|
|
42
|
+
.action(async (opts) => {
|
|
43
|
+
const { upcomingCommand } = await import("./commands/upcoming.js");
|
|
44
|
+
await upcomingCommand(opts);
|
|
45
|
+
});
|
|
46
|
+
program
|
|
47
|
+
.command("overdue")
|
|
48
|
+
.description("Show overdue reminders")
|
|
49
|
+
.action(async () => {
|
|
50
|
+
const { overdueCommand } = await import("./commands/overdue.js");
|
|
51
|
+
await overdueCommand();
|
|
52
|
+
});
|
|
53
|
+
// -- Browse --
|
|
54
|
+
program
|
|
55
|
+
.command("list <name>")
|
|
56
|
+
.description("Show contents of a reminder list")
|
|
57
|
+
.option("--section <section>", "Filter by section")
|
|
58
|
+
.option("--include-completed", "Include completed reminders")
|
|
59
|
+
.action(async (name, opts) => {
|
|
60
|
+
const { listCommand } = await import("./commands/list.js");
|
|
61
|
+
await listCommand(name, opts);
|
|
62
|
+
});
|
|
63
|
+
program
|
|
64
|
+
.command("lists")
|
|
65
|
+
.alias("ls")
|
|
66
|
+
.description("List all reminder lists")
|
|
67
|
+
.action(async () => {
|
|
68
|
+
const { listsCommand } = await import("./commands/lists.js");
|
|
69
|
+
await listsCommand();
|
|
70
|
+
});
|
|
71
|
+
program
|
|
72
|
+
.command("search <query>")
|
|
73
|
+
.description("Search reminders across all lists")
|
|
74
|
+
.action(async (query) => {
|
|
75
|
+
const { searchCommand } = await import("./commands/search.js");
|
|
76
|
+
await searchCommand(query);
|
|
77
|
+
});
|
|
78
|
+
// -- Task actions --
|
|
79
|
+
program
|
|
80
|
+
.command("add <list> <title>")
|
|
81
|
+
.description("Add a reminder to a list")
|
|
82
|
+
.option("--section <section>", "Add to a specific section")
|
|
83
|
+
.option("--due <date>", 'Due date: YYYY-MM-DD or natural language ("tomorrow", "next friday")')
|
|
84
|
+
.option("--priority <level>", "Priority: none, low, medium, high", "none")
|
|
85
|
+
.option("--notes <text>", "Reminder notes")
|
|
86
|
+
.option("--repeat <rule>", 'Recurrence: "daily", "weekly", "every 2 weeks", "every 3 months"')
|
|
87
|
+
.action(async (list, title, opts) => {
|
|
88
|
+
const { addCommand } = await import("./commands/add.js");
|
|
89
|
+
await addCommand(list, title, opts);
|
|
90
|
+
});
|
|
91
|
+
program
|
|
92
|
+
.command("complete <list> <title>")
|
|
93
|
+
.alias("done")
|
|
94
|
+
.description("Mark a reminder as complete")
|
|
95
|
+
.option("--id <id>", "Match by reminder ID instead of title")
|
|
96
|
+
.action(async (list, title, opts) => {
|
|
97
|
+
const { completeCommand } = await import("./commands/complete.js");
|
|
98
|
+
await completeCommand(list, title, opts);
|
|
99
|
+
});
|
|
100
|
+
program
|
|
101
|
+
.command("update <list> <title>")
|
|
102
|
+
.description("Update a reminder")
|
|
103
|
+
.option("--title <newTitle>", "New title")
|
|
104
|
+
.option("--due <date>", "New due date: YYYY-MM-DD or natural language")
|
|
105
|
+
.option("--clear-due", "Remove due date")
|
|
106
|
+
.option("--priority <level>", "New priority: none, low, medium, high")
|
|
107
|
+
.option("--notes <text>", "New notes")
|
|
108
|
+
.action(async (list, title, opts) => {
|
|
109
|
+
const { updateCommand } = await import("./commands/update.js");
|
|
110
|
+
await updateCommand(list, title, opts);
|
|
111
|
+
});
|
|
112
|
+
program
|
|
113
|
+
.command("delete <list> <title>")
|
|
114
|
+
.alias("rm")
|
|
115
|
+
.description("Delete a reminder")
|
|
116
|
+
.option("--id <id>", "Match by reminder ID instead of title")
|
|
117
|
+
.option("--confirm", "Confirm deletion (required in interactive mode)")
|
|
118
|
+
.action(async (list, title, opts) => {
|
|
119
|
+
const { deleteCommand } = await import("./commands/delete.js");
|
|
120
|
+
await deleteCommand(list, title, opts);
|
|
121
|
+
});
|
|
122
|
+
// -- Organization: sections and lists --
|
|
123
|
+
program
|
|
124
|
+
.command("sections <list>")
|
|
125
|
+
.description("List sections in a reminder list")
|
|
126
|
+
.action(async (list) => {
|
|
127
|
+
const { sectionsCommand } = await import("./commands/sections.js");
|
|
128
|
+
await sectionsCommand(list);
|
|
129
|
+
});
|
|
130
|
+
program
|
|
131
|
+
.command("move <list> <title>")
|
|
132
|
+
.description("Move a reminder to a different section")
|
|
133
|
+
.requiredOption("--to-section <section>", "Target section name")
|
|
134
|
+
.action(async (list, title, opts) => {
|
|
135
|
+
const { moveCommand } = await import("./commands/move.js");
|
|
136
|
+
await moveCommand(list, title, opts);
|
|
137
|
+
});
|
|
138
|
+
program
|
|
139
|
+
.command("create-section <list> <name>")
|
|
140
|
+
.description("Create a section in a reminder list")
|
|
141
|
+
.action(async (list, name) => {
|
|
142
|
+
const { createSectionCommand } = await import("./commands/create-section.js");
|
|
143
|
+
await createSectionCommand(list, name);
|
|
144
|
+
});
|
|
145
|
+
program
|
|
146
|
+
.command("delete-section <list> <name>")
|
|
147
|
+
.description("Delete a section from a reminder list")
|
|
148
|
+
.action(async (list, name) => {
|
|
149
|
+
const { deleteSectionCommand } = await import("./commands/delete-section.js");
|
|
150
|
+
await deleteSectionCommand(list, name);
|
|
151
|
+
});
|
|
152
|
+
program
|
|
153
|
+
.command("create-list <name>")
|
|
154
|
+
.description("Create a new reminder list")
|
|
155
|
+
.action(async (name) => {
|
|
156
|
+
const { createListCommand } = await import("./commands/create-list.js");
|
|
157
|
+
await createListCommand(name);
|
|
158
|
+
});
|
|
159
|
+
program
|
|
160
|
+
.command("delete-list <name>")
|
|
161
|
+
.description("Delete a reminder list")
|
|
162
|
+
.option("--confirm", "Confirm deletion (required in interactive mode)")
|
|
163
|
+
.action(async (name, opts) => {
|
|
164
|
+
const { deleteListCommand } = await import("./commands/delete-list.js");
|
|
165
|
+
await deleteListCommand(name, opts);
|
|
166
|
+
});
|
|
167
|
+
// -- System --
|
|
168
|
+
program
|
|
169
|
+
.command("demo", { hidden: true })
|
|
170
|
+
.description("Create a demo list to showcase remi features")
|
|
171
|
+
.option("--cleanup", "Remove the demo list")
|
|
172
|
+
.action(async (opts) => {
|
|
173
|
+
const { demoCommand } = await import("./commands/demo.js");
|
|
174
|
+
await demoCommand(opts);
|
|
175
|
+
});
|
|
176
|
+
program
|
|
177
|
+
.command("authorize")
|
|
178
|
+
.description("Request Reminders access permission")
|
|
179
|
+
.action(async () => {
|
|
180
|
+
const { authorizeCommand } = await import("./commands/authorize.js");
|
|
181
|
+
await authorizeCommand();
|
|
182
|
+
});
|
|
183
|
+
program
|
|
184
|
+
.command("doctor")
|
|
185
|
+
.description("Check system health and diagnostics")
|
|
186
|
+
.option("--sync", "Verify sync status")
|
|
187
|
+
.option("--db", "Show database location and stats")
|
|
188
|
+
.action(async (opts) => {
|
|
189
|
+
const { doctorCommand } = await import("./commands/doctor.js");
|
|
190
|
+
await doctorCommand(opts);
|
|
191
|
+
});
|
|
192
|
+
program
|
|
193
|
+
.command("completions")
|
|
194
|
+
.description("Generate shell completions (bash, zsh, fish)")
|
|
195
|
+
.argument("<shell>", "Shell type: bash, zsh, or fish")
|
|
196
|
+
.action(async (shell) => {
|
|
197
|
+
const commands = program.commands.map((c) => c.name()).filter((n) => n !== "completions");
|
|
198
|
+
if (shell === "zsh") {
|
|
199
|
+
const completions = `#compdef remi
|
|
183
200
|
_remi() {
|
|
184
201
|
local -a commands
|
|
185
202
|
commands=(
|
|
@@ -188,45 +205,47 @@ ${commands.map((c) => ` '${c}:${program.commands.find((cmd) => cmd.name() ===
|
|
|
188
205
|
_describe 'command' commands
|
|
189
206
|
}
|
|
190
207
|
compdef _remi remi`;
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
208
|
+
process.stdout.write(`${completions}\n`);
|
|
209
|
+
}
|
|
210
|
+
else if (shell === "bash") {
|
|
211
|
+
const completions = `_remi() {
|
|
195
212
|
local commands="${commands.join(" ")}"
|
|
196
213
|
COMPREPLY=($(compgen -W "$commands" -- "\${COMP_WORDS[COMP_CWORD]}"))
|
|
197
214
|
}
|
|
198
215
|
complete -F _remi remi`;
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
});
|
|
215
|
-
// -- Error handling --
|
|
216
|
-
async function main() {
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
216
|
+
process.stdout.write(`${completions}\n`);
|
|
217
|
+
}
|
|
218
|
+
else if (shell === "fish") {
|
|
219
|
+
const lines = commands
|
|
220
|
+
.map((c) => {
|
|
221
|
+
const desc = program.commands.find((cmd) => cmd.name() === c)?.description() || "";
|
|
222
|
+
return `complete -c remi -n '__fish_use_subcommand' -a '${c}' -d '${desc}'`;
|
|
223
|
+
})
|
|
224
|
+
.join("\n");
|
|
225
|
+
process.stdout.write(`${lines}\n`);
|
|
226
|
+
}
|
|
227
|
+
else {
|
|
228
|
+
process.stderr.write(`Unknown shell: ${shell}. Use: bash, zsh, or fish\n`);
|
|
229
|
+
process.exit(1);
|
|
230
|
+
}
|
|
231
|
+
});
|
|
232
|
+
// -- Error handling --
|
|
233
|
+
async function main() {
|
|
234
|
+
try {
|
|
235
|
+
await program.parseAsync(process.argv);
|
|
236
|
+
}
|
|
237
|
+
catch (err) {
|
|
238
|
+
if (err instanceof RemiCommandError) {
|
|
239
|
+
outputError(err.toRemiError());
|
|
240
|
+
process.exit(1);
|
|
241
|
+
}
|
|
242
|
+
// Unknown error
|
|
243
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
244
|
+
outputError({ code: "UNKNOWN", message });
|
|
223
245
|
process.exit(1);
|
|
224
246
|
}
|
|
225
|
-
// Unknown error
|
|
226
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
227
|
-
outputError({ code: "UNKNOWN", message });
|
|
228
|
-
process.exit(1);
|
|
229
247
|
}
|
|
230
|
-
|
|
231
|
-
|
|
248
|
+
main();
|
|
249
|
+
} // end of runCli()
|
|
250
|
+
export {};
|
|
232
251
|
//# sourceMappingURL=index.js.map
|