obsidian-mcp-server 3.5.0 → 3.5.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 (68) hide show
  1. package/AGENTS.md +8 -7
  2. package/CLAUDE.md +8 -7
  3. package/Dockerfile +3 -1
  4. package/README.md +8 -5
  5. package/changelog/3.5.x/3.5.1.md +27 -0
  6. package/changelog/3.5.x/3.5.2.md +27 -0
  7. package/dist/config/server-config.d.ts +4 -4
  8. package/dist/mcp-server/resources/definitions/index.d.ts +5 -0
  9. package/dist/mcp-server/resources/definitions/index.d.ts.map +1 -1
  10. package/dist/mcp-server/resources/definitions/obsidian-status.resource.d.ts +11 -4
  11. package/dist/mcp-server/resources/definitions/obsidian-status.resource.d.ts.map +1 -1
  12. package/dist/mcp-server/resources/definitions/obsidian-status.resource.js +21 -12
  13. package/dist/mcp-server/resources/definitions/obsidian-status.resource.js.map +1 -1
  14. package/dist/mcp-server/tools/definitions/index.d.ts +88 -39
  15. package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
  16. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts +6 -1
  17. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.d.ts.map +1 -1
  18. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js +7 -1
  19. package/dist/mcp-server/tools/definitions/obsidian-append-to-note.tool.js.map +1 -1
  20. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts +6 -1
  21. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.d.ts.map +1 -1
  22. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js +7 -1
  23. package/dist/mcp-server/tools/definitions/obsidian-delete-note.tool.js.map +1 -1
  24. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts +11 -2
  25. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.d.ts.map +1 -1
  26. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js +41 -15
  27. package/dist/mcp-server/tools/definitions/obsidian-get-note.tool.js.map +1 -1
  28. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts +8 -3
  29. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.d.ts.map +1 -1
  30. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js +12 -5
  31. package/dist/mcp-server/tools/definitions/obsidian-list-notes.tool.js.map +1 -1
  32. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts +6 -1
  33. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.d.ts.map +1 -1
  34. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js +7 -1
  35. package/dist/mcp-server/tools/definitions/obsidian-manage-frontmatter.tool.js.map +1 -1
  36. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts +8 -3
  37. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.d.ts.map +1 -1
  38. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js +10 -4
  39. package/dist/mcp-server/tools/definitions/obsidian-manage-tags.tool.js.map +1 -1
  40. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts +6 -1
  41. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.d.ts.map +1 -1
  42. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js +7 -1
  43. package/dist/mcp-server/tools/definitions/obsidian-patch-note.tool.js.map +1 -1
  44. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts +6 -1
  45. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.d.ts.map +1 -1
  46. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js +7 -1
  47. package/dist/mcp-server/tools/definitions/obsidian-replace-in-note.tool.js.map +1 -1
  48. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts +6 -1
  49. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.d.ts.map +1 -1
  50. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js +7 -1
  51. package/dist/mcp-server/tools/definitions/obsidian-write-note.tool.js.map +1 -1
  52. package/dist/services/obsidian/frontmatter-ops.d.ts +9 -5
  53. package/dist/services/obsidian/frontmatter-ops.d.ts.map +1 -1
  54. package/dist/services/obsidian/frontmatter-ops.js +70 -16
  55. package/dist/services/obsidian/frontmatter-ops.js.map +1 -1
  56. package/dist/services/obsidian/obsidian-service.d.ts +10 -7
  57. package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
  58. package/dist/services/obsidian/obsidian-service.js +193 -38
  59. package/dist/services/obsidian/obsidian-service.js.map +1 -1
  60. package/dist/services/obsidian/section-extractor.d.ts +17 -1
  61. package/dist/services/obsidian/section-extractor.d.ts.map +1 -1
  62. package/dist/services/obsidian/section-extractor.js +109 -40
  63. package/dist/services/obsidian/section-extractor.js.map +1 -1
  64. package/dist/services/obsidian/types.d.ts +17 -0
  65. package/dist/services/obsidian/types.d.ts.map +1 -1
  66. package/manifest.json +1 -1
  67. package/package.json +10 -10
  68. package/server.json +3 -3
@@ -5,7 +5,15 @@
5
5
  * @module services/obsidian/frontmatter-ops
6
6
  */
7
7
  import { isMap, parseDocument } from 'yaml';
8
- const FM_RE = /^(---\r?\n)([\s\S]*?)(\r?\n---\r?\n?)/;
8
+ /**
9
+ * The one frontmatter boundary: an opening `---` alone on the first line, YAML,
10
+ * then a `---` that starts its own line. The YAML span and the newline that
11
+ * separates it from the closing fence are one atomic optional unit, so an empty
12
+ * block (`---` immediately followed by `---`) matches while a `---` sitting
13
+ * mid-scalar still cannot close the block — making the separator newline
14
+ * independently optional would close `key: a---b` at the `---` inside it.
15
+ */
16
+ const FM_RE = /^(---\r?\n)(?:([\s\S]*?)\r?\n)?(?:---\r?\n?)/;
9
17
  /**
10
18
  * Split a note into its raw frontmatter prefix and its body. `raw + body`
11
19
  * reconstructs the input byte for byte, which is what makes this the primitive
@@ -15,20 +23,31 @@ const FM_RE = /^(---\r?\n)([\s\S]*?)(\r?\n---\r?\n?)/;
15
23
  *
16
24
  * A file whose fence is never closed, whose `---` sits below the first line, or
17
25
  * whose opening `---` carries trailing whitespace has no frontmatter — the whole
18
- * thing is body, which is also how Obsidian reads each of those shapes.
26
+ * thing is body, which is also how Obsidian reads each of those shapes. An empty
27
+ * block is a block: `---` immediately followed by `---` splits with an empty
28
+ * `yamlText`, matching the properties block Obsidian reads there.
19
29
  */
20
30
  export function splice(content) {
21
31
  const m = FM_RE.exec(content);
22
32
  if (!m) {
23
33
  return { hasFrontmatter: false, raw: '', open: '', yamlText: '', close: '', body: content };
24
34
  }
35
+ const raw = m[0];
36
+ const open = m[1] ?? '';
37
+ const yamlText = m[2] ?? '';
25
38
  return {
26
39
  hasFrontmatter: true,
27
- raw: m[0],
28
- open: m[1] ?? '',
29
- yamlText: m[2] ?? '',
30
- close: m[3] ?? '',
31
- body: content.slice(m[0].length),
40
+ raw,
41
+ open,
42
+ yamlText,
43
+ /**
44
+ * Sliced rather than taken from the closing-fence capture: the separator
45
+ * newline belongs to `close` when there is YAML and does not exist at all
46
+ * for an empty block, and slicing keeps `open + yamlText + close === raw`
47
+ * in both shapes.
48
+ */
49
+ close: raw.slice(open.length + yamlText.length),
50
+ body: content.slice(raw.length),
32
51
  };
33
52
  }
34
53
  /**
@@ -90,8 +109,8 @@ export function deleteFrontmatterKey(content, key) {
90
109
  }
91
110
  /**
92
111
  * Add or remove tags across frontmatter (`tags:` array) and inline `#tag`
93
- * syntax. Inline occurrences inside fenced code blocks are left alone — they
94
- * are code, not tags.
112
+ * syntax. Inline detection skips code spans, link spans, and a hash escaped as
113
+ * `\#` — see `splitProtectedSegments` and `TAG_LEFT_BOUNDARY`.
95
114
  */
96
115
  export function reconcileTags(content, tags, operation, location) {
97
116
  const norm = (t) => t.replace(/^#+/, '').trim();
@@ -166,8 +185,32 @@ function normalizeTagList(value) {
166
185
  }
167
186
  return [];
168
187
  }
169
- const FENCED_CODE_BLOCK = /(```[\s\S]*?```|~~~[\s\S]*?~~~)/g;
170
- const INLINE_CODE = /(`[^`\n]+`)/g;
188
+ const FENCED_CODE_BLOCK = /```[\s\S]*?```|~~~[\s\S]*?~~~/;
189
+ const INLINE_CODE = /`[^`\n]+`/;
190
+ /**
191
+ * `[[Target#Heading|Alias]]`. The `#` in a wikilink opens a heading anchor and
192
+ * the text after `|` is display text — neither is a tag. Protecting the whole
193
+ * span rather than tightening the tag's left boundary is what makes the result
194
+ * independent of what the linked note is named: `[[Note#Overview]]` only escapes
195
+ * a boundary rule because the name happens to end in a word character, while
196
+ * `[[Note (Draft)#Overview]]` does not. Obsidian rejects `[` and `]` inside a
197
+ * link target, so a span never nests.
198
+ */
199
+ const WIKILINK = /\[\[[^[\]\n]*\]\]/;
200
+ /** `[text](destination)` — a `#` in the link text or in a URL fragment is link syntax. */
201
+ const MARKDOWN_LINK = /\[[^[\]\n]*\]\([^()\n]*\)/;
202
+ /**
203
+ * `[text][label]` and `[text][]` — the reference-style forms of the same link.
204
+ * The label must follow the text immediately; a bracketed phrase on its own
205
+ * (`[note #work]`) is not a link and its `#` stays a tag.
206
+ */
207
+ const REFERENCE_LINK = /\[[^[\]\n]+\]\[[^[\]\n]*\]/;
208
+ /**
209
+ * A tag's left boundary: the start of a segment, or a character that is neither
210
+ * part of a tag nor the `\` that escapes one. Obsidian documents `\#` as an
211
+ * escaped hashtag — a literal `#` carrying no formatting.
212
+ */
213
+ const TAG_LEFT_BOUNDARY = '(^|[^\\w/\\\\])';
171
214
  /**
172
215
  * Inline `#tag` syntax lives in the body. The frontmatter block is spliced off
173
216
  * first and re-attached verbatim, so a `#` inside a YAML scalar is neither read
@@ -261,10 +304,18 @@ function removeAt(full, leading, trailing, offset, whole) {
261
304
  return leading;
262
305
  return trailing;
263
306
  }
307
+ /**
308
+ * Split the body into stretches a tag may live in and stretches it may not:
309
+ * code, where a `#` is code, and link syntax, where a `#` is a heading anchor
310
+ * or link text. Both the read and the write path run over the result, so
311
+ * `list` and `remove` agree on what counts as a tag.
312
+ */
264
313
  function splitProtectedSegments(content) {
265
314
  const segments = [];
266
315
  let cursor = 0;
267
- const re = new RegExp(`${FENCED_CODE_BLOCK.source}|${INLINE_CODE.source}`, 'g');
316
+ const re = new RegExp([FENCED_CODE_BLOCK, INLINE_CODE, WIKILINK, MARKDOWN_LINK, REFERENCE_LINK]
317
+ .map((r) => r.source)
318
+ .join('|'), 'g');
268
319
  for (;;) {
269
320
  const m = re.exec(content);
270
321
  if (!m)
@@ -284,21 +335,24 @@ function splitProtectedSegments(content) {
284
335
  /** Captures the character before the tag and the single horizontal space after it, if any. */
285
336
  function makeInlineTagRegex(tag) {
286
337
  const escaped = tag.replace(/[\\^$.*+?()[\]{}|]/g, '\\$&');
287
- return new RegExp(`(^|[^\\w/])#${escaped}(?![\\w/-])([ \\t]?)`, 'g');
338
+ return new RegExp(`${TAG_LEFT_BOUNDARY}#${escaped}(?![\\w/-])([ \\t]?)`, 'g');
288
339
  }
289
340
  /**
290
341
  * Read-only helpers for `obsidian_manage_tags list`. Inline tags are read from
291
- * the body only, matching where a removal can actually reach — a `#` inside a
292
- * YAML scalar is frontmatter, not a tag.
342
+ * the body only, and through the same protected-segment split and left boundary
343
+ * a removal uses, so what `list` reports is exactly what `remove` can reach — a
344
+ * `#` inside a YAML scalar, a code span, a link span, or escaped as `\#` is
345
+ * none of them.
293
346
  */
294
347
  export function listTagsFromContent(content, frontmatter) {
295
348
  const fmTags = normalizeTagList(frontmatter.tags);
296
349
  const inline = [];
297
350
  const seen = new Set();
351
+ /** Each segment is scanned to exhaustion, which resets `lastIndex` between them. */
352
+ const re = new RegExp(`${TAG_LEFT_BOUNDARY}#([a-zA-Z][\\w/-]*)`, 'g');
298
353
  for (const seg of splitProtectedSegments(splice(content).body)) {
299
354
  if (seg.protected)
300
355
  continue;
301
- const re = /(^|[^\w/])#([a-zA-Z][\w/-]*)/g;
302
356
  for (;;) {
303
357
  const m = re.exec(seg.text);
304
358
  if (!m)
@@ -1 +1 @@
1
- {"version":3,"file":"frontmatter-ops.js","sourceRoot":"","sources":["../../../src/services/obsidian/frontmatter-ops.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAiB,KAAK,EAAE,aAAa,EAAE,MAAM,MAAM,CAAC;AAE3D,MAAM,KAAK,GAAG,uCAAuC,CAAC;AAiBtD;;;;;;;;;;GAUG;AACH,MAAM,UAAU,MAAM,CAAC,OAAe;IACpC,MAAM,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC9B,IAAI,CAAC,CAAC,EAAE,CAAC;QACP,OAAO,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,QAAQ,EAAE,EAAE,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;IAC9F,CAAC;IACD,OAAO;QACL,cAAc,EAAE,IAAI;QACpB,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC;QACT,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QAChB,QAAQ,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QACpB,KAAK,EAAE,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;QACjB,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;KACjC,CAAC;AACJ,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,QAAgB;IACpD,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAC5B,IAAI,KAAK;QAAE,OAAO,KAAK,CAAC,OAAO,CAAC;IAChC,IAAI,GAAG,CAAC,QAAQ,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,QAAQ,CAAC,EAAE,CAAC;QAClD,OAAO,mDAAmD,CAAC;IAC7D,CAAC;IACD,OAAO;AACT,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAS,oBAAoB,CAAC,GAAa,EAAE,IAAY;IACvD,MAAM,IAAI,GAAG,GAAG,CAAC,QAAQ,CAAC;IAC1B,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,CAAC,EAAE,CAAC;QACtD,OAAO,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC;IAClC,CAAC;IACD,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAC,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC,CAAC,OAAO,EAAE,CAAC;IAC1D,OAAO,QAAQ,QAAQ,UAAU,IAAI,EAAE,CAAC;AAC1C,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAAe,EAAE,GAAW;IAC/D,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC;IACpC,MAAM,GAAG,GAAG,aAAa,CAAC,QAAQ,CAAC,CAAC;IACpC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;QAAE,OAAO,OAAO,CAAC;IAClC,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;IAChB,OAAO,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAcD;;;;GAIG;AACH,MAAM,UAAU,aAAa,CAC3B,OAAe,EACf,IAAc,EACd,SAAuB,EACvB,QAAqB;IAErB,MAAM,IAAI,GAAG,CAAC,CAAS,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;IACxD,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IAC1D,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAClC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAU,CAAC;IAElC,IAAI,OAAO,GAAG,OAAO,CAAC;IAEtB,IAAI,QAAQ,KAAK,aAAa,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACtD,OAAO,GAAG,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAChF,CAAC;IACD,IAAI,QAAQ,KAAK,QAAQ,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACjD,OAAO,GAAG,gBAAgB,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IAC3E,CAAC;IAED,2EAA2E;IAC3E,4EAA4E;IAC5E,mBAAmB;IACnB,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC;IAE3C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,OAAO,CAAC,EAAE,CAAC;AAC5E,CAAC;AAED,SAAS,qBAAqB,CAC5B,OAAe,EACf,IAAc,EACd,SAAuB,EACvB,OAAoB,EACpB,OAAoB;IAEpB,MAAM,EAAE,cAAc,EAAE,QAAQ,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IAC3D,MAAM,GAAG,GAAG,aAAa,CAAC,cAAc,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAC1D,MAAM,EAAE,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,EAAE,CAA4B,CAAC;IAEzD,MAAM,QAAQ,GAAG,gBAAgB,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC;IAC3C,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,QAAQ,CAAC,CAAC;IAC9B,IAAI,OAAO,GAAG,KAAK,CAAC;IAEpB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;QACvB,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;YACxB,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC;gBAAE,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;iBAC9B,CAAC;gBACJ,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACb,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,EAAE,CAAC;gBACjB,GAAG,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;gBAChB,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjB,OAAO,GAAG,IAAI,CAAC;YACjB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,OAAO;QAAE,OAAO,OAAO,CAAC;IAE7B,MAAM,OAAO,GAAG,CAAC,GAAG,GAAG,CAAC,CAAC;IACzB,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,GAAG,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IACrB,CAAC;SAAM,CAAC;QACN,GAAG,CAAC,GAAG,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC3B,CAAC;IAED,OAAO,oBAAoB,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,gBAAgB,CAAC,KAAc;IACtC,IAAI,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,CAAC;QACzB,OAAO,KAAK;aACT,MAAM,CAAC,CAAC,CAAC,EAAe,EAAE,CAAC,OAAO,CAAC,KAAK,QAAQ,CAAC;aACjD,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;aACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,KAAK;aACT,KAAK,CAAC,QAAQ,CAAC;aACf,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;aACvC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,EAAE,CAAC;AACZ,CAAC;AAED,MAAM,iBAAiB,GAAG,kCAAkC,CAAC;AAC7D,MAAM,WAAW,GAAG,cAAc,CAAC;AAEnC;;;;GAIG;AACH,SAAS,gBAAgB,CACvB,OAAe,EACf,IAAc,EACd,SAAuB,EACvB,OAAoB,EACpB,OAAoB;IAEpB,MAAM,EAAE,GAAG,EAAE,IAAI,EAAE,GAAG,MAAM,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,QAAQ,GAAG,sBAAsB,CAAC,IAAI,CAAC,CAAC;IAC9C,IAAI,cAAc,GAAG,KAAK,CAAC;IAE3B,IAAI,SAAS,KAAK,KAAK,EAAE,CAAC;QACxB,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACnC,MAAM,OAAO,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,SAAS,IAAI,EAAE,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC;YACtE,IAAI,OAAO,EAAE,CAAC;gBACZ,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;QACD,MAAM,SAAS,GAAG,IAAI;aACnB,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;aAC7B,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC;aACnB,IAAI,CAAC,GAAG,CAAC,CAAC;QACb,IAAI,SAAS,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACzB;;;;;;eAMG;YACH,MAAM,SAAS,GAAG,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;YAC7D,MAAM,GAAG,GAAG,SAAS,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;YACjD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC;YACtF,IAAI,QAAQ,IAAI,CAAC,QAAQ,CAAC,SAAS,EAAE,CAAC;gBACpC,QAAQ,CAAC,IAAI,GAAG,GAAG,QAAQ,CAAC,IAAI,GAAG,GAAG,GAAG,SAAS,IAAI,CAAC;YACzD,CAAC;iBAAM,CAAC;gBACN,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,GAAG,GAAG,GAAG,SAAS,IAAI,EAAE,CAAC,CAAC;YACpE,CAAC;YACD,cAAc,GAAG,IAAI,CAAC;QACxB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,MAAM,EAAE,GAAG,kBAAkB,CAAC,GAAG,CAAC,CAAC;YACnC,IAAI,KAAK,GAAG,KAAK,CAAC;YAClB,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;gBACzB,IAAI,CAAC,CAAC,SAAS;oBAAE,SAAS;gBAC1B;;;;;;mBAMG;gBACH,KACE,IAAI,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,EACvC,IAAI,KAAK,CAAC,CAAC,IAAI,EACf,IAAI,GAAG,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,QAAQ,CAAC,EACnC,CAAC;oBACD,CAAC,CAAC,IAAI,GAAG,IAAI,CAAC;oBACd,KAAK,GAAG,IAAI,CAAC;gBACf,CAAC;YACH,CAAC;YACD,IAAI,KAAK,EAAE,CAAC;gBACV,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;gBACjB,cAAc,GAAG,IAAI,CAAC;YACxB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;YACnB,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,cAAc;QAAE,OAAO,OAAO,CAAC;IACpC,OAAO,GAAG,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;AACpD,CAAC;AAED;;;;;;;GAOG;AACH,SAAS,QAAQ,CACf,IAAY,EACZ,OAAe,EACf,QAAgB,EAChB,MAAc,EACd,KAAa;IAEb,IAAI,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC;QAAE,OAAO,OAAO,CAAC;IAC7C,wEAAwE;IACxE,oDAAoD;IACpD,IAAI,QAAQ,KAAK,EAAE,IAAI,KAAK,CAAC,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG;QAAE,OAAO,OAAO,CAAC;IAC3E,OAAO,QAAQ,CAAC;AAClB,CAAC;AAOD,SAAS,sBAAsB,CAAC,OAAe;IAC7C,MAAM,QAAQ,GAAc,EAAE,CAAC;IAC/B,IAAI,MAAM,GAAG,CAAC,CAAC;IACf,MAAM,EAAE,GAAG,IAAI,MAAM,CAAC,GAAG,iBAAiB,CAAC,MAAM,IAAI,WAAW,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;IAChF,SAAS,CAAC;QACR,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;QAC3B,IAAI,CAAC,CAAC;YAAE,MAAM;QACd,MAAM,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;QAC3B,IAAI,CAAC,CAAC,KAAK,GAAG,MAAM,EAAE,CAAC;YACrB,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5E,CAAC;QACD,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,CAAC;QAClD,MAAM,GAAG,CAAC,CAAC,KAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IACpC,CAAC;IACD,IAAI,MAAM,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC;QAC5B,QAAQ,CAAC,IAAI,CAAC,EAAE,SAAS,EAAE,KAAK,EAAE,IAAI,EAAE,OAAO,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;IACnE,CAAC;IACD,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,8FAA8F;AAC9F,SAAS,kBAAkB,CAAC,GAAW;IACrC,MAAM,OAAO,GAAG,GAAG,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;IAC3D,OAAO,IAAI,MAAM,CAAC,eAAe,OAAO,sBAAsB,EAAE,GAAG,CAAC,CAAC;AACvE,CAAC;AAED;;;;GAIG;AACH,MAAM,UAAU,mBAAmB,CACjC,OAAe,EACf,WAAoC;IAKpC,MAAM,MAAM,GAAG,gBAAgB,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;IAClD,MAAM,MAAM,GAAa,EAAE,CAAC;IAC5B,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAC;IAC/B,KAAK,MAAM,GAAG,IAAI,sBAAsB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/D,IAAI,GAAG,CAAC,SAAS;YAAE,SAAS;QAC5B,MAAM,EAAE,GAAG,+BAA+B,CAAC;QAC3C,SAAS,CAAC;YACR,MAAM,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;YAC5B,IAAI,CAAC,CAAC;gBAAE,MAAM;YACd,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;YACf,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;gBACtB,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;gBACZ,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;YACjB,CAAC;QACH,CAAC;IACH,CAAC;IACD,OAAO,EAAE,WAAW,EAAE,MAAM,EAAE,MAAM,EAAE,CAAC;AACzC,CAAC"}
1
+ {"version":3,"file":"frontmatter-ops.js","sourceRoot":"","sources":["../../../src/services/obsidian/frontmatter-ops.ts"],"names":[],"mappings":"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"}
@@ -32,15 +32,18 @@ export declare class ObsidianService {
32
32
  get policy(): PathPolicy;
33
33
  /** Resolved Omnisearch URL (derived from baseUrl or OBSIDIAN_OMNISEARCH_URL override). */
34
34
  get omnisearchUrl(): string;
35
- getStatus(ctx: Context): Promise<VaultStatus>;
36
35
  /**
37
- * Probe whether the configured `OBSIDIAN_API_KEY` is accepted. Hits the
38
- * authenticated `/vault/` listing endpoint and reports `true` only on a 2xx
39
- * response. Network/auth errors yield `false` — the resource caller wants a
40
- * boolean, not an exception. Aborts are re-thrown so cancellation/timeout
41
- * doesn't masquerade as an auth failure.
36
+ * The plugin's root capability report: reachability, versions, manifest, and
37
+ * the registered API extensions.
38
+ *
39
+ * Sent authenticated. `GET /` never 401s — it answers `200` either way and
40
+ * self-reports `authenticated`, which is a direct string comparison against
41
+ * the configured key upstream — so the misconfigured-key case still returns
42
+ * the full reachability payload with `authenticated: false` rather than
43
+ * throwing. `apiExtensions` appears only on the authenticated response,
44
+ * which is why the request carries the key at all.
42
45
  */
43
- probeAuthenticated(ctx: Context): Promise<boolean>;
46
+ getStatus(ctx: Context): Promise<VaultStatus>;
44
47
  getNoteContent(ctx: Context, target: NoteTarget): Promise<string>;
45
48
  getNoteJson(ctx: Context, target: NoteTarget): Promise<NoteJson>;
46
49
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"obsidian-service.d.ts","sourceRoot":"","sources":["../../../src/services/obsidian/obsidian-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"obsidian-service.d.ts","sourceRoot":"","sources":["../../../src/services/obsidian/obsidian-service.ts"],"names":[],"mappings":"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"}
@@ -11,6 +11,16 @@ import { getServerConfig } from '../../config/server-config.js';
11
11
  import { PathPolicy } from './path-policy.js';
12
12
  /** Per-call timeout for the startup probe — covers the 4-tuple TCP handshake + a tiny GET. */
13
13
  const OMNISEARCH_PROBE_TIMEOUT_MS = 500;
14
+ /**
15
+ * Ceiling on the capability probe. It runs only *after* an upstream error has
16
+ * already come back, so it delays a response the caller is waiting on — a
17
+ * diagnostic is not worth another full request timeout.
18
+ */
19
+ const CAPABILITY_PROBE_TIMEOUT_MS = 2_000;
20
+ /** Manifest id of the extension that re-adds `/periodic/` on plugin v5.0.2+. */
21
+ const PERIODIC_EXTENSION_ID = 'local-rest-api-periodic-notes';
22
+ /** First Local REST API version that ships without the built-in `/periodic/` routes. */
23
+ const PERIODIC_ROUTES_REMOVED_IN = [5, 0, 2];
14
24
  const OMNISEARCH_DEFAULT_PORT = '51361';
15
25
  const NOTE_JSON_ACCEPT = 'application/vnd.olrapi.note+json';
16
26
  const DOCUMENT_MAP_ACCEPT = 'application/vnd.olrapi.document-map+json';
@@ -46,6 +56,13 @@ export class ObsidianService {
46
56
  #fetch;
47
57
  #policy;
48
58
  #omnisearchUrl;
59
+ /**
60
+ * Memoized capability probe, consulted only when an error response is
61
+ * ambiguous without it. Holds the in-flight promise so concurrent failures
62
+ * share one request; a failed probe is evicted so a later failure can try
63
+ * again rather than inheriting a transient outage forever.
64
+ */
65
+ #capabilities;
49
66
  /**
50
67
  * @param config - Validated server config (api key, base URL, TLS, timeouts).
51
68
  * @param fetchImpl - Optional fetch override for tests. Defaults to undici's
@@ -82,32 +99,20 @@ export class ObsidianService {
82
99
  return this.#omnisearchUrl;
83
100
  }
84
101
  // ── Status ───────────────────────────────────────────────────────────────
85
- async getStatus(ctx) {
86
- const res = await this.#request(ctx, '/', { method: 'GET', skipAuth: true });
87
- return (await res.json());
88
- }
89
102
  /**
90
- * Probe whether the configured `OBSIDIAN_API_KEY` is accepted. Hits the
91
- * authenticated `/vault/` listing endpoint and reports `true` only on a 2xx
92
- * response. Network/auth errors yield `false` — the resource caller wants a
93
- * boolean, not an exception. Aborts are re-thrown so cancellation/timeout
94
- * doesn't masquerade as an auth failure.
103
+ * The plugin's root capability report: reachability, versions, manifest, and
104
+ * the registered API extensions.
105
+ *
106
+ * Sent authenticated. `GET /` never 401s — it answers `200` either way and
107
+ * self-reports `authenticated`, which is a direct string comparison against
108
+ * the configured key upstream — so the misconfigured-key case still returns
109
+ * the full reachability payload with `authenticated: false` rather than
110
+ * throwing. `apiExtensions` appears only on the authenticated response,
111
+ * which is why the request carries the key at all.
95
112
  */
96
- async probeAuthenticated(ctx) {
97
- try {
98
- const res = await this.#fetch(`${this.#config.baseUrl}/vault/`, {
99
- method: 'GET',
100
- headers: { Authorization: `Bearer ${this.#config.apiKey}` },
101
- dispatcher: this.#dispatcher,
102
- signal: ctx.signal,
103
- });
104
- return res.ok;
105
- }
106
- catch (err) {
107
- if (ctx.signal?.aborted)
108
- throw err;
109
- return false;
110
- }
113
+ async getStatus(ctx) {
114
+ const res = await this.#request(ctx, '/', { method: 'GET' });
115
+ return normalizeVaultStatus((await res.json()));
111
116
  }
112
117
  // ── Notes ────────────────────────────────────────────────────────────────
113
118
  async getNoteContent(ctx, target) {
@@ -287,7 +292,7 @@ export class ObsidianService {
287
292
  if (normalized) {
288
293
  this.#policy.assertReadable(normalized);
289
294
  }
290
- const res = await this.#request(ctx, url, { method: 'GET' });
295
+ const res = await this.#request(ctx, url, { method: 'GET', listRead: true });
291
296
  return (await res.json());
292
297
  }
293
298
  async listTags(ctx) {
@@ -575,10 +580,10 @@ export class ObsidianService {
575
580
  }
576
581
  #request(ctx, pathAndQuery, init) {
577
582
  const url = `${this.#config.baseUrl}${pathAndQuery}`;
578
- const headers = { ...(init.headers ?? {}) };
579
- if (!init.skipAuth) {
580
- headers.Authorization = `Bearer ${this.#config.apiKey}`;
581
- }
583
+ const headers = {
584
+ ...(init.headers ?? {}),
585
+ Authorization: `Bearer ${this.#config.apiKey}`,
586
+ };
582
587
  const exec = async () => {
583
588
  const res = await this.#fetch(url, {
584
589
  method: init.method,
@@ -588,11 +593,14 @@ export class ObsidianService {
588
593
  signal: ctx.signal,
589
594
  });
590
595
  if (!res.ok) {
591
- await this.#throwForStatus(res, pathAndQuery, ctx);
596
+ await this.#throwForStatus(res, pathAndQuery, ctx, { listRead: init.listRead });
592
597
  }
593
598
  if (init.noteRead) {
594
599
  this.#assertNotDirectory(res, pathAndQuery, ctx);
595
600
  }
601
+ if (init.listRead) {
602
+ this.#assertNotFile(res, pathAndQuery, ctx);
603
+ }
596
604
  return res;
597
605
  };
598
606
  if (!RETRY_SAFE_METHODS.has(init.method.toUpperCase())) {
@@ -644,6 +652,65 @@ export class ObsidianService {
644
652
  ...ctx.recoveryFor('path_is_directory'),
645
653
  });
646
654
  }
655
+ /**
656
+ * Reject a `2xx` folder listing that actually served a file. The inverse of
657
+ * `#assertNotDirectory`, read off the same header: a trailing slash is a
658
+ * no-op upstream, so `GET /vault/<file>/` answers `200`
659
+ * with the file's own body and `Content-Disposition: attachment`. Without
660
+ * this guard the body reaches `res.json()`, which throws an untyped
661
+ * `SyntaxError` on markdown and — worse — succeeds on a vault `.json` file,
662
+ * handing the walk a listing with no `files` array.
663
+ */
664
+ #assertNotFile(res, path, ctx) {
665
+ if (!path.startsWith('/vault/'))
666
+ return;
667
+ if (res.headers.get('content-disposition') === null)
668
+ return;
669
+ const display = displayPath(path);
670
+ throw validationError(`${display} is a file, not a directory.`, {
671
+ path: display,
672
+ reason: 'path_is_file',
673
+ ...ctx.recoveryFor('path_is_file'),
674
+ });
675
+ }
676
+ /**
677
+ * The plugin's capability report, fetched at most once per service instance
678
+ * and only when a failure is ambiguous without it — never as a startup probe.
679
+ *
680
+ * Deliberately not routed through `#request`: this runs while a caller is
681
+ * already waiting on a failed request, so it takes neither the retry budget
682
+ * nor the full request timeout. Every failure resolves to `undefined`, which
683
+ * callers must read as "unknown" and fall back on — a diagnostic must never
684
+ * sink the response it was issued to diagnose.
685
+ *
686
+ * The cache never expires, and does not need to: it is read only to word an
687
+ * error on a call that already failed. Installing the missing extension
688
+ * mid-session makes the route resolve, so no 404 arrives to be classified.
689
+ */
690
+ async #vaultCapabilities(ctx) {
691
+ this.#capabilities ??= this.#probeCapabilities(ctx);
692
+ const capabilities = await this.#capabilities;
693
+ if (!capabilities)
694
+ this.#capabilities = undefined;
695
+ return capabilities;
696
+ }
697
+ async #probeCapabilities(ctx) {
698
+ const deadline = AbortSignal.timeout(CAPABILITY_PROBE_TIMEOUT_MS);
699
+ try {
700
+ const res = await this.#fetch(`${this.#config.baseUrl}/`, {
701
+ method: 'GET',
702
+ headers: { Authorization: `Bearer ${this.#config.apiKey}` },
703
+ dispatcher: this.#dispatcher,
704
+ signal: ctx.signal ? AbortSignal.any([ctx.signal, deadline]) : deadline,
705
+ });
706
+ if (!res.ok)
707
+ return;
708
+ return normalizeVaultStatus((await res.json()));
709
+ }
710
+ catch {
711
+ return;
712
+ }
713
+ }
647
714
  /**
648
715
  * Classify an upstream error response and throw.
649
716
  *
@@ -677,7 +744,7 @@ export class ObsidianService {
677
744
  *
678
745
  * Issues #104 and #116.
679
746
  */
680
- async #throwForStatus(res, path, ctx) {
747
+ async #throwForStatus(res, path, ctx, opts = {}) {
681
748
  const text = await this.#readBodySafe(res);
682
749
  const body = parseJsonObject(text);
683
750
  const display = displayPath(path);
@@ -698,6 +765,18 @@ export class ObsidianService {
698
765
  throw notFound('No file is currently active in Obsidian — open a file in the app first.', data('no_active_file'), { cause });
699
766
  }
700
767
  if (path.startsWith('/periodic/')) {
768
+ /**
769
+ * Two different failures answer identically here. Local REST API
770
+ * v5.0.2 removed the built-in `/periodic/` routes — a request against
771
+ * a version past that, with no companion extension registered to
772
+ * re-add them, gets Express's route-miss 404, byte-identical to the
773
+ * plugin's own "that note does not exist". Only the capability report
774
+ * separates them, and an unreadable one keeps the older, weaker
775
+ * reading rather than asserting a cause it cannot see.
776
+ */
777
+ if (periodicRoutesAbsent(await this.#vaultCapabilities(ctx))) {
778
+ throw notFound(`This vault's Local REST API serves no /periodic/ routes: plugin v5.0.2 removed them, and the companion extension that restores them (${PERIODIC_EXTENSION_ID}) is not registered here.`, data('periodic_unsupported'), { cause });
779
+ }
701
780
  const dateMatch = /\/(\d{4})\/(\d{2})\/(\d{2})\/?$/.exec(path);
702
781
  const suffix = dateMatch ? ` for ${dateMatch[1]}-${dateMatch[2]}-${dateMatch[3]}` : '';
703
782
  throw notFound(`No ${periodOf(path)} note found${suffix}. Check that the Periodic Notes plugin is enabled and the note exists.`, data('periodic_not_found'), { cause });
@@ -705,6 +784,17 @@ export class ObsidianService {
705
784
  if (path.startsWith('/commands/')) {
706
785
  throw notFound(`Unknown Obsidian command: ${display}. Use \`obsidian_list_commands\` to discover valid command IDs.`, data('command_unknown'), { cause });
707
786
  }
787
+ /**
788
+ * A folder listing 404s for two reasons the upstream does not
789
+ * separate: the folder is not there, or it is there and holds no
790
+ * files — the plugin computes the listing from loaded vault files, so
791
+ * an empty folder never reports. The recovery names both; the reason
792
+ * at least keeps the object right, where `note_missing` sent a caller
793
+ * who just listed a folder off to look for a note.
794
+ */
795
+ if (opts.listRead) {
796
+ throw notFound(`Directory not found: ${display}`, data('directory_missing'), { cause });
797
+ }
708
798
  throw notFound(`Not found: ${display}`, data('note_missing'), { cause });
709
799
  }
710
800
  case 405:
@@ -755,21 +845,28 @@ export class ObsidianService {
755
845
  default: {
756
846
  /**
757
847
  * Unhandled 4xx and all 5xx. `httpStatusToErrorCode` supplies the same
758
- * canonical mapping `httpErrorFromResponse` would (500/501 →
759
- * InternalError, 502/503 → ServiceUnavailable, 504 → Timeout) without
760
- * that helper's response-derived extras: it builds its message from
761
- * the upstream's reason phrase and mirrors the body onto
848
+ * canonical mapping `httpErrorFromResponse` would (the whole 5xx range
849
+ * except 504 → ServiceUnavailable, 504 → Timeout) without that
850
+ * helper's response-derived extras: it builds its message from the
851
+ * upstream's reason phrase and mirrors the body onto
762
852
  * `data.body`/`data.responseBody`, which is the #104 leak.
763
853
  *
764
- * `Retry-After` is re-attached by hand: it is a duration, never vault
765
- * data, and `withRetry` reads `data.retryAfter` to pace its backoff, so
766
- * dropping it with the rest would quietly change retry timing.
854
+ * Two `data` fields are re-attached by hand because both steer
855
+ * `withRetry` and neither carries vault content:
856
+ *
857
+ * - `retryAfter` is a duration the backoff paces itself against, so
858
+ * dropping it with the rest would quietly change retry timing.
859
+ * - `retryable: false` on a 501 is the in-band opt-out. 501 shares
860
+ * ServiceUnavailable's transient code, so without the flag a method
861
+ * the plugin does not implement would burn the full retry budget on
862
+ * a result that cannot change.
767
863
  */
768
864
  const retryAfter = res.headers.get('retry-after');
769
865
  throw new McpError(httpStatusToErrorCode(res.status) ?? JsonRpcErrorCode.InternalError, `Obsidian Local REST API returned HTTP ${res.status}.`, {
770
866
  ...data(),
771
867
  status: res.status,
772
868
  ...(retryAfter !== null ? { retryAfter } : {}),
869
+ ...(res.status === 501 ? { retryable: false } : {}),
773
870
  }, { cause });
774
871
  }
775
872
  }
@@ -896,6 +993,64 @@ function upstreamTextOf(err) {
896
993
  function isStringCapacityOverflow(err) {
897
994
  return /invalid string length/i.test(upstreamTextOf(err) ?? '');
898
995
  }
996
+ /**
997
+ * Normalize the upstream `GET /` payload. `apiExtensions` entries arrive as a
998
+ * whole `PluginManifest` spread plus the extension's `routes` and `mcpTools`;
999
+ * only the identity trio is kept, since that is all either the capability
1000
+ * check or a calling agent reads.
1001
+ */
1002
+ function normalizeVaultStatus(raw) {
1003
+ const extensions = raw.apiExtensions?.flatMap((e) => typeof e.id === 'string'
1004
+ ? [
1005
+ {
1006
+ id: e.id,
1007
+ ...(typeof e.name === 'string' ? { name: e.name } : {}),
1008
+ ...(typeof e.version === 'string' ? { version: e.version } : {}),
1009
+ },
1010
+ ]
1011
+ : []);
1012
+ return {
1013
+ /** Absent means the plugin did not accept the key, which is not authenticated. */
1014
+ authenticated: raw.authenticated === true,
1015
+ service: raw.service,
1016
+ status: raw.status,
1017
+ ...(raw.versions ? { versions: raw.versions } : {}),
1018
+ ...(raw.manifest ? { manifest: raw.manifest } : {}),
1019
+ ...(extensions ? { apiExtensions: extensions } : {}),
1020
+ };
1021
+ }
1022
+ /**
1023
+ * True when this plugin build cannot serve `/periodic/` at all: version past
1024
+ * the removal, and the companion extension absent from a capability report
1025
+ * that actually listed its extensions.
1026
+ *
1027
+ * The version is the deciding factor, not extension presence — `apiExtensions`
1028
+ * predates the removal and reads empty on older builds that still route
1029
+ * `/periodic/` natively. A missing `apiExtensions` key means the report was
1030
+ * unauthenticated (the plugin omits it there) and so says nothing either way.
1031
+ */
1032
+ function periodicRoutesAbsent(capabilities) {
1033
+ const extensions = capabilities?.apiExtensions;
1034
+ if (!extensions)
1035
+ return false;
1036
+ if (!atLeastVersion(capabilities.versions?.self, PERIODIC_ROUTES_REMOVED_IN))
1037
+ return false;
1038
+ return !extensions.some((e) => e.id === PERIODIC_EXTENSION_ID);
1039
+ }
1040
+ /** Dotted-version comparison against a numeric floor. Unparseable reads as "below". */
1041
+ function atLeastVersion(version, floor) {
1042
+ if (!version)
1043
+ return false;
1044
+ const parts = version.split('.').map((p) => Number.parseInt(p, 10));
1045
+ for (const [i, bound] of floor.entries()) {
1046
+ const part = parts[i];
1047
+ if (part === undefined || Number.isNaN(part))
1048
+ return false;
1049
+ if (part !== bound)
1050
+ return part > bound;
1051
+ }
1052
+ return true;
1053
+ }
899
1054
  /** The period segment of a `/periodic/…` request path, for message copy. */
900
1055
  function periodOf(urlPath) {
901
1056
  return /^\/periodic\/(daily|weekly|monthly|quarterly|yearly)\//.exec(urlPath)?.[1] ?? 'periodic';