@j0hanz/fetch-url-mcp 1.9.4 → 1.9.6

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.
@@ -6,7 +6,7 @@ declare class CorsPolicy {
6
6
  handle(ctx: RequestContext): boolean;
7
7
  }
8
8
  export declare const corsPolicy: CorsPolicy;
9
- export declare class InsufficientScopeError extends InvalidTokenError {
9
+ declare class InsufficientScopeError extends InvalidTokenError {
10
10
  readonly requiredScopes: readonly string[];
11
11
  constructor(requiredScopes: readonly string[], message?: string);
12
12
  }
@@ -1 +1 @@
1
- {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/http/auth.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"auth.d.ts","sourceRoot":"","sources":["../../src/http/auth.ts"],"names":[],"mappings":"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"}
package/dist/http/auth.js CHANGED
@@ -35,7 +35,7 @@ export const corsPolicy = new CorsPolicy();
35
35
  // ---------------------------------------------------------------------------
36
36
  const LOOPBACK_HOSTS = new Set(['localhost', '127.0.0.1', '::1']);
37
37
  const WILDCARD_HOSTS = new Set(['0.0.0.0', '::']);
38
- export class InsufficientScopeError extends InvalidTokenError {
38
+ class InsufficientScopeError extends InvalidTokenError {
39
39
  requiredScopes;
40
40
  constructor(requiredScopes, message = 'Insufficient scope') {
41
41
  super(message);
@@ -251,7 +251,9 @@ class AuthService {
251
251
  if (apiKey && config.auth.mode === 'oauth') {
252
252
  throw new InvalidTokenError('X-API-Key not supported for OAuth');
253
253
  }
254
- throw new InvalidTokenError('Missing Authorization header');
254
+ throw new InvalidTokenError(config.auth.mode === 'static'
255
+ ? 'Missing Authorization or X-API-Key header'
256
+ : 'Missing Authorization header');
255
257
  }
256
258
  resolveBearerToken(authHeader) {
257
259
  if (!authHeader.startsWith('Bearer ')) {
@@ -19,7 +19,6 @@ export interface AuthenticatedContext extends RequestContext {
19
19
  auth: AuthInfo;
20
20
  }
21
21
  export declare function sendJson(res: ServerResponse, status: number, body: unknown): void;
22
- export declare function sendText(res: ServerResponse, status: number, body: string): void;
23
22
  export declare function sendEmpty(res: ServerResponse, status: number): void;
24
23
  export declare function sendError(res: ServerResponse, code: number, message: string, status?: number, id?: JsonRpcId): void;
25
24
  export declare function getHeaderValue(req: IncomingMessage, name: string): string | null;
@@ -1 +1 @@
1
- {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/http/helpers.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/http/helpers.ts"],"names":[],"mappings":"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"}
@@ -31,12 +31,6 @@ export function sendJson(res, status, body) {
31
31
  setNoStoreHeaders(res);
32
32
  res.end(JSON.stringify(body));
33
33
  }
34
- export function sendText(res, status, body) {
35
- res.statusCode = status;
36
- res.setHeader('Content-Type', 'text/plain; charset=utf-8');
37
- setNoStoreHeaders(res);
38
- res.end(body);
39
- }
40
34
  export function sendEmpty(res, status) {
41
35
  res.statusCode = status;
42
36
  res.setHeader('Content-Length', '0');
@@ -1 +1 @@
1
- {"version":3,"file":"code-lang.d.ts","sourceRoot":"","sources":["../../src/lib/code-lang.ts"],"names":[],"mappings":"AA6QA,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAuBpB;AAqBD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAKpB;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqBvE"}
1
+ {"version":3,"file":"code-lang.d.ts","sourceRoot":"","sources":["../../src/lib/code-lang.ts"],"names":[],"mappings":"AAgRA,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,MAAM,GAChB,MAAM,GAAG,SAAS,CAuBpB;AAqBD,wBAAgB,6BAA6B,CAC3C,SAAS,EAAE,MAAM,EACjB,QAAQ,EAAE,MAAM,GACf,MAAM,GAAG,SAAS,CAKpB;AACD,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,GAAG,SAAS,CAqBvE"}
@@ -82,7 +82,7 @@ const RUST_REGEX = /\b(?:fn|impl|struct|enum)\b/;
82
82
  const JS_REGEX = /\b(?:const|let|var|function|class|async|await|export|import)\b/;
83
83
  const PYTHON_UNIQUE_REGEX = /\b(?:def |elif |except |finally:|yield |lambda |raise |pass$)/m;
84
84
  const JS_SIGNAL_REGEX = /\b(?:const |let |var |function |require\(|=>|===|!==|console\.)/;
85
- const CSS_REGEX = /@media|@import|@keyframes/;
85
+ const CSS_REGEX = /@media|@import|@keyframes|@theme\b|@utility\b|@layer\b|@apply\b|@variant\b|@custom-variant\b|@reference\b|@source\b/;
86
86
  const CSS_PROPERTY_REGEX = /^\s*[a-z][\w-]*\s*:/;
87
87
  function containsJsxTag(code) {
88
88
  const len = code.length;
@@ -195,6 +195,8 @@ function hasJsSignals(lowerCode) {
195
195
  lowerCode.includes("from '"));
196
196
  }
197
197
  function matchPython(ctx) {
198
+ if (matchHtml(ctx))
199
+ return false;
198
200
  const l = ctx.lower;
199
201
  if (l.includes('print(') || l.includes('__name__'))
200
202
  return true;
@@ -229,6 +231,7 @@ const LANGUAGES = [
229
231
  { lang: 'jsx', weight: 22, match: matchJsx },
230
232
  { lang: 'typescript', weight: 20, match: matchTypeScript },
231
233
  { lang: 'sql', weight: 20, match: matchSql },
234
+ { lang: 'html', weight: 19, match: matchHtml },
232
235
  { lang: 'python', weight: 18, match: matchPython },
233
236
  {
234
237
  lang: 'css',
@@ -238,7 +241,6 @@ const LANGUAGES = [
238
241
  { lang: 'bash', weight: 15, match: (ctx) => detectBashIndicators(ctx.lines) },
239
242
  { lang: 'yaml', weight: 15, match: (ctx) => detectYamlStructure(ctx.lines) },
240
243
  { lang: 'javascript', weight: 15, match: (ctx) => JS_REGEX.test(ctx.lower) },
241
- { lang: 'html', weight: 12, match: matchHtml },
242
244
  {
243
245
  lang: 'json',
244
246
  weight: 10,
@@ -34,7 +34,7 @@ interface HttpsConfig {
34
34
  interface RuntimeState {
35
35
  httpMode: boolean;
36
36
  }
37
- export interface AppServerHttpConfig {
37
+ interface AppServerHttpConfig {
38
38
  headersTimeoutMs: number | undefined;
39
39
  requestTimeoutMs: number | undefined;
40
40
  keepAliveTimeoutMs: number | undefined;
@@ -45,7 +45,7 @@ export interface AppServerHttpConfig {
45
45
  shutdownCloseIdleConnections: boolean;
46
46
  shutdownCloseAllConnections: boolean;
47
47
  }
48
- export interface AppServerConfig {
48
+ interface AppServerConfig {
49
49
  name: string;
50
50
  version: string;
51
51
  port: number;
@@ -56,13 +56,13 @@ export interface AppServerConfig {
56
56
  maxSessions: number;
57
57
  http: AppServerHttpConfig;
58
58
  }
59
- export interface AppFetcherConfig {
59
+ interface AppFetcherConfig {
60
60
  timeout: number;
61
61
  maxRedirects: number;
62
62
  userAgent: string;
63
63
  maxContentLength: number;
64
64
  }
65
- export interface AppTransformConfig {
65
+ interface AppTransformConfig {
66
66
  timeoutMs: number;
67
67
  stageWarnRatio: number;
68
68
  metadataFormat: string;
@@ -71,19 +71,19 @@ export interface AppTransformConfig {
71
71
  workerMode: TransformWorkerMode;
72
72
  workerResourceLimits: WorkerResourceLimits | undefined;
73
73
  }
74
- export interface AppTasksConfig {
74
+ interface AppTasksConfig {
75
75
  maxTotal: number;
76
76
  maxPerOwner: number;
77
77
  emitStatusNotifications: boolean;
78
78
  requireInterception: boolean;
79
79
  }
80
- export interface AppCacheConfig {
80
+ interface AppCacheConfig {
81
81
  enabled: boolean;
82
82
  ttl: number;
83
83
  maxKeys: number;
84
84
  maxSizeBytes: number;
85
85
  }
86
- export interface AppNoiseRemovalConfig {
86
+ interface AppNoiseRemovalConfig {
87
87
  extraTokens: string[];
88
88
  extraSelectors: string[];
89
89
  enabledCategories: string[];
@@ -98,7 +98,7 @@ export interface AppNoiseRemovalConfig {
98
98
  threshold: number;
99
99
  };
100
100
  }
101
- export interface AppMarkdownCleanupConfig {
101
+ interface AppMarkdownCleanupConfig {
102
102
  promoteOrphanHeadings: boolean;
103
103
  removeSkipLinks: boolean;
104
104
  removeTocBlocks: boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,EAAE,KAAK,6BAA6B,EAAE,MAAM,oDAAoD,CAAC;AAexG,eAAO,MAAM,aAAa,EAAE,MAA2C,CAAC;AACxE,KAAK,QAAQ,GAAG,OAAO,GAAG,MAAM,GAAG,MAAM,GAAG,OAAO,CAAC;AAwBpD,KAAK,mBAAmB,GAAG,SAAS,GAAG,SAAS,CAAC;AACjD,KAAK,QAAQ,GAAG,OAAO,GAAG,QAAQ,CAAC;AA4LnC,UAAU,oBAAoB;IAC5B,sBAAsB,CAAC,EAAE,MAAM,CAAC;IAChC,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAuCD,UAAU,UAAU;IAClB,IAAI,EAAE,QAAQ,CAAC;IACf,SAAS,EAAE,GAAG,GAAG,SAAS,CAAC;IAC3B,gBAAgB,EAAE,GAAG,GAAG,SAAS,CAAC;IAClC,QAAQ,EAAE,GAAG,GAAG,SAAS,CAAC;IAC1B,aAAa,EAAE,GAAG,GAAG,SAAS,CAAC;IAC/B,eAAe,EAAE,GAAG,GAAG,SAAS,CAAC;IACjC,gBAAgB,EAAE,GAAG,GAAG,SAAS,CAAC;IAClC,WAAW,EAAE,GAAG,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,YAAY,EAAE,MAAM,GAAG,SAAS,CAAC;IACjC,sBAAsB,EAAE,MAAM,CAAC;IAC/B,YAAY,EAAE,MAAM,EAAE,CAAC;CACxB;AAED,UAAU,WAAW;IACnB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,GAAG,SAAS,CAAC;IAC5B,QAAQ,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC;CAC5B;AAiGD,UAAU,YAAY;IACpB,QAAQ,EAAE,OAAO,CAAC;CACnB;AAKD,MAAM,WAAW,mBAAmB;IAClC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,gBAAgB,EAAE,MAAM,GAAG,SAAS,CAAC;IACrC,kBAAkB,EAAE,MAAM,GAAG,SAAS,CAAC;IACvC,wBAAwB,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7C,eAAe,EAAE,MAAM,GAAG,SAAS,CAAC;IACpC,cAAc,EAAE,MAAM,CAAC;IACvB,uBAAuB,EAAE,OAAO,CAAC;IACjC,4BAA4B,EAAE,OAAO,CAAC;IACtC,2BAA2B,EAAE,OAAO,CAAC;CACtC;AAED,MAAM,WAAW,eAAe;IAC9B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,WAAW,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,mBAAmB,CAAC;CAC3B;AA4CD,MAAM,WAAW,gBAAgB;IAC/B,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAWD,MAAM,WAAW,kBAAkB;IACjC,SAAS,EAAE,MAAM,CAAC;IAClB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,cAAc,EAAE,MAAM,CAAC;IACvB,kBAAkB,EAAE,MAAM,CAAC;IAC3B,UAAU,EAAE,mBAAmB,CAAC;IAChC,oBAAoB,EAAE,oBAAoB,GAAG,SAAS,CAAC;CACxD;AAmBD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,uBAAuB,EAAE,OAAO,CAAC;IACjC,mBAAmB,EAAE,OAAO,CAAC;CAC9B;AAiBD,MAAM,WAAW,cAAc;IAC7B,OAAO,EAAE,OAAO,CAAC;IACjB,GAAG,EAAE,MAAM,CAAC;IACZ,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,MAAM,CAAC;CACtB;AAWD,MAAM,WAAW,qBAAqB;IACpC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,KAAK,EAAE,OAAO,CAAC;IACf,cAAc,EAAE,OAAO,CAAC;IACxB,iBAAiB,EAAE,OAAO,CAAC;IAC3B,OAAO,EAAE;QACP,MAAM,EAAE,MAAM,CAAC;QACf,UAAU,EAAE,MAAM,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;QACpB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAyBD,MAAM,WAAW,wBAAwB;IACvC,qBAAqB,EAAE,OAAO,CAAC;IAC/B,eAAe,EAAE,OAAO,CAAC;IACzB,eAAe,EAAE,OAAO,CAAC;IACzB,qBAAqB,EAAE,OAAO,CAAC;IAC/B,eAAe,EAAE,MAAM,EAAE,CAAC;CAC3B;AAeD,eAAO,MAAM,MAAM;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA2ClB,CAAC;AACF,wBAAgB,cAAc,IAAI,IAAI,CAErC;AAED,UAAU,UAAU;IAClB,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;CACnB;AACD,UAAU,aAAa;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;CACjB;AACD,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AACD,UAAU,eAAe;IACvB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB;AACD,UAAU,kBAAkB;IAC1B,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAID,UAAU,gBAAgB;IACxB,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AACD,KAAK,mBAAmB,GAAG,CAAC,KAAK,EAAE,gBAAgB,KAAK,OAAO,CAAC;AAChE,wBAAgB,cAAc,CAC5B,SAAS,EAAE,MAAM,EACjB,GAAG,EAAE,MAAM,EACX,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,GACtC,MAAM,GAAG,IAAI,CAyBf;AACD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CASpE;AAoLD,wBAAgB,aAAa,CAAC,QAAQ,EAAE,mBAAmB,GAAG,MAAM,IAAI,CAEvE;AACD,wBAAgB,GAAG,CACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,CAAC,EAAE,eAAe,GACxB,UAAU,GAAG,SAAS,CAExB;AACD,wBAAgB,GAAG,CACjB,QAAQ,EAAE,MAAM,GAAG,IAAI,EACvB,OAAO,EAAE,MAAM,EACf,QAAQ,EAAE,kBAAkB,EAC5B,OAAO,CAAC,EAAE,eAAe,GACxB,IAAI,CAEN;AACD,wBAAgB,IAAI,IAAI,SAAS,MAAM,EAAE,CAExC;AACD,wBAAgB,YAAY,CAC1B,QAAQ,EAAE,MAAM,GACf;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAC;IAAC,SAAS,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,SAAS,CAQjE;AACD,wBAAgB,SAAS,IAAI,OAAO,CAEnC;AA4BD,KAAK,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAC3C,UAAU,cAAc;IACtB,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,QAAQ,CAAC,SAAS,CAAC,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAC;CAC/B;AAYD,wBAAgB,YAAY,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAEpD;AACD,wBAAgB,wBAAwB,CACtC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,SAAS,GAChB,IAAI,CAGN;AACD,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,MAAM,GAAG,IAAI,CAIlE;AACD,wBAAgB,kCAAkC,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAM1E;AACD,wBAAgB,2BAA2B,CACzC,MAAM,EAAE,SAAS,GAChB,MAAM,GAAG,SAAS,CAKpB;AACD,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,OAAO,EAAE,cAAc,EACvB,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAEH;AAID,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAGjD;AACD,wBAAgB,YAAY,IAAI,MAAM,GAAG,SAAS,CAEjD;AACD,wBAAgB,cAAc,IAAI,MAAM,GAAG,SAAS,CAEnD;AAsJD,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAEjE;AACD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAElE;AACD,wBAAgB,OAAO,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,WAAW,GAAG,IAAI,CAEjE;AAcD,wBAAgB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,KAAK,GAAG,WAAW,GAAG,IAAI,CAI3E;AACD,wBAAgB,cAAc,CAAC,SAAS,CAAC,EAAE,MAAM,GAAG,QAAQ,CAK3D;AACD,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAUnE;AACD,wBAAgB,SAAS,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAWhD;AACD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,MAAM,EAAE,SAAS,CAAC;IAC3B,QAAQ,CAAC,SAAS,EAAE,6BAA6B,CAAC;IAClD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,yBAAyB,EAAE,MAAM,CAAC;IAClC,eAAe,EAAE,MAAM,CAAC;CACzB;AACD,MAAM,WAAW,YAAY;IAC3B,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,CAAC;IACrD,KAAK,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,IAAI,CAAC;IACnC,GAAG,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY,KAAK,IAAI,CAAC;IACtD,MAAM,EAAE,CAAC,SAAS,EAAE,MAAM,KAAK,YAAY,GAAG,SAAS,CAAC;IACxD,IAAI,EAAE,MAAM,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,MAAM,CAAC;IACvB,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,iBAAiB,EAAE,MAAM,IAAI,CAAC;IAC9B,KAAK,EAAE,MAAM,YAAY,EAAE,CAAC;IAC5B,YAAY,EAAE,MAAM,YAAY,EAAE,CAAC;IACnC,WAAW,EAAE,MAAM,YAAY,GAAG,SAAS,CAAC;CAC7C;AACD,UAAU,WAAW;IACnB,QAAQ,CAAC,WAAW,EAAE,MAAM,IAAI,CAAC;IACjC,QAAQ,CAAC,eAAe,EAAE,MAAM,IAAI,CAAC;IACrC,QAAQ,CAAC,aAAa,EAAE,MAAM,OAAO,CAAC;CACvC;AACD,KAAK,YAAY,GAAG,CAAC,MAAM,IAAI,CAAC,GAAG,SAAS,CAAC;AAC7C,wBAAgB,oBAAoB,CAClC,KAAK,EAAE,YAAY,EACnB,MAAM,EAAE,YAAY,GACnB,YAAY,CAWd;AAuHD,wBAAgB,uBAAuB,CACrC,KAAK,EAAE,YAAY,EACnB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;IACR,cAAc,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IACjE,iBAAiB,CAAC,EAAE,MAAM,CAAC;CAC5B,GACA,eAAe,CAOjB;AAoFD,wBAAgB,kBAAkB,CAAC,YAAY,EAAE,MAAM,GAAG,YAAY,CAErE;AACD,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,YAAY,GAAG,WAAW,CAiBlE;AACD,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,YAAY,EACnB,WAAW,EAAE,MAAM,GAClB,OAAO,CAMT;AACD,wBAAgB,qBAAqB,CAAC,EACpC,KAAK,EACL,WAAW,EACX,WAAW,GACZ,EAAE;IACD,KAAK,EAAE,YAAY,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,OAAO,CAAC;CAC/C,GAAG,OAAO,CAeV"}
1
+ {"version":3,"file":"core.d.ts","sourceRoot":"","sources":["../../src/lib/core.ts"],"names":[],"mappings":"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"}
package/dist/lib/core.js CHANGED
@@ -807,6 +807,57 @@ function resolveErrorText(err) {
807
807
  return err;
808
808
  return 'unknown error';
809
809
  }
810
+ const MCP_LOG_META_BLOCKLIST = new Set(['stack']);
811
+ const MCP_LOG_MAX_DEPTH = 5;
812
+ function isPlainLogObject(value) {
813
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
814
+ }
815
+ function sanitizeMcpLogValue(value, depth = 0) {
816
+ if (depth >= MCP_LOG_MAX_DEPTH) {
817
+ return '[truncated]';
818
+ }
819
+ if (value === null ||
820
+ typeof value === 'string' ||
821
+ typeof value === 'number' ||
822
+ typeof value === 'boolean') {
823
+ return value;
824
+ }
825
+ if (typeof value === 'bigint')
826
+ return value.toString();
827
+ if (value instanceof Error)
828
+ return value.message;
829
+ if (Array.isArray(value)) {
830
+ return value
831
+ .map((entry) => sanitizeMcpLogValue(entry, depth + 1))
832
+ .filter((entry) => entry !== undefined);
833
+ }
834
+ if (isPlainLogObject(value)) {
835
+ const sanitized = {};
836
+ for (const [key, entry] of Object.entries(value)) {
837
+ if (MCP_LOG_META_BLOCKLIST.has(key))
838
+ continue;
839
+ const normalized = sanitizeMcpLogValue(entry, depth + 1);
840
+ if (normalized !== undefined) {
841
+ sanitized[key] = normalized;
842
+ }
843
+ }
844
+ return sanitized;
845
+ }
846
+ return undefined;
847
+ }
848
+ function buildMcpLogData(message, meta) {
849
+ if (!meta || Object.keys(meta).length === 0) {
850
+ return message;
851
+ }
852
+ const sanitized = sanitizeMcpLogValue(meta);
853
+ if (!isPlainLogObject(sanitized) || Object.keys(sanitized).length === 0) {
854
+ return { message };
855
+ }
856
+ return {
857
+ ...sanitized,
858
+ message,
859
+ };
860
+ }
810
861
  function safeWriteStderr(line) {
811
862
  if (!stderrAvailable)
812
863
  return;
@@ -840,8 +891,7 @@ function writeLog(level, message, meta) {
840
891
  .sendLoggingMessage({
841
892
  level: level === 'warn' ? 'warning' : level,
842
893
  logger: 'fetch-url-mcp',
843
- // Preserve existing behavior: MCP payload includes only message + provided meta (not ALS context meta).
844
- data: meta ? { message, ...meta } : message,
894
+ data: buildMcpLogData(message, meta),
845
895
  }, sessionId)
846
896
  .catch((err) => {
847
897
  if (!isDebugEnabled())
@@ -1 +1 @@
1
- {"version":3,"file":"dom-prep.d.ts","sourceRoot":"","sources":["../../src/lib/dom-prep.ts"],"names":[],"mappings":"AA8hBA,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAQR;AA4DD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,IAAI,CAiBN;AA+DD,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,QAAQ,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,CAcR"}
1
+ {"version":3,"file":"dom-prep.d.ts","sourceRoot":"","sources":["../../src/lib/dom-prep.ts"],"names":[],"mappings":"AAwlBA,wBAAgB,4BAA4B,CAC1C,QAAQ,EAAE,QAAQ,EAClB,QAAQ,EAAE,MAAM,GACf,MAAM,CAQR;AAmPD,wBAAgB,0BAA0B,CACxC,QAAQ,EAAE,QAAQ,EAClB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,IAAI,CAkBN;AAiED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,QAAQ,EACnB,OAAO,CAAC,EAAE,MAAM,EAChB,MAAM,CAAC,EAAE,WAAW,GACnB,MAAM,CAcR"}
@@ -17,6 +17,8 @@ const NOISE_PATTERNS = [
17
17
  ];
18
18
  const HEADER_NOISE_PATTERN = /\b(site-header|masthead|topbar|navbar|nav(?:bar)?|menu|header-nav)\b/i;
19
19
  const FIXED_OR_HIGH_Z_PATTERN = /\b(?:fixed|sticky|z-(?:4\d|50)|isolate)\b/;
20
+ const HEADING_PERMALINK_TEXT_PATTERN = /^(?:#|¶|§|¤|🔗)$/u;
21
+ const HEADING_PERMALINK_CLASS_PATTERN = /\b(?:mark|permalink|hash-link|anchor(?:js)?-?link|header-?link|heading-anchor|deep-link)\b/i;
20
22
  const SKIP_URL_PREFIXES = [
21
23
  '#',
22
24
  'javascript:',
@@ -50,6 +52,9 @@ const NAVIGATION_ROLES = new Set([
50
52
  'alertdialog',
51
53
  'search',
52
54
  ]);
55
+ const INLINE_DEMO_INSTRUCTION_MAX_CHARS = 160;
56
+ const REDUNDANT_PREVIEW_SEGMENT_MAX_CHARS = 60;
57
+ const REDUNDANT_PREVIEW_MAX_SEGMENTS = 12;
53
58
  const INTERACTIVE_CONTENT_ROLES = new Set([
54
59
  'tabpanel',
55
60
  'tab',
@@ -362,11 +367,8 @@ function cleanHeadings(document) {
362
367
  const a = anchors[j];
363
368
  if (!a?.parentNode)
364
369
  continue;
365
- const href = a.getAttribute('href') ?? '';
366
- const txt = (a.textContent || '').replace(/[\u200B\s]/g, '');
367
- if (href.startsWith('#') && txt.length === 0) {
370
+ if (isHeadingPermalinkAnchor(a))
368
371
  a.remove();
369
- }
370
372
  }
371
373
  // Strip zero-width spaces from text nodes
372
374
  const walker = document.createTreeWalker(h, NODE_FILTER_SHOW_TEXT);
@@ -378,6 +380,47 @@ function cleanHeadings(document) {
378
380
  }
379
381
  }
380
382
  }
383
+ function getCollapsedHeadingAnchorText(anchor) {
384
+ return (anchor.textContent || '').replace(/[\u200B\s]/g, '');
385
+ }
386
+ function isHeadingPermalinkAnchor(anchor) {
387
+ const href = anchor.getAttribute('href') ?? '';
388
+ if (!href.startsWith('#'))
389
+ return false;
390
+ const text = getCollapsedHeadingAnchorText(anchor);
391
+ if (text.length === 0 || HEADING_PERMALINK_TEXT_PATTERN.test(text)) {
392
+ return true;
393
+ }
394
+ const className = anchor.getAttribute('class') ?? '';
395
+ if (HEADING_PERMALINK_CLASS_PATTERN.test(className) && text.length <= 2) {
396
+ return true;
397
+ }
398
+ const ariaHidden = anchor.getAttribute('aria-hidden');
399
+ const tabindex = anchor.getAttribute('tabindex');
400
+ return (ariaHidden === 'true' || tabindex === '-1') && text.length <= 2;
401
+ }
402
+ function getDirectRows(section) {
403
+ return Array.from(section.children).filter((child) => child.tagName === 'TR');
404
+ }
405
+ function getDirectCells(row) {
406
+ return Array.from(row.children).filter((child) => child.tagName === 'TH' || child.tagName === 'TD');
407
+ }
408
+ function hoistNestedRows(table) {
409
+ const sections = Array.from(table.querySelectorAll('thead,tbody,tfoot'));
410
+ for (const section of sections) {
411
+ const rows = getDirectRows(section);
412
+ for (const row of rows) {
413
+ let insertAfter = row;
414
+ for (const cell of getDirectCells(row)) {
415
+ const nestedRows = Array.from(cell.querySelectorAll('tr')).filter((nested) => nested.closest('table') === table);
416
+ for (const nestedRow of nestedRows) {
417
+ insertAfter.after(nestedRow);
418
+ insertAfter = nestedRow;
419
+ }
420
+ }
421
+ }
422
+ }
423
+ }
381
424
  function stripNoise(document, context, signal) {
382
425
  cleanHeadings(document);
383
426
  // Structural Removal
@@ -506,6 +549,130 @@ function escapeTableCellPipes(document) {
506
549
  }
507
550
  }
508
551
  }
552
+ function normalizeWhitespace(value) {
553
+ return value.replace(/\s+/g, ' ').trim();
554
+ }
555
+ function hasDirectPreDescendant(element) {
556
+ return (element.tagName === 'PRE' ||
557
+ Array.from(element.children).some((child) => child.tagName === 'PRE' || child.querySelector('pre') !== null));
558
+ }
559
+ function collectLeafTextSegments(element) {
560
+ const seen = new Set();
561
+ const segments = [];
562
+ const candidates = element.querySelectorAll('p,li,div,span');
563
+ for (const candidate of candidates) {
564
+ if (candidate.children.length > 0 ||
565
+ candidate.querySelector('pre,code,table,ul,ol,blockquote,figure') !== null) {
566
+ continue;
567
+ }
568
+ const text = normalizeWhitespace(candidate.textContent || '');
569
+ if (text.length === 0 ||
570
+ text.length > REDUNDANT_PREVIEW_SEGMENT_MAX_CHARS ||
571
+ seen.has(text)) {
572
+ continue;
573
+ }
574
+ seen.add(text);
575
+ segments.push(text);
576
+ }
577
+ if (segments.length > 0)
578
+ return segments;
579
+ const fallback = normalizeWhitespace(element.textContent || '');
580
+ return fallback ? [fallback] : [];
581
+ }
582
+ function isHostnameLike(value) {
583
+ return /^[a-z0-9.-]+\.[a-z]{2,}$/i.test(value);
584
+ }
585
+ function hasPreviewMedia(element) {
586
+ return element.querySelector('svg,canvas') !== null;
587
+ }
588
+ function isRedundantCodePreview(preview, codeContainer) {
589
+ if (preview.tagName === 'FIGCAPTION' ||
590
+ preview.querySelector('a[href],button,input,select,textarea,form,video,audio,iframe,table,ul,ol,blockquote') !== null) {
591
+ return false;
592
+ }
593
+ const segments = collectLeafTextSegments(preview);
594
+ if (segments.length === 0 ||
595
+ segments.length > REDUNDANT_PREVIEW_MAX_SEGMENTS ||
596
+ segments.some((segment) => segment.length > REDUNDANT_PREVIEW_SEGMENT_MAX_CHARS)) {
597
+ return false;
598
+ }
599
+ const codeText = normalizeWhitespace(codeContainer.textContent || '');
600
+ if (!codeText)
601
+ return false;
602
+ const matchingSegments = segments.filter((segment) => codeText.includes(segment));
603
+ if (matchingSegments.length === segments.length)
604
+ return true;
605
+ return ((hasPreviewMedia(preview) ||
606
+ segments.some((segment) => isHostnameLike(segment))) &&
607
+ matchingSegments.length > 0 &&
608
+ segments.every((segment) => segment.length <= REDUNDANT_PREVIEW_SEGMENT_MAX_CHARS));
609
+ }
610
+ function pruneFigurePreviewPanes(document) {
611
+ for (const figure of document.querySelectorAll('figure')) {
612
+ const directChildren = Array.from(figure.children);
613
+ const codeChild = directChildren.find((child) => hasDirectPreDescendant(child));
614
+ if (!codeChild)
615
+ continue;
616
+ for (const child of directChildren) {
617
+ if (child === codeChild || child.tagName === 'FIGCAPTION')
618
+ continue;
619
+ if (isRedundantCodePreview(child, codeChild))
620
+ child.remove();
621
+ }
622
+ }
623
+ }
624
+ function isDemoInstructionBlock(element) {
625
+ if (element.querySelector('a[href],pre,code,table,ul,ol,blockquote,figure,h1,h2,h3,h4,h5,h6') !== null) {
626
+ return false;
627
+ }
628
+ const text = normalizeWhitespace(element.textContent || '');
629
+ if (text.length === 0 ||
630
+ text.length > INLINE_DEMO_INSTRUCTION_MAX_CHARS ||
631
+ /[.!?]$/.test(text)) {
632
+ return false;
633
+ }
634
+ return collectLeafTextSegments(element).length <= 3;
635
+ }
636
+ function pruneDemoInstructionBlocks(document) {
637
+ for (const container of document.querySelectorAll('div,section,article')) {
638
+ const children = Array.from(container.children);
639
+ const figureIndex = children.findIndex((child) => child.tagName === 'FIGURE' && child.querySelector('pre') !== null);
640
+ if (figureIndex <= 0)
641
+ continue;
642
+ for (let i = 0; i < figureIndex; i++) {
643
+ const child = children[i];
644
+ if (child && isDemoInstructionBlock(child))
645
+ child.remove();
646
+ }
647
+ }
648
+ }
649
+ function normalizeHighlightedCodeLines(document) {
650
+ for (const code of document.querySelectorAll('pre > code')) {
651
+ const directChildren = Array.from(code.children);
652
+ if (directChildren.length < 2)
653
+ continue;
654
+ const directSpans = directChildren.filter((child) => child.tagName === 'SPAN');
655
+ if (directSpans.length !== directChildren.length)
656
+ continue;
657
+ const hasLineClass = directSpans.some((child) => (child.getAttribute('class') ?? '').split(/\s+/).includes('line'));
658
+ const hasNewlineNode = Array.from(code.childNodes).some((node) => node.nodeType === 3 && /[\r\n]/.test(node.textContent ?? ''));
659
+ if (hasNewlineNode || !hasLineClass)
660
+ continue;
661
+ for (let i = 0; i < directSpans.length - 1; i++) {
662
+ const current = directSpans[i];
663
+ const next = current?.nextSibling;
664
+ if (next?.nodeType === 3 && (next.textContent ?? '').startsWith('\n')) {
665
+ continue;
666
+ }
667
+ current?.after(document.createTextNode('\n'));
668
+ }
669
+ }
670
+ }
671
+ function cleanCodeExamples(document) {
672
+ pruneFigurePreviewPanes(document);
673
+ pruneDemoInstructionBlocks(document);
674
+ normalizeHighlightedCodeLines(document);
675
+ }
509
676
  function separateAdjacentInlineElements(document) {
510
677
  const badges = document.querySelectorAll('span.chakra-badge, [data-scope="badge"], [class*="badge"]');
511
678
  for (const badge of badges) {
@@ -524,6 +691,7 @@ export function prepareDocumentForMarkdown(document, baseUrl, signal) {
524
691
  }
525
692
  stripNoise(document, context, signal);
526
693
  stripTabTriggers(document);
694
+ cleanCodeExamples(document);
527
695
  separateAdjacentInlineElements(document);
528
696
  flattenTableCellBreaks(document);
529
697
  escapeTableCellPipes(document);
@@ -552,6 +720,7 @@ function normalizeTableStructure(document) {
552
720
  }
553
721
  }
554
722
  }
723
+ hoistNestedRows(table);
555
724
  }
556
725
  }
557
726
  function flattenTableCellBreaks(document) {
@@ -1,4 +1,5 @@
1
1
  interface CleanupOptions {
2
+ preserveEmptyHeadings?: boolean;
2
3
  signal?: AbortSignal;
3
4
  url?: string;
4
5
  }
@@ -1 +1 @@
1
- {"version":3,"file":"md-cleanup.d.ts","sourceRoot":"","sources":["../../src/lib/md-cleanup.ts"],"names":[],"mappings":"AAmEA,UAAU,cAAc;IACtB,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA6VD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC3C,MAAM,CAuCR;AAWD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,CAUR"}
1
+ {"version":3,"file":"md-cleanup.d.ts","sourceRoot":"","sources":["../../src/lib/md-cleanup.ts"],"names":[],"mappings":"AAwEA,UAAU,cAAc;IACtB,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA6cD;;;;GAIG;AACH,wBAAgB,oBAAoB,CAClC,OAAO,EAAE,MAAM,EACf,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,GAC3C,MAAM,CAuCR;AAWD,wBAAgB,wBAAwB,CACtC,OAAO,EAAE,MAAM,EACf,OAAO,CAAC,EAAE,cAAc,GACvB,MAAM,CAmBR"}
@@ -22,6 +22,7 @@ const REGEX = {
22
22
  HEADING_STRICT: /^#{1,6}\s+/m,
23
23
  EMPTY_HEADING_LINE: /^#{1,6}[ \t\u00A0]*$/,
24
24
  ANCHOR_ONLY_HEADING: /^#{1,6}\s+\[[^\]]+\]\(#[^)]+\)\s*$/,
25
+ HEADING_TRAILING_PERMALINK: /^(#{1,6}\s+.+?)\s*\[(?:#|¶|§|¤|🔗)\]\(#[^)]+\)\s*$/gmu,
25
26
  FENCE_START: FENCE_PATTERN,
26
27
  LIST_MARKER: /^(?:[-*+])\s/m,
27
28
  TOC_LINK: /^- \[[^\]]+\]\(#[^)]+\)\s*$/,
@@ -36,7 +37,10 @@ const REGEX = {
36
37
  HEADING_CODE_BLOCK: /(^#{1,6}\s+\w+)```/gm,
37
38
  SPACING_LINK_FIX: /\]\(([^)]+)\)\[/g,
38
39
  SPACING_ADJ_COMBINED: /(?:\]\([^)]+\)|`[^`]+`)(?=[A-Za-z0-9])/g,
40
+ SPACING_CODE_PAD_BEFORE: /(\S)[ \t]{2,}(?=`[^`\n]+`)/g,
41
+ SPACING_CODE_PAD_AFTER: /(`[^`\n]+`)[ \t]{2,}(?=\S)/g,
39
42
  SPACING_CODE_DASH: /(`[^`]+`)\s*\\-\s*/g,
43
+ SPACING_ESCAPED_DASH: /(?<=[\w)\]`])\s*\\-\s*(?=[A-Za-z0-9([])/g,
40
44
  SPACING_ESCAPES: /\\([[\].])/g,
41
45
  SPACING_LIST_NUM_COMBINED: /^((?![-*+] |\d+\. |[ \t]).+)\n((?:[-*+]|\d+\.) )/gm,
42
46
  PUNCT_ONLY_LIST_ARTIFACT: /^(?:[-*+]|\d+\.)\s*(?:\\[-*+|/]|[-*+|/])(?:\s+(?:\\[-*+|/]|[-*+|/]))*\s*$/gm,
@@ -72,6 +76,14 @@ function hasFollowingContent(lines, startIndex) {
72
76
  }
73
77
  return false;
74
78
  }
79
+ function findNextNonBlankLine(lines, startIndex) {
80
+ for (let i = startIndex + 1; i < Math.min(lines.length, startIndex + HAS_FOLLOWING_LOOKAHEAD); i++) {
81
+ const line = lines[i];
82
+ if (!isBlank(line))
83
+ return line?.trim();
84
+ }
85
+ return undefined;
86
+ }
75
87
  function stripAnchorOnlyHeading(line) {
76
88
  return line.replace(/^(#{1,6})\s+\[([^\]]+)\]\(#[^)]+\)\s*$/, '$1 $2');
77
89
  }
@@ -191,6 +203,11 @@ function tryPromoteOrphan(lines, i, trimmed) {
191
203
  const isSpecialPrefix = SPECIAL_PREFIXES.test(trimmed);
192
204
  if (!isSpecialPrefix && !hasFollowingContent(lines, i))
193
205
  return null;
206
+ if (!isSpecialPrefix) {
207
+ const nextLine = findNextNonBlankLine(lines, i);
208
+ if (nextLine && REGEX.HEADING_MARKER.test(nextLine))
209
+ return null;
210
+ }
194
211
  return `${prefix}${trimmed}`;
195
212
  }
196
213
  function shouldSkipAsToc(lines, i, trimmed, removeToc, options) {
@@ -205,13 +222,16 @@ function shouldSkipAsToc(lines, i, trimmed, removeToc, options) {
205
222
  throwIfAborted(options?.signal, options?.url ?? '', 'markdown:cleanup:toc');
206
223
  return skipTocLines(lines, i + 1);
207
224
  }
208
- function normalizePreprocessLine(lines, i, trimmed, line) {
225
+ function normalizePreprocessLine(lines, i, trimmed, line, options) {
209
226
  if (REGEX.EMPTY_HEADING_LINE.test(trimmed))
210
227
  return null;
211
228
  if (!REGEX.ANCHOR_ONLY_HEADING.test(trimmed))
212
229
  return line;
213
- if (!hasFollowingContent(lines, i))
214
- return null;
230
+ if (!hasFollowingContent(lines, i)) {
231
+ return options?.preserveEmptyHeadings
232
+ ? stripAnchorOnlyHeading(trimmed)
233
+ : null;
234
+ }
215
235
  return stripAnchorOnlyHeading(trimmed);
216
236
  }
217
237
  function maybeSkipTocBlock(lines, i, trimmed, options) {
@@ -235,7 +255,7 @@ function preprocessLines(lines, options) {
235
255
  if (currentLine === undefined)
236
256
  continue;
237
257
  const trimmed = currentLine.trim();
238
- const normalizedLine = normalizePreprocessLine(lines, i, trimmed, currentLine);
258
+ const normalizedLine = normalizePreprocessLine(lines, i, trimmed, currentLine, options);
239
259
  if (normalizedLine === null)
240
260
  continue;
241
261
  const tocSkip = maybeSkipTocBlock(lines, i, trimmed, options);
@@ -269,21 +289,91 @@ function removeSkipLinks(text) {
269
289
  function normalizeInlineCodeTokens(text) {
270
290
  return text.replace(/`([^`\n]+)`/g, (match, inner) => {
271
291
  const trimmed = inner.trim();
272
- if (trimmed === inner)
273
- return match;
274
292
  if (!/[A-Za-z0-9]/.test(trimmed))
275
293
  return match;
276
294
  const parts = /^(\s*)(.*?)(\s*)$/.exec(inner);
277
295
  if (!parts)
278
296
  return match;
279
- return `${parts[1] ?? ''}\`${parts[2] ?? ''}\`${parts[3] ?? ''}`;
297
+ const normalized = collapseQualifiedIdentifierSpacing(parts[2] ?? '');
298
+ if (trimmed === inner && normalized === inner)
299
+ return match;
300
+ return `${parts[1] ?? ''}\`${normalized}\`${parts[3] ?? ''}`;
280
301
  });
281
302
  }
303
+ function collapseQualifiedIdentifierSpacing(text) {
304
+ let result = text;
305
+ for (let i = 0; i < PROPERTY_FIX_MAX_PASSES; i++) {
306
+ const next = result.replace(/\b([A-Za-z_$][\w$]*)\.\s+(?=[A-Za-z_$<])/g, '$1.');
307
+ if (next === result)
308
+ break;
309
+ result = next;
310
+ }
311
+ return result;
312
+ }
313
+ function normalizeMarkdownLinkText(text) {
314
+ const normalized = collapseQualifiedIdentifierSpacing(text.replace(/\\`/g, '`').replace(/\\</g, '<').replace(/\\>/g, '>'));
315
+ return normalized.replace(/</g, '\\<').replace(/>/g, '\\>');
316
+ }
317
+ function normalizeMarkdownLinkLabels(text) {
318
+ return text.replace(/\[([^\]]+)\]\(([^)]+)\)/g, (_match, linkText, url) => `[${normalizeMarkdownLinkText(linkText)}](${url})`);
319
+ }
320
+ function collapseInlineCodePadding(text) {
321
+ return text
322
+ .replace(/(\S)[ \t]{2,}(?=`[^`\n]+`)/g, '$1 ')
323
+ .replace(/(`[^`\n]+`)[ \t]{2,}(?=\S)/g, '$1 ');
324
+ }
325
+ function escapeAngleBracketsInMarkdownTables(text) {
326
+ return text.replace(/^(?!\|\s*[-: ]+\|)(\|.*\|)\s*$/gm, (line) => line
327
+ .replace(/<\/([A-Za-z][A-Za-z0-9-]*)>/g, '\\</$1\\>')
328
+ .replace(/<([A-Za-z][A-Za-z0-9-]*)>/g, '\\<$1\\>'));
329
+ }
330
+ function stripTrailingHeadingPermalinks(text) {
331
+ return text
332
+ .replace(REGEX.HEADING_TRAILING_PERMALINK, '$1')
333
+ .replace(/^(#{1,6})\s{2,}/gm, '$1 ')
334
+ .replace(/^(#{1,6}\s+.*?)[ \t]+$/gm, '$1');
335
+ }
336
+ function getHeadingInfo(line) {
337
+ const match = /^(#{1,6})\s+/.exec(line.trim());
338
+ if (!match)
339
+ return null;
340
+ return { level: match[1]?.length ?? 0 };
341
+ }
342
+ function removeEmptyHeadingSections(text) {
343
+ const lines = text.split('\n');
344
+ const kept = [];
345
+ for (let i = 0; i < lines.length; i++) {
346
+ const line = lines[i] ?? '';
347
+ const heading = getHeadingInfo(line);
348
+ if (!heading) {
349
+ kept.push(line);
350
+ continue;
351
+ }
352
+ let nextIndex = i + 1;
353
+ while (nextIndex < lines.length && isBlank(lines[nextIndex])) {
354
+ nextIndex += 1;
355
+ }
356
+ const nextLine = lines[nextIndex];
357
+ if (nextLine === undefined) {
358
+ kept.push(line);
359
+ continue;
360
+ }
361
+ const nextHeading = getHeadingInfo(nextLine);
362
+ if (nextHeading && nextHeading.level <= heading.level) {
363
+ continue;
364
+ }
365
+ kept.push(line);
366
+ }
367
+ return kept.join('\n').replace(REGEX.DOUBLE_NEWLINE_REDUCER, '\n\n');
368
+ }
282
369
  function normalizeMarkdownSpacing(text) {
283
370
  let result = text
284
- .replace(REGEX.SPACING_LINK_FIX, ']($1)\n\n[')
371
+ .replace(REGEX.SPACING_LINK_FIX, ']($1) [')
285
372
  .replace(REGEX.SPACING_ADJ_COMBINED, '$& ')
373
+ .replace(REGEX.SPACING_CODE_PAD_BEFORE, '$1 ')
374
+ .replace(REGEX.SPACING_CODE_PAD_AFTER, '$1 ')
286
375
  .replace(REGEX.SPACING_CODE_DASH, '$1 - ')
376
+ .replace(REGEX.SPACING_ESCAPED_DASH, ' - ')
287
377
  .replace(REGEX.SPACING_ESCAPES, '$1')
288
378
  .replace(REGEX.SPACING_LIST_NUM_COMBINED, '$1\n\n$2')
289
379
  .replace(REGEX.PUNCT_ONLY_LIST_ARTIFACT, '')
@@ -292,9 +382,9 @@ function normalizeMarkdownSpacing(text) {
292
382
  result = result.replace(/([.!?:;])([A-Z])/g, '$1 $2');
293
383
  // Trim whitespace around token-like inline code spans.
294
384
  result = normalizeInlineCodeTokens(result);
295
- // Unescape backticks inside markdown link text
296
- result = result.replace(/\[([^\]]*\\`[^\]]*)\]\(([^)]+)\)/g, (_match, linkText, url) => `[${linkText.replace(/\\`/g, '`')}](${url})`);
297
- result = result.replace(/\[([^\]]*<[^\]]*)\]\(([^)]+)\)/g, (_match, linkText, url) => `[${linkText.replace(/</g, '\\<').replace(/>/g, '\\>')}](${url})`);
385
+ result = collapseInlineCodePadding(result);
386
+ result = normalizeMarkdownLinkLabels(result);
387
+ result = escapeAngleBracketsInMarkdownTables(result);
298
388
  return normalizeNestedListIndentation(result);
299
389
  }
300
390
  function fixConcatenatedProperties(text) {
@@ -325,7 +415,8 @@ function applyGlobalRegexes(text, options) {
325
415
  checkAbort('markdown:cleanup:spacing');
326
416
  result = normalizeMarkdownSpacing(result);
327
417
  checkAbort('markdown:cleanup:properties');
328
- return fixConcatenatedProperties(result);
418
+ result = fixConcatenatedProperties(result);
419
+ return stripTrailingHeadingPermalinks(result);
329
420
  }
330
421
  function normalizeNestedListIndentation(text) {
331
422
  return text.replace(REGEX.NESTED_LIST_INDENT, (match, spaces, marker) => {
@@ -386,6 +477,10 @@ export function cleanupMarkdownArtifacts(content, options) {
386
477
  if (!content)
387
478
  return '';
388
479
  throwIfAborted(options?.signal, options?.url ?? '', 'markdown:cleanup:begin');
389
- const result = processFencedContent(content, (text) => processTextBuffer(text.split('\n'), options)).trim();
480
+ let result = processFencedContent(content, (text) => processTextBuffer(text.split('\n'), options)).trim();
481
+ if (!options?.preserveEmptyHeadings) {
482
+ throwIfAborted(options?.signal, options?.url ?? '', 'markdown:cleanup:empty-headings');
483
+ result = removeEmptyHeadingSections(result);
484
+ }
390
485
  return stripLeadingBreadcrumbNoise(result);
391
486
  }
package/dist/schemas.d.ts CHANGED
@@ -1,23 +1,5 @@
1
1
  import { z } from 'zod';
2
2
  import type { ExtractedMetadata } from './transform/types.js';
3
- export declare const METADATA_LIMITS: {
4
- readonly title: 512;
5
- readonly description: 2048;
6
- readonly author: 512;
7
- readonly image: 2048;
8
- readonly favicon: 2048;
9
- readonly publishedAt: 64;
10
- readonly modifiedAt: 64;
11
- };
12
- export declare const extractedMetadataSchema: z.ZodObject<{
13
- title: z.ZodOptional<z.ZodString>;
14
- description: z.ZodOptional<z.ZodString>;
15
- author: z.ZodOptional<z.ZodString>;
16
- image: z.ZodOptional<z.ZodString>;
17
- favicon: z.ZodOptional<z.ZodString>;
18
- publishedAt: z.ZodOptional<z.ZodString>;
19
- modifiedAt: z.ZodOptional<z.ZodString>;
20
- }, z.core.$strict>;
21
3
  export declare function normalizeExtractedMetadata(value: unknown): ExtractedMetadata | undefined;
22
4
  export declare function normalizePageTitle(value: unknown): string | undefined;
23
5
  export declare const cachedPayloadSchema: z.ZodObject<{
@@ -1 +1 @@
1
- {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAI9D,eAAO,MAAM,eAAe;;;;;;;;CAQlB,CAAC;AAiCX,eAAO,MAAM,uBAAuB;;;;;;;;kBAQlC,CAAC;AAgBH,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,SAAS,CAQ/B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;AAUD,eAAO,MAAM,mBAAmB;;;;;iBAqB5B,CAAC;AAEL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,mBAAmB;;;kBAU9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;kBAqC/B,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAkBpE;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,GACrB,MAAM,GAAG,IAAI,CAEf"}
1
+ {"version":3,"file":"schemas.d.ts","sourceRoot":"","sources":["../src/schemas.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAIxB,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAqE9D,wBAAgB,0BAA0B,CACxC,KAAK,EAAE,OAAO,GACb,iBAAiB,GAAG,SAAS,CAQ/B;AAED,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAErE;AAUD,eAAO,MAAM,mBAAmB;;;;;iBAqB5B,CAAC;AAEL,MAAM,MAAM,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEhE,eAAO,MAAM,mBAAmB;;;kBAU9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;;;;;kBAqC/B,CAAC;AAEH,wBAAgB,kBAAkB,CAAC,GAAG,EAAE,MAAM,GAAG,aAAa,GAAG,IAAI,CAkBpE;AAED,wBAAgB,2BAA2B,CACzC,OAAO,EAAE,aAAa,GACrB,MAAM,GAAG,IAAI,CAEf"}
package/dist/schemas.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import { z } from 'zod';
2
2
  import { config, logWarn } from './lib/core.js';
3
3
  const URL_FIELD_MAX_LENGTH = 2048;
4
- export const METADATA_LIMITS = {
4
+ const METADATA_LIMITS = {
5
5
  title: 512,
6
6
  description: 2048,
7
7
  author: 512,
@@ -29,7 +29,7 @@ const normalizedMetadataSchema = z.object({
29
29
  publishedAt: normalizedMetadataField(METADATA_LIMITS.publishedAt),
30
30
  modifiedAt: normalizedMetadataField(METADATA_LIMITS.modifiedAt),
31
31
  });
32
- export const extractedMetadataSchema = z.strictObject({
32
+ const extractedMetadataSchema = z.strictObject({
33
33
  title: metadataTextField(METADATA_LIMITS.title).optional(),
34
34
  description: metadataTextField(METADATA_LIMITS.description).optional(),
35
35
  author: metadataTextField(METADATA_LIMITS.author).optional(),
@@ -1 +1 @@
1
- {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/tasks/manager.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/tasks/manager.ts"],"names":[],"mappings":"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"}
@@ -15,9 +15,51 @@ const DEFAULT_PAGE_SIZE = 50;
15
15
  const CLEANUP_INTERVAL_MS = 60_000;
16
16
  const MAX_CURSOR_LENGTH = 256;
17
17
  const RESULT_DELIVERY_GRACE_MS = 10_000;
18
+ const TASK_STATUS_VALUES = new Set([
19
+ 'working',
20
+ 'input_required',
21
+ 'completed',
22
+ 'failed',
23
+ 'cancelled',
24
+ ]);
25
+ const TASK_STATUS_TRANSITIONS = {
26
+ working: new Set([
27
+ 'working',
28
+ 'input_required',
29
+ 'completed',
30
+ 'failed',
31
+ 'cancelled',
32
+ ]),
33
+ input_required: new Set([
34
+ 'input_required',
35
+ 'working',
36
+ 'completed',
37
+ 'failed',
38
+ 'cancelled',
39
+ ]),
40
+ completed: new Set(['completed']),
41
+ failed: new Set(['failed']),
42
+ cancelled: new Set(['cancelled']),
43
+ };
18
44
  function isTerminalStatus(status) {
19
45
  return (status === 'completed' || status === 'failed' || status === 'cancelled');
20
46
  }
47
+ function isTaskStatus(value) {
48
+ return (typeof value === 'string' && TASK_STATUS_VALUES.has(value));
49
+ }
50
+ function resolveNextTaskStatus(task, updates) {
51
+ const nextStatus = updates.status;
52
+ if (nextStatus === undefined)
53
+ return task.status;
54
+ if (!isTaskStatus(nextStatus)) {
55
+ throw new McpError(ErrorCode.InternalError, `Invalid task status '${String(nextStatus)}'`);
56
+ }
57
+ const allowedTransitions = TASK_STATUS_TRANSITIONS[task.status];
58
+ if (!allowedTransitions.has(nextStatus)) {
59
+ throw new McpError(ErrorCode.InternalError, `Invalid task status transition: '${task.status}' -> '${nextStatus}'`);
60
+ }
61
+ return nextStatus;
62
+ }
21
63
  function normalizeTaskTtl(ttl) {
22
64
  if (!Number.isFinite(ttl))
23
65
  return DEFAULT_TTL_MS;
@@ -154,7 +196,11 @@ class TaskManager {
154
196
  return;
155
197
  if (isTerminalStatus(task.status))
156
198
  return;
157
- this.applyTaskUpdate(task, updates);
199
+ const nextStatus = resolveNextTaskStatus(task, updates);
200
+ this.applyTaskUpdate(task, {
201
+ ...updates,
202
+ ...(updates.status === undefined ? {} : { status: nextStatus }),
203
+ });
158
204
  this.notifyWaiters(task);
159
205
  }
160
206
  cancelTask(taskId, ownerKey) {
@@ -1 +1 @@
1
- {"version":3,"file":"fetch-url.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;AAMvB,KAAK,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEzD,UAAU,gBAAgB;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,cAAc,CAAC;AAuN/C,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAK3B;AAsBD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAC5E,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC7D,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAmBvD;AAwBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqCrD"}
1
+ {"version":3,"file":"fetch-url.d.ts","sourceRoot":"","sources":["../../src/tools/fetch-url.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACzE,OAAO,KAAK,EACV,YAAY,EAEb,MAAM,oCAAoC,CAAC;AAE5C,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAyBxB,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EACL,mBAAmB,EAIpB,MAAM,eAAe,CAAC;AAMvB,KAAK,aAAa,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,mBAAmB,CAAC,CAAC;AAEzD,UAAU,gBAAgB;IACxB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC;IACvB,OAAO,EAAE,YAAY,EAAE,CAAC;IACxB,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,SAAS,CAAC;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;CACnB;AAED,eAAO,MAAM,mBAAmB,cAAc,CAAC;AA4N/C,wBAAsB,mBAAmB,CACvC,KAAK,EAAE,aAAa,EACpB,KAAK,CAAC,EAAE,gBAAgB,GACvB,OAAO,CAAC,gBAAgB,CAAC,CAQ3B;AAsBD;;;;;;GAMG;AACH,wBAAgB,2BAA2B,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,EAC5E,OAAO,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,GAC7D,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,KAAK,OAAO,CAAC,OAAO,CAAC,CAmBvD;AAwBD,wBAAgB,aAAa,CAAC,MAAM,EAAE,SAAS,GAAG,IAAI,CAqCrD"}
@@ -113,11 +113,12 @@ function buildResponse(pipeline, inlineResult, inputUrl) {
113
113
  ];
114
114
  const validation = fetchUrlOutputSchema.safeParse(structuredContent);
115
115
  if (!validation.success) {
116
+ const issues = formatZodError(validation.error);
116
117
  logWarn('Tool output schema validation failed', {
117
118
  url: inputUrl,
118
- issues: formatZodError(validation.error),
119
+ issues,
119
120
  });
120
- return { content };
121
+ throw new McpError(ErrorCode.InternalError, 'fetch-url produced output that does not match its declared outputSchema', { issues });
121
122
  }
122
123
  return { content, structuredContent };
123
124
  }
@@ -173,6 +174,9 @@ async function executeFetch(input, extra) {
173
174
  export async function fetchUrlToolHandler(input, extra) {
174
175
  return executeFetch(input, extra).catch((error) => {
175
176
  logError('fetch-url tool error', toError(error));
177
+ if (error instanceof McpError) {
178
+ throw error;
179
+ }
176
180
  return handleToolError(error, input.url, 'Failed to fetch URL');
177
181
  });
178
182
  }
@@ -20,14 +20,6 @@ export declare function htmlToMarkdown(html: string, metadata?: MetadataBlock, o
20
20
  export declare function isExtractionSufficient(article: ExtractedArticle | null, originalHtmlOrDocument: string | Document): boolean;
21
21
  export declare function determineContentExtractionSource(article: ExtractedArticle | null): article is ExtractedArticle;
22
22
  export declare function createContentMetadataBlock(url: string, article: ExtractedArticle | null, extractedMeta: ExtractedMetadata, shouldExtractFromArticle: boolean, includeMetadata: boolean): MetadataBlock | undefined;
23
- declare function findContentRoot(document: Document): string | undefined;
24
- declare function findPrimaryHeading(document: Document): string | undefined;
25
- declare function isGithubRepositoryRootUrl(url: string): boolean;
26
- export declare const TransformHeuristics: {
27
- readonly findContentRoot: typeof findContentRoot;
28
- readonly findPrimaryHeading: typeof findPrimaryHeading;
29
- readonly isGithubRepositoryRootUrl: typeof isGithubRepositoryRootUrl;
30
- };
31
23
  export declare function transformHtmlToMarkdownInProcess(html: string, url: string, options: TransformOptions): MarkdownTransformResult;
32
24
  interface TransformPoolStats {
33
25
  queueDepth: number;
@@ -1 +1 @@
1
- {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/transform/transform.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transform.d.ts","sourceRoot":"","sources":["../../src/transform/transform.ts"],"names":[],"mappings":"AAgDA,OAAO,KAAK,EACV,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,aAAa,EACb,gBAAgB,EAChB,qBAAqB,EAEtB,MAAM,YAAY,CAAC;AAqCpB,UAAU,WAAW;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;CACnB;AAqJD,wBAAgB,mBAAmB,CACjC,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,MAAM,EACb,MAAM,CAAC,EAAE,WAAW,GACnB,qBAAqB,GAAG,IAAI,CAE9B;AAED,wBAAgB,iBAAiB,CAC/B,OAAO,EAAE,qBAAqB,GAAG,IAAI,EACrC,OAAO,CAAC,EAAE;IAAE,SAAS,CAAC,EAAE,OAAO,CAAA;CAAE,GAChC,MAAM,CAER;AAwYD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,GAAE;IAAE,cAAc,CAAC,EAAE,OAAO,CAAC;IAAC,MAAM,CAAC,EAAE,WAAW,CAAA;CAExD,GACA,gBAAgB,CAGlB;AAgLD,wBAAgB,cAAc,CAC5B,IAAI,EAAE,MAAM,EACZ,QAAQ,CAAC,EAAE,aAAa,EACxB,OAAO,CAAC,EAAE;IACR,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B,GACA,MAAM,CAsBR;AAuJD,wBAAgB,sBAAsB,CACpC,OAAO,EAAE,gBAAgB,GAAG,IAAI,EAChC,sBAAsB,EAAE,MAAM,GAAG,QAAQ,GACxC,OAAO,CAQT;AAiED,wBAAgB,gCAAgC,CAC9C,OAAO,EAAE,gBAAgB,GAAG,IAAI,GAC/B,OAAO,IAAI,gBAAgB,CAE7B;AAED,wBAAgB,0BAA0B,CACxC,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,gBAAgB,GAAG,IAAI,EAChC,aAAa,EAAE,iBAAiB,EAChC,wBAAwB,EAAE,OAAO,EACjC,eAAe,EAAE,OAAO,GACvB,aAAa,GAAG,SAAS,CAuB3B;AAo8BD,wBAAgB,gCAAgC,CAC9C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,gBAAgB,GACxB,uBAAuB,CAqCzB;AAaD,UAAU,kBAAkB;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,IAAI,kBAAkB,GAAG,IAAI,CAEjE;AAED,wBAAsB,2BAA2B,IAAI,OAAO,CAAC,IAAI,CAAC,CAEjE;AAED,KAAK,yBAAyB,GAAG,gBAAgB,GAAG;IAAE,QAAQ,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAkH1E,wBAAsB,uBAAuB,CAC3C,IAAI,EAAE,MAAM,EACZ,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,gBAAgB,GACxB,OAAO,CAAC,uBAAuB,CAAC,CAElC;AAED,wBAAsB,yBAAyB,CAC7C,UAAU,EAAE,UAAU,EACtB,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,yBAAyB,GACjC,OAAO,CAAC,uBAAuB,CAAC,CAElC"}
@@ -553,7 +553,9 @@ function translateHtmlToMarkdown(params) {
553
553
  throwIfAborted(signal, url, 'markdown:cleaned');
554
554
  const content = stageTracker.run(url, 'markdown:translate', () => translateHtmlFragmentToMarkdown(cleanedHtml));
555
555
  throwIfAborted(signal, url, 'markdown:translated');
556
- const cleaned = cleanupMarkdownArtifacts(content, signal ? { signal, url } : { url });
556
+ const cleaned = cleanupMarkdownArtifacts(content, signal
557
+ ? { preserveEmptyHeadings: true, signal, url }
558
+ : { preserveEmptyHeadings: true, url });
557
559
  return url ? resolveRelativeUrls(cleaned, url, signal) : cleaned;
558
560
  }
559
561
  function appendMetadataFooter(content, metadata, url) {
@@ -815,6 +817,22 @@ const PRIMARY_HEADING_ROOT_SELECTORS = [
815
817
  '.entry-content',
816
818
  '[itemprop="text"]',
817
819
  ];
820
+ function normalizeSyntheticTitleToken(value) {
821
+ return (value ?? '').replace(/\s+/g, ' ').trim().toLowerCase();
822
+ }
823
+ function shouldPreferPrimaryHeadingTitle(primaryHeading, title) {
824
+ const primary = normalizeSyntheticTitleToken(primaryHeading);
825
+ if (!primary)
826
+ return false;
827
+ const normalizedTitle = normalizeSyntheticTitleToken(title);
828
+ if (!normalizedTitle)
829
+ return true;
830
+ if (normalizedTitle === primary)
831
+ return true;
832
+ return normalizedTitle
833
+ .split(/\s*(?:[-|:•·]|–|—)\s*/u)
834
+ .some((part) => part === primary);
835
+ }
818
836
  function findContentRoot(document) {
819
837
  for (const selector of CONTENT_ROOT_SELECTORS) {
820
838
  const element = document.querySelector(selector);
@@ -829,17 +847,31 @@ function findContentRoot(document) {
829
847
  return undefined;
830
848
  }
831
849
  function findPrimaryHeading(document) {
832
- for (const selector of PRIMARY_HEADING_ROOT_SELECTORS) {
833
- const root = document.querySelector(selector);
834
- if (!root)
835
- continue;
836
- const heading = root.querySelector('h1, h2');
850
+ for (const headingSelector of ['[data-title="true"]', 'h1']) {
851
+ const heading = document.querySelector(headingSelector);
837
852
  if (!heading)
838
853
  continue;
839
854
  const text = heading.textContent.trim();
840
855
  if (text)
841
856
  return text;
842
857
  }
858
+ for (const selector of PRIMARY_HEADING_ROOT_SELECTORS) {
859
+ const root = document.querySelector(selector);
860
+ if (!root)
861
+ continue;
862
+ for (const headingSelector of [
863
+ '[data-title="true"]',
864
+ 'h1',
865
+ 'h2',
866
+ ]) {
867
+ const heading = root.querySelector(headingSelector);
868
+ if (!heading)
869
+ continue;
870
+ const text = heading.textContent.trim();
871
+ if (text)
872
+ return text;
873
+ }
874
+ }
843
875
  return undefined;
844
876
  }
845
877
  function countMatchingElements(root, selector) {
@@ -893,7 +925,7 @@ function isGithubRepositoryRootUrl(url) {
893
925
  }
894
926
  return parsed.pathname.split('/').filter(Boolean).length === 2;
895
927
  }
896
- export const TransformHeuristics = {
928
+ const TransformHeuristics = {
897
929
  findContentRoot,
898
930
  findPrimaryHeading,
899
931
  isGithubRepositoryRootUrl,
@@ -971,39 +1003,56 @@ function shouldUseArticleContent(article, document) {
971
1003
  function buildContentSource(params) {
972
1004
  const { html, url, article, extractedMeta, includeMetadata, useArticleContent, document, truncated, signal, } = params;
973
1005
  const metadata = createContentMetadataBlock(url, article, extractedMeta, useArticleContent, includeMetadata);
1006
+ const preparedDocument = document;
1007
+ let primaryHeading = document
1008
+ ? TransformHeuristics.findPrimaryHeading(document)
1009
+ : undefined;
1010
+ if (preparedDocument) {
1011
+ prepareDocumentForMarkdown(preparedDocument, url, signal);
1012
+ primaryHeading =
1013
+ TransformHeuristics.findPrimaryHeading(preparedDocument) ??
1014
+ primaryHeading;
1015
+ }
974
1016
  const base = {
975
1017
  favicon: extractedMeta.favicon,
976
1018
  metadata,
977
1019
  extractedMetadata: extractedMeta,
978
1020
  truncated,
979
- primaryHeading: document
980
- ? TransformHeuristics.findPrimaryHeading(document)
981
- : undefined,
1021
+ primaryHeading,
982
1022
  originalHtml: html,
983
1023
  };
984
1024
  if (useArticleContent && article) {
985
1025
  const { document: articleDoc } = parseHTML(`<!DOCTYPE html><html><body>${article.content}</body></html>`);
986
1026
  prepareDocumentForMarkdown(articleDoc, url, signal);
987
- const preferPrimaryHeading = TransformHeuristics.isGithubRepositoryRootUrl(url);
1027
+ const articleTitle = article.title !== undefined
1028
+ ? normalizeDocumentTitle(article.title, url)
1029
+ : extractedMeta.title;
1030
+ const preferPrimaryHeading = TransformHeuristics.isGithubRepositoryRootUrl(url) ||
1031
+ shouldPreferPrimaryHeadingTitle(base.primaryHeading, articleTitle);
1032
+ const resolvedTitle = (preferPrimaryHeading ? base.primaryHeading : undefined) ?? articleTitle;
988
1033
  return {
989
1034
  ...base,
990
1035
  sourceHtml: articleDoc.body.innerHTML,
991
- title: (preferPrimaryHeading ? base.primaryHeading : undefined) ??
992
- (article.title !== undefined
993
- ? normalizeDocumentTitle(article.title, url)
994
- : undefined),
1036
+ title: resolvedTitle,
1037
+ suppressSyntheticFavicon: normalizeSyntheticTitleToken(resolvedTitle) ===
1038
+ normalizeSyntheticTitleToken(base.primaryHeading),
995
1039
  skipNoiseRemoval: true,
996
1040
  };
997
1041
  }
998
1042
  if (document) {
999
- prepareDocumentForMarkdown(document, url, signal);
1000
- const contentRoot = TransformHeuristics.findContentRoot(document);
1043
+ const resolvedDocument = preparedDocument ?? document;
1044
+ const contentRoot = TransformHeuristics.findContentRoot(resolvedDocument);
1045
+ const preferPrimaryHeading = shouldPreferPrimaryHeadingTitle(base.primaryHeading, extractedMeta.title);
1046
+ const resolvedTitle = (preferPrimaryHeading ? base.primaryHeading : undefined) ??
1047
+ extractedMeta.title;
1001
1048
  return {
1002
1049
  ...base,
1003
- sourceHtml: contentRoot ?? serializeDocumentForMarkdown(document, html),
1004
- title: extractedMeta.title,
1050
+ sourceHtml: contentRoot ?? serializeDocumentForMarkdown(resolvedDocument, html),
1051
+ title: resolvedTitle,
1052
+ suppressSyntheticFavicon: normalizeSyntheticTitleToken(resolvedTitle) ===
1053
+ normalizeSyntheticTitleToken(base.primaryHeading),
1005
1054
  skipNoiseRemoval: true,
1006
- document,
1055
+ document: resolvedDocument,
1007
1056
  };
1008
1057
  }
1009
1058
  return {
@@ -1326,8 +1375,8 @@ function maybeStripGithubPrimaryHeading(markdown, context, url) {
1326
1375
  return markdown;
1327
1376
  return stripLeadingHeading(markdown, context.primaryHeading ?? '');
1328
1377
  }
1329
- function buildSyntheticTitlePrefix(url, favicon) {
1330
- if (!favicon)
1378
+ function buildSyntheticTitlePrefix(url, favicon, suppressFavicon) {
1379
+ if (!favicon || suppressFavicon)
1331
1380
  return ' ';
1332
1381
  let alt = '';
1333
1382
  try {
@@ -1342,7 +1391,7 @@ function maybePrependSyntheticTitle(markdown, context, url) {
1342
1391
  if (!context.title || /^(#{1,6})\s/.test(markdown.trimStart())) {
1343
1392
  return markdown;
1344
1393
  }
1345
- return `#${buildSyntheticTitlePrefix(url, context.favicon)}${context.title}\n\n${markdown}`;
1394
+ return `#${buildSyntheticTitlePrefix(url, context.favicon, context.suppressSyntheticFavicon)}${context.title}\n\n${markdown}`;
1346
1395
  }
1347
1396
  function buildMarkdownFromContext(context, url, signal) {
1348
1397
  let content = stageTracker.run(url, 'transform:markdown', () => htmlToMarkdown(context.sourceHtml, context.metadata, {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@j0hanz/fetch-url-mcp",
3
- "version": "1.9.4",
3
+ "version": "1.9.6",
4
4
  "mcpName": "io.github.j0hanz/fetch-url-mcp",
5
5
  "description": "A web content fetcher MCP server that converts HTML to clean, AI and human readable markdown.",
6
6
  "type": "module",
@@ -74,8 +74,7 @@
74
74
  "@mozilla/readability": "^0.6.0",
75
75
  "linkedom": "^0.18.12",
76
76
  "node-html-markdown": "^2.0.0",
77
- "ts-morph": "^27.0.2",
78
- "undici": "^7.24.1",
77
+ "undici": "^7.24.3",
79
78
  "zod": "^4.3.6"
80
79
  },
81
80
  "devDependencies": {