obsidian-mcp-server 1.5.8 → 2.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (221) hide show
  1. package/README.md +248 -104
  2. package/dist/config/index.d.ts +41 -0
  3. package/dist/config/index.js +191 -0
  4. package/dist/index.d.ts +1 -5
  5. package/dist/index.js +296 -18
  6. package/dist/mcp-server/server.d.ts +33 -0
  7. package/dist/mcp-server/server.js +211 -0
  8. package/dist/mcp-server/tools/obsidianDeleteFileTool/index.d.ts +12 -0
  9. package/dist/mcp-server/tools/obsidianDeleteFileTool/index.js +12 -0
  10. package/dist/mcp-server/tools/obsidianDeleteFileTool/logic.d.ts +51 -0
  11. package/dist/mcp-server/tools/obsidianDeleteFileTool/logic.js +168 -0
  12. package/dist/mcp-server/tools/obsidianDeleteFileTool/registration.d.ts +19 -0
  13. package/dist/mcp-server/tools/obsidianDeleteFileTool/registration.js +91 -0
  14. package/dist/mcp-server/tools/obsidianGlobalSearchTool/index.d.ts +12 -0
  15. package/dist/mcp-server/tools/obsidianGlobalSearchTool/index.js +12 -0
  16. package/dist/mcp-server/tools/obsidianGlobalSearchTool/logic.d.ts +77 -0
  17. package/dist/mcp-server/tools/obsidianGlobalSearchTool/logic.js +341 -0
  18. package/dist/mcp-server/tools/obsidianGlobalSearchTool/registration.d.ts +18 -0
  19. package/dist/mcp-server/tools/obsidianGlobalSearchTool/registration.js +69 -0
  20. package/dist/mcp-server/tools/obsidianListFilesTool/index.d.ts +12 -0
  21. package/dist/mcp-server/tools/obsidianListFilesTool/index.js +12 -0
  22. package/dist/mcp-server/tools/obsidianListFilesTool/logic.d.ts +64 -0
  23. package/dist/mcp-server/tools/obsidianListFilesTool/logic.js +179 -0
  24. package/dist/mcp-server/tools/obsidianListFilesTool/registration.d.ts +19 -0
  25. package/dist/mcp-server/tools/obsidianListFilesTool/registration.js +96 -0
  26. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/index.d.ts +3 -0
  27. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/index.js +2 -0
  28. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/logic.d.ts +42 -0
  29. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/logic.js +152 -0
  30. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/registration.d.ts +3 -0
  31. package/dist/mcp-server/tools/obsidianManageFrontmatterTool/registration.js +52 -0
  32. package/dist/mcp-server/tools/obsidianManageTagsTool/index.d.ts +3 -0
  33. package/dist/mcp-server/tools/obsidianManageTagsTool/index.js +2 -0
  34. package/dist/mcp-server/tools/obsidianManageTagsTool/logic.d.ts +28 -0
  35. package/dist/mcp-server/tools/obsidianManageTagsTool/logic.js +161 -0
  36. package/dist/mcp-server/tools/obsidianManageTagsTool/registration.d.ts +3 -0
  37. package/dist/mcp-server/tools/obsidianManageTagsTool/registration.js +52 -0
  38. package/dist/mcp-server/tools/obsidianReadFileTool/index.d.ts +12 -0
  39. package/dist/mcp-server/tools/obsidianReadFileTool/index.js +12 -0
  40. package/dist/mcp-server/tools/obsidianReadFileTool/logic.d.ts +87 -0
  41. package/dist/mcp-server/tools/obsidianReadFileTool/logic.js +216 -0
  42. package/dist/mcp-server/tools/obsidianReadFileTool/registration.d.ts +20 -0
  43. package/dist/mcp-server/tools/obsidianReadFileTool/registration.js +101 -0
  44. package/dist/mcp-server/tools/obsidianSearchReplaceTool/index.d.ts +12 -0
  45. package/dist/mcp-server/tools/obsidianSearchReplaceTool/index.js +12 -0
  46. package/dist/mcp-server/tools/obsidianSearchReplaceTool/logic.d.ts +255 -0
  47. package/dist/mcp-server/tools/obsidianSearchReplaceTool/logic.js +583 -0
  48. package/dist/mcp-server/tools/obsidianSearchReplaceTool/registration.d.ts +22 -0
  49. package/dist/mcp-server/tools/obsidianSearchReplaceTool/registration.js +111 -0
  50. package/dist/mcp-server/tools/obsidianUpdateFileTool/index.d.ts +12 -0
  51. package/dist/mcp-server/tools/obsidianUpdateFileTool/index.js +12 -0
  52. package/dist/mcp-server/tools/obsidianUpdateFileTool/logic.d.ts +183 -0
  53. package/dist/mcp-server/tools/obsidianUpdateFileTool/logic.js +490 -0
  54. package/dist/mcp-server/tools/obsidianUpdateFileTool/registration.d.ts +21 -0
  55. package/dist/mcp-server/tools/obsidianUpdateFileTool/registration.js +108 -0
  56. package/dist/mcp-server/transports/authentication/authContext.d.ts +33 -0
  57. package/dist/mcp-server/transports/authentication/authContext.js +24 -0
  58. package/dist/mcp-server/transports/authentication/authMiddleware.d.ts +30 -0
  59. package/dist/mcp-server/transports/authentication/authMiddleware.js +145 -0
  60. package/dist/mcp-server/transports/authentication/authUtils.d.ts +18 -0
  61. package/dist/mcp-server/transports/authentication/authUtils.js +45 -0
  62. package/dist/mcp-server/transports/authentication/oauthMiddleware.d.ts +24 -0
  63. package/dist/mcp-server/transports/authentication/oauthMiddleware.js +109 -0
  64. package/dist/mcp-server/transports/authentication/types.d.ts +17 -0
  65. package/dist/mcp-server/transports/authentication/types.js +5 -0
  66. package/dist/mcp-server/transports/httpTransport.d.ts +24 -0
  67. package/dist/mcp-server/transports/httpTransport.js +496 -0
  68. package/dist/mcp-server/transports/stdioTransport.d.ts +42 -0
  69. package/dist/mcp-server/transports/stdioTransport.js +63 -0
  70. package/dist/services/obsidianRestAPI/index.d.ts +15 -0
  71. package/dist/services/obsidianRestAPI/index.js +17 -0
  72. package/dist/services/obsidianRestAPI/methods/activeFileMethods.d.ts +38 -0
  73. package/dist/services/obsidianRestAPI/methods/activeFileMethods.js +62 -0
  74. package/dist/services/obsidianRestAPI/methods/commandMethods.d.ts +22 -0
  75. package/dist/services/obsidianRestAPI/methods/commandMethods.js +31 -0
  76. package/dist/services/obsidianRestAPI/methods/openMethods.d.ts +16 -0
  77. package/dist/services/obsidianRestAPI/methods/openMethods.js +21 -0
  78. package/dist/services/obsidianRestAPI/methods/patchMethods.d.ts +37 -0
  79. package/dist/services/obsidianRestAPI/methods/patchMethods.js +94 -0
  80. package/dist/services/obsidianRestAPI/methods/periodicNoteMethods.d.ts +42 -0
  81. package/dist/services/obsidianRestAPI/methods/periodicNoteMethods.js +66 -0
  82. package/dist/services/obsidianRestAPI/methods/searchMethods.d.ts +25 -0
  83. package/dist/services/obsidianRestAPI/methods/searchMethods.js +36 -0
  84. package/dist/services/obsidianRestAPI/methods/vaultMethods.d.ts +58 -0
  85. package/dist/services/obsidianRestAPI/methods/vaultMethods.js +144 -0
  86. package/dist/services/obsidianRestAPI/service.d.ts +195 -0
  87. package/dist/services/obsidianRestAPI/service.js +379 -0
  88. package/dist/services/obsidianRestAPI/types.d.ts +127 -0
  89. package/dist/services/obsidianRestAPI/types.js +7 -0
  90. package/dist/services/obsidianRestAPI/vaultCache/index.d.ts +4 -0
  91. package/dist/services/obsidianRestAPI/vaultCache/index.js +4 -0
  92. package/dist/services/obsidianRestAPI/vaultCache/service.d.ts +88 -0
  93. package/dist/services/obsidianRestAPI/vaultCache/service.js +299 -0
  94. package/dist/types-global/errors.d.ts +73 -0
  95. package/dist/types-global/errors.js +71 -0
  96. package/dist/utils/index.d.ts +5 -8
  97. package/dist/utils/index.js +13 -9
  98. package/dist/utils/internal/asyncUtils.d.ts +54 -0
  99. package/dist/utils/internal/asyncUtils.js +101 -0
  100. package/dist/utils/internal/errorHandler.d.ts +176 -0
  101. package/dist/utils/internal/errorHandler.js +351 -0
  102. package/dist/utils/internal/index.d.ts +4 -0
  103. package/dist/utils/internal/index.js +4 -0
  104. package/dist/utils/internal/logger.d.ts +141 -0
  105. package/dist/utils/internal/logger.js +406 -0
  106. package/dist/utils/internal/requestContext.d.ts +83 -0
  107. package/dist/utils/internal/requestContext.js +72 -0
  108. package/dist/utils/metrics/index.d.ts +1 -0
  109. package/dist/utils/metrics/index.js +1 -0
  110. package/dist/utils/metrics/tokenCounter.d.ts +27 -0
  111. package/dist/utils/metrics/tokenCounter.js +128 -0
  112. package/dist/utils/obsidian/index.d.ts +5 -0
  113. package/dist/utils/obsidian/index.js +5 -0
  114. package/dist/utils/obsidian/obsidianApiUtils.d.ts +14 -0
  115. package/dist/utils/obsidian/obsidianApiUtils.js +29 -0
  116. package/dist/utils/obsidian/obsidianStatUtils.d.ts +68 -0
  117. package/dist/utils/obsidian/obsidianStatUtils.js +143 -0
  118. package/dist/utils/parsing/dateParser.d.ts +56 -0
  119. package/dist/utils/parsing/dateParser.js +104 -0
  120. package/dist/utils/parsing/index.d.ts +2 -0
  121. package/dist/utils/parsing/index.js +3 -0
  122. package/dist/utils/parsing/jsonParser.d.ts +80 -0
  123. package/dist/utils/parsing/jsonParser.js +133 -0
  124. package/dist/utils/security/idGenerator.d.ts +140 -0
  125. package/dist/utils/security/idGenerator.js +194 -0
  126. package/dist/utils/security/index.d.ts +3 -0
  127. package/dist/utils/security/index.js +3 -0
  128. package/dist/utils/security/rateLimiter.d.ts +156 -0
  129. package/dist/utils/security/rateLimiter.js +235 -0
  130. package/dist/utils/security/sanitization.d.ts +244 -0
  131. package/dist/utils/security/sanitization.js +599 -0
  132. package/package.json +58 -37
  133. package/dist/index.js.map +0 -1
  134. package/dist/mcp/handlers.d.ts +0 -29
  135. package/dist/mcp/handlers.js +0 -305
  136. package/dist/mcp/handlers.js.map +0 -1
  137. package/dist/mcp/index.d.ts +0 -6
  138. package/dist/mcp/index.js +0 -7
  139. package/dist/mcp/index.js.map +0 -1
  140. package/dist/mcp/server.d.ts +0 -18
  141. package/dist/mcp/server.js +0 -240
  142. package/dist/mcp/server.js.map +0 -1
  143. package/dist/mcp/types.d.ts +0 -70
  144. package/dist/mcp/types.js +0 -49
  145. package/dist/mcp/types.js.map +0 -1
  146. package/dist/obsidian/client.d.ts +0 -109
  147. package/dist/obsidian/client.js +0 -403
  148. package/dist/obsidian/client.js.map +0 -1
  149. package/dist/obsidian/errors.d.ts +0 -28
  150. package/dist/obsidian/errors.js +0 -75
  151. package/dist/obsidian/errors.js.map +0 -1
  152. package/dist/obsidian/index.d.ts +0 -6
  153. package/dist/obsidian/index.js +0 -7
  154. package/dist/obsidian/index.js.map +0 -1
  155. package/dist/obsidian/types.d.ts +0 -107
  156. package/dist/obsidian/types.js +0 -12
  157. package/dist/obsidian/types.js.map +0 -1
  158. package/dist/resources/index.d.ts +0 -13
  159. package/dist/resources/index.js +0 -15
  160. package/dist/resources/index.js.map +0 -1
  161. package/dist/resources/tags.d.ts +0 -39
  162. package/dist/resources/tags.js +0 -257
  163. package/dist/resources/tags.js.map +0 -1
  164. package/dist/resources/types.d.ts +0 -27
  165. package/dist/resources/types.js +0 -5
  166. package/dist/resources/types.js.map +0 -1
  167. package/dist/tools/base.d.ts +0 -46
  168. package/dist/tools/base.js +0 -88
  169. package/dist/tools/base.js.map +0 -1
  170. package/dist/tools/files/content.d.ts +0 -58
  171. package/dist/tools/files/content.js +0 -171
  172. package/dist/tools/files/content.js.map +0 -1
  173. package/dist/tools/files/index.d.ts +0 -14
  174. package/dist/tools/files/index.js +0 -22
  175. package/dist/tools/files/index.js.map +0 -1
  176. package/dist/tools/files/list.d.ts +0 -35
  177. package/dist/tools/files/list.js +0 -133
  178. package/dist/tools/files/list.js.map +0 -1
  179. package/dist/tools/index.d.ts +0 -21
  180. package/dist/tools/index.js +0 -31
  181. package/dist/tools/index.js.map +0 -1
  182. package/dist/tools/properties/index.d.ts +0 -14
  183. package/dist/tools/properties/index.js +0 -19
  184. package/dist/tools/properties/index.js.map +0 -1
  185. package/dist/tools/properties/manager.d.ts +0 -62
  186. package/dist/tools/properties/manager.js +0 -302
  187. package/dist/tools/properties/manager.js.map +0 -1
  188. package/dist/tools/properties/tools.d.ts +0 -47
  189. package/dist/tools/properties/tools.js +0 -239
  190. package/dist/tools/properties/tools.js.map +0 -1
  191. package/dist/tools/properties/types.d.ts +0 -141
  192. package/dist/tools/properties/types.js +0 -70
  193. package/dist/tools/properties/types.js.map +0 -1
  194. package/dist/tools/search/complex.d.ts +0 -38
  195. package/dist/tools/search/complex.js +0 -270
  196. package/dist/tools/search/complex.js.map +0 -1
  197. package/dist/tools/search/index.d.ts +0 -14
  198. package/dist/tools/search/index.js +0 -20
  199. package/dist/tools/search/index.js.map +0 -1
  200. package/dist/tools/search/simple.d.ts +0 -25
  201. package/dist/tools/search/simple.js +0 -127
  202. package/dist/tools/search/simple.js.map +0 -1
  203. package/dist/utils/errors.d.ts +0 -24
  204. package/dist/utils/errors.js +0 -59
  205. package/dist/utils/errors.js.map +0 -1
  206. package/dist/utils/idGenerator.d.ts +0 -15
  207. package/dist/utils/idGenerator.js +0 -21
  208. package/dist/utils/idGenerator.js.map +0 -1
  209. package/dist/utils/index.js.map +0 -1
  210. package/dist/utils/logging.d.ts +0 -245
  211. package/dist/utils/logging.js +0 -417
  212. package/dist/utils/logging.js.map +0 -1
  213. package/dist/utils/rate-limiting.d.ts +0 -50
  214. package/dist/utils/rate-limiting.js +0 -94
  215. package/dist/utils/rate-limiting.js.map +0 -1
  216. package/dist/utils/tokenization.d.ts +0 -28
  217. package/dist/utils/tokenization.js +0 -75
  218. package/dist/utils/tokenization.js.map +0 -1
  219. package/dist/utils/validation.d.ts +0 -22
  220. package/dist/utils/validation.js +0 -92
  221. package/dist/utils/validation.js.map +0 -1
@@ -1,302 +0,0 @@
1
- /**
2
- * Property manager for Obsidian notes
3
- */
4
- import { EOL } from 'os';
5
- import { parse, stringify } from 'yaml';
6
- import { createLogger } from '../../utils/logging.js';
7
- import { ObsidianPropertiesSchema, PropertyUpdateSchema } from './types.js';
8
- // Create a logger for property operations
9
- const logger = createLogger('PropertyManager');
10
- /**
11
- * Simple deep merge function for plain objects and arrays.
12
- * Merges 'source' into 'target'. Modifies 'target' in place.
13
- */
14
- function deepMerge(target, source) {
15
- if (typeof target !== 'object' || target === null || typeof source !== 'object' || source === null) {
16
- return source; // Overwrite if not both are mergeable objects
17
- }
18
- for (const key in source) {
19
- // eslint-disable-next-line no-prototype-builtins
20
- if (source.hasOwnProperty(key)) {
21
- const targetValue = target[key];
22
- const sourceValue = source[key];
23
- if (Array.isArray(targetValue) && Array.isArray(sourceValue)) {
24
- // For arrays, concatenate and remove duplicates for simple arrays,
25
- // otherwise, replace (could be enhanced for object arrays if needed)
26
- target[key] = [...new Set([...targetValue, ...sourceValue])];
27
- }
28
- else if (typeof targetValue === 'object' && targetValue !== null && typeof sourceValue === 'object' && sourceValue !== null) {
29
- // Recursively merge nested objects
30
- deepMerge(targetValue, sourceValue);
31
- }
32
- else {
33
- // Overwrite primitive values or if types mismatch
34
- target[key] = sourceValue;
35
- }
36
- }
37
- }
38
- return target;
39
- }
40
- /**
41
- * Manages YAML frontmatter properties in Obsidian notes
42
- */
43
- export class PropertyManager {
44
- client;
45
- constructor(client) {
46
- this.client = client;
47
- }
48
- /**
49
- * Parse YAML frontmatter from note content. Finds the *first* valid block.
50
- * @param content The note content
51
- * @returns ParseResult containing properties and match details or error.
52
- */
53
- parseProperties(content) {
54
- try {
55
- // Regex to find the first frontmatter block (allows leading content)
56
- // It captures the content between the --- markers.
57
- const match = content.match(/(?:^|\r?\n)---\r?\n([\s\S]*?)\r?\n---/);
58
- if (!match) {
59
- logger.debug('No frontmatter found in content');
60
- return { properties: {} };
61
- }
62
- const frontmatterYaml = match[1];
63
- // Calculate accurate start/end indices of the *entire* matched block (including ---)
64
- const blockStartIndex = match.index ?? 0;
65
- const blockEndIndex = blockStartIndex + match[0].length;
66
- // Parse YAML first
67
- const rawProperties = parse(frontmatterYaml);
68
- // Validate the raw parsed object against the schema
69
- const validationResult = ObsidianPropertiesSchema.safeParse(rawProperties);
70
- if (!validationResult.success) {
71
- const error = new Error(`Frontmatter validation failed: ${validationResult.error.message}`);
72
- logger.warn(error.message, { validationError: validationResult.error.flatten() });
73
- // Return parsed (but invalid) data along with the error and match info
74
- return {
75
- properties: rawProperties, // Cast, knowing it's invalid
76
- match: { startIndex: blockStartIndex, endIndex: blockEndIndex, rawFrontmatter: frontmatterYaml },
77
- error
78
- };
79
- }
80
- // Use the validated data from now on
81
- const validatedProperties = validationResult.data;
82
- // Handle tags transformation (remove '#') on validated data
83
- if (validatedProperties.tags && Array.isArray(validatedProperties.tags)) {
84
- validatedProperties.tags = validatedProperties.tags.map((tag) => typeof tag === 'string' && tag.startsWith('#') ? tag.substring(1) : tag);
85
- }
86
- // Return the validated properties and match info
87
- return {
88
- properties: validatedProperties,
89
- match: { startIndex: blockStartIndex, endIndex: blockEndIndex, rawFrontmatter: frontmatterYaml }
90
- };
91
- }
92
- catch (error) {
93
- const parseError = error instanceof Error ? error : new Error(String(error));
94
- logger.error('Error parsing properties:', parseError);
95
- // Return error information
96
- return {
97
- properties: {},
98
- error: parseError
99
- };
100
- }
101
- }
102
- /**
103
- * Generate YAML frontmatter from properties
104
- * @param properties The properties to convert to YAML
105
- * @returns YAML frontmatter string
106
- */
107
- generateProperties(properties) {
108
- try {
109
- // Create a deep copy to avoid modifying the original object
110
- const propsToGenerate = JSON.parse(JSON.stringify(properties));
111
- // Add '#' prefix back to tags before stringifying
112
- if (propsToGenerate.tags && Array.isArray(propsToGenerate.tags)) {
113
- propsToGenerate.tags = propsToGenerate.tags.map((tag) => typeof tag === 'string' && !tag.startsWith('#') ? `#${tag}` : tag);
114
- }
115
- // Remove undefined values explicitly (shouldn't be necessary with JSON.stringify/parse but safe)
116
- const cleanProperties = Object.fromEntries(Object.entries(propsToGenerate).filter(([_, v]) => v !== undefined));
117
- // Generate YAML with platform-specific line endings
118
- const yaml = stringify(cleanProperties);
119
- // Ensure consistent EOL for the markers and the content
120
- return `---${EOL}${yaml.trimEnd()}${EOL}---`; // Return block without trailing EOL initially
121
- }
122
- catch (error) {
123
- logger.error('Error generating properties:', error instanceof Error ? error : { error: String(error) });
124
- // Re-throw to be caught by the caller
125
- throw error instanceof Error ? error : new Error(String(error));
126
- }
127
- }
128
- /**
129
- * Validate property values against schema
130
- * @param properties The properties to validate
131
- * @returns Validation result
132
- */
133
- validateProperties(properties) {
134
- const result = PropertyUpdateSchema.safeParse(properties);
135
- if (result.success) {
136
- return { valid: true, errors: [] };
137
- }
138
- return {
139
- valid: false,
140
- errors: result.error.errors.map(err => `${err.path.join('.')}: ${err.message}`)
141
- };
142
- }
143
- /**
144
- * Merge new properties with existing ones
145
- * @param existing The existing properties
146
- * @param updates The new properties to merge
147
- * @param replace Whether to replace arrays instead of merging them
148
- * @returns The merged properties
149
- */
150
- mergeProperties(existing, updates, replace = false) {
151
- // Start with a deep copy of existing properties to avoid modifying the original
152
- const merged = JSON.parse(JSON.stringify(existing));
153
- for (const [key, value] of Object.entries(updates)) {
154
- // Skip undefined values and timestamp fields (created is handled separately)
155
- if (value === undefined || key === 'modified')
156
- continue;
157
- const currentValue = merged[key];
158
- // Handle arrays based on replace flag
159
- if (Array.isArray(value) && Array.isArray(currentValue)) {
160
- merged[key] = replace ?
161
- value : // Replace array
162
- [...new Set([...currentValue, ...value])]; // Merge unique elements
163
- }
164
- // Special handling for custom object - use deep merge
165
- else if (key === 'custom' && typeof value === 'object' && value !== null && typeof currentValue === 'object' && currentValue !== null) {
166
- // Ensure target 'custom' exists before merging into it
167
- if (!merged.custom)
168
- merged.custom = {};
169
- merged.custom = deepMerge(merged.custom, value); // Deep merge 'custom'
170
- }
171
- // Default case - replace value
172
- else {
173
- merged[key] = value;
174
- }
175
- }
176
- // Handle 'created' timestamp: preserve existing or set if new
177
- merged.created = existing.created ?? new Date().toISOString();
178
- // Always update 'modified' timestamp
179
- merged.modified = new Date().toISOString();
180
- // Remove properties that are explicitly set to null in the update
181
- for (const [key, value] of Object.entries(updates)) {
182
- if (value === null) {
183
- delete merged[key];
184
- }
185
- }
186
- return merged;
187
- }
188
- /**
189
- * Get properties from a note
190
- * @param filepath Path to the note
191
- * @returns The result including properties or errors
192
- */
193
- async getProperties(filepath) {
194
- try {
195
- logger.debug(`Getting properties from file: ${filepath}`);
196
- const content = await this.client.getFileContents(filepath);
197
- const parseResult = this.parseProperties(content);
198
- // Handle parsing/validation errors reported by parseProperties
199
- if (parseResult.error) {
200
- // If validation failed but we have a match, still return the raw (invalid) props?
201
- // For getProperties, it's better to report failure clearly.
202
- return {
203
- success: false,
204
- message: `Failed to parse or validate properties: ${parseResult.error.message}`,
205
- errors: [parseResult.error.message]
206
- };
207
- }
208
- return {
209
- success: true,
210
- message: 'Properties retrieved successfully',
211
- properties: parseResult.properties
212
- };
213
- }
214
- catch (error) {
215
- // Catch errors from getFileContents or other unexpected issues
216
- const err = error instanceof Error ? error : new Error(String(error));
217
- logger.error(`Failed to get properties from ${filepath}:`, err);
218
- return {
219
- success: false,
220
- message: `Failed to get properties: ${err.message}`,
221
- errors: [err.message]
222
- };
223
- }
224
- }
225
- /**
226
- * Update properties of a note
227
- * @param filepath Path to the note
228
- * @param newProperties The new properties to apply
229
- * @param replace Whether to replace arrays instead of merging them
230
- * @returns The result of the update operation
231
- */
232
- async updateProperties(filepath, newProperties, replace = false) {
233
- try {
234
- // Validate new properties first
235
- const validation = this.validateProperties(newProperties);
236
- if (!validation.valid) {
237
- logger.warn(`Invalid properties provided for update in ${filepath}:`, { errors: validation.errors });
238
- return {
239
- success: false,
240
- message: 'Invalid properties provided for update',
241
- errors: validation.errors
242
- };
243
- }
244
- // Get existing content and parse properties
245
- logger.debug(`Updating properties for file: ${filepath}`);
246
- const content = await this.client.getFileContents(filepath);
247
- const parseResult = this.parseProperties(content);
248
- // Handle parsing/validation errors from existing frontmatter *before* merging
249
- if (parseResult.error) {
250
- logger.warn(`Could not parse existing frontmatter in ${filepath}, but proceeding with update: ${parseResult.error.message}`);
251
- // We proceed, merging with potentially empty or invalid existing properties.
252
- // The new valid frontmatter will overwrite the old invalid one.
253
- }
254
- // Merge properties
255
- const mergedProperties = this.mergeProperties(parseResult.properties, newProperties, replace);
256
- // Generate new frontmatter YAML string
257
- const newFrontmatterBlock = this.generateProperties(mergedProperties);
258
- let updatedContent;
259
- const bodyContentStartIndex = parseResult.match ? parseResult.match.endIndex : 0;
260
- let bodyContent = content.substring(bodyContentStartIndex);
261
- // Ensure body content starts with a newline if it's not empty
262
- if (bodyContent.length > 0 && !bodyContent.startsWith('\n') && !bodyContent.startsWith('\r\n')) {
263
- bodyContent = EOL + bodyContent;
264
- }
265
- else if (bodyContent.length === 0 && content.length > 0 && parseResult.match) {
266
- // If there was frontmatter but no body, ensure a newline after new frontmatter
267
- bodyContent = EOL;
268
- }
269
- if (parseResult.match) {
270
- // Replace the existing block accurately using start/end indices
271
- updatedContent =
272
- content.substring(0, parseResult.match.startIndex) + // Content before frontmatter
273
- newFrontmatterBlock + // New frontmatter
274
- bodyContent; // Content after frontmatter (with adjusted leading newline)
275
- }
276
- else {
277
- // No frontmatter found, prepend the new block
278
- updatedContent = newFrontmatterBlock + bodyContent;
279
- }
280
- // Update file content via client
281
- // Trim trailing whitespace from the final content before saving
282
- await this.client.updateContent(filepath, updatedContent.trimEnd() + EOL);
283
- logger.debug(`Successfully updated properties for ${filepath}`);
284
- return {
285
- success: true,
286
- message: 'Properties updated successfully',
287
- properties: mergedProperties // Return the final merged properties
288
- };
289
- }
290
- catch (error) {
291
- // Catch errors from getFileContents, generateProperties, updateContent, etc.
292
- const err = error instanceof Error ? error : new Error(String(error));
293
- logger.error(`Failed to update properties for ${filepath}:`, err);
294
- return {
295
- success: false,
296
- message: `Failed to update properties: ${err.message}`,
297
- errors: [err.message]
298
- };
299
- }
300
- }
301
- }
302
- //# sourceMappingURL=manager.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"manager.js","sourceRoot":"","sources":["../../../src/tools/properties/manager.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,OAAO,EAAE,GAAG,EAAE,MAAM,IAAI,CAAC;AACzB,OAAO,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,MAAM,CAAC;AAExC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EAEL,wBAAwB,EAExB,oBAAoB,EAErB,MAAM,YAAY,CAAC;AAEpB,0CAA0C;AAC1C,MAAM,MAAM,GAAG,YAAY,CAAC,iBAAiB,CAAC,CAAC;AAE/C;;;GAGG;AACH,SAAS,SAAS,CAAC,MAAW,EAAE,MAAW;IACzC,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,IAAI,OAAO,MAAM,KAAK,QAAQ,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACnG,OAAO,MAAM,CAAC,CAAC,8CAA8C;IAC/D,CAAC;IAED,KAAK,MAAM,GAAG,IAAI,MAAM,EAAE,CAAC;QACzB,iDAAiD;QACjD,IAAI,MAAM,CAAC,cAAc,CAAC,GAAG,CAAC,EAAE,CAAC;YAC/B,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAChC,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC;YAEhC,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,WAAW,CAAC,EAAE,CAAC;gBAC7D,mEAAmE;gBACnE,qEAAqE;gBACrE,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,WAAW,EAAE,GAAG,WAAW,CAAC,CAAC,CAAC,CAAC;YAC/D,CAAC;iBAAM,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,IAAI,OAAO,WAAW,KAAK,QAAQ,IAAI,WAAW,KAAK,IAAI,EAAE,CAAC;gBAC9H,mCAAmC;gBACnC,SAAS,CAAC,WAAW,EAAE,WAAW,CAAC,CAAC;YACtC,CAAC;iBAAM,CAAC;gBACN,kDAAkD;gBAClD,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC;YAC5B,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAiBD;;GAEG;AACH,MAAM,OAAO,eAAe;IACN;IAApB,YAAoB,MAAsB;QAAtB,WAAM,GAAN,MAAM,CAAgB;IAAG,CAAC;IAE9C;;;;OAIG;IACH,eAAe,CAAC,OAAe;QAC7B,IAAI,CAAC;YACH,qEAAqE;YACrE,mDAAmD;YACnD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YAErE,IAAI,CAAC,KAAK,EAAE,CAAC;gBACX,MAAM,CAAC,KAAK,CAAC,iCAAiC,CAAC,CAAC;gBAChD,OAAO,EAAE,UAAU,EAAE,EAAE,EAAE,CAAC;YAC5B,CAAC;YAED,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACjC,qFAAqF;YACrF,MAAM,eAAe,GAAG,KAAK,CAAC,KAAK,IAAI,CAAC,CAAC;YACzC,MAAM,aAAa,GAAG,eAAe,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAGxD,mBAAmB;YACnB,MAAM,aAAa,GAAG,KAAK,CAAC,eAAe,CAAC,CAAC;YAE7C,oDAAoD;YACpD,MAAM,gBAAgB,GAAG,wBAAwB,CAAC,SAAS,CAAC,aAAa,CAAC,CAAC;YAE3E,IAAI,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC;gBAC9B,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC,kCAAkC,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC5F,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,eAAe,EAAE,gBAAgB,CAAC,KAAK,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;gBAClF,uEAAuE;gBACvE,OAAO;oBACL,UAAU,EAAE,aAAmC,EAAE,6BAA6B;oBAC9E,KAAK,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE;oBAChG,KAAK;iBACN,CAAC;YACJ,CAAC;YAED,qCAAqC;YACrC,MAAM,mBAAmB,GAAG,gBAAgB,CAAC,IAAI,CAAC;YAElD,4DAA4D;YAC5D,IAAI,mBAAmB,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;gBACxE,mBAAmB,CAAC,IAAI,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAW,EAAE,EAAE,CACtE,OAAO,GAAG,KAAK,QAAQ,IAAI,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CACxE,CAAC;YACJ,CAAC;YAED,iDAAiD;YACjD,OAAO;gBACL,UAAU,EAAE,mBAAmB;gBAC/B,KAAK,EAAE,EAAE,UAAU,EAAE,eAAe,EAAE,QAAQ,EAAE,aAAa,EAAE,cAAc,EAAE,eAAe,EAAE;aACjG,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,UAAU,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YAC7E,MAAM,CAAC,KAAK,CAAC,2BAA2B,EAAE,UAAU,CAAC,CAAC;YACtD,2BAA2B;YAC3B,OAAO;gBACL,UAAU,EAAE,EAAE;gBACd,KAAK,EAAE,UAAU;aAClB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,UAAuC;QACxD,IAAI,CAAC;YACH,4DAA4D;YAC5D,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC,CAAC;YAE/D,kDAAkD;YAClD,IAAI,eAAe,CAAC,IAAI,IAAI,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC;gBAChE,eAAe,CAAC,IAAI,GAAG,eAAe,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAW,EAAE,EAAE,CAC9D,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAClE,CAAC;YACJ,CAAC;YAED,iGAAiG;YACjG,MAAM,eAAe,GAAG,MAAM,CAAC,WAAW,CACxC,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,SAAS,CAAC,CACpE,CAAC;YAEF,oDAAoD;YACpD,MAAM,IAAI,GAAG,SAAS,CAAC,eAAe,CAAC,CAAC;YACxC,wDAAwD;YACxD,OAAO,MAAM,GAAG,GAAG,IAAI,CAAC,OAAO,EAAE,GAAG,GAAG,KAAK,CAAC,CAAC,8CAA8C;QAC9F,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,MAAM,CAAC,KAAK,CAAC,8BAA8B,EAAE,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;YACxG,sCAAsC;YACtC,MAAM,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED;;;;OAIG;IACH,kBAAkB,CAAC,UAAuC;QACxD,MAAM,MAAM,GAAG,oBAAoB,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;QAE1D,IAAI,MAAM,CAAC,OAAO,EAAE,CAAC;YACnB,OAAO,EAAE,KAAK,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC;QACrC,CAAC;QAED,OAAO;YACL,KAAK,EAAE,KAAK;YACZ,MAAM,EAAE,MAAM,CAAC,KAAK,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CACpC,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,KAAK,GAAG,CAAC,OAAO,EAAE,CACxC;SACF,CAAC;IACJ,CAAC;IAED;;;;;;OAMG;IACH,eAAe,CACb,QAA4B,EAC5B,OAAoC,EACpC,UAAmB,KAAK;QAExB,gFAAgF;QAChF,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,SAAS,CAAC,QAAQ,CAAC,CAAC,CAAC;QAEpD,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACnD,6EAA6E;YAC7E,IAAI,KAAK,KAAK,SAAS,IAAI,GAAG,KAAK,UAAU;gBAAE,SAAS;YAExD,MAAM,YAAY,GAAG,MAAM,CAAC,GAA+B,CAAC,CAAC;YAE7D,sCAAsC;YACtC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,OAAO,CAAC,YAAY,CAAC,EAAE,CAAC;gBACxD,MAAM,CAAC,GAA+B,CAAC,GAAG,OAAO,CAAC,CAAC;oBACjD,KAAK,CAAC,CAAC,CAAC,gBAAgB;oBACxB,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,YAAY,EAAE,GAAG,KAAK,CAAC,CAAC,CAAQ,CAAC,CAAC,wBAAwB;YAC9E,CAAC;YACD,sDAAsD;iBACjD,IAAI,GAAG,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,IAAI,IAAI,OAAO,YAAY,KAAK,QAAQ,IAAI,YAAY,KAAK,IAAI,EAAE,CAAC;gBACtI,uDAAuD;gBACtD,IAAI,CAAC,MAAM,CAAC,MAAM;oBAAE,MAAM,CAAC,MAAM,GAAG,EAAE,CAAC;gBACxC,MAAM,CAAC,MAAM,GAAG,SAAS,CAAC,MAAM,CAAC,MAAM,EAAE,KAAK,CAAC,CAAC,CAAC,sBAAsB;YACzE,CAAC;YACD,+BAA+B;iBAC1B,CAAC;gBACJ,MAAM,CAAC,GAA+B,CAAC,GAAG,KAAY,CAAC;YACzD,CAAC;QACH,CAAC;QAED,8DAA8D;QAC9D,MAAM,CAAC,OAAO,GAAG,QAAQ,CAAC,OAAO,IAAI,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAC9D,qCAAqC;QACrC,MAAM,CAAC,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAE3C,kEAAkE;QAClE,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC;YACjD,IAAI,KAAK,KAAK,IAAI,EAAE,CAAC;gBACjB,OAAO,MAAM,CAAC,GAA+B,CAAC,CAAC;YACnD,CAAC;QACL,CAAC;QAGD,OAAO,MAAM,CAAC;IAChB,CAAC;IAED;;;;OAIG;IACH,KAAK,CAAC,aAAa,CAAC,QAAgB;QAClC,IAAI,CAAC;YACH,MAAM,CAAC,KAAK,CAAC,iCAAiC,QAAQ,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAElD,+DAA+D;YAC/D,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;gBACtB,kFAAkF;gBAClF,4DAA4D;gBAC5D,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,2CAA2C,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE;oBAC/E,MAAM,EAAE,CAAC,WAAW,CAAC,KAAK,CAAC,OAAO,CAAC;iBACpC,CAAC;YACJ,CAAC;YAED,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,mCAAmC;gBAC5C,UAAU,EAAE,WAAW,CAAC,UAAU;aACnC,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,+DAA+D;YAC/D,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,MAAM,CAAC,KAAK,CAAC,iCAAiC,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;YAChE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,6BAA6B,GAAG,CAAC,OAAO,EAAE;gBACnD,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;aACtB,CAAC;QACJ,CAAC;IACH,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,gBAAgB,CACpB,QAAgB,EAChB,aAA0C,EAC1C,UAAmB,KAAK;QAExB,IAAI,CAAC;YACH,gCAAgC;YAChC,MAAM,UAAU,GAAG,IAAI,CAAC,kBAAkB,CAAC,aAAa,CAAC,CAAC;YAC1D,IAAI,CAAC,UAAU,CAAC,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,6CAA6C,QAAQ,GAAG,EAAE,EAAE,MAAM,EAAE,UAAU,CAAC,MAAM,EAAE,CAAC,CAAC;gBACrG,OAAO;oBACL,OAAO,EAAE,KAAK;oBACd,OAAO,EAAE,wCAAwC;oBACjD,MAAM,EAAE,UAAU,CAAC,MAAM;iBAC1B,CAAC;YACJ,CAAC;YAED,4CAA4C;YAC5C,MAAM,CAAC,KAAK,CAAC,iCAAiC,QAAQ,EAAE,CAAC,CAAC;YAC1D,MAAM,OAAO,GAAG,MAAM,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC;YAC5D,MAAM,WAAW,GAAG,IAAI,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC;YAElD,8EAA8E;YAC9E,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;gBACtB,MAAM,CAAC,IAAI,CAAC,2CAA2C,QAAQ,iCAAiC,WAAW,CAAC,KAAK,CAAC,OAAO,EAAE,CAAC,CAAC;gBAC7H,6EAA6E;gBAC7E,gEAAgE;YAClE,CAAC;YAED,mBAAmB;YACnB,MAAM,gBAAgB,GAAG,IAAI,CAAC,eAAe,CAAC,WAAW,CAAC,UAAU,EAAE,aAAa,EAAE,OAAO,CAAC,CAAC;YAE9F,uCAAuC;YACvC,MAAM,mBAAmB,GAAG,IAAI,CAAC,kBAAkB,CAAC,gBAAgB,CAAC,CAAC;YAEtE,IAAI,cAAsB,CAAC;YAC3B,MAAM,qBAAqB,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC,CAAC,WAAW,CAAC,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC;YACjF,IAAI,WAAW,GAAG,OAAO,CAAC,SAAS,CAAC,qBAAqB,CAAC,CAAC;YAE3D,8DAA8D;YAC9D,IAAI,WAAW,CAAC,MAAM,GAAG,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,IAAI,CAAC,IAAI,CAAC,WAAW,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;gBAC7F,WAAW,GAAG,GAAG,GAAG,WAAW,CAAC;YACpC,CAAC;iBAAM,IAAI,WAAW,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;gBAC7E,+EAA+E;gBAC/E,WAAW,GAAG,GAAG,CAAC;YACtB,CAAC;YAGD,IAAI,WAAW,CAAC,KAAK,EAAE,CAAC;gBACtB,gEAAgE;gBAChE,cAAc;oBACZ,OAAO,CAAC,SAAS,CAAC,CAAC,EAAE,WAAW,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,6BAA6B;wBAClF,mBAAmB,GAAG,kBAAkB;wBACxC,WAAW,CAAC,CAAC,4DAA4D;YAC7E,CAAC;iBAAM,CAAC;gBACN,8CAA8C;gBAC9C,cAAc,GAAG,mBAAmB,GAAG,WAAW,CAAC;YACrD,CAAC;YAED,iCAAiC;YACjC,gEAAgE;YAChE,MAAM,IAAI,CAAC,MAAM,CAAC,aAAa,CAAC,QAAQ,EAAE,cAAc,CAAC,OAAO,EAAE,GAAG,GAAG,CAAC,CAAC;YAC1E,MAAM,CAAC,KAAK,CAAC,uCAAuC,QAAQ,EAAE,CAAC,CAAC;YAEhE,OAAO;gBACL,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,iCAAiC;gBAC1C,UAAU,EAAE,gBAAgB,CAAC,qCAAqC;aACnE,CAAC;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,6EAA6E;YAC7E,MAAM,GAAG,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC;YACtE,MAAM,CAAC,KAAK,CAAC,mCAAmC,QAAQ,GAAG,EAAE,GAAG,CAAC,CAAC;YAClE,OAAO;gBACL,OAAO,EAAE,KAAK;gBACd,OAAO,EAAE,gCAAgC,GAAG,CAAC,OAAO,EAAE;gBACtD,MAAM,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC;aACtB,CAAC;QACJ,CAAC;IACH,CAAC;CACF"}
@@ -1,47 +0,0 @@
1
- /**
2
- * Property-related tool implementations
3
- */
4
- import { TextContent, Tool } from "@modelcontextprotocol/sdk/types.js";
5
- import { ObsidianClient } from "../../obsidian/client.js";
6
- import { BaseToolHandler } from "../base.js";
7
- import { ObsidianProperties } from "./types.js";
8
- /**
9
- * Tool names for property operations
10
- */
11
- export declare const PROPERTY_TOOL_NAMES: {
12
- readonly GET_PROPERTIES: "obsidian_get_properties";
13
- readonly UPDATE_PROPERTIES: "obsidian_update_properties";
14
- };
15
- /**
16
- * Arguments for getting properties
17
- */
18
- interface GetPropertiesArgs {
19
- filepath: string;
20
- }
21
- /**
22
- * Arguments for updating properties
23
- */
24
- interface UpdatePropertiesArgs {
25
- filepath: string;
26
- properties: Partial<ObsidianProperties>;
27
- replace?: boolean;
28
- }
29
- /**
30
- * Tool handler for getting properties from a note
31
- */
32
- export declare class GetPropertiesToolHandler extends BaseToolHandler<GetPropertiesArgs> {
33
- private propertyManager;
34
- constructor(client: ObsidianClient);
35
- getToolDescription(): Tool;
36
- runTool(args: GetPropertiesArgs): Promise<Array<TextContent>>;
37
- }
38
- /**
39
- * Tool handler for updating properties in a note
40
- */
41
- export declare class UpdatePropertiesToolHandler extends BaseToolHandler<UpdatePropertiesArgs> {
42
- private propertyManager;
43
- constructor(client: ObsidianClient);
44
- getToolDescription(): Tool;
45
- runTool(args: UpdatePropertiesArgs): Promise<Array<TextContent>>;
46
- }
47
- export {};
@@ -1,239 +0,0 @@
1
- import { createLogger, ErrorCategoryType } from "../../utils/logging.js";
2
- import { BaseToolHandler } from "../base.js";
3
- import { PropertyManager } from "./manager.js";
4
- // Create a logger for property tools
5
- const logger = createLogger('PropertyTools');
6
- /**
7
- * Helper function to safely convert any error to an object
8
- */
9
- function errorToObject(error) {
10
- if (error instanceof Error) {
11
- return {
12
- name: error.name,
13
- message: error.message,
14
- stack: error.stack,
15
- errorCategory: ErrorCategoryType.CATEGORY_SYSTEM
16
- };
17
- }
18
- else if (typeof error === 'object' && error !== null) {
19
- return error;
20
- }
21
- else {
22
- return {
23
- error: String(error),
24
- errorCategory: ErrorCategoryType.CATEGORY_UNKNOWN
25
- };
26
- }
27
- }
28
- /**
29
- * Tool names for property operations
30
- */
31
- export const PROPERTY_TOOL_NAMES = {
32
- GET_PROPERTIES: "obsidian_get_properties",
33
- UPDATE_PROPERTIES: "obsidian_update_properties"
34
- };
35
- /**
36
- * Tool handler for getting properties from a note
37
- */
38
- export class GetPropertiesToolHandler extends BaseToolHandler {
39
- propertyManager;
40
- constructor(client) {
41
- super(PROPERTY_TOOL_NAMES.GET_PROPERTIES, client);
42
- this.propertyManager = new PropertyManager(client);
43
- }
44
- getToolDescription() {
45
- return {
46
- name: this.name,
47
- description: "Retrieves properties (like title, tags, status) from the YAML frontmatter of a specified Obsidian note. Returns all defined properties, including any custom fields.",
48
- examples: [
49
- {
50
- description: "Get properties from a specific note",
51
- args: {
52
- filepath: "path/to/note.md"
53
- }
54
- },
55
- {
56
- description: "Get properties from a documentation file",
57
- args: {
58
- filepath: "docs/architecture.md"
59
- }
60
- }
61
- ],
62
- inputSchema: {
63
- type: "object",
64
- properties: {
65
- filepath: {
66
- type: "string",
67
- description: "Path to the note file (relative to vault root)",
68
- format: "path"
69
- }
70
- },
71
- required: ["filepath"]
72
- }
73
- };
74
- }
75
- async runTool(args) {
76
- logger.startTimer(`get_properties_${args.filepath}`);
77
- try {
78
- logger.debug(`Getting properties from: ${args.filepath}`);
79
- const result = await this.propertyManager.getProperties(args.filepath);
80
- const elapsedMs = logger.endTimer(`get_properties_${args.filepath}`);
81
- logger.logOperationResult(true, 'get_properties', elapsedMs, {
82
- filepath: args.filepath,
83
- propertyCount: Object.keys(result.properties || {}).length
84
- });
85
- return this.createResponse(result);
86
- }
87
- catch (error) {
88
- const elapsedMs = logger.endTimer(`get_properties_${args.filepath}`);
89
- logger.logOperationResult(false, 'get_properties', elapsedMs, {
90
- filepath: args.filepath
91
- });
92
- logger.error(`Error getting properties from ${args.filepath}:`, errorToObject(error));
93
- return this.handleError(error);
94
- }
95
- }
96
- }
97
- /**
98
- * Tool handler for updating properties in a note
99
- */
100
- export class UpdatePropertiesToolHandler extends BaseToolHandler {
101
- propertyManager;
102
- constructor(client) {
103
- super(PROPERTY_TOOL_NAMES.UPDATE_PROPERTIES, client);
104
- this.propertyManager = new PropertyManager(client);
105
- }
106
- getToolDescription() {
107
- return {
108
- name: this.name,
109
- description: "Updates properties within the YAML frontmatter of a specified Obsidian note. By default, array properties (like tags, type, status) are merged; use the 'replace' option to overwrite them instead. Handles custom fields and manages timestamps automatically. See schema for supported standard fields (title, author, tags, status, etc.).",
110
- examples: [
111
- {
112
- description: "Update title and author, merge tags",
113
- args: {
114
- filepath: "path/to/note.md",
115
- properties: {
116
- title: "Architecture Overview",
117
- author: "Development Team",
118
- type: ["architecture", "specification"]
119
- }
120
- }
121
- },
122
- {
123
- description: "Update tags and status with replace",
124
- args: {
125
- filepath: "docs/feature.md",
126
- properties: {
127
- tags: ["#feature", "#in-development", "#high-priority"],
128
- status: ["in-progress"]
129
- },
130
- replace: true
131
- }
132
- },
133
- {
134
- description: "Add custom fields",
135
- args: {
136
- filepath: "projects/project-x.md",
137
- properties: {
138
- custom: {
139
- priority: "high",
140
- reviewedBy: ["Alice", "Bob"],
141
- dueDate: "2025-03-01"
142
- }
143
- }
144
- }
145
- }
146
- ],
147
- inputSchema: {
148
- type: "object",
149
- properties: {
150
- filepath: {
151
- type: "string",
152
- description: "Path to the note file (relative to vault root)",
153
- format: "path"
154
- },
155
- properties: {
156
- type: "object",
157
- description: "Properties to update",
158
- properties: {
159
- title: { type: "string" },
160
- author: { type: "string" },
161
- type: {
162
- type: "array",
163
- items: { type: "string" }
164
- },
165
- tags: {
166
- type: "array",
167
- // Allow tags with or without leading # - manager handles normalization
168
- items: { type: "string" }
169
- },
170
- status: {
171
- type: "array",
172
- items: {
173
- type: "string",
174
- enum: ["draft", "in-progress", "review", "complete"]
175
- }
176
- },
177
- version: { type: "string" },
178
- platform: { type: "string" },
179
- repository: { type: "string", format: "uri" },
180
- dependencies: {
181
- type: "array",
182
- items: { type: "string" }
183
- },
184
- sources: {
185
- type: "array",
186
- items: { type: "string" }
187
- },
188
- urls: {
189
- type: "array",
190
- items: { type: "string", format: "uri" }
191
- },
192
- papers: {
193
- type: "array",
194
- items: { type: "string" }
195
- },
196
- custom: {
197
- type: "object",
198
- additionalProperties: true
199
- }
200
- },
201
- additionalProperties: false
202
- },
203
- replace: {
204
- type: "boolean",
205
- description: "If true, array properties (like tags, status) will be completely replaced with the provided values instead of being merged with existing values. Defaults to false (merge)."
206
- }
207
- },
208
- required: ["filepath", "properties"]
209
- }
210
- };
211
- }
212
- async runTool(args) {
213
- logger.startTimer(`update_properties_${args.filepath}`);
214
- try {
215
- logger.debug(`Updating properties for: ${args.filepath}`, {
216
- filepath: args.filepath,
217
- propertyCount: Object.keys(args.properties || {}).length,
218
- replace: args.replace || false
219
- });
220
- const result = await this.propertyManager.updateProperties(args.filepath, args.properties, args.replace);
221
- const elapsedMs = logger.endTimer(`update_properties_${args.filepath}`);
222
- logger.logOperationResult(true, 'update_properties', elapsedMs, {
223
- filepath: args.filepath,
224
- propertyCount: Object.keys(args.properties || {}).length,
225
- success: result.success
226
- });
227
- return this.createResponse(result);
228
- }
229
- catch (error) {
230
- const elapsedMs = logger.endTimer(`update_properties_${args.filepath}`);
231
- logger.logOperationResult(false, 'update_properties', elapsedMs, {
232
- filepath: args.filepath
233
- });
234
- logger.error(`Error updating properties for ${args.filepath}:`, errorToObject(error));
235
- return this.handleError(error);
236
- }
237
- }
238
- }
239
- //# sourceMappingURL=tools.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"tools.js","sourceRoot":"","sources":["../../../src/tools/properties/tools.ts"],"names":[],"mappings":"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"}