@noteplanco/noteplan-mcp 1.1.1
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 +257 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +8 -0
- package/dist/index.js.map +1 -0
- package/dist/noteplan/embeddings.d.ts +170 -0
- package/dist/noteplan/embeddings.d.ts.map +1 -0
- package/dist/noteplan/embeddings.js +684 -0
- package/dist/noteplan/embeddings.js.map +1 -0
- package/dist/noteplan/file-reader.d.ts +77 -0
- package/dist/noteplan/file-reader.d.ts.map +1 -0
- package/dist/noteplan/file-reader.js +488 -0
- package/dist/noteplan/file-reader.js.map +1 -0
- package/dist/noteplan/file-writer.d.ts +108 -0
- package/dist/noteplan/file-writer.d.ts.map +1 -0
- package/dist/noteplan/file-writer.js +621 -0
- package/dist/noteplan/file-writer.js.map +1 -0
- package/dist/noteplan/filter-store.d.ts +28 -0
- package/dist/noteplan/filter-store.d.ts.map +1 -0
- package/dist/noteplan/filter-store.js +180 -0
- package/dist/noteplan/filter-store.js.map +1 -0
- package/dist/noteplan/frontmatter-parser.d.ts +45 -0
- package/dist/noteplan/frontmatter-parser.d.ts.map +1 -0
- package/dist/noteplan/frontmatter-parser.js +259 -0
- package/dist/noteplan/frontmatter-parser.js.map +1 -0
- package/dist/noteplan/fuzzy-search.d.ts +7 -0
- package/dist/noteplan/fuzzy-search.d.ts.map +1 -0
- package/dist/noteplan/fuzzy-search.js +66 -0
- package/dist/noteplan/fuzzy-search.js.map +1 -0
- package/dist/noteplan/markdown-parser.d.ts +87 -0
- package/dist/noteplan/markdown-parser.d.ts.map +1 -0
- package/dist/noteplan/markdown-parser.js +519 -0
- package/dist/noteplan/markdown-parser.js.map +1 -0
- package/dist/noteplan/preferences.d.ts +44 -0
- package/dist/noteplan/preferences.d.ts.map +1 -0
- package/dist/noteplan/preferences.js +156 -0
- package/dist/noteplan/preferences.js.map +1 -0
- package/dist/noteplan/ripgrep-search.d.ts +29 -0
- package/dist/noteplan/ripgrep-search.d.ts.map +1 -0
- package/dist/noteplan/ripgrep-search.js +110 -0
- package/dist/noteplan/ripgrep-search.js.map +1 -0
- package/dist/noteplan/sqlite-reader.d.ts +77 -0
- package/dist/noteplan/sqlite-reader.d.ts.map +1 -0
- package/dist/noteplan/sqlite-reader.js +605 -0
- package/dist/noteplan/sqlite-reader.js.map +1 -0
- package/dist/noteplan/sqlite-writer.d.ts +63 -0
- package/dist/noteplan/sqlite-writer.d.ts.map +1 -0
- package/dist/noteplan/sqlite-writer.js +574 -0
- package/dist/noteplan/sqlite-writer.js.map +1 -0
- package/dist/noteplan/types.d.ts +97 -0
- package/dist/noteplan/types.d.ts.map +1 -0
- package/dist/noteplan/types.js +33 -0
- package/dist/noteplan/types.js.map +1 -0
- package/dist/noteplan/unified-store.d.ts +289 -0
- package/dist/noteplan/unified-store.d.ts.map +1 -0
- package/dist/noteplan/unified-store.js +1308 -0
- package/dist/noteplan/unified-store.js.map +1 -0
- package/dist/server.d.ts +4 -0
- package/dist/server.d.ts.map +1 -0
- package/dist/server.js +2468 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/calendar.d.ts +311 -0
- package/dist/tools/calendar.d.ts.map +1 -0
- package/dist/tools/calendar.js +504 -0
- package/dist/tools/calendar.js.map +1 -0
- package/dist/tools/embeddings.d.ts +244 -0
- package/dist/tools/embeddings.d.ts.map +1 -0
- package/dist/tools/embeddings.js +226 -0
- package/dist/tools/embeddings.js.map +1 -0
- package/dist/tools/events.d.ts +176 -0
- package/dist/tools/events.d.ts.map +1 -0
- package/dist/tools/events.js +326 -0
- package/dist/tools/events.js.map +1 -0
- package/dist/tools/filters.d.ts +205 -0
- package/dist/tools/filters.d.ts.map +1 -0
- package/dist/tools/filters.js +347 -0
- package/dist/tools/filters.js.map +1 -0
- package/dist/tools/memory.d.ts +6 -0
- package/dist/tools/memory.d.ts.map +1 -0
- package/dist/tools/memory.js +161 -0
- package/dist/tools/memory.js.map +1 -0
- package/dist/tools/notes.d.ts +1221 -0
- package/dist/tools/notes.d.ts.map +1 -0
- package/dist/tools/notes.js +1868 -0
- package/dist/tools/notes.js.map +1 -0
- package/dist/tools/plugins.d.ts +140 -0
- package/dist/tools/plugins.d.ts.map +1 -0
- package/dist/tools/plugins.js +782 -0
- package/dist/tools/plugins.js.map +1 -0
- package/dist/tools/reminders.d.ts +207 -0
- package/dist/tools/reminders.d.ts.map +1 -0
- package/dist/tools/reminders.js +323 -0
- package/dist/tools/reminders.js.map +1 -0
- package/dist/tools/search.d.ts +58 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +373 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/spaces.d.ts +484 -0
- package/dist/tools/spaces.d.ts.map +1 -0
- package/dist/tools/spaces.js +870 -0
- package/dist/tools/spaces.js.map +1 -0
- package/dist/tools/tasks.d.ts +313 -0
- package/dist/tools/tasks.d.ts.map +1 -0
- package/dist/tools/tasks.js +690 -0
- package/dist/tools/tasks.js.map +1 -0
- package/dist/tools/themes.d.ts +91 -0
- package/dist/tools/themes.d.ts.map +1 -0
- package/dist/tools/themes.js +294 -0
- package/dist/tools/themes.js.map +1 -0
- package/dist/tools/ui.d.ts +89 -0
- package/dist/tools/ui.d.ts.map +1 -0
- package/dist/tools/ui.js +137 -0
- package/dist/tools/ui.js.map +1 -0
- package/dist/utils/applescript.d.ts +5 -0
- package/dist/utils/applescript.d.ts.map +1 -0
- package/dist/utils/applescript.js +27 -0
- package/dist/utils/applescript.js.map +1 -0
- package/dist/utils/confirmation-tokens.d.ts +19 -0
- package/dist/utils/confirmation-tokens.d.ts.map +1 -0
- package/dist/utils/confirmation-tokens.js +58 -0
- package/dist/utils/confirmation-tokens.js.map +1 -0
- package/dist/utils/date-filters.d.ts +15 -0
- package/dist/utils/date-filters.d.ts.map +1 -0
- package/dist/utils/date-filters.js +129 -0
- package/dist/utils/date-filters.js.map +1 -0
- package/dist/utils/date-utils.d.ts +113 -0
- package/dist/utils/date-utils.d.ts.map +1 -0
- package/dist/utils/date-utils.js +341 -0
- package/dist/utils/date-utils.js.map +1 -0
- package/dist/utils/folder-matcher.d.ts +14 -0
- package/dist/utils/folder-matcher.d.ts.map +1 -0
- package/dist/utils/folder-matcher.js +191 -0
- package/dist/utils/folder-matcher.js.map +1 -0
- package/dist/utils/version.d.ts +10 -0
- package/dist/utils/version.d.ts.map +1 -0
- package/dist/utils/version.js +88 -0
- package/dist/utils/version.js.map +1 -0
- package/docs/plugin-api/Calendar.md +448 -0
- package/docs/plugin-api/CalendarItem.md +198 -0
- package/docs/plugin-api/Clipboard.md +101 -0
- package/docs/plugin-api/CommandBar.md +251 -0
- package/docs/plugin-api/DataStore.md +700 -0
- package/docs/plugin-api/Editor.md +982 -0
- package/docs/plugin-api/HTMLView.md +337 -0
- package/docs/plugin-api/NoteObject.md +588 -0
- package/docs/plugin-api/NotePlan.md +398 -0
- package/docs/plugin-api/ParagraphObject.md +242 -0
- package/docs/plugin-api/RangeObject.md +56 -0
- package/docs/plugin-api/getting-started.md +545 -0
- package/docs/plugin-api/plugin-api-condensed.md +526 -0
- package/docs/plugin-api/plugin.json +26 -0
- package/docs/plugin-api/script.js +542 -0
- package/package.json +60 -0
- package/scripts/calendar-helper +0 -0
- package/scripts/reminders-helper +0 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface FilterItemRecord {
|
|
2
|
+
param: string;
|
|
3
|
+
value: string;
|
|
4
|
+
display: boolean;
|
|
5
|
+
}
|
|
6
|
+
export interface FilterRecord {
|
|
7
|
+
name: string;
|
|
8
|
+
path: string;
|
|
9
|
+
items: FilterItemRecord[];
|
|
10
|
+
createdAt?: Date;
|
|
11
|
+
modifiedAt?: Date;
|
|
12
|
+
}
|
|
13
|
+
export declare function listFilters(): Array<{
|
|
14
|
+
name: string;
|
|
15
|
+
path: string;
|
|
16
|
+
modifiedAt?: Date;
|
|
17
|
+
createdAt?: Date;
|
|
18
|
+
}>;
|
|
19
|
+
export declare function getFilter(name: string): FilterRecord | null;
|
|
20
|
+
export declare function saveFilter(name: string, items: Array<{
|
|
21
|
+
param?: unknown;
|
|
22
|
+
value?: unknown;
|
|
23
|
+
display?: unknown;
|
|
24
|
+
}>, options?: {
|
|
25
|
+
overwrite?: boolean;
|
|
26
|
+
}): FilterRecord;
|
|
27
|
+
export declare function renameFilter(oldName: string, newName: string, overwrite?: boolean): FilterRecord;
|
|
28
|
+
//# sourceMappingURL=filter-store.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-store.d.ts","sourceRoot":"","sources":["../../src/noteplan/filter-store.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,gBAAgB;IAC/B,KAAK,EAAE,MAAM,CAAC;IACd,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,gBAAgB,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,IAAI,CAAC;IACjB,UAAU,CAAC,EAAE,IAAI,CAAC;CACnB;AAwGD,wBAAgB,WAAW,IAAI,KAAK,CAAC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,UAAU,CAAC,EAAE,IAAI,CAAC;IAAC,SAAS,CAAC,EAAE,IAAI,CAAA;CAAE,CAAC,CAkBxG;AAED,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI,CAgB3D;AAED,wBAAgB,UAAU,CACxB,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,KAAK,CAAC;IAAE,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,OAAO,CAAC;IAAC,OAAO,CAAC,EAAE,OAAO,CAAA;CAAE,CAAC,EACrE,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAO,GACpC,YAAY,CAkCd;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,SAAS,UAAQ,GAAG,YAAY,CAsB9F"}
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as os from 'os';
|
|
3
|
+
import * as path from 'path';
|
|
4
|
+
import { execFileSync } from 'child_process';
|
|
5
|
+
import { getNotePlanPath } from './file-reader.js';
|
|
6
|
+
function sanitizeFilterName(name) {
|
|
7
|
+
return name.trim().replace(/[\\/]/g, '-');
|
|
8
|
+
}
|
|
9
|
+
function assertFilterName(name) {
|
|
10
|
+
const sanitized = sanitizeFilterName(name);
|
|
11
|
+
if (!sanitized || sanitized === '.' || sanitized === '..') {
|
|
12
|
+
throw new Error('Filter name is required');
|
|
13
|
+
}
|
|
14
|
+
return sanitized;
|
|
15
|
+
}
|
|
16
|
+
function normalizeFilterItem(input) {
|
|
17
|
+
const rawParam = typeof input.param === 'string' ? input.param.trim() : '';
|
|
18
|
+
if (!rawParam) {
|
|
19
|
+
throw new Error('Each filter item must include a non-empty param');
|
|
20
|
+
}
|
|
21
|
+
let storedValue = '';
|
|
22
|
+
if (typeof input.value === 'string') {
|
|
23
|
+
storedValue = input.value;
|
|
24
|
+
}
|
|
25
|
+
else if (typeof input.value === 'boolean' || typeof input.value === 'number') {
|
|
26
|
+
storedValue = String(input.value);
|
|
27
|
+
}
|
|
28
|
+
else if (Array.isArray(input.value)) {
|
|
29
|
+
const tokens = input.value
|
|
30
|
+
.map((value) => (typeof value === 'string' ? value.trim() : String(value ?? '').trim()))
|
|
31
|
+
.filter((value) => value.length > 0);
|
|
32
|
+
storedValue = tokens.join('$$::$$');
|
|
33
|
+
}
|
|
34
|
+
else if (input.value === null || input.value === undefined) {
|
|
35
|
+
storedValue = '';
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
storedValue = String(input.value);
|
|
39
|
+
}
|
|
40
|
+
const display = input.display === undefined ? true : input.display === true;
|
|
41
|
+
return {
|
|
42
|
+
param: rawParam,
|
|
43
|
+
value: storedValue,
|
|
44
|
+
display,
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
function getFiltersPath() {
|
|
48
|
+
return path.join(getNotePlanPath(), 'Filters');
|
|
49
|
+
}
|
|
50
|
+
function isFilterFileName(name) {
|
|
51
|
+
if (!name || name.startsWith('.'))
|
|
52
|
+
return false;
|
|
53
|
+
const lower = name.toLowerCase();
|
|
54
|
+
if (lower.endsWith('.view') || lower.endsWith('.views'))
|
|
55
|
+
return false;
|
|
56
|
+
return true;
|
|
57
|
+
}
|
|
58
|
+
function ensureFiltersPath() {
|
|
59
|
+
const filtersPath = getFiltersPath();
|
|
60
|
+
if (!fs.existsSync(filtersPath)) {
|
|
61
|
+
fs.mkdirSync(filtersPath, { recursive: true });
|
|
62
|
+
}
|
|
63
|
+
return filtersPath;
|
|
64
|
+
}
|
|
65
|
+
function toFilterFilePath(name) {
|
|
66
|
+
const safeName = assertFilterName(name);
|
|
67
|
+
return path.join(getFiltersPath(), safeName);
|
|
68
|
+
}
|
|
69
|
+
function toJsonViaPlutil(filePath) {
|
|
70
|
+
try {
|
|
71
|
+
const output = execFileSync('plutil', ['-convert', 'json', '-o', '-', filePath], {
|
|
72
|
+
encoding: 'utf-8',
|
|
73
|
+
});
|
|
74
|
+
return JSON.parse(output);
|
|
75
|
+
}
|
|
76
|
+
catch (error) {
|
|
77
|
+
const reason = error instanceof Error ? error.message : 'Unknown error';
|
|
78
|
+
throw new Error(`Failed to read filter plist via plutil: ${reason}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
function toBinaryPlistViaPlutil(jsonPath, outputPath) {
|
|
82
|
+
try {
|
|
83
|
+
execFileSync('plutil', ['-convert', 'binary1', '-o', outputPath, jsonPath], {
|
|
84
|
+
encoding: 'utf-8',
|
|
85
|
+
stdio: ['ignore', 'ignore', 'pipe'],
|
|
86
|
+
});
|
|
87
|
+
}
|
|
88
|
+
catch (error) {
|
|
89
|
+
const reason = error instanceof Error ? error.message : 'Unknown error';
|
|
90
|
+
throw new Error(`Failed to write filter plist via plutil: ${reason}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
function normalizeFilterItems(raw) {
|
|
94
|
+
if (!Array.isArray(raw)) {
|
|
95
|
+
throw new Error('Filter file is malformed: expected an array');
|
|
96
|
+
}
|
|
97
|
+
return raw.map((entry) => normalizeFilterItem(entry));
|
|
98
|
+
}
|
|
99
|
+
export function listFilters() {
|
|
100
|
+
const filtersPath = getFiltersPath();
|
|
101
|
+
if (!fs.existsSync(filtersPath))
|
|
102
|
+
return [];
|
|
103
|
+
const entries = fs.readdirSync(filtersPath, { withFileTypes: true });
|
|
104
|
+
return entries
|
|
105
|
+
.filter((entry) => entry.isFile() && isFilterFileName(entry.name))
|
|
106
|
+
.map((entry) => {
|
|
107
|
+
const fullPath = path.join(filtersPath, entry.name);
|
|
108
|
+
const stats = fs.statSync(fullPath);
|
|
109
|
+
return {
|
|
110
|
+
name: entry.name,
|
|
111
|
+
path: fullPath,
|
|
112
|
+
modifiedAt: stats.mtime,
|
|
113
|
+
createdAt: stats.birthtime,
|
|
114
|
+
};
|
|
115
|
+
})
|
|
116
|
+
.sort((a, b) => a.name.localeCompare(b.name));
|
|
117
|
+
}
|
|
118
|
+
export function getFilter(name) {
|
|
119
|
+
const safeName = assertFilterName(name);
|
|
120
|
+
const filePath = toFilterFilePath(safeName);
|
|
121
|
+
if (!fs.existsSync(filePath))
|
|
122
|
+
return null;
|
|
123
|
+
const stats = fs.statSync(filePath);
|
|
124
|
+
const raw = toJsonViaPlutil(filePath);
|
|
125
|
+
const items = normalizeFilterItems(raw);
|
|
126
|
+
return {
|
|
127
|
+
name: safeName,
|
|
128
|
+
path: filePath,
|
|
129
|
+
items,
|
|
130
|
+
createdAt: stats.birthtime,
|
|
131
|
+
modifiedAt: stats.mtime,
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
export function saveFilter(name, items, options = {}) {
|
|
135
|
+
const safeName = assertFilterName(name);
|
|
136
|
+
const overwrite = options.overwrite !== false;
|
|
137
|
+
const normalizedItems = items.map((item) => normalizeFilterItem(item));
|
|
138
|
+
if (normalizedItems.length === 0) {
|
|
139
|
+
throw new Error('Filter items are required');
|
|
140
|
+
}
|
|
141
|
+
const filtersPath = ensureFiltersPath();
|
|
142
|
+
const outputPath = path.join(filtersPath, safeName);
|
|
143
|
+
if (!overwrite && fs.existsSync(outputPath)) {
|
|
144
|
+
throw new Error(`Filter already exists: ${safeName}`);
|
|
145
|
+
}
|
|
146
|
+
const tempPath = path.join(os.tmpdir(), `noteplan-filter-${Date.now()}-${Math.random().toString(16).slice(2)}.json`);
|
|
147
|
+
try {
|
|
148
|
+
fs.writeFileSync(tempPath, JSON.stringify(normalizedItems), { encoding: 'utf-8' });
|
|
149
|
+
toBinaryPlistViaPlutil(tempPath, outputPath);
|
|
150
|
+
}
|
|
151
|
+
finally {
|
|
152
|
+
if (fs.existsSync(tempPath)) {
|
|
153
|
+
fs.unlinkSync(tempPath);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
const stored = getFilter(safeName);
|
|
157
|
+
if (!stored) {
|
|
158
|
+
throw new Error(`Filter save succeeded but reload failed: ${safeName}`);
|
|
159
|
+
}
|
|
160
|
+
return stored;
|
|
161
|
+
}
|
|
162
|
+
export function renameFilter(oldName, newName, overwrite = false) {
|
|
163
|
+
const sourceName = assertFilterName(oldName);
|
|
164
|
+
const targetName = assertFilterName(newName);
|
|
165
|
+
const sourcePath = toFilterFilePath(sourceName);
|
|
166
|
+
const targetPath = toFilterFilePath(targetName);
|
|
167
|
+
if (!fs.existsSync(sourcePath)) {
|
|
168
|
+
throw new Error(`Filter not found: ${sourceName}`);
|
|
169
|
+
}
|
|
170
|
+
if (!overwrite && fs.existsSync(targetPath)) {
|
|
171
|
+
throw new Error(`Filter already exists: ${targetName}`);
|
|
172
|
+
}
|
|
173
|
+
fs.renameSync(sourcePath, targetPath);
|
|
174
|
+
const stored = getFilter(targetName);
|
|
175
|
+
if (!stored) {
|
|
176
|
+
throw new Error(`Filter rename succeeded but reload failed: ${targetName}`);
|
|
177
|
+
}
|
|
178
|
+
return stored;
|
|
179
|
+
}
|
|
180
|
+
//# sourceMappingURL=filter-store.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"filter-store.js","sourceRoot":"","sources":["../../src/noteplan/filter-store.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Parsed note structure
|
|
3
|
+
*/
|
|
4
|
+
export interface ParsedNote {
|
|
5
|
+
frontmatter: Record<string, string> | null;
|
|
6
|
+
body: string;
|
|
7
|
+
hasFrontmatter: boolean;
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Options for inserting content
|
|
11
|
+
*/
|
|
12
|
+
export interface InsertOptions {
|
|
13
|
+
position: 'start' | 'end' | 'after-heading' | 'at-line' | 'in-section';
|
|
14
|
+
heading?: string;
|
|
15
|
+
line?: number;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Parse a note's content into frontmatter and body
|
|
19
|
+
*/
|
|
20
|
+
export declare function parseNoteContent(content: string): ParsedNote;
|
|
21
|
+
/**
|
|
22
|
+
* Serialize frontmatter back to YAML format
|
|
23
|
+
*/
|
|
24
|
+
export declare function serializeFrontmatter(frontmatter: Record<string, string>): string;
|
|
25
|
+
/**
|
|
26
|
+
* Reconstruct note from parsed parts
|
|
27
|
+
*/
|
|
28
|
+
export declare function reconstructNote(parsed: ParsedNote): string;
|
|
29
|
+
/**
|
|
30
|
+
* Set a frontmatter property, creating frontmatter if needed
|
|
31
|
+
*/
|
|
32
|
+
export declare function setFrontmatterProperty(content: string, key: string, value: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Remove a frontmatter property
|
|
35
|
+
*/
|
|
36
|
+
export declare function removeFrontmatterProperty(content: string, key: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Insert content at a specified position
|
|
39
|
+
*/
|
|
40
|
+
export declare function insertContentAtPosition(content: string, newContent: string, options: InsertOptions): string;
|
|
41
|
+
/**
|
|
42
|
+
* Delete lines from content (1-indexed, inclusive)
|
|
43
|
+
*/
|
|
44
|
+
export declare function deleteLines(content: string, startLine: number, endLine: number): string;
|
|
45
|
+
//# sourceMappingURL=frontmatter-parser.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-parser.d.ts","sourceRoot":"","sources":["../../src/noteplan/frontmatter-parser.ts"],"names":[],"mappings":"AAEA;;GAEG;AACH,MAAM,WAAW,UAAU;IACzB,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,IAAI,CAAC;IAC3C,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,OAAO,CAAC;CACzB;AAED;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,GAAG,KAAK,GAAG,eAAe,GAAG,SAAS,GAAG,YAAY,CAAC;IACvE,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,UAAU,CAkD5D;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAOhF;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,MAAM,CAK1D;AAED;;GAEG;AACH,wBAAgB,sBAAsB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,CAW1F;AAED;;GAEG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAW9E;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CACrC,OAAO,EAAE,MAAM,EACf,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,aAAa,GACrB,MAAM,CAsIR;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBvF"}
|
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
// Frontmatter parsing and content manipulation utilities
|
|
2
|
+
/**
|
|
3
|
+
* Parse a note's content into frontmatter and body
|
|
4
|
+
*/
|
|
5
|
+
export function parseNoteContent(content) {
|
|
6
|
+
const lines = content.split('\n');
|
|
7
|
+
// Check if content starts with frontmatter delimiter
|
|
8
|
+
if (lines[0]?.trim() !== '---') {
|
|
9
|
+
return {
|
|
10
|
+
frontmatter: null,
|
|
11
|
+
body: content,
|
|
12
|
+
hasFrontmatter: false,
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
// Find closing delimiter
|
|
16
|
+
let closingIndex = -1;
|
|
17
|
+
for (let i = 1; i < lines.length; i++) {
|
|
18
|
+
if (lines[i]?.trim() === '---') {
|
|
19
|
+
closingIndex = i;
|
|
20
|
+
break;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
if (closingIndex === -1) {
|
|
24
|
+
// No closing delimiter found, treat as no frontmatter
|
|
25
|
+
return {
|
|
26
|
+
frontmatter: null,
|
|
27
|
+
body: content,
|
|
28
|
+
hasFrontmatter: false,
|
|
29
|
+
};
|
|
30
|
+
}
|
|
31
|
+
// Parse frontmatter
|
|
32
|
+
const frontmatterLines = lines.slice(1, closingIndex);
|
|
33
|
+
const frontmatter = {};
|
|
34
|
+
for (const line of frontmatterLines) {
|
|
35
|
+
const match = line.match(/^(\S+):\s*(.*)$/);
|
|
36
|
+
if (match) {
|
|
37
|
+
const [, key, value] = match;
|
|
38
|
+
frontmatter[key] = value.trim();
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
// Extract body (everything after closing delimiter)
|
|
42
|
+
const body = lines.slice(closingIndex + 1).join('\n');
|
|
43
|
+
return {
|
|
44
|
+
frontmatter,
|
|
45
|
+
body,
|
|
46
|
+
hasFrontmatter: true,
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Serialize frontmatter back to YAML format
|
|
51
|
+
*/
|
|
52
|
+
export function serializeFrontmatter(frontmatter) {
|
|
53
|
+
const lines = ['---'];
|
|
54
|
+
for (const [key, value] of Object.entries(frontmatter)) {
|
|
55
|
+
lines.push(`${key}: ${value}`);
|
|
56
|
+
}
|
|
57
|
+
lines.push('---');
|
|
58
|
+
return lines.join('\n');
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Reconstruct note from parsed parts
|
|
62
|
+
*/
|
|
63
|
+
export function reconstructNote(parsed) {
|
|
64
|
+
if (!parsed.frontmatter || Object.keys(parsed.frontmatter).length === 0) {
|
|
65
|
+
return parsed.body;
|
|
66
|
+
}
|
|
67
|
+
return serializeFrontmatter(parsed.frontmatter) + '\n' + parsed.body;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Set a frontmatter property, creating frontmatter if needed
|
|
71
|
+
*/
|
|
72
|
+
export function setFrontmatterProperty(content, key, value) {
|
|
73
|
+
const parsed = parseNoteContent(content);
|
|
74
|
+
if (!parsed.frontmatter) {
|
|
75
|
+
// Create new frontmatter
|
|
76
|
+
parsed.frontmatter = {};
|
|
77
|
+
}
|
|
78
|
+
parsed.frontmatter[key] = value;
|
|
79
|
+
return reconstructNote(parsed);
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* Remove a frontmatter property
|
|
83
|
+
*/
|
|
84
|
+
export function removeFrontmatterProperty(content, key) {
|
|
85
|
+
const parsed = parseNoteContent(content);
|
|
86
|
+
if (!parsed.frontmatter) {
|
|
87
|
+
// No frontmatter, nothing to remove
|
|
88
|
+
return content;
|
|
89
|
+
}
|
|
90
|
+
delete parsed.frontmatter[key];
|
|
91
|
+
return reconstructNote(parsed);
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* Insert content at a specified position
|
|
95
|
+
*/
|
|
96
|
+
export function insertContentAtPosition(content, newContent, options) {
|
|
97
|
+
const { position, heading, line } = options;
|
|
98
|
+
const lines = content.split('\n');
|
|
99
|
+
// Split newContent into individual lines so splice inserts one element per
|
|
100
|
+
// line. Strip a single trailing newline first — trailing \n in the content
|
|
101
|
+
// string is almost never intentional and would otherwise create an extra
|
|
102
|
+
// blank line after join('\n'). Callers who need an explicit blank line
|
|
103
|
+
// should insert content="" separately.
|
|
104
|
+
const newLines = newContent.replace(/\n$/, '').split('\n');
|
|
105
|
+
switch (position) {
|
|
106
|
+
case 'start': {
|
|
107
|
+
// Insert after frontmatter if present
|
|
108
|
+
let insertIndex = 0;
|
|
109
|
+
if (lines[0]?.trim() === '---') {
|
|
110
|
+
for (let i = 1; i < lines.length; i++) {
|
|
111
|
+
if (lines[i]?.trim() === '---') {
|
|
112
|
+
insertIndex = i + 1;
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
lines.splice(insertIndex, 0, ...newLines);
|
|
118
|
+
break;
|
|
119
|
+
}
|
|
120
|
+
case 'end': {
|
|
121
|
+
// Append at end — use original newContent (no trailing-\n strip)
|
|
122
|
+
// because appending doesn't go through splice+join.
|
|
123
|
+
if (content.endsWith('\n')) {
|
|
124
|
+
return content + newContent;
|
|
125
|
+
}
|
|
126
|
+
return content + '\n' + newContent;
|
|
127
|
+
}
|
|
128
|
+
case 'after-heading': {
|
|
129
|
+
if (!heading) {
|
|
130
|
+
throw new Error('Heading is required for after-heading position');
|
|
131
|
+
}
|
|
132
|
+
const targetHeading = normalizeHeadingForMatch(heading);
|
|
133
|
+
const headingIndex = lines.findIndex((lineValue) => {
|
|
134
|
+
const lineHeading = extractSectionBoundaryText(lineValue);
|
|
135
|
+
if (!lineHeading)
|
|
136
|
+
return false;
|
|
137
|
+
return normalizeHeadingForMatch(lineHeading) === targetHeading;
|
|
138
|
+
});
|
|
139
|
+
if (headingIndex === -1) {
|
|
140
|
+
const availableHeadings = lines
|
|
141
|
+
.map((lineValue) => extractSectionBoundaryText(lineValue))
|
|
142
|
+
.filter((value) => Boolean(value))
|
|
143
|
+
.slice(0, 15);
|
|
144
|
+
if (availableHeadings.length > 0) {
|
|
145
|
+
throw new Error(`Heading "${heading}" not found. Available headings include: ${availableHeadings.join(' | ')}`);
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`Heading "${heading}" not found`);
|
|
148
|
+
}
|
|
149
|
+
// Insert after the heading
|
|
150
|
+
lines.splice(headingIndex + 1, 0, ...newLines);
|
|
151
|
+
break;
|
|
152
|
+
}
|
|
153
|
+
case 'at-line': {
|
|
154
|
+
if (line === undefined || line < 0) {
|
|
155
|
+
throw new Error('Valid line number is required for at-line position');
|
|
156
|
+
}
|
|
157
|
+
// Ensure we have enough lines
|
|
158
|
+
while (lines.length < line) {
|
|
159
|
+
lines.push('');
|
|
160
|
+
}
|
|
161
|
+
// When inserting at a blank line, consume it to avoid double gaps
|
|
162
|
+
if (line < lines.length && lines[line].trim() === '') {
|
|
163
|
+
lines.splice(line, 1, ...newLines);
|
|
164
|
+
}
|
|
165
|
+
else {
|
|
166
|
+
lines.splice(line, 0, ...newLines);
|
|
167
|
+
}
|
|
168
|
+
break;
|
|
169
|
+
}
|
|
170
|
+
case 'in-section': {
|
|
171
|
+
if (!heading) {
|
|
172
|
+
throw new Error('Heading is required for in-section position');
|
|
173
|
+
}
|
|
174
|
+
const targetSectionHeading = normalizeHeadingForMatch(heading);
|
|
175
|
+
const sectionHeadingIndex = lines.findIndex((lineValue) => {
|
|
176
|
+
const lineHeading = extractSectionBoundaryText(lineValue);
|
|
177
|
+
if (!lineHeading)
|
|
178
|
+
return false;
|
|
179
|
+
return normalizeHeadingForMatch(lineHeading) === targetSectionHeading;
|
|
180
|
+
});
|
|
181
|
+
if (sectionHeadingIndex === -1) {
|
|
182
|
+
const availableSectionHeadings = lines
|
|
183
|
+
.map((lineValue) => extractSectionBoundaryText(lineValue))
|
|
184
|
+
.filter((value) => Boolean(value))
|
|
185
|
+
.slice(0, 15);
|
|
186
|
+
if (availableSectionHeadings.length > 0) {
|
|
187
|
+
throw new Error(`Heading "${heading}" not found. Available headings include: ${availableSectionHeadings.join(' | ')}`);
|
|
188
|
+
}
|
|
189
|
+
throw new Error(`Heading "${heading}" not found`);
|
|
190
|
+
}
|
|
191
|
+
// Find end of section: next heading/section marker or end of file
|
|
192
|
+
let sectionEndIndex = lines.length;
|
|
193
|
+
for (let i = sectionHeadingIndex + 1; i < lines.length; i++) {
|
|
194
|
+
if (isSectionBoundary(lines[i])) {
|
|
195
|
+
sectionEndIndex = i;
|
|
196
|
+
break;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
// Walk backward from section end to skip trailing blank lines
|
|
200
|
+
let insertIndex = sectionEndIndex;
|
|
201
|
+
while (insertIndex > sectionHeadingIndex + 1 && lines[insertIndex - 1].trim() === '') {
|
|
202
|
+
insertIndex--;
|
|
203
|
+
}
|
|
204
|
+
lines.splice(insertIndex, 0, ...newLines);
|
|
205
|
+
break;
|
|
206
|
+
}
|
|
207
|
+
default:
|
|
208
|
+
throw new Error(`Unknown position: ${position}`);
|
|
209
|
+
}
|
|
210
|
+
return lines.join('\n');
|
|
211
|
+
}
|
|
212
|
+
/**
|
|
213
|
+
* Delete lines from content (1-indexed, inclusive)
|
|
214
|
+
*/
|
|
215
|
+
export function deleteLines(content, startLine, endLine) {
|
|
216
|
+
if (startLine < 1 || endLine < startLine) {
|
|
217
|
+
throw new Error(`Invalid line range: ${startLine}-${endLine}`);
|
|
218
|
+
}
|
|
219
|
+
const lines = content.split('\n');
|
|
220
|
+
if (startLine > lines.length) {
|
|
221
|
+
throw new Error(`Start line ${startLine} exceeds content length (${lines.length} lines)`);
|
|
222
|
+
}
|
|
223
|
+
// Convert to 0-indexed
|
|
224
|
+
const startIndex = startLine - 1;
|
|
225
|
+
const endIndex = Math.min(endLine, lines.length);
|
|
226
|
+
// Remove the lines
|
|
227
|
+
lines.splice(startIndex, endIndex - startIndex);
|
|
228
|
+
return lines.join('\n');
|
|
229
|
+
}
|
|
230
|
+
function extractAtxHeadingText(line) {
|
|
231
|
+
const match = line.match(/^\s{0,3}(#{1,6})\s*(.*?)\s*#*\s*$/);
|
|
232
|
+
if (!match)
|
|
233
|
+
return null;
|
|
234
|
+
const text = match[2]?.trim() || '';
|
|
235
|
+
if (!text)
|
|
236
|
+
return null;
|
|
237
|
+
return text;
|
|
238
|
+
}
|
|
239
|
+
function extractBoldSectionMarker(line) {
|
|
240
|
+
const match = line.match(/^\s*\*\*(.+?)\*\*:?\s*$/);
|
|
241
|
+
if (!match)
|
|
242
|
+
return null;
|
|
243
|
+
return match[1].trim() || null;
|
|
244
|
+
}
|
|
245
|
+
function extractSectionBoundaryText(line) {
|
|
246
|
+
return extractAtxHeadingText(line) ?? extractBoldSectionMarker(line);
|
|
247
|
+
}
|
|
248
|
+
function isSectionBoundary(line) {
|
|
249
|
+
return extractSectionBoundaryText(line) !== null;
|
|
250
|
+
}
|
|
251
|
+
function normalizeHeadingForMatch(value) {
|
|
252
|
+
let normalized = value.trim();
|
|
253
|
+
normalized = normalized.replace(/^\s{0,3}#{1,6}\s*/, '');
|
|
254
|
+
normalized = normalized.replace(/\s+#+\s*$/, '');
|
|
255
|
+
normalized = normalized.replace(/^\*\*(.+?)\*\*:?\s*$/, '$1');
|
|
256
|
+
normalized = normalized.replace(/\s+/g, ' ').trim();
|
|
257
|
+
return normalized.toLowerCase();
|
|
258
|
+
}
|
|
259
|
+
//# sourceMappingURL=frontmatter-parser.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"frontmatter-parser.js","sourceRoot":"","sources":["../../src/noteplan/frontmatter-parser.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import { Note, SearchResult } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Perform fuzzy search on notes using Fuse.js
|
|
4
|
+
* Handles typos and partial matches
|
|
5
|
+
*/
|
|
6
|
+
export declare function fuzzySearch(notes: Note[], query: string, limit?: number): SearchResult[];
|
|
7
|
+
//# sourceMappingURL=fuzzy-search.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzy-search.d.ts","sourceRoot":"","sources":["../../src/noteplan/fuzzy-search.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,IAAI,EAAE,YAAY,EAAe,MAAM,YAAY,CAAC;AAc7D;;;GAGG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,GAAE,MAAW,GAAG,YAAY,EAAE,CAS5F"}
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
// Fuzzy search layer using Fuse.js
|
|
2
|
+
import Fuse from 'fuse.js';
|
|
3
|
+
const fuseOptions = {
|
|
4
|
+
keys: [
|
|
5
|
+
{ name: 'title', weight: 2 },
|
|
6
|
+
{ name: 'content', weight: 1 },
|
|
7
|
+
],
|
|
8
|
+
threshold: 0.4, // 0 = exact match only, 1 = match anything
|
|
9
|
+
includeScore: true,
|
|
10
|
+
includeMatches: true,
|
|
11
|
+
minMatchCharLength: 2,
|
|
12
|
+
ignoreLocation: true, // Match anywhere in string
|
|
13
|
+
};
|
|
14
|
+
/**
|
|
15
|
+
* Perform fuzzy search on notes using Fuse.js
|
|
16
|
+
* Handles typos and partial matches
|
|
17
|
+
*/
|
|
18
|
+
export function fuzzySearch(notes, query, limit = 50) {
|
|
19
|
+
const fuse = new Fuse(notes, fuseOptions);
|
|
20
|
+
const results = fuse.search(query, { limit });
|
|
21
|
+
return results.map((result) => ({
|
|
22
|
+
note: result.item,
|
|
23
|
+
score: Math.round((1 - (result.score || 0)) * 100), // Convert to 0-100 scale
|
|
24
|
+
matches: convertFuseMatches(result.matches || []),
|
|
25
|
+
}));
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Convert Fuse.js match format to our SearchMatch format
|
|
29
|
+
*/
|
|
30
|
+
function convertFuseMatches(fuseMatches) {
|
|
31
|
+
const matches = [];
|
|
32
|
+
for (const fm of fuseMatches) {
|
|
33
|
+
if (fm.key === 'content' && fm.value) {
|
|
34
|
+
// Find line number for content matches
|
|
35
|
+
const lines = fm.value.split('\n');
|
|
36
|
+
let charIndex = 0;
|
|
37
|
+
for (let lineNum = 0; lineNum < lines.length; lineNum++) {
|
|
38
|
+
const line = lines[lineNum];
|
|
39
|
+
for (const [start, end] of fm.indices || []) {
|
|
40
|
+
if (start >= charIndex && start < charIndex + line.length + 1) {
|
|
41
|
+
matches.push({
|
|
42
|
+
lineNumber: lineNum + 1,
|
|
43
|
+
lineContent: line,
|
|
44
|
+
matchStart: start - charIndex,
|
|
45
|
+
matchEnd: end - charIndex + 1,
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
charIndex += line.length + 1; // +1 for newline
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
else if (fm.key === 'title' && fm.value) {
|
|
53
|
+
// Title match - add as line 0
|
|
54
|
+
for (const [start, end] of fm.indices || []) {
|
|
55
|
+
matches.push({
|
|
56
|
+
lineNumber: 0, // Title is "line 0"
|
|
57
|
+
lineContent: fm.value,
|
|
58
|
+
matchStart: start,
|
|
59
|
+
matchEnd: end + 1,
|
|
60
|
+
});
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
return matches;
|
|
65
|
+
}
|
|
66
|
+
//# sourceMappingURL=fuzzy-search.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fuzzy-search.js","sourceRoot":"","sources":["../../src/noteplan/fuzzy-search.ts"],"names":[],"mappings":"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"}
|