obsidian-mcp-server 3.3.0 → 3.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +7 -5
- package/CLAUDE.md +7 -5
- package/Dockerfile +9 -1
- package/README.md +4 -4
- package/changelog/3.3.x/3.3.1.md +11 -0
- package/changelog/3.4.x/3.4.0.md +25 -0
- package/dist/mcp-server/resources/definitions/obsidian-tags.resource.d.ts +8 -2
- package/dist/mcp-server/resources/definitions/obsidian-tags.resource.d.ts.map +1 -1
- package/dist/mcp-server/resources/definitions/obsidian-tags.resource.js +10 -4
- package/dist/mcp-server/resources/definitions/obsidian-tags.resource.js.map +1 -1
- package/dist/mcp-server/tools/definitions/index.d.ts +9 -2
- package/dist/mcp-server/tools/definitions/index.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts +15 -6
- package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js +90 -21
- package/dist/mcp-server/tools/definitions/obsidian-list-tags.tool.js.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts +30 -2
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.d.ts.map +1 -1
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js +57 -12
- package/dist/mcp-server/tools/definitions/obsidian-search-notes.tool.js.map +1 -1
- package/dist/services/obsidian/obsidian-service.d.ts +7 -0
- package/dist/services/obsidian/obsidian-service.d.ts.map +1 -1
- package/dist/services/obsidian/obsidian-service.js +205 -48
- package/dist/services/obsidian/obsidian-service.js.map +1 -1
- package/dist/services/obsidian/types.d.ts +8 -0
- package/dist/services/obsidian/types.d.ts.map +1 -1
- package/manifest.json +1 -1
- package/package.json +2 -2
- package/server.json +3 -3
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian-search-notes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-search-notes.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;
|
|
1
|
+
{"version":3,"file":"obsidian-search-notes.tool.d.ts","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-search-notes.tool.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAsB,CAAC,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,EAAE,gBAAgB,EAAE,MAAM,+BAA+B,CAAC;AAoGjE;;;;;GAKG;AACH,wBAAgB,oBAAoB,CAAC,EAAE,mBAAmB,EAAE,EAAE;IAAE,mBAAmB,EAAE,OAAO,CAAA;CAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBAkIhF,0BAA0B;;mBAE5B,uFAAuF;uBACnF,8DAA8D;;qBAGhE,gBAAgB;;mBAElB,yEAAyE;uBAE7E,uIAAuI;;qBAGjI,0BAA0B;;mBAE5B,0HAA0H;uBAE9H,iLAAiL;;qBAG3K,gBAAgB;;mBAElB,0CAA0C;uBAE9C,qJAAqJ;;qBAG/I,eAAe;;mBAEjB,kPAAkP;uBAEtP,6MAA6M;;qBAGvM,wBAAwB;;mBAE1B,iHAAiH;;uBAGrH,mHAAmH;;;;GA2J1H;AAED;;;;;;;;;;GAUG;AACH,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qBA/MlB,0BAA0B;;mBAE5B,uFAAuF;uBACnF,8DAA8D;;qBAGhE,gBAAgB;;mBAElB,yEAAyE;uBAE7E,uIAAuI;;qBAGjI,0BAA0B;;mBAE5B,0HAA0H;uBAE9H,iLAAiL;;qBAG3K,gBAAgB;;mBAElB,0CAA0C;uBAE9C,qJAAqJ;;qBAG/I,eAAe;;mBAEjB,kPAAkP;uBAEtP,6MAA6M;;qBAGvM,wBAAwB;;mBAE1B,iHAAiH;;uBAGrH,mHAAmH;;;;EAwKpC,CAAC"}
|
|
@@ -29,10 +29,18 @@ const TextHitSchema = z
|
|
|
29
29
|
context: z.string().describe('Surrounding text around the match.'),
|
|
30
30
|
match: z
|
|
31
31
|
.object({
|
|
32
|
-
start: z
|
|
33
|
-
|
|
32
|
+
start: z
|
|
33
|
+
.number()
|
|
34
|
+
.describe('Match start offset within the subject upstream matched — the note body in the usual case, or the note basename (extension stripped) when the filename itself matched, in which case `context` is that basename. This is not an offset into `context`; use `contextStart` for that. Note-body values index the same string `obsidian_get_note` returns.'),
|
|
35
|
+
end: z
|
|
36
|
+
.number()
|
|
37
|
+
.describe('Match end offset within the same subject `start` indexes.'),
|
|
38
|
+
contextStart: z
|
|
39
|
+
.number()
|
|
40
|
+
.describe('Match start offset within `context`. `context.slice(contextStart, contextEnd)` is the matched text.'),
|
|
41
|
+
contextEnd: z.number().describe('Match end offset within `context`.'),
|
|
34
42
|
})
|
|
35
|
-
.describe('
|
|
43
|
+
.describe('Where the match sits, on two origins: `start`/`end` index the matched subject, `contextStart`/`contextEnd` index the accompanying `context` window.'),
|
|
36
44
|
})
|
|
37
45
|
.describe('A single match within a file.'))
|
|
38
46
|
.describe('Per-match context windows. Capped per file by `maxMatchesPerHit`.'),
|
|
@@ -90,8 +98,8 @@ export function buildSearchNotesTool({ omnisearchReachable }) {
|
|
|
90
98
|
mode: z
|
|
91
99
|
.enum(modeEnum)
|
|
92
100
|
.describe(omnisearchReachable
|
|
93
|
-
? 'Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators. `omnisearch` runs a BM25-ranked query via the Omnisearch plugin — supports quoted phrases, `-exclusion`, `path:` / `ext:` filters, typo tolerance, and PDF/OCR (with Text Extractor); upstream caps results at 50.'
|
|
94
|
-
: 'Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators.'),
|
|
101
|
+
? 'Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators — both take their arguments as `[PATTERN, VALUE]`, so the pattern comes first and the `{"var": ...}` reference second. `omnisearch` runs a BM25-ranked query via the Omnisearch plugin — supports quoted phrases, `-exclusion`, `path:` / `ext:` filters, typo tolerance, and PDF/OCR (with Text Extractor); upstream caps results at 50.'
|
|
102
|
+
: 'Which search algorithm to run. `text` matches a substring case-insensitively across filenames and note bodies, returning surrounding context windows. `jsonlogic` evaluates a JSONLogic tree against each note, with `var` paths into `path`, `content`, `frontmatter.<key>`, `tags`, and `stat.{ctime,mtime,size}`, plus `glob` and `regexp` operators — both take their arguments as `[PATTERN, VALUE]`, so the pattern comes first and the `{"var": ...}` reference second.'),
|
|
95
103
|
query: z
|
|
96
104
|
.string()
|
|
97
105
|
.optional()
|
|
@@ -99,7 +107,7 @@ export function buildSearchNotesTool({ omnisearchReachable }) {
|
|
|
99
107
|
logic: z
|
|
100
108
|
.record(z.string(), z.unknown())
|
|
101
109
|
.optional()
|
|
102
|
-
.describe('JSONLogic tree. Required for `jsonlogic` mode; ignored in `text` and `omnisearch` modes (use `query` instead — this field must be an object, so passing a string here is rejected).'),
|
|
110
|
+
.describe('JSONLogic tree. Required for `jsonlogic` mode; ignored in `text` and `omnisearch` modes (use `query` instead — this field must be an object, so passing a string here is rejected). `glob` and `regexp` take `[PATTERN, VALUE]` — pattern first: `{"glob": ["Projects/*.md", {"var": "path"}]}`. Backlinks ("what links here") have no dedicated tool or upstream endpoint but are expressible this way: `{"regexp": ["\\\\[\\\\[Target Note(\\\\||#|\\\\]\\\\])", {"var": "content"}]}` finds every note whose body wikilinks `Target Note`, in plain, aliased, or section form. `obsidian_get_note` with `includeLinks: true` covers the outgoing direction.'),
|
|
103
111
|
contextLength: z
|
|
104
112
|
.number()
|
|
105
113
|
.int()
|
|
@@ -192,11 +200,23 @@ export function buildSearchNotesTool({ omnisearchReachable }) {
|
|
|
192
200
|
when: '`query` is missing for `text` or `omnisearch` mode (required for both).',
|
|
193
201
|
recovery: 'Pass `query` — substring for text mode, or BM25 query syntax (quoted phrases, `-exclusion`, `path:` / `ext:` filters) for omnisearch.',
|
|
194
202
|
},
|
|
203
|
+
{
|
|
204
|
+
reason: 'context_length_too_large',
|
|
205
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
206
|
+
when: 'The Local REST API exhausted its string capacity building one context window per match, so the whole text search failed.',
|
|
207
|
+
recovery: 'Lower `contextLength`, or narrow the query so fewer notes match. The ceiling is the product of the two, so a broad query fails at a much smaller window than a narrow one does.',
|
|
208
|
+
},
|
|
195
209
|
{
|
|
196
210
|
reason: 'logic_required',
|
|
197
211
|
code: JsonRpcErrorCode.ValidationError,
|
|
198
212
|
when: '`logic` is missing for `jsonlogic` mode.',
|
|
199
|
-
recovery: 'Pass a JSONLogic tree as `logic
|
|
213
|
+
recovery: 'Pass a JSONLogic tree as `logic`. `glob` and `regexp` take `[PATTERN, VALUE]` — pattern first, e.g. `{"glob": ["Projects/*.md", {"var": "path"}]}`.',
|
|
214
|
+
},
|
|
215
|
+
{
|
|
216
|
+
reason: 'logic_invalid',
|
|
217
|
+
code: JsonRpcErrorCode.ValidationError,
|
|
218
|
+
when: 'The Local REST API rejected the JSONLogic tree — an unrecognized operator, or an operand it could not evaluate (an uncompilable `regexp` pattern). A mis-arity operator is not rejected: it evaluates to false and the search returns zero hits.',
|
|
219
|
+
recovery: 'Check the operator names and arity. `glob` and `regexp` take `[PATTERN, VALUE]` — pattern first, e.g. `{"regexp": ["^Inbox/", {"var": "path"}]}`; the reverse order compiles the note field as the pattern.',
|
|
200
220
|
},
|
|
201
221
|
{
|
|
202
222
|
reason: 'omnisearch_unreachable',
|
|
@@ -309,7 +329,8 @@ export function buildSearchNotesTool({ omnisearchReachable }) {
|
|
|
309
329
|
: '';
|
|
310
330
|
lines.push(`### ${h.filename}${trunc}`);
|
|
311
331
|
for (const m of h.matches) {
|
|
312
|
-
lines.push(
|
|
332
|
+
lines.push(`match at context[${m.match.contextStart}–${m.match.contextEnd}] · subject[${m.match.start}–${m.match.end}]`);
|
|
333
|
+
lines.push(...fenced(m.context));
|
|
313
334
|
}
|
|
314
335
|
}
|
|
315
336
|
}
|
|
@@ -319,17 +340,18 @@ export function buildSearchNotesTool({ omnisearchReachable }) {
|
|
|
319
340
|
if (h.foundWords.length > 0) {
|
|
320
341
|
lines.push(`**Matched:** ${h.foundWords.map((w) => `\`${w}\``).join(', ')}`);
|
|
321
342
|
}
|
|
343
|
+
if (h.matches.length > 0) {
|
|
344
|
+
lines.push(`**Offsets:** ${h.matches.map((mm) => `\`${mm.match}\` @ ${mm.offset}`).join(', ')}`);
|
|
345
|
+
}
|
|
322
346
|
if (h.excerpt)
|
|
323
|
-
lines.push(
|
|
347
|
+
lines.push(...fenced(h.excerpt));
|
|
324
348
|
}
|
|
325
349
|
}
|
|
326
350
|
else {
|
|
327
351
|
for (const h of result.hits) {
|
|
328
352
|
lines.push(`### ${h.filename}`);
|
|
329
353
|
lines.push(`result:`);
|
|
330
|
-
lines.push('
|
|
331
|
-
lines.push(safeJsonStringify(h.result));
|
|
332
|
-
lines.push('```');
|
|
354
|
+
lines.push(...fenced(safeJsonStringify(h.result), 'json'));
|
|
333
355
|
}
|
|
334
356
|
}
|
|
335
357
|
return [{ type: 'text', text: lines.join('\n') }];
|
|
@@ -373,6 +395,29 @@ function clipMatches(hit, cap) {
|
|
|
373
395
|
totalMatches: hit.matches.length,
|
|
374
396
|
};
|
|
375
397
|
}
|
|
398
|
+
/**
|
|
399
|
+
* Wrap upstream-authored text in a code fence long enough that nothing inside
|
|
400
|
+
* it can close the block.
|
|
401
|
+
*
|
|
402
|
+
* `content[]` is markdown the model reads as this tool's own output, and note
|
|
403
|
+
* excerpts, Omnisearch excerpts, and JSONLogic payloads are all vault text the
|
|
404
|
+
* server does not control — a heading, list marker, or fence inside one would
|
|
405
|
+
* otherwise end the quoted region and have the remainder reparsed as document
|
|
406
|
+
* structure. This is the single escaping boundary for all three: the payload
|
|
407
|
+
* is emitted byte-for-byte (clipping it would put `content[]` back out of
|
|
408
|
+
* parity with `structuredContent` — see #97) and only the delimiter around it
|
|
409
|
+
* adapts, sized past the longest backtick run in the payload.
|
|
410
|
+
*/
|
|
411
|
+
function fenced(body, lang = 'text') {
|
|
412
|
+
/**
|
|
413
|
+
* Reduced rather than spread into `Math.max` — a note that is mostly
|
|
414
|
+
* backticks yields more runs than the engine's argument limit, and arbitrary
|
|
415
|
+
* vault text is precisely what this function is for.
|
|
416
|
+
*/
|
|
417
|
+
const longestRun = (body.match(/`+/g) ?? []).reduce((max, run) => Math.max(max, run.length), 0);
|
|
418
|
+
const fence = '`'.repeat(Math.max(3, longestRun + 1));
|
|
419
|
+
return [`${fence}${lang}`, body, fence];
|
|
420
|
+
}
|
|
376
421
|
function safeJsonStringify(v) {
|
|
377
422
|
try {
|
|
378
423
|
return JSON.stringify(v, null, 2);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian-search-notes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-search-notes.tool.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"obsidian-search-notes.tool.js","sourceRoot":"","sources":["../../../../src/mcp-server/tools/definitions/obsidian-search-notes.tool.ts"],"names":[],"mappings":"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"}
|
|
@@ -86,6 +86,13 @@ export declare class ObsidianService {
|
|
|
86
86
|
listFiles(ctx: Context, dirPath?: string): Promise<FileListing>;
|
|
87
87
|
listTags(ctx: Context): Promise<ObsidianTag[]>;
|
|
88
88
|
listCommands(ctx: Context): Promise<ObsidianCommand[]>;
|
|
89
|
+
/**
|
|
90
|
+
* Text search. The upstream materializes one context window per matching
|
|
91
|
+
* note before it responds, so an oversized `contextLength` on a broad query
|
|
92
|
+
* exhausts V8's string capacity and comes back as an opaque 500 — caught
|
|
93
|
+
* here and re-thrown typed, the way `searchOmnisearch` re-throws its own
|
|
94
|
+
* reachability failure.
|
|
95
|
+
*/
|
|
89
96
|
searchText(ctx: Context, query: string, contextLength?: number): Promise<TextSearchHit[]>;
|
|
90
97
|
searchJsonLogic(ctx: Context, logic: Record<string, unknown>): Promise<StructuredSearchHit[]>;
|
|
91
98
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"obsidian-service.d.ts","sourceRoot":"","sources":["../../../src/services/obsidian/obsidian-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"obsidian-service.d.ts","sourceRoot":"","sources":["../../../src/services/obsidian/obsidian-service.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAYtD,OAAO,EAAS,KAAK,UAAU,EAAE,KAAK,WAAW,EAAE,KAAK,IAAI,WAAW,EAAE,MAAM,QAAQ,CAAC;AACxF,OAAO,EAAmB,KAAK,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAC/E,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAC9C,OAAO,KAAK,EACV,WAAW,EACX,WAAW,EACX,QAAQ,EACR,UAAU,EACV,eAAe,EACf,WAAW,EACX,aAAa,EACb,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,WAAW,EACZ,MAAM,YAAY,CAAC;AAEpB,KAAK,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC,OAAO,WAAW,CAAC,CAAC,CAAC;AAE9D;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG,CAC1B,GAAG,EAAE,MAAM,EACX,IAAI,EAAE,WAAW,GAAG;IAAE,UAAU,CAAC,EAAE,UAAU,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAAE,KAClE,OAAO,CAAC,cAAc,CAAC,CAAC;AAqF7B,qBAAa,eAAe;;IAO1B;;;;OAIG;IACH,YAAY,MAAM,EAAE,YAAY,EAAE,SAAS,CAAC,EAAE,aAAa,EAqB1D;IAED,6EAA6E;IAC7E,IAAI,MAAM,IAAI,UAAU,CAEvB;IAED,0FAA0F;IAC1F,IAAI,aAAa,IAAI,MAAM,CAE1B;IAIK,SAAS,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,CAAC,CAGlD;IAED;;;;;;OAMG;IACG,kBAAkB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAavD;IAIK,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CA2BtE;IAEK,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,QAAQ,CAAC,CASrE;IAED;;;;OAIG;IACG,WAAW,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAGnE;IAEK,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,WAAW,CAAC,CAmB3E;IAEK,SAAS,CACb,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,UAAU,GAAG,MAAmB,GAC5C,OAAO,CAAC,IAAI,CAAC,CAQf;IAEK,YAAY,CAChB,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,WAAW,GAAE,UAAU,GAAG,MAAmB,GAC5C,OAAO,CAAC,IAAI,CAAC,CAQf;IAED;;;;;;OAMG;IACG,SAAS,CACb,GAAG,EAAE,OAAO,EACZ,MAAM,EAAE,UAAU,EAClB,OAAO,EAAE,MAAM,EACf,OAAO,EAAE,YAAY,GACpB,OAAO,CAAC,MAAM,CAAC,CAUjB;IAEK,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC,CAIhE;IAED;;;;;;;;;;;;;;;OAeG;IACG,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAezE;IAED;;;OAGG;IACG,OAAO,CAAC,GAAG,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,MAAM,CAAC,CAW/D;IAIK,SAAS,CAAC,GAAG,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,WAAW,CAAC,CAkBpE;IAEK,QAAQ,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC,CAInD;IAEK,YAAY,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,eAAe,EAAE,CAAC,CAI3D;IAID;;;;;;OAMG;IACG,UAAU,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,aAAa,SAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkC3F;IAEK,eAAe,CACnB,GAAG,EAAE,OAAO,EACZ,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAC7B,OAAO,CAAC,mBAAmB,EAAE,CAAC,CAOhC;IAED;;;;;;;;OAQG;IACG,eAAe,CAAC,MAAM,CAAC,EAAE,WAAW,GAAG,OAAO,CAAC,OAAO,CAAC,CAgB5D;IAED;;;;;;;OAOG;IACG,gBAAgB,CAAC,GAAG,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,EAAE,CAAC,CAkC5E;IAIK,cAAc,CAAC,GAAG,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEnE;IAED;;;;;;;;;OASG;IACG,QAAQ,CACZ,GAAG,EAAE,OAAO,EACZ,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE;QAAE,OAAO,CAAC,EAAE,OAAO,CAAC;QAAC,eAAe,CAAC,EAAE,OAAO,CAAA;KAAE,GACtD,OAAO,CAAC,IAAI,CAAC,CAYf;CA2ZF;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBpD;AAyND,wBAAgB,mBAAmB,CACjC,MAAM,GAAE,YAAgC,EACxC,SAAS,CAAC,EAAE,aAAa,GACxB,IAAI,CAEN;AAED,kFAAkF;AAClF,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,eAAe,GAAG,SAAS,GAAG,IAAI,CAE7E;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAKpD"}
|
|
@@ -4,8 +4,8 @@
|
|
|
4
4
|
* `target` discriminator, and classifies errors for the framework.
|
|
5
5
|
* @module services/obsidian/obsidian-service
|
|
6
6
|
*/
|
|
7
|
-
import { conflict, forbidden, notFound, serviceUnavailable, unauthorized, validationError, } from '@cyanheads/mcp-ts-core/errors';
|
|
8
|
-
import {
|
|
7
|
+
import { conflict, forbidden, JsonRpcErrorCode, McpError, notFound, serviceUnavailable, unauthorized, validationError, } from '@cyanheads/mcp-ts-core/errors';
|
|
8
|
+
import { httpStatusToErrorCode, withRetry } from '@cyanheads/mcp-ts-core/utils';
|
|
9
9
|
import { Agent, fetch as undiciFetch } from 'undici';
|
|
10
10
|
import { getServerConfig } from '../../config/server-config.js';
|
|
11
11
|
import { PathPolicy } from './path-policy.js';
|
|
@@ -301,14 +301,45 @@ export class ObsidianService {
|
|
|
301
301
|
return body.commands ?? [];
|
|
302
302
|
}
|
|
303
303
|
// ── Search ───────────────────────────────────────────────────────────────
|
|
304
|
+
/**
|
|
305
|
+
* Text search. The upstream materializes one context window per matching
|
|
306
|
+
* note before it responds, so an oversized `contextLength` on a broad query
|
|
307
|
+
* exhausts V8's string capacity and comes back as an opaque 500 — caught
|
|
308
|
+
* here and re-thrown typed, the way `searchOmnisearch` re-throws its own
|
|
309
|
+
* reachability failure.
|
|
310
|
+
*/
|
|
304
311
|
async searchText(ctx, query, contextLength = 100) {
|
|
305
312
|
const params = new URLSearchParams({ query, contextLength: String(contextLength) });
|
|
306
|
-
|
|
313
|
+
let res;
|
|
314
|
+
try {
|
|
315
|
+
res = await this.#request(ctx, `/search/simple/?${params}`, { method: 'POST' });
|
|
316
|
+
}
|
|
317
|
+
catch (err) {
|
|
318
|
+
if (!isStringCapacityOverflow(err))
|
|
319
|
+
throw err;
|
|
320
|
+
/**
|
|
321
|
+
* Built fresh rather than decorated: `contextLength` is the actionable
|
|
322
|
+
* fact and only this frame knows it. `cause` keeps the caught error —
|
|
323
|
+
* and through it the upstream body `#throwForStatus` attached — on the
|
|
324
|
+
* server side for the log record.
|
|
325
|
+
*/
|
|
326
|
+
throw validationError(`The Local REST API ran out of string capacity assembling match contexts for this search (contextLength ${contextLength}). It builds a context window for every matching note before responding, so the ceiling tracks contextLength multiplied by the number of matches rather than either alone.`, {
|
|
327
|
+
reason: 'context_length_too_large',
|
|
328
|
+
contextLength,
|
|
329
|
+
...ctx.recoveryFor('context_length_too_large'),
|
|
330
|
+
}, { cause: err });
|
|
331
|
+
}
|
|
307
332
|
const raw = (await res.json());
|
|
308
333
|
// Upstream returns a constant `score` that carries no ranking signal for
|
|
309
334
|
// text mode — drop it on the way out so consumers don't mistake it for
|
|
310
335
|
// relevance. Omnisearch is the source of real BM25 ranking.
|
|
311
|
-
return raw.map((h) => ({
|
|
336
|
+
return raw.map((h) => ({
|
|
337
|
+
filename: h.filename,
|
|
338
|
+
matches: h.matches.map((m) => ({
|
|
339
|
+
context: m.context,
|
|
340
|
+
match: { ...m.match, ...contextRelativeSpan(m, h.filename, contextLength, query) },
|
|
341
|
+
})),
|
|
342
|
+
}));
|
|
312
343
|
}
|
|
313
344
|
async searchJsonLogic(ctx, logic) {
|
|
314
345
|
const res = await this.#request(ctx, '/search/', {
|
|
@@ -613,81 +644,133 @@ export class ObsidianService {
|
|
|
613
644
|
...ctx.recoveryFor('path_is_directory'),
|
|
614
645
|
});
|
|
615
646
|
}
|
|
647
|
+
/**
|
|
648
|
+
* Classify an upstream error response and throw.
|
|
649
|
+
*
|
|
650
|
+
* **Containment invariant.** Four things leave this method on the wire and
|
|
651
|
+
* nothing else: a message authored in this file, the request path the caller
|
|
652
|
+
* supplied (`data.path`), the HTTP status (`data.status`, default branch),
|
|
653
|
+
* and the calling tool's own contract `reason` + `recovery`. The upstream's
|
|
654
|
+
* response body never crosses, in any branch, under any key.
|
|
655
|
+
*
|
|
656
|
+
* That is stricter than redaction, deliberately. The Local REST API
|
|
657
|
+
* interleaves genuine diagnostics with vault data in one string: a rejected
|
|
658
|
+
* JSONLogic tree names the note the plugin was evaluating when it gave up
|
|
659
|
+
* (`(while processing <path>)`) and, when `regexp`'s operands are reversed,
|
|
660
|
+
* quotes that note's body back as the pattern it failed to compile; 5xx
|
|
661
|
+
* bodies relay Node `fs` errors carrying the vault's absolute on-disk
|
|
662
|
+
* location. `PathPolicy` gates the success path only, so none of that is
|
|
663
|
+
* scoped to what the caller may read. The two halves cannot be separated
|
|
664
|
+
* reliably — the pattern echo is delimited by characters the note body may
|
|
665
|
+
* itself contain, so any parse that keeps "the diagnostic half" fails open
|
|
666
|
+
* on exactly the input a caller controls, and failing open is the wrong
|
|
667
|
+
* direction for a containment control. So containment wins: the upstream
|
|
668
|
+
* text is read here only to *classify*, and what the caller receives is this
|
|
669
|
+
* file's own account of the failure. A misclassification therefore costs
|
|
670
|
+
* accuracy, never containment.
|
|
671
|
+
*
|
|
672
|
+
* The body is not discarded. It rides as `cause`, which the framework's
|
|
673
|
+
* error handler walks into the log record and neither client surface
|
|
674
|
+
* serializes — `ErrorOptions` makes `cause` non-enumerable, the tool error
|
|
675
|
+
* envelope is built from `code`/`message`/`data` alone, and so is the
|
|
676
|
+
* JSON-RPC error object the SDK emits for resources.
|
|
677
|
+
*
|
|
678
|
+
* Issues #104 and #116.
|
|
679
|
+
*/
|
|
616
680
|
async #throwForStatus(res, path, ctx) {
|
|
617
681
|
const text = await this.#readBodySafe(res);
|
|
618
682
|
const body = parseJsonObject(text);
|
|
619
683
|
const display = displayPath(path);
|
|
620
|
-
|
|
684
|
+
/** Classification input and log payload only — never a wire value. */
|
|
685
|
+
const upstreamMsg = typeof body?.message === 'string' ? body.message : text.trim();
|
|
686
|
+
const cause = new UpstreamErrorText(upstreamMsg);
|
|
621
687
|
const data = (reason) => ({
|
|
622
688
|
path: display,
|
|
623
689
|
...(reason !== undefined ? { reason, ...ctx.recoveryFor(reason) } : {}),
|
|
624
|
-
...(upstream ? { upstream } : {}),
|
|
625
690
|
});
|
|
626
691
|
switch (res.status) {
|
|
627
692
|
case 401:
|
|
628
|
-
throw unauthorized('Obsidian Local REST API rejected the API key. Verify OBSIDIAN_API_KEY matches the value in Obsidian → Settings → Local REST API.', data());
|
|
693
|
+
throw unauthorized('Obsidian Local REST API rejected the API key. Verify OBSIDIAN_API_KEY matches the value in Obsidian → Settings → Local REST API.', data(), { cause });
|
|
629
694
|
case 403:
|
|
630
|
-
throw forbidden('Obsidian Local REST API forbids this request. Check the plugin permissions.', data());
|
|
695
|
+
throw forbidden('Obsidian Local REST API forbids this request. Check the plugin permissions.', data(), { cause });
|
|
631
696
|
case 404: {
|
|
632
697
|
if (path.startsWith('/active/')) {
|
|
633
|
-
throw notFound('No file is currently active in Obsidian — open a file in the app first.', data('no_active_file'));
|
|
698
|
+
throw notFound('No file is currently active in Obsidian — open a file in the app first.', data('no_active_file'), { cause });
|
|
634
699
|
}
|
|
635
700
|
if (path.startsWith('/periodic/')) {
|
|
636
|
-
const periodMatch = /^\/periodic\/(daily|weekly|monthly|quarterly|yearly)\//.exec(path);
|
|
637
|
-
const period = periodMatch?.[1] ?? 'periodic';
|
|
638
701
|
const dateMatch = /\/(\d{4})\/(\d{2})\/(\d{2})\/?$/.exec(path);
|
|
639
702
|
const suffix = dateMatch ? ` for ${dateMatch[1]}-${dateMatch[2]}-${dateMatch[3]}` : '';
|
|
640
|
-
throw notFound(`No ${
|
|
703
|
+
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 });
|
|
641
704
|
}
|
|
642
705
|
if (path.startsWith('/commands/')) {
|
|
643
|
-
throw notFound(`Unknown Obsidian command: ${display}. Use \`obsidian_list_commands\` to discover valid command IDs.`, data('command_unknown'));
|
|
706
|
+
throw notFound(`Unknown Obsidian command: ${display}. Use \`obsidian_list_commands\` to discover valid command IDs.`, data('command_unknown'), { cause });
|
|
644
707
|
}
|
|
645
|
-
throw notFound(`Not found: ${display}`, data('note_missing'));
|
|
708
|
+
throw notFound(`Not found: ${display}`, data('note_missing'), { cause });
|
|
646
709
|
}
|
|
647
710
|
case 405:
|
|
648
|
-
throw validationError(`${display} cannot accept this method (often: the path is a directory, not a file).`, data('path_is_directory'));
|
|
711
|
+
throw validationError(`${display} cannot accept this method (often: the path is a directory, not a file).`, data('path_is_directory'), { cause });
|
|
649
712
|
case 400: {
|
|
650
|
-
|
|
713
|
+
/**
|
|
714
|
+
* A malformed JSONLogic tree is rejected by the plugin's query parser
|
|
715
|
+
* with a bare 400. Keyed on the exact route rather than the message,
|
|
716
|
+
* because the upstream wording varies with which parse stage failed
|
|
717
|
+
* and `/search/simple/` (text mode) shares the `/search/` prefix
|
|
718
|
+
* without sharing the cause.
|
|
719
|
+
*
|
|
720
|
+
* The uncompilable-`regexp` case is named separately: it is the
|
|
721
|
+
* ordinary failure of a hand-written backlink query, and it is also
|
|
722
|
+
* the one whose upstream text quotes a note body. Classifying it here
|
|
723
|
+
* keeps the diagnostic a caller needs without relaying the pattern
|
|
724
|
+
* that carries it. The `logic_invalid` contract recovery supplies the
|
|
725
|
+
* operand order, and the framework mirrors it onto both surfaces.
|
|
726
|
+
*/
|
|
727
|
+
if (routeOf(path) === '/search/') {
|
|
728
|
+
throw validationError(/invalid regular expression/i.test(upstreamMsg)
|
|
729
|
+
? 'The Local REST API could not compile a `regexp` operand in the JSONLogic tree. `regexp` takes `[PATTERN, VALUE]` — with the operands reversed, the note field is compiled as the pattern.'
|
|
730
|
+
: 'The Local REST API could not evaluate the JSONLogic tree.', data('logic_invalid'), { cause });
|
|
731
|
+
}
|
|
651
732
|
// Content-preexists is a more specific case nested inside the broader
|
|
652
733
|
// "could not be applied" family — branch on it first so retries with
|
|
653
734
|
// identical content surface the right reason and recovery (toggle
|
|
654
735
|
// `applyIfContentPreexists`) instead of misleading section-miss copy.
|
|
655
736
|
if (/content-already-preexists-in-target/i.test(upstreamMsg)) {
|
|
656
|
-
throw validationError(`The supplied content already appears at the target in ${display}. Pass \`applyIfContentPreexists: true\` to force-apply, or change the content.`, data('content_preexists'));
|
|
737
|
+
throw validationError(`The supplied content already appears at the target in ${display}. Pass \`applyIfContentPreexists: true\` to force-apply, or change the content.`, data('content_preexists'), { cause });
|
|
657
738
|
}
|
|
658
739
|
// The Local REST API returns a "could not be applied to the target
|
|
659
740
|
// content" / "invalid-target" message when a PATCH names a section that
|
|
660
741
|
// doesn't exist. Translate to actionable guidance.
|
|
661
742
|
const isTargetMiss = /\bcould not be applied\b|\binvalid-target\b/i.test(upstreamMsg);
|
|
662
743
|
if (isTargetMiss) {
|
|
663
|
-
throw validationError(`Section target not found in ${display}. Use \`obsidian_get_note\` with \`format: "document-map"\` to list available headings, blocks, and frontmatter fields, then retry with one of those locators.`, data('section_target_missing'));
|
|
744
|
+
throw validationError(`Section target not found in ${display}. Use \`obsidian_get_note\` with \`format: "document-map"\` to list available headings, blocks, and frontmatter fields, then retry with one of those locators.`, data('section_target_missing'), { cause });
|
|
664
745
|
}
|
|
665
746
|
// Periodic Notes plugin returns 400 with "Specified period is not enabled"
|
|
666
747
|
// when the requested period (daily/weekly/monthly/...) is disabled in the
|
|
667
748
|
// user's plugin settings. Distinct from periodic_not_found (404) — caller
|
|
668
749
|
// can enable it or fall back to an explicit path target.
|
|
669
750
|
if (path.startsWith('/periodic/') && /\bnot enabled\b/i.test(upstreamMsg)) {
|
|
670
|
-
throw validationError(
|
|
751
|
+
throw validationError(`The ${periodOf(path)} period is not enabled in Obsidian's Periodic Notes plugin settings. Enable it there, or address the note by an explicit vault path instead.`, data('periodic_disabled'), { cause });
|
|
671
752
|
}
|
|
672
|
-
throw validationError(
|
|
753
|
+
throw validationError(`Obsidian Local REST API rejected the request to ${display} as malformed (HTTP 400).`, data(), { cause });
|
|
673
754
|
}
|
|
674
755
|
default: {
|
|
675
756
|
/**
|
|
676
|
-
* Unhandled 4xx and all 5xx
|
|
677
|
-
*
|
|
678
|
-
* 502/503→ServiceUnavailable, 504→Timeout)
|
|
679
|
-
*
|
|
680
|
-
* and
|
|
757
|
+
* 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
|
|
762
|
+
* `data.body`/`data.responseBody`, which is the #104 leak.
|
|
763
|
+
*
|
|
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.
|
|
681
767
|
*/
|
|
682
|
-
const
|
|
683
|
-
throw
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
...(truncated !== undefined ? { body: truncated } : {}),
|
|
689
|
-
},
|
|
690
|
-
});
|
|
768
|
+
const retryAfter = res.headers.get('retry-after');
|
|
769
|
+
throw new McpError(httpStatusToErrorCode(res.status) ?? JsonRpcErrorCode.InternalError, `Obsidian Local REST API returned HTTP ${res.status}.`, {
|
|
770
|
+
...data(),
|
|
771
|
+
status: res.status,
|
|
772
|
+
...(retryAfter !== null ? { retryAfter } : {}),
|
|
773
|
+
}, { cause });
|
|
691
774
|
}
|
|
692
775
|
}
|
|
693
776
|
}
|
|
@@ -734,6 +817,93 @@ export function encodeVaultPath(path) {
|
|
|
734
817
|
}
|
|
735
818
|
return segments.map((seg) => encodeURIComponent(seg)).join('/');
|
|
736
819
|
}
|
|
820
|
+
/**
|
|
821
|
+
* Locate the match span inside the `context` window the upstream ships with it.
|
|
822
|
+
*
|
|
823
|
+
* `start`/`end` are offsets into whichever subject the plugin matched, and
|
|
824
|
+
* there are two. For a **body match** the subject is the note text and the
|
|
825
|
+
* window is `body.slice(max(0, start - contextLength), min(len, end + contextLength))`,
|
|
826
|
+
* so the span sits `min(start, contextLength)` characters into `context`. For a
|
|
827
|
+
* **filename match** the subject is the note's basename and the plugin returns
|
|
828
|
+
* that basename whole as `context`, so the span sits at `start` — which runs
|
|
829
|
+
* past `min(start, contextLength)` as soon as the name is longer than the
|
|
830
|
+
* window. A single hit's `matches[]` can carry both kinds. Verified against
|
|
831
|
+
* Local REST API v5.0.3.
|
|
832
|
+
*
|
|
833
|
+
* `context === basename` is the cheap separator, but it is not decisive: a body
|
|
834
|
+
* window whose left edge is trimmed can coincide with the basename (a note whose
|
|
835
|
+
* own name is quoted in its body, matched so the window lands on that quote),
|
|
836
|
+
* and then the two readings disagree and the filename one slices the wrong text
|
|
837
|
+
* — often past the end of `context` entirely. Where they disagree, settle it on
|
|
838
|
+
* the text rather than the coincidence: the plugin matches whole query tokens,
|
|
839
|
+
* so the correct reading reproduces one. An inconclusive check keeps the
|
|
840
|
+
* filename reading, which is what the coincidence test alone would have picked.
|
|
841
|
+
*/
|
|
842
|
+
function contextRelativeSpan(m, filename, contextLength, query) {
|
|
843
|
+
const span = m.match.end - m.match.start;
|
|
844
|
+
const bodyStart = Math.min(m.match.start, contextLength);
|
|
845
|
+
const basename = (filename.split('/').pop() ?? filename).replace(/\.[^./]+$/, '');
|
|
846
|
+
const at = (i) => ({ contextStart: i, contextEnd: i + span });
|
|
847
|
+
if (m.context !== basename || m.match.start === bodyStart)
|
|
848
|
+
return at(bodyStart);
|
|
849
|
+
const reproducesToken = (i) => {
|
|
850
|
+
const slice = m.context.slice(i, i + span);
|
|
851
|
+
return slice.length === span && query.toLowerCase().includes(slice.toLowerCase());
|
|
852
|
+
};
|
|
853
|
+
return reproducesToken(m.match.start) || !reproducesToken(bodyStart)
|
|
854
|
+
? at(m.match.start)
|
|
855
|
+
: at(bodyStart);
|
|
856
|
+
}
|
|
857
|
+
/**
|
|
858
|
+
* The upstream error body, carried as the `cause` of everything
|
|
859
|
+
* `#throwForStatus` throws.
|
|
860
|
+
*
|
|
861
|
+
* `cause` is the one channel that reaches the server's logs without reaching
|
|
862
|
+
* the client, which is what lets the containment invariant hold while the
|
|
863
|
+
* text stays available for debugging and for the classifiers below. The body
|
|
864
|
+
* is the `Error` message so the framework's cause-chain extractor records it.
|
|
865
|
+
*/
|
|
866
|
+
class UpstreamErrorText extends Error {
|
|
867
|
+
constructor(text) {
|
|
868
|
+
super(text);
|
|
869
|
+
this.name = 'UpstreamErrorText';
|
|
870
|
+
}
|
|
871
|
+
}
|
|
872
|
+
/**
|
|
873
|
+
* The upstream body behind an error, when `#throwForStatus` raised it. Walks
|
|
874
|
+
* the `cause` chain rather than reading one level: `withRetry` re-wraps an
|
|
875
|
+
* exhausted error, so on a retry-safe method the carrier sits a level deeper
|
|
876
|
+
* than the throw site left it.
|
|
877
|
+
*/
|
|
878
|
+
function upstreamTextOf(err) {
|
|
879
|
+
let current = err;
|
|
880
|
+
for (let depth = 0; depth < 4; depth++) {
|
|
881
|
+
if (current instanceof UpstreamErrorText)
|
|
882
|
+
return current.message;
|
|
883
|
+
if (!(current instanceof Error))
|
|
884
|
+
return;
|
|
885
|
+
current = current.cause;
|
|
886
|
+
}
|
|
887
|
+
return;
|
|
888
|
+
}
|
|
889
|
+
/**
|
|
890
|
+
* True for the V8 `RangeError: Invalid string length` the Local REST API
|
|
891
|
+
* surfaces (as an opaque HTTP 500) when it cannot concatenate the response.
|
|
892
|
+
* Read off the `cause` carrier: since the containment invariant on
|
|
893
|
+
* `#throwForStatus`, the upstream text appears on neither the message nor
|
|
894
|
+
* `data`, and this is the only place it survives.
|
|
895
|
+
*/
|
|
896
|
+
function isStringCapacityOverflow(err) {
|
|
897
|
+
return /invalid string length/i.test(upstreamTextOf(err) ?? '');
|
|
898
|
+
}
|
|
899
|
+
/** The period segment of a `/periodic/…` request path, for message copy. */
|
|
900
|
+
function periodOf(urlPath) {
|
|
901
|
+
return /^\/periodic\/(daily|weekly|monthly|quarterly|yearly)\//.exec(urlPath)?.[1] ?? 'periodic';
|
|
902
|
+
}
|
|
903
|
+
/** The request path with its query string dropped — the route alone. */
|
|
904
|
+
function routeOf(urlPath) {
|
|
905
|
+
return urlPath.split('?')[0] ?? urlPath;
|
|
906
|
+
}
|
|
737
907
|
/**
|
|
738
908
|
* Convert an internal URL path (e.g. `/vault/Projects/My%20Note.md`) to the
|
|
739
909
|
* vault-relative form a caller would recognize. Used in error messages so the
|
|
@@ -742,7 +912,7 @@ export function encodeVaultPath(path) {
|
|
|
742
912
|
function displayPath(urlPath) {
|
|
743
913
|
if (urlPath.startsWith('/active/'))
|
|
744
914
|
return '(active file)';
|
|
745
|
-
const noQuery = urlPath
|
|
915
|
+
const noQuery = routeOf(urlPath);
|
|
746
916
|
let decoded;
|
|
747
917
|
try {
|
|
748
918
|
decoded = decodeURIComponent(noQuery);
|
|
@@ -764,19 +934,6 @@ function displayPath(urlPath) {
|
|
|
764
934
|
}
|
|
765
935
|
return decoded;
|
|
766
936
|
}
|
|
767
|
-
/**
|
|
768
|
-
* Trim the upstream error body down to a safe, user-presentable shape — drops
|
|
769
|
-
* `errorCode` and any other plugin-internal fields that would otherwise leak
|
|
770
|
-
* into JSON-RPC `error.data`.
|
|
771
|
-
*/
|
|
772
|
-
function safeUpstream(body, text) {
|
|
773
|
-
if (body?.message)
|
|
774
|
-
return { message: body.message };
|
|
775
|
-
const trimmed = text.trim();
|
|
776
|
-
if (trimmed)
|
|
777
|
-
return { message: trimmed.length > 200 ? `${trimmed.slice(0, 200)}…` : trimmed };
|
|
778
|
-
return;
|
|
779
|
-
}
|
|
780
937
|
/**
|
|
781
938
|
* Read the `Content-Length` header from a HEAD response and parse it as a
|
|
782
939
|
* non-negative integer byte count. Throws when the upstream omits the header
|