@tekmidian/devon 3.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +472 -0
- package/dist/index.d.ts +12 -0
- package/dist/index.js +82 -0
- package/dist/index.js.map +1 -0
- package/dist/jxa/escape.d.ts +22 -0
- package/dist/jxa/escape.js +38 -0
- package/dist/jxa/escape.js.map +1 -0
- package/dist/jxa/executor.d.ts +32 -0
- package/dist/jxa/executor.js +65 -0
- package/dist/jxa/executor.js.map +1 -0
- package/dist/jxa/helpers.d.ts +51 -0
- package/dist/jxa/helpers.js +136 -0
- package/dist/jxa/helpers.js.map +1 -0
- package/dist/jxa/types.d.ts +33 -0
- package/dist/jxa/types.js +43 -0
- package/dist/jxa/types.js.map +1 -0
- package/dist/server.d.ts +10 -0
- package/dist/server.js +65 -0
- package/dist/server.js.map +1 -0
- package/dist/setup.d.ts +12 -0
- package/dist/setup.js +323 -0
- package/dist/setup.js.map +1 -0
- package/dist/shared/plist/parser.d.ts +29 -0
- package/dist/shared/plist/parser.js +112 -0
- package/dist/shared/plist/parser.js.map +1 -0
- package/dist/shared/plist/reader.d.ts +31 -0
- package/dist/shared/plist/reader.js +127 -0
- package/dist/shared/plist/reader.js.map +1 -0
- package/dist/shared/shell.d.ts +15 -0
- package/dist/shared/shell.js +22 -0
- package/dist/shared/shell.js.map +1 -0
- package/dist/tools/ai/ask-ai-about-documents.d.ts +8 -0
- package/dist/tools/ai/ask-ai-about-documents.js +88 -0
- package/dist/tools/ai/ask-ai-about-documents.js.map +1 -0
- package/dist/tools/ai/check-ai-health.d.ts +8 -0
- package/dist/tools/ai/check-ai-health.js +40 -0
- package/dist/tools/ai/check-ai-health.js.map +1 -0
- package/dist/tools/ai/create-summary-document.d.ts +8 -0
- package/dist/tools/ai/create-summary-document.js +102 -0
- package/dist/tools/ai/create-summary-document.js.map +1 -0
- package/dist/tools/ai/get-ai-tool-documentation.d.ts +8 -0
- package/dist/tools/ai/get-ai-tool-documentation.js +220 -0
- package/dist/tools/ai/get-ai-tool-documentation.js.map +1 -0
- package/dist/tools/application/is-running.d.ts +7 -0
- package/dist/tools/application/is-running.js +24 -0
- package/dist/tools/application/is-running.js.map +1 -0
- package/dist/tools/custom/column-layout.d.ts +9 -0
- package/dist/tools/custom/column-layout.js +244 -0
- package/dist/tools/custom/column-layout.js.map +1 -0
- package/dist/tools/custom/list-smart-groups.d.ts +8 -0
- package/dist/tools/custom/list-smart-groups.js +79 -0
- package/dist/tools/custom/list-smart-groups.js.map +1 -0
- package/dist/tools/custom/list-smart-rules.d.ts +8 -0
- package/dist/tools/custom/list-smart-rules.js +85 -0
- package/dist/tools/custom/list-smart-rules.js.map +1 -0
- package/dist/tools/custom/parse-eml-headers.d.ts +8 -0
- package/dist/tools/custom/parse-eml-headers.js +155 -0
- package/dist/tools/custom/parse-eml-headers.js.map +1 -0
- package/dist/tools/database/get-current-database.d.ts +7 -0
- package/dist/tools/database/get-current-database.js +29 -0
- package/dist/tools/database/get-current-database.js.map +1 -0
- package/dist/tools/database/get-open-databases.d.ts +6 -0
- package/dist/tools/database/get-open-databases.js +32 -0
- package/dist/tools/database/get-open-databases.js.map +1 -0
- package/dist/tools/groups/get-selected-records.d.ts +8 -0
- package/dist/tools/groups/get-selected-records.js +30 -0
- package/dist/tools/groups/get-selected-records.js.map +1 -0
- package/dist/tools/groups/list-group-content.d.ts +8 -0
- package/dist/tools/groups/list-group-content.js +65 -0
- package/dist/tools/groups/list-group-content.js.map +1 -0
- package/dist/tools/index.d.ts +9 -0
- package/dist/tools/index.js +87 -0
- package/dist/tools/index.js.map +1 -0
- package/dist/tools/intelligence/classify.d.ts +8 -0
- package/dist/tools/intelligence/classify.js +83 -0
- package/dist/tools/intelligence/classify.js.map +1 -0
- package/dist/tools/intelligence/compare.d.ts +8 -0
- package/dist/tools/intelligence/compare.js +121 -0
- package/dist/tools/intelligence/compare.js.map +1 -0
- package/dist/tools/records/convert-record.d.ts +10 -0
- package/dist/tools/records/convert-record.js +77 -0
- package/dist/tools/records/convert-record.js.map +1 -0
- package/dist/tools/records/create-record.d.ts +8 -0
- package/dist/tools/records/create-record.js +64 -0
- package/dist/tools/records/create-record.js.map +1 -0
- package/dist/tools/records/delete-record.d.ts +9 -0
- package/dist/tools/records/delete-record.js +50 -0
- package/dist/tools/records/delete-record.js.map +1 -0
- package/dist/tools/records/duplicate-record.d.ts +8 -0
- package/dist/tools/records/duplicate-record.js +53 -0
- package/dist/tools/records/duplicate-record.js.map +1 -0
- package/dist/tools/records/get-record-by-id.d.ts +8 -0
- package/dist/tools/records/get-record-by-id.js +51 -0
- package/dist/tools/records/get-record-by-id.js.map +1 -0
- package/dist/tools/records/get-record-content.d.ts +7 -0
- package/dist/tools/records/get-record-content.js +48 -0
- package/dist/tools/records/get-record-content.js.map +1 -0
- package/dist/tools/records/get-record-properties.d.ts +7 -0
- package/dist/tools/records/get-record-properties.js +42 -0
- package/dist/tools/records/get-record-properties.js.map +1 -0
- package/dist/tools/records/move-record.d.ts +8 -0
- package/dist/tools/records/move-record.js +60 -0
- package/dist/tools/records/move-record.js.map +1 -0
- package/dist/tools/records/rename-record.d.ts +7 -0
- package/dist/tools/records/rename-record.js +40 -0
- package/dist/tools/records/rename-record.js.map +1 -0
- package/dist/tools/records/replicate-record.d.ts +8 -0
- package/dist/tools/records/replicate-record.js +53 -0
- package/dist/tools/records/replicate-record.js.map +1 -0
- package/dist/tools/records/set-record-properties.d.ts +10 -0
- package/dist/tools/records/set-record-properties.js +76 -0
- package/dist/tools/records/set-record-properties.js.map +1 -0
- package/dist/tools/records/update-record-content.d.ts +7 -0
- package/dist/tools/records/update-record-content.js +43 -0
- package/dist/tools/records/update-record-content.js.map +1 -0
- package/dist/tools/search/lookup-record.d.ts +7 -0
- package/dist/tools/search/lookup-record.js +160 -0
- package/dist/tools/search/lookup-record.js.map +1 -0
- package/dist/tools/search/search.d.ts +8 -0
- package/dist/tools/search/search.js +146 -0
- package/dist/tools/search/search.js.map +1 -0
- package/dist/tools/tags/add-tags.d.ts +7 -0
- package/dist/tools/tags/add-tags.js +47 -0
- package/dist/tools/tags/add-tags.js.map +1 -0
- package/dist/tools/tags/remove-tags.d.ts +7 -0
- package/dist/tools/tags/remove-tags.js +53 -0
- package/dist/tools/tags/remove-tags.js.map +1 -0
- package/dist/tools/web/create-from-url.d.ts +8 -0
- package/dist/tools/web/create-from-url.js +140 -0
- package/dist/tools/web/create-from-url.js.map +1 -0
- package/package.json +48 -0
|
@@ -0,0 +1,244 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* column-layout.ts — Read and copy DEVONthink column layouts for smart groups/rules.
|
|
3
|
+
*
|
|
4
|
+
* Column layouts are stored in ~/Library/Preferences/com.devon-technologies.think.plist
|
|
5
|
+
* under three related keys per smart group or rule.
|
|
6
|
+
*/
|
|
7
|
+
import { homedir } from "node:os";
|
|
8
|
+
import { join } from "node:path";
|
|
9
|
+
import { plistRead, parsePlistBuddyArray, parsePlistBuddyDict, getPlistKeysByPrefix, copyPlistKeys, } from "../../shared/plist/reader.js";
|
|
10
|
+
const PLIST_PATH = join(homedir(), "Library", "Preferences", "com.devon-technologies.think.plist");
|
|
11
|
+
const LAYOUT_PREFIXES = [
|
|
12
|
+
"ListColumnsHorizontal-",
|
|
13
|
+
"TableView Columns ListColumnsHorizontal-",
|
|
14
|
+
"TableView Column Widths ListColumnsHorizontal-",
|
|
15
|
+
];
|
|
16
|
+
const LAYOUT_SUFFIXES = [
|
|
17
|
+
"ListColumnsHorizontal",
|
|
18
|
+
"TableView Columns ListColumnsHorizontal",
|
|
19
|
+
"TableView Column Widths ListColumnsHorizontal",
|
|
20
|
+
];
|
|
21
|
+
function keysForName(name) {
|
|
22
|
+
return {
|
|
23
|
+
columnsKey: `ListColumnsHorizontal-${name}`,
|
|
24
|
+
tableViewColumnsKey: `TableView Columns ListColumnsHorizontal-${name}`,
|
|
25
|
+
tableViewWidthsKey: `TableView Column Widths ListColumnsHorizontal-${name}`,
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
function readLayoutForName(baseName) {
|
|
29
|
+
const { columnsKey, tableViewColumnsKey, tableViewWidthsKey } = keysForName(baseName);
|
|
30
|
+
const rawColumns = plistRead(PLIST_PATH, `Print ':${columnsKey}'`);
|
|
31
|
+
const rawTableViewColumns = plistRead(PLIST_PATH, `Print ':${tableViewColumnsKey}'`);
|
|
32
|
+
const rawWidths = plistRead(PLIST_PATH, `Print ':${tableViewWidthsKey}'`);
|
|
33
|
+
if (!rawColumns && !rawTableViewColumns && !rawWidths) {
|
|
34
|
+
return null;
|
|
35
|
+
}
|
|
36
|
+
const keysFound = [];
|
|
37
|
+
if (rawColumns)
|
|
38
|
+
keysFound.push(columnsKey);
|
|
39
|
+
if (rawTableViewColumns)
|
|
40
|
+
keysFound.push(tableViewColumnsKey);
|
|
41
|
+
if (rawWidths)
|
|
42
|
+
keysFound.push(tableViewWidthsKey);
|
|
43
|
+
return {
|
|
44
|
+
found: true,
|
|
45
|
+
name: baseName,
|
|
46
|
+
resolvedKey: baseName,
|
|
47
|
+
columns: rawColumns ? parsePlistBuddyArray(rawColumns) : null,
|
|
48
|
+
tableViewColumns: rawTableViewColumns ? parsePlistBuddyArray(rawTableViewColumns) : null,
|
|
49
|
+
widths: rawWidths ? parsePlistBuddyDict(rawWidths) : null,
|
|
50
|
+
keysFound,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
function getExistingNames(limit = 20) {
|
|
54
|
+
return getPlistKeysByPrefix(PLIST_PATH, LAYOUT_PREFIXES, limit);
|
|
55
|
+
}
|
|
56
|
+
function findMatchingNames(searchTerm) {
|
|
57
|
+
const allNames = getExistingNames(200);
|
|
58
|
+
const lower = searchTerm.toLowerCase();
|
|
59
|
+
return allNames.filter((n) => n.toLowerCase().includes(lower));
|
|
60
|
+
}
|
|
61
|
+
// ---------------------------------------------------------------------------
|
|
62
|
+
// get_column_layout
|
|
63
|
+
// ---------------------------------------------------------------------------
|
|
64
|
+
const getColumnLayout = async (args) => {
|
|
65
|
+
const name = args.name;
|
|
66
|
+
const uuid = args.uuid;
|
|
67
|
+
if (!name || typeof name !== "string") {
|
|
68
|
+
return { success: false, error: "name parameter is required" };
|
|
69
|
+
}
|
|
70
|
+
const exactResult = readLayoutForName(name);
|
|
71
|
+
if (exactResult) {
|
|
72
|
+
return { success: true, ...exactResult };
|
|
73
|
+
}
|
|
74
|
+
if (uuid && typeof uuid === "string") {
|
|
75
|
+
const uuidResult = readLayoutForName(uuid);
|
|
76
|
+
if (uuidResult) {
|
|
77
|
+
return { success: true, ...uuidResult, name };
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
const fuzzyMatches = findMatchingNames(name);
|
|
81
|
+
if (fuzzyMatches.length === 1) {
|
|
82
|
+
const fuzzyResult = readLayoutForName(fuzzyMatches[0]);
|
|
83
|
+
if (fuzzyResult) {
|
|
84
|
+
return {
|
|
85
|
+
success: true,
|
|
86
|
+
...fuzzyResult,
|
|
87
|
+
nameSearched: name,
|
|
88
|
+
note: `Exact name not found; matched "${fuzzyMatches[0]}" via partial search`,
|
|
89
|
+
};
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
const examples = getExistingNames(15);
|
|
93
|
+
if (fuzzyMatches.length > 1) {
|
|
94
|
+
return {
|
|
95
|
+
success: false,
|
|
96
|
+
name,
|
|
97
|
+
error: `No exact match for "${name}". Multiple partial matches found — be more specific.`,
|
|
98
|
+
partialMatches: fuzzyMatches,
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return {
|
|
102
|
+
success: false,
|
|
103
|
+
name,
|
|
104
|
+
error: `No column layout found for "${name}". ` +
|
|
105
|
+
"This smart group may not have a custom layout yet (it will use defaults). " +
|
|
106
|
+
"Use copy_column_layout to copy an existing layout to it.",
|
|
107
|
+
exampleNames: examples,
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
export const getColumnLayoutTool = {
|
|
111
|
+
name: "get_column_layout",
|
|
112
|
+
description: "Read the column layout for a DEVONthink smart group or smart rule from preferences. " +
|
|
113
|
+
"Returns the ordered visible columns, all table view columns, and column widths. " +
|
|
114
|
+
"Looks up by name (or UUID). Supports partial name matching. " +
|
|
115
|
+
'Input: { "name": "Archivieren - Jobs" } or { "name": "Jobs", "uuid": "4A469368-..." }',
|
|
116
|
+
inputSchema: {
|
|
117
|
+
type: "object",
|
|
118
|
+
properties: {
|
|
119
|
+
name: {
|
|
120
|
+
type: "string",
|
|
121
|
+
description: "Name of the smart group or smart rule whose column layout to read",
|
|
122
|
+
},
|
|
123
|
+
uuid: {
|
|
124
|
+
type: "string",
|
|
125
|
+
description: "Optional UUID of the smart group (fallback if name not found). " +
|
|
126
|
+
"DEVONthink sometimes stores layouts under the UUID rather than the display name.",
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
required: ["name"],
|
|
130
|
+
},
|
|
131
|
+
run: getColumnLayout,
|
|
132
|
+
};
|
|
133
|
+
const copyColumnLayout = async (args) => {
|
|
134
|
+
const sourceName = args.sourceName;
|
|
135
|
+
const targetName = args.targetName;
|
|
136
|
+
const sourceUuid = args.sourceUuid;
|
|
137
|
+
const targetUuid = args.targetUuid;
|
|
138
|
+
if (!sourceName || typeof sourceName !== "string") {
|
|
139
|
+
return { success: false, error: "sourceName parameter is required" };
|
|
140
|
+
}
|
|
141
|
+
if (!targetName || typeof targetName !== "string") {
|
|
142
|
+
return { success: false, error: "targetName parameter is required" };
|
|
143
|
+
}
|
|
144
|
+
let resolvedSourceKey = null;
|
|
145
|
+
if (readLayoutForName(sourceName)) {
|
|
146
|
+
resolvedSourceKey = sourceName;
|
|
147
|
+
}
|
|
148
|
+
else if (sourceUuid && readLayoutForName(sourceUuid)) {
|
|
149
|
+
resolvedSourceKey = sourceUuid;
|
|
150
|
+
}
|
|
151
|
+
else {
|
|
152
|
+
const fuzzy = findMatchingNames(sourceName);
|
|
153
|
+
if (fuzzy.length === 1 && readLayoutForName(fuzzy[0])) {
|
|
154
|
+
resolvedSourceKey = fuzzy[0];
|
|
155
|
+
}
|
|
156
|
+
else if (fuzzy.length > 1) {
|
|
157
|
+
return {
|
|
158
|
+
success: false,
|
|
159
|
+
sourceName,
|
|
160
|
+
targetName,
|
|
161
|
+
error: `Ambiguous source name "${sourceName}". Multiple matches: ${fuzzy.slice(0, 8).join(", ")}`,
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
if (!resolvedSourceKey) {
|
|
166
|
+
const examples = getExistingNames(10);
|
|
167
|
+
return {
|
|
168
|
+
success: false,
|
|
169
|
+
sourceName,
|
|
170
|
+
targetName,
|
|
171
|
+
error: `Source column layout for "${sourceName}" not found. ` +
|
|
172
|
+
"This smart group may not have a custom layout saved yet. " +
|
|
173
|
+
`Known layouts include: ${examples.slice(0, 8).join(", ")}`,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
const resolvedTargetKey = targetUuid ?? targetName;
|
|
177
|
+
const copyResult = copyPlistKeys(PLIST_PATH, LAYOUT_SUFFIXES, resolvedSourceKey, resolvedTargetKey);
|
|
178
|
+
if (!copyResult.ok) {
|
|
179
|
+
return {
|
|
180
|
+
success: false,
|
|
181
|
+
sourceName,
|
|
182
|
+
targetName,
|
|
183
|
+
resolvedSourceKey,
|
|
184
|
+
resolvedTargetKey,
|
|
185
|
+
error: `Copy failed: ${copyResult.error}`,
|
|
186
|
+
};
|
|
187
|
+
}
|
|
188
|
+
const verification = readLayoutForName(resolvedTargetKey);
|
|
189
|
+
if (!verification) {
|
|
190
|
+
return {
|
|
191
|
+
success: false,
|
|
192
|
+
sourceName,
|
|
193
|
+
targetName,
|
|
194
|
+
resolvedSourceKey,
|
|
195
|
+
resolvedTargetKey,
|
|
196
|
+
error: "Copy appeared to succeed but target keys not readable after write",
|
|
197
|
+
};
|
|
198
|
+
}
|
|
199
|
+
return {
|
|
200
|
+
success: true,
|
|
201
|
+
sourceName,
|
|
202
|
+
targetName,
|
|
203
|
+
resolvedSourceKey,
|
|
204
|
+
resolvedTargetKey,
|
|
205
|
+
keysCopied: copyResult.keysCopied,
|
|
206
|
+
message: `Copied column layout from "${sourceName}" to "${targetName}". ` +
|
|
207
|
+
`Keys written: ${copyResult.keysCopied.join(", ")}. ` +
|
|
208
|
+
`Columns: [${verification.columns?.join(", ") ?? "n/a"}]. ` +
|
|
209
|
+
"Restart DEVONthink or close/reopen the smart group window for the change to take effect.",
|
|
210
|
+
};
|
|
211
|
+
};
|
|
212
|
+
export const copyColumnLayoutTool = {
|
|
213
|
+
name: "copy_column_layout",
|
|
214
|
+
description: "Copy the column layout (column order, visible columns, and column widths) from one " +
|
|
215
|
+
"DEVONthink smart group or smart rule to another. " +
|
|
216
|
+
"All three layout keys are copied atomically. Supports partial name matching. " +
|
|
217
|
+
'Input: { "sourceName": "Archivieren - Jobs", "targetName": "Jobs - To Review" }',
|
|
218
|
+
inputSchema: {
|
|
219
|
+
type: "object",
|
|
220
|
+
properties: {
|
|
221
|
+
sourceName: {
|
|
222
|
+
type: "string",
|
|
223
|
+
description: "Name of the source smart group or smart rule (must have a saved layout)",
|
|
224
|
+
},
|
|
225
|
+
targetName: {
|
|
226
|
+
type: "string",
|
|
227
|
+
description: "Name of the target smart group or smart rule to copy the layout to",
|
|
228
|
+
},
|
|
229
|
+
sourceUuid: {
|
|
230
|
+
type: "string",
|
|
231
|
+
description: "Optional UUID of the source smart group (fallback if name lookup fails). " +
|
|
232
|
+
"DEVONthink sometimes stores layouts under the UUID.",
|
|
233
|
+
},
|
|
234
|
+
targetUuid: {
|
|
235
|
+
type: "string",
|
|
236
|
+
description: "Optional UUID of the target smart group. If supplied, the layout is written " +
|
|
237
|
+
"under the UUID key (which DEVONthink prefers for smart groups).",
|
|
238
|
+
},
|
|
239
|
+
},
|
|
240
|
+
required: ["sourceName", "targetName"],
|
|
241
|
+
},
|
|
242
|
+
run: copyColumnLayout,
|
|
243
|
+
};
|
|
244
|
+
//# sourceMappingURL=column-layout.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"column-layout.js","sourceRoot":"","sources":["../../../src/tools/custom/column-layout.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EACL,SAAS,EACT,oBAAoB,EACpB,mBAAmB,EACnB,oBAAoB,EACpB,aAAa,GACd,MAAM,8BAA8B,CAAC;AAGtC,MAAM,UAAU,GAAG,IAAI,CACrB,OAAO,EAAE,EACT,SAAS,EACT,aAAa,EACb,oCAAoC,CACrC,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,wBAAwB;IACxB,0CAA0C;IAC1C,gDAAgD;CACjD,CAAC;AAEF,MAAM,eAAe,GAAG;IACtB,uBAAuB;IACvB,yCAAyC;IACzC,+CAA+C;CAChD,CAAC;AAEF,SAAS,WAAW,CAAC,IAAY;IAC/B,OAAO;QACL,UAAU,EAAE,yBAAyB,IAAI,EAAE;QAC3C,mBAAmB,EAAE,2CAA2C,IAAI,EAAE;QACtE,kBAAkB,EAAE,iDAAiD,IAAI,EAAE;KAC5E,CAAC;AACJ,CAAC;AAYD,SAAS,iBAAiB,CAAC,QAAgB;IACzC,MAAM,EAAE,UAAU,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,GAAG,WAAW,CAAC,QAAQ,CAAC,CAAC;IAEtF,MAAM,UAAU,GAAG,SAAS,CAAC,UAAU,EAAE,WAAW,UAAU,GAAG,CAAC,CAAC;IACnE,MAAM,mBAAmB,GAAG,SAAS,CAAC,UAAU,EAAE,WAAW,mBAAmB,GAAG,CAAC,CAAC;IACrF,MAAM,SAAS,GAAG,SAAS,CAAC,UAAU,EAAE,WAAW,kBAAkB,GAAG,CAAC,CAAC;IAE1E,IAAI,CAAC,UAAU,IAAI,CAAC,mBAAmB,IAAI,CAAC,SAAS,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,SAAS,GAAa,EAAE,CAAC;IAC/B,IAAI,UAAU;QAAE,SAAS,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;IAC3C,IAAI,mBAAmB;QAAE,SAAS,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;IAC7D,IAAI,SAAS;QAAE,SAAS,CAAC,IAAI,CAAC,kBAAkB,CAAC,CAAC;IAElD,OAAO;QACL,KAAK,EAAE,IAAI;QACX,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,QAAQ;QACrB,OAAO,EAAE,UAAU,CAAC,CAAC,CAAC,oBAAoB,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,IAAI;QAC7D,gBAAgB,EAAE,mBAAmB,CAAC,CAAC,CAAC,oBAAoB,CAAC,mBAAmB,CAAC,CAAC,CAAC,CAAC,IAAI;QACxF,MAAM,EAAE,SAAS,CAAC,CAAC,CAAC,mBAAmB,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,IAAI;QACzD,SAAS;KACV,CAAC;AACJ,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAK,GAAG,EAAE;IAClC,OAAO,oBAAoB,CAAC,UAAU,EAAE,eAAe,EAAE,KAAK,CAAC,CAAC;AAClE,CAAC;AAED,SAAS,iBAAiB,CAAC,UAAkB;IAC3C,MAAM,QAAQ,GAAG,gBAAgB,CAAC,GAAG,CAAC,CAAC;IACvC,MAAM,KAAK,GAAG,UAAU,CAAC,WAAW,EAAE,CAAC;IACvC,OAAO,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC;AACjE,CAAC;AAED,8EAA8E;AAC9E,oBAAoB;AACpB,8EAA8E;AAE9E,MAAM,eAAe,GAAG,KAAK,EAAE,IAA6B,EAAoB,EAAE;IAChF,MAAM,IAAI,GAAG,IAAI,CAAC,IAA0B,CAAC;IAC7C,MAAM,IAAI,GAAG,IAAI,CAAC,IAA0B,CAAC;IAE7C,IAAI,CAAC,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACtC,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,4BAA4B,EAAE,CAAC;IACjE,CAAC;IAED,MAAM,WAAW,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAC5C,IAAI,WAAW,EAAE,CAAC;QAChB,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,WAAW,EAAE,CAAC;IAC3C,CAAC;IAED,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ,EAAE,CAAC;QACrC,MAAM,UAAU,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QAC3C,IAAI,UAAU,EAAE,CAAC;YACf,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,UAAU,EAAE,IAAI,EAAE,CAAC;QAChD,CAAC;IACH,CAAC;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;IAE7C,IAAI,YAAY,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,MAAM,WAAW,GAAG,iBAAiB,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;QACvD,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,GAAG,WAAW;gBACd,YAAY,EAAE,IAAI;gBAClB,IAAI,EAAE,kCAAkC,YAAY,CAAC,CAAC,CAAC,sBAAsB;aAC9E,CAAC;QACJ,CAAC;IACH,CAAC;IAED,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;IAEtC,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,IAAI;YACJ,KAAK,EAAE,uBAAuB,IAAI,uDAAuD;YACzF,cAAc,EAAE,YAAY;SAC7B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,KAAK;QACd,IAAI;QACJ,KAAK,EACH,+BAA+B,IAAI,KAAK;YACxC,4EAA4E;YAC5E,0DAA0D;QAC5D,YAAY,EAAE,QAAQ;KACvB,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,mBAAmB,GAAY;IAC1C,IAAI,EAAE,mBAAmB;IACzB,WAAW,EACT,sFAAsF;QACtF,kFAAkF;QAClF,8DAA8D;QAC9D,uFAAuF;IACzF,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,mEAAmE;aACjF;YACD,IAAI,EAAE;gBACJ,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,iEAAiE;oBACjE,kFAAkF;aACrF;SACF;QACD,QAAQ,EAAE,CAAC,MAAM,CAAC;KACnB;IACD,GAAG,EAAE,eAAe;CACrB,CAAC;AAiBF,MAAM,gBAAgB,GAAG,KAAK,EAAE,IAA6B,EAAmC,EAAE;IAChG,MAAM,UAAU,GAAG,IAAI,CAAC,UAAgC,CAAC;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAgC,CAAC;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAgC,CAAC;IACzD,MAAM,UAAU,GAAG,IAAI,CAAC,UAAgC,CAAC;IAEzD,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IACvE,CAAC;IACD,IAAI,CAAC,UAAU,IAAI,OAAO,UAAU,KAAK,QAAQ,EAAE,CAAC;QAClD,OAAO,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,kCAAkC,EAAE,CAAC;IACvE,CAAC;IAED,IAAI,iBAAiB,GAAkB,IAAI,CAAC;IAE5C,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QAClC,iBAAiB,GAAG,UAAU,CAAC;IACjC,CAAC;SAAM,IAAI,UAAU,IAAI,iBAAiB,CAAC,UAAU,CAAC,EAAE,CAAC;QACvD,iBAAiB,GAAG,UAAU,CAAC;IACjC,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,GAAG,iBAAiB,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,IAAI,iBAAiB,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YACtD,iBAAiB,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;QAC/B,CAAC;aAAM,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC5B,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,UAAU;gBACV,UAAU;gBACV,KAAK,EAAE,0BAA0B,UAAU,wBAAwB,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;aAClG,CAAC;QACJ,CAAC;IACH,CAAC;IAED,IAAI,CAAC,iBAAiB,EAAE,CAAC;QACvB,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,CAAC;QACtC,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU;YACV,UAAU;YACV,KAAK,EACH,6BAA6B,UAAU,eAAe;gBACtD,2DAA2D;gBAC3D,0BAA0B,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE;SAC9D,CAAC;IACJ,CAAC;IAED,MAAM,iBAAiB,GAAG,UAAU,IAAI,UAAU,CAAC;IAEnD,MAAM,UAAU,GAAG,aAAa,CAAC,UAAU,EAAE,eAAe,EAAE,iBAAiB,EAAE,iBAAiB,CAAC,CAAC;IAEpG,IAAI,CAAC,UAAU,CAAC,EAAE,EAAE,CAAC;QACnB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU;YACV,UAAU;YACV,iBAAiB;YACjB,iBAAiB;YACjB,KAAK,EAAE,gBAAgB,UAAU,CAAC,KAAK,EAAE;SAC1C,CAAC;IACJ,CAAC;IAED,MAAM,YAAY,GAAG,iBAAiB,CAAC,iBAAiB,CAAC,CAAC;IAE1D,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO;YACL,OAAO,EAAE,KAAK;YACd,UAAU;YACV,UAAU;YACV,iBAAiB;YACjB,iBAAiB;YACjB,KAAK,EAAE,mEAAmE;SAC3E,CAAC;IACJ,CAAC;IAED,OAAO;QACL,OAAO,EAAE,IAAI;QACb,UAAU;QACV,UAAU;QACV,iBAAiB;QACjB,iBAAiB;QACjB,UAAU,EAAE,UAAU,CAAC,UAAU;QACjC,OAAO,EACL,8BAA8B,UAAU,SAAS,UAAU,KAAK;YAChE,iBAAiB,UAAU,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI;YACrD,aAAa,YAAY,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,KAAK,KAAK;YAC3D,0FAA0F;KAC7F,CAAC;AACJ,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,oBAAoB,GAAY;IAC3C,IAAI,EAAE,oBAAoB;IAC1B,WAAW,EACT,qFAAqF;QACrF,mDAAmD;QACnD,+EAA+E;QAC/E,iFAAiF;IACnF,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE;YACV,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,yEAAyE;aACvF;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EAAE,oEAAoE;aAClF;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,2EAA2E;oBAC3E,qDAAqD;aACxD;YACD,UAAU,EAAE;gBACV,IAAI,EAAE,QAAQ;gBACd,WAAW,EACT,8EAA8E;oBAC9E,iEAAiE;aACpE;SACF;QACD,QAAQ,EAAE,CAAC,YAAY,EAAE,YAAY,CAAC;KACvC;IACD,GAAG,EAAE,gBAAgB;CACtB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* list-smart-groups.ts — Parse DEVONthink SmartGroups.plist to enumerate all smart groups.
|
|
3
|
+
*
|
|
4
|
+
* Smart groups are NOT accessible via the standard AppleScript scripting dictionary.
|
|
5
|
+
* This tool reads the plist file directly using `plutil -convert xml1`.
|
|
6
|
+
*/
|
|
7
|
+
import type { McpTool } from "../../jxa/types.js";
|
|
8
|
+
export declare const listSmartGroupsTool: McpTool;
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* list-smart-groups.ts — Parse DEVONthink SmartGroups.plist to enumerate all smart groups.
|
|
3
|
+
*
|
|
4
|
+
* Smart groups are NOT accessible via the standard AppleScript scripting dictionary.
|
|
5
|
+
* This tool reads the plist file directly using `plutil -convert xml1`.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { extractTopLevelDicts, extractStringAfterKey, extractDateAfterKey, extractBoolAfterKey, extractSubDictAfterKey, } from "../../shared/plist/parser.js";
|
|
12
|
+
const PLIST_PATH = join(homedir(), "Library", "Application Support", "DEVONthink", "SmartGroups.plist");
|
|
13
|
+
function parsePlistXmlToSmartGroups(xml) {
|
|
14
|
+
const topLevelDicts = extractTopLevelDicts(xml);
|
|
15
|
+
const results = [];
|
|
16
|
+
for (const dictContent of topLevelDicts) {
|
|
17
|
+
const name = extractStringAfterKey(dictContent, "name");
|
|
18
|
+
const useUuidKey = extractBoolAfterKey(dictContent, "UseUUIDKey");
|
|
19
|
+
const syncContent = extractSubDictAfterKey(dictContent, "sync");
|
|
20
|
+
const uuid = syncContent ? extractStringAfterKey(syncContent, "UUID") : null;
|
|
21
|
+
const syncDate = syncContent ? extractDateAfterKey(syncContent, "date") : null;
|
|
22
|
+
if (!name && !uuid)
|
|
23
|
+
continue;
|
|
24
|
+
results.push({
|
|
25
|
+
name: name ?? "(unnamed)",
|
|
26
|
+
uuid: uuid ?? "",
|
|
27
|
+
syncDate: syncDate ?? null,
|
|
28
|
+
useUuidKey,
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
return results;
|
|
32
|
+
}
|
|
33
|
+
const listSmartGroups = async () => {
|
|
34
|
+
if (!existsSync(PLIST_PATH)) {
|
|
35
|
+
return {
|
|
36
|
+
success: false,
|
|
37
|
+
error: `SmartGroups.plist not found at: ${PLIST_PATH}. Ensure DEVONthink has been run at least once.`,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
let xml;
|
|
41
|
+
try {
|
|
42
|
+
xml = execSync(`plutil -convert xml1 -o - "${PLIST_PATH}"`, {
|
|
43
|
+
encoding: "utf-8",
|
|
44
|
+
timeout: 10000,
|
|
45
|
+
});
|
|
46
|
+
}
|
|
47
|
+
catch (err) {
|
|
48
|
+
return {
|
|
49
|
+
success: false,
|
|
50
|
+
error: `Failed to parse SmartGroups.plist: ${err instanceof Error ? err.message : String(err)}`,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
let smartGroups;
|
|
54
|
+
try {
|
|
55
|
+
smartGroups = parsePlistXmlToSmartGroups(xml);
|
|
56
|
+
}
|
|
57
|
+
catch (err) {
|
|
58
|
+
return {
|
|
59
|
+
success: false,
|
|
60
|
+
error: `Failed to parse XML output from plutil: ${err instanceof Error ? err.message : String(err)}`,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
smartGroups.sort((a, b) => a.name.localeCompare(b.name));
|
|
64
|
+
return { success: true, smartGroups, totalCount: smartGroups.length };
|
|
65
|
+
};
|
|
66
|
+
export const listSmartGroupsTool = {
|
|
67
|
+
name: "list_smart_groups",
|
|
68
|
+
description: "List all DEVONthink smart groups by parsing SmartGroups.plist. " +
|
|
69
|
+
"Returns name, UUID (from sync.UUID), sync date, and UseUUIDKey flag for each smart group. " +
|
|
70
|
+
"Smart groups are NOT accessible via the standard AppleScript API — this is the only way to enumerate them. " +
|
|
71
|
+
"Use the returned uuid with the search tool (groupUuid parameter) to query the contents of a smart group.",
|
|
72
|
+
inputSchema: {
|
|
73
|
+
type: "object",
|
|
74
|
+
properties: {},
|
|
75
|
+
required: [],
|
|
76
|
+
},
|
|
77
|
+
run: listSmartGroups,
|
|
78
|
+
};
|
|
79
|
+
//# sourceMappingURL=list-smart-groups.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-smart-groups.js","sourceRoot":"","sources":["../../../src/tools/custom/list-smart-groups.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* list-smart-rules.ts — Parse DEVONthink SmartRules.plist to enumerate all smart rules.
|
|
3
|
+
*
|
|
4
|
+
* Smart rules are NOT accessible via the standard AppleScript scripting dictionary.
|
|
5
|
+
* This tool reads the plist file directly using `plutil -convert xml1`.
|
|
6
|
+
*/
|
|
7
|
+
import type { McpTool } from "../../jxa/types.js";
|
|
8
|
+
export declare const listSmartRulesTool: McpTool;
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* list-smart-rules.ts — Parse DEVONthink SmartRules.plist to enumerate all smart rules.
|
|
3
|
+
*
|
|
4
|
+
* Smart rules are NOT accessible via the standard AppleScript scripting dictionary.
|
|
5
|
+
* This tool reads the plist file directly using `plutil -convert xml1`.
|
|
6
|
+
*/
|
|
7
|
+
import { execSync } from "node:child_process";
|
|
8
|
+
import { homedir } from "node:os";
|
|
9
|
+
import { join } from "node:path";
|
|
10
|
+
import { existsSync } from "node:fs";
|
|
11
|
+
import { extractTopLevelDicts, extractStringAfterKey, extractDateAfterKey, extractBoolAfterKey, extractIntegerAfterKey, extractRealAfterKey, extractSubDictAfterKey, } from "../../shared/plist/parser.js";
|
|
12
|
+
const PLIST_PATH = join(homedir(), "Library", "Application Support", "DEVONthink", "SmartRules.plist");
|
|
13
|
+
function parsePlistXmlToSmartRules(xml) {
|
|
14
|
+
const topLevelDicts = extractTopLevelDicts(xml);
|
|
15
|
+
const results = [];
|
|
16
|
+
for (const dictContent of topLevelDicts) {
|
|
17
|
+
const name = extractStringAfterKey(dictContent, "name");
|
|
18
|
+
const enabled = extractBoolAfterKey(dictContent, "Enabled");
|
|
19
|
+
const indexOffset = extractIntegerAfterKey(dictContent, "IndexOffset");
|
|
20
|
+
const lastExecution = extractRealAfterKey(dictContent, "LastExecution");
|
|
21
|
+
const useUuidKey = extractBoolAfterKey(dictContent, "UseUUIDKey");
|
|
22
|
+
const syncContent = extractSubDictAfterKey(dictContent, "sync");
|
|
23
|
+
const uuid = syncContent ? extractStringAfterKey(syncContent, "UUID") : null;
|
|
24
|
+
const syncDate = syncContent ? extractDateAfterKey(syncContent, "date") : null;
|
|
25
|
+
if (!name && !uuid)
|
|
26
|
+
continue;
|
|
27
|
+
results.push({
|
|
28
|
+
name: name ?? "(unnamed)",
|
|
29
|
+
uuid: uuid ?? "",
|
|
30
|
+
enabled,
|
|
31
|
+
indexOffset,
|
|
32
|
+
lastExecution,
|
|
33
|
+
syncDate: syncDate ?? null,
|
|
34
|
+
useUuidKey,
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
return results;
|
|
38
|
+
}
|
|
39
|
+
const listSmartRules = async () => {
|
|
40
|
+
if (!existsSync(PLIST_PATH)) {
|
|
41
|
+
return {
|
|
42
|
+
success: false,
|
|
43
|
+
error: `SmartRules.plist not found at: ${PLIST_PATH}. Ensure DEVONthink has been run at least once and smart rules have been created.`,
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
let xml;
|
|
47
|
+
try {
|
|
48
|
+
xml = execSync(`plutil -convert xml1 -o - "${PLIST_PATH}"`, {
|
|
49
|
+
encoding: "utf-8",
|
|
50
|
+
timeout: 10000,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
return {
|
|
55
|
+
success: false,
|
|
56
|
+
error: `Failed to parse SmartRules.plist: ${err instanceof Error ? err.message : String(err)}`,
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
let smartRules;
|
|
60
|
+
try {
|
|
61
|
+
smartRules = parsePlistXmlToSmartRules(xml);
|
|
62
|
+
}
|
|
63
|
+
catch (err) {
|
|
64
|
+
return {
|
|
65
|
+
success: false,
|
|
66
|
+
error: `Failed to parse XML output from plutil: ${err instanceof Error ? err.message : String(err)}`,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
smartRules.sort((a, b) => a.name.localeCompare(b.name));
|
|
70
|
+
return { success: true, smartRules, totalCount: smartRules.length };
|
|
71
|
+
};
|
|
72
|
+
export const listSmartRulesTool = {
|
|
73
|
+
name: "list_smart_rules",
|
|
74
|
+
description: "List all DEVONthink smart rules by parsing SmartRules.plist. " +
|
|
75
|
+
"Returns name, UUID (from sync.UUID), enabled state, indexOffset, lastExecution timestamp, " +
|
|
76
|
+
"and sync date for each rule. " +
|
|
77
|
+
"Smart rules are NOT accessible via the standard AppleScript API — this is the only way to enumerate them.",
|
|
78
|
+
inputSchema: {
|
|
79
|
+
type: "object",
|
|
80
|
+
properties: {},
|
|
81
|
+
required: [],
|
|
82
|
+
},
|
|
83
|
+
run: listSmartRules,
|
|
84
|
+
};
|
|
85
|
+
//# sourceMappingURL=list-smart-rules.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-smart-rules.js","sourceRoot":"","sources":["../../../src/tools/custom/list-smart-rules.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EACL,oBAAoB,EACpB,qBAAqB,EACrB,mBAAmB,EACnB,mBAAmB,EACnB,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,GACvB,MAAM,8BAA8B,CAAC;AAGtC,MAAM,UAAU,GAAG,IAAI,CACrB,OAAO,EAAE,EACT,SAAS,EACT,qBAAqB,EACrB,YAAY,EACZ,kBAAkB,CACnB,CAAC;AAmBF,SAAS,yBAAyB,CAAC,GAAW;IAC5C,MAAM,aAAa,GAAG,oBAAoB,CAAC,GAAG,CAAC,CAAC;IAChD,MAAM,OAAO,GAAqB,EAAE,CAAC;IAErC,KAAK,MAAM,WAAW,IAAI,aAAa,EAAE,CAAC;QACxC,MAAM,IAAI,GAAG,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QACxD,MAAM,OAAO,GAAG,mBAAmB,CAAC,WAAW,EAAE,SAAS,CAAC,CAAC;QAC5D,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,EAAE,aAAa,CAAC,CAAC;QACvE,MAAM,aAAa,GAAG,mBAAmB,CAAC,WAAW,EAAE,eAAe,CAAC,CAAC;QACxE,MAAM,UAAU,GAAG,mBAAmB,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;QAElE,MAAM,WAAW,GAAG,sBAAsB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC;QAChE,MAAM,IAAI,GAAG,WAAW,CAAC,CAAC,CAAC,qBAAqB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAC7E,MAAM,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,mBAAmB,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;QAE/E,IAAI,CAAC,IAAI,IAAI,CAAC,IAAI;YAAE,SAAS;QAE7B,OAAO,CAAC,IAAI,CAAC;YACX,IAAI,EAAE,IAAI,IAAI,WAAW;YACzB,IAAI,EAAE,IAAI,IAAI,EAAE;YAChB,OAAO;YACP,WAAW;YACX,aAAa;YACb,QAAQ,EAAE,QAAQ,IAAI,IAAI;YAC1B,UAAU;SACX,CAAC,CAAC;IACL,CAAC;IAED,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,MAAM,cAAc,GAAG,KAAK,IAA+B,EAAE;IAC3D,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,kCAAkC,UAAU,mFAAmF;SACvI,CAAC;IACJ,CAAC;IAED,IAAI,GAAW,CAAC;IAChB,IAAI,CAAC;QACH,GAAG,GAAG,QAAQ,CAAC,8BAA8B,UAAU,GAAG,EAAE;YAC1D,QAAQ,EAAE,OAAO;YACjB,OAAO,EAAE,KAAK;SACf,CAAC,CAAC;IACL,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,qCAAqC,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SAC/F,CAAC;IACJ,CAAC;IAED,IAAI,UAA4B,CAAC;IACjC,IAAI,CAAC;QACH,UAAU,GAAG,yBAAyB,CAAC,GAAG,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,OAAO;YACL,OAAO,EAAE,KAAK;YACd,KAAK,EAAE,2CAA2C,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC,EAAE;SACrG,CAAC;IACJ,CAAC;IAED,UAAU,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;IAExD,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC;AACtE,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,kBAAkB,GAAY;IACzC,IAAI,EAAE,kBAAkB;IACxB,WAAW,EACT,+DAA+D;QAC/D,4FAA4F;QAC5F,+BAA+B;QAC/B,2GAA2G;IAC7G,WAAW,EAAE;QACX,IAAI,EAAE,QAAiB;QACvB,UAAU,EAAE,EAAE;QACd,QAAQ,EAAE,EAAE;KACb;IACD,GAAG,EAAE,cAAc;CACpB,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* parse-eml-headers.ts — Extract MIME headers from .eml files.
|
|
3
|
+
*
|
|
4
|
+
* Reads an RFC 2822 email file and returns key headers for thread correlation.
|
|
5
|
+
* Handles CRLF/LF line endings, folded headers, and RFC 2047 encoded words.
|
|
6
|
+
*/
|
|
7
|
+
import type { McpTool } from "../../jxa/types.js";
|
|
8
|
+
export declare const parseEmlHeadersTool: McpTool;
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* parse-eml-headers.ts — Extract MIME headers from .eml files.
|
|
3
|
+
*
|
|
4
|
+
* Reads an RFC 2822 email file and returns key headers for thread correlation.
|
|
5
|
+
* Handles CRLF/LF line endings, folded headers, and RFC 2047 encoded words.
|
|
6
|
+
*/
|
|
7
|
+
import { existsSync, createReadStream } from "node:fs";
|
|
8
|
+
function decodeEncodedWords(input) {
|
|
9
|
+
return input.replace(/=\?([^?]+)\?([BbQq])\?([^?]*)\?=/g, (_match, charset, encoding, text) => {
|
|
10
|
+
try {
|
|
11
|
+
const enc = encoding.toUpperCase();
|
|
12
|
+
let bytes;
|
|
13
|
+
if (enc === "B") {
|
|
14
|
+
bytes = Buffer.from(text, "base64");
|
|
15
|
+
}
|
|
16
|
+
else {
|
|
17
|
+
const decoded = text
|
|
18
|
+
.replace(/_/g, " ")
|
|
19
|
+
.replace(/=([0-9A-Fa-f]{2})/g, (_m, h) => String.fromCharCode(parseInt(h, 16)));
|
|
20
|
+
bytes = Buffer.from(decoded, "binary");
|
|
21
|
+
}
|
|
22
|
+
const csLower = charset.toLowerCase();
|
|
23
|
+
const csNorm = csLower === "us-ascii" ? "ascii" :
|
|
24
|
+
csLower === "iso-8859-1" || csLower === "iso-8859-15" ? "latin1" :
|
|
25
|
+
csLower || "utf-8";
|
|
26
|
+
return bytes.toString(csNorm);
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return _match;
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
function parseHeaders(headerSection) {
|
|
34
|
+
const headers = new Map();
|
|
35
|
+
const normalised = headerSection.replace(/\r\n/g, "\n");
|
|
36
|
+
const lines = normalised.split("\n");
|
|
37
|
+
let currentName = null;
|
|
38
|
+
let currentValue = "";
|
|
39
|
+
const flush = () => {
|
|
40
|
+
if (currentName !== null) {
|
|
41
|
+
const unfolded = currentValue.replace(/\n[ \t]+/g, " ").trim();
|
|
42
|
+
const key = currentName.toLowerCase();
|
|
43
|
+
if (headers.has(key)) {
|
|
44
|
+
headers.set(key, headers.get(key) + "\n" + unfolded);
|
|
45
|
+
}
|
|
46
|
+
else {
|
|
47
|
+
headers.set(key, unfolded);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
};
|
|
51
|
+
for (const line of lines) {
|
|
52
|
+
if (line === "")
|
|
53
|
+
break;
|
|
54
|
+
if (line[0] === " " || line[0] === "\t") {
|
|
55
|
+
if (currentName !== null) {
|
|
56
|
+
currentValue += "\n" + line;
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
else {
|
|
60
|
+
flush();
|
|
61
|
+
const colonIdx = line.indexOf(":");
|
|
62
|
+
if (colonIdx > 0) {
|
|
63
|
+
currentName = line.slice(0, colonIdx).trim();
|
|
64
|
+
currentValue = line.slice(colonIdx + 1);
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
currentName = null;
|
|
68
|
+
currentValue = "";
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
flush();
|
|
73
|
+
return headers;
|
|
74
|
+
}
|
|
75
|
+
function parseReferences(raw) {
|
|
76
|
+
const matches = raw.match(/<[^>]+>/g);
|
|
77
|
+
return matches ?? [];
|
|
78
|
+
}
|
|
79
|
+
const parseEmlHeaders = async (args) => {
|
|
80
|
+
const filePath = args.filePath;
|
|
81
|
+
if (!filePath || typeof filePath !== "string") {
|
|
82
|
+
return { success: false, error: "filePath parameter is required and must be a string" };
|
|
83
|
+
}
|
|
84
|
+
if (!existsSync(filePath)) {
|
|
85
|
+
return { success: false, filePath, error: `File not found: ${filePath}` };
|
|
86
|
+
}
|
|
87
|
+
let rawContent;
|
|
88
|
+
try {
|
|
89
|
+
const HEADER_READ_LIMIT = 65536;
|
|
90
|
+
const fd = await new Promise((resolve, reject) => {
|
|
91
|
+
const stream = createReadStream(filePath, { start: 0, end: HEADER_READ_LIMIT - 1 });
|
|
92
|
+
const chunks = [];
|
|
93
|
+
stream.on("data", (chunk) => chunks.push(Buffer.isBuffer(chunk) ? chunk : Buffer.from(chunk)));
|
|
94
|
+
stream.on("end", () => resolve(Buffer.concat(chunks)));
|
|
95
|
+
stream.on("error", reject);
|
|
96
|
+
});
|
|
97
|
+
rawContent = fd.toString("utf-8");
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
return {
|
|
101
|
+
success: false,
|
|
102
|
+
filePath,
|
|
103
|
+
error: `Failed to read file: ${err instanceof Error ? err.message : String(err)}`,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
const crlf = rawContent.indexOf("\r\n\r\n");
|
|
107
|
+
const lf = rawContent.indexOf("\n\n");
|
|
108
|
+
let headerSection;
|
|
109
|
+
if (crlf !== -1 && (lf === -1 || crlf < lf)) {
|
|
110
|
+
headerSection = rawContent.slice(0, crlf);
|
|
111
|
+
}
|
|
112
|
+
else if (lf !== -1) {
|
|
113
|
+
headerSection = rawContent.slice(0, lf);
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
headerSection = rawContent;
|
|
117
|
+
}
|
|
118
|
+
const headers = parseHeaders(headerSection);
|
|
119
|
+
const get = (name) => {
|
|
120
|
+
const val = headers.get(name);
|
|
121
|
+
return val !== undefined ? decodeEncodedWords(val.trim()) : null;
|
|
122
|
+
};
|
|
123
|
+
const referencesRaw = get("references");
|
|
124
|
+
return {
|
|
125
|
+
success: true,
|
|
126
|
+
filePath,
|
|
127
|
+
messageId: get("message-id"),
|
|
128
|
+
inReplyTo: get("in-reply-to"),
|
|
129
|
+
references: referencesRaw ? parseReferences(referencesRaw) : [],
|
|
130
|
+
subject: get("subject"),
|
|
131
|
+
from: get("from"),
|
|
132
|
+
to: get("to"),
|
|
133
|
+
cc: get("cc"),
|
|
134
|
+
date: get("date"),
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
export const parseEmlHeadersTool = {
|
|
138
|
+
name: "parse_eml_headers",
|
|
139
|
+
description: "Extract MIME headers from an .eml file for email thread correlation. " +
|
|
140
|
+
"Returns message_id, in_reply_to, references (array), subject, from, to, cc, and date. " +
|
|
141
|
+
"Handles CRLF/LF line endings, folded headers, and RFC 2047 encoded words in Subject/From/To. " +
|
|
142
|
+
'Input: { "filePath": "/path/to/email.eml" }',
|
|
143
|
+
inputSchema: {
|
|
144
|
+
type: "object",
|
|
145
|
+
properties: {
|
|
146
|
+
filePath: {
|
|
147
|
+
type: "string",
|
|
148
|
+
description: "Absolute path to the .eml file to parse",
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
required: ["filePath"],
|
|
152
|
+
},
|
|
153
|
+
run: parseEmlHeaders,
|
|
154
|
+
};
|
|
155
|
+
//# sourceMappingURL=parse-eml-headers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"parse-eml-headers.js","sourceRoot":"","sources":["../../../src/tools/custom/parse-eml-headers.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* get-current-database.ts — Get information about the currently selected database.
|
|
3
|
+
*
|
|
4
|
+
* Returns name, uuid, path, and record count for whichever database is currently
|
|
5
|
+
* active in the DEVONthink UI.
|
|
6
|
+
*/
|
|
7
|
+
export declare const currentDatabaseTool: import("../../jxa/types.js").McpTool;
|