@cyanheads/hn-mcp-server 0.5.18 → 0.5.20

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/AGENTS.md +6 -3
  2. package/CLAUDE.md +6 -3
  3. package/README.md +15 -8
  4. package/changelog/0.5.x/0.5.19.md +19 -0
  5. package/changelog/0.5.x/0.5.20.md +23 -0
  6. package/dist/mcp-server/tools/definitions/get-stories.tool.d.ts +2 -1
  7. package/dist/mcp-server/tools/definitions/get-stories.tool.d.ts.map +1 -1
  8. package/dist/mcp-server/tools/definitions/get-stories.tool.js +37 -14
  9. package/dist/mcp-server/tools/definitions/get-stories.tool.js.map +1 -1
  10. package/dist/mcp-server/tools/definitions/get-thread.tool.d.ts +30 -2
  11. package/dist/mcp-server/tools/definitions/get-thread.tool.d.ts.map +1 -1
  12. package/dist/mcp-server/tools/definitions/get-thread.tool.js +516 -174
  13. package/dist/mcp-server/tools/definitions/get-thread.tool.js.map +1 -1
  14. package/dist/mcp-server/tools/definitions/get-user.tool.d.ts +4 -1
  15. package/dist/mcp-server/tools/definitions/get-user.tool.d.ts.map +1 -1
  16. package/dist/mcp-server/tools/definitions/get-user.tool.js +64 -26
  17. package/dist/mcp-server/tools/definitions/get-user.tool.js.map +1 -1
  18. package/dist/mcp-server/tools/definitions/search-content.tool.d.ts +1 -1
  19. package/dist/mcp-server/tools/definitions/search-content.tool.d.ts.map +1 -1
  20. package/dist/mcp-server/tools/definitions/search-content.tool.js +41 -18
  21. package/dist/mcp-server/tools/definitions/search-content.tool.js.map +1 -1
  22. package/dist/mcp-server/tools/markdown-escape.d.ts +38 -0
  23. package/dist/mcp-server/tools/markdown-escape.d.ts.map +1 -0
  24. package/dist/mcp-server/tools/markdown-escape.js +76 -0
  25. package/dist/mcp-server/tools/markdown-escape.js.map +1 -0
  26. package/dist/services/hn/hn-service.d.ts +72 -17
  27. package/dist/services/hn/hn-service.d.ts.map +1 -1
  28. package/dist/services/hn/hn-service.js +235 -59
  29. package/dist/services/hn/hn-service.js.map +1 -1
  30. package/package.json +1 -1
  31. package/server.json +3 -3
@@ -0,0 +1,76 @@
1
+ /**
2
+ * @fileoverview Markdown boundaries for upstream text that `format()` interpolates
3
+ * into `content[]`. A single-line field (title, highlight title, poll-option text)
4
+ * is escaped just enough that it cannot end the server's own markup around it. A
5
+ * body is quoted line by line and otherwise left verbatim, so code stays intact.
6
+ * Usernames, URLs, IDs, and server tokens are interpolated as they are.
7
+ * @module mcp-server/tools/markdown-escape
8
+ */
9
+ /** `\`, `*`, backtick, the `]` of `](`, and `<` before a letter, `/`, `!`, or `?`. */
10
+ const INLINE_SPECIAL = /[\\*`]|\](?=\()|<(?=[A-Za-z/!?])/g;
11
+ /** {@link INLINE_SPECIAL} plus `"`, for a field that sits inside `"…"`. */
12
+ const QUOTED_INLINE_SPECIAL = /[\\*`"]|\](?=\()|<(?=[A-Za-z/!?])/g;
13
+ /** {@link INLINE_SPECIAL} plus `|`, for the title segment of the `match — … | …` footer. */
14
+ const FOOTER_INLINE_SPECIAL = /[\\*`|]|\](?=\()|<(?=[A-Za-z/!?])/g;
15
+ /** A highlight marker, captured so `split` keeps it. */
16
+ const HIGHLIGHT_MARKER = /(<\/?em>)/;
17
+ /** Every line ending CommonMark recognizes. */
18
+ const LINE_BREAK = /\r\n|\r|\n/;
19
+ const LINE_BREAKS = /\r\n|\r|\n/g;
20
+ /**
21
+ * The line-leading `[` that could open a link reference definition: after any
22
+ * spaces, tabs, and quote or list markers, a `[` whose label closes into `]:`
23
+ * on the same line, or one with no `]` after it at all, whose label may close
24
+ * on a later line. CommonMark applies a definition to the whole document, even
25
+ * from inside a block quote, so one left live in a body would turn `[1]` or
26
+ * `[deleted]` in server text into a link. Indentation is no exemption: a line
27
+ * indented four or more spaces is code at the top level but continuation text
28
+ * after a list item, so an indented code line shaped `[x]: y` takes the escape
29
+ * too.
30
+ */
31
+ const REFERENCE_DEFINITION = /^([ \t]*(?:(?:>|[-+*]|\d{1,9}[.)])[ \t]*)*)\[(?=[^\]]+\]:|[^\]]*$)/;
32
+ /**
33
+ * Escape a single-line upstream field so it cannot close or open the server's
34
+ * markup around it — a `**…**` wrapper, a code span, a link, an HTML tag, or a
35
+ * new line (each line break becomes a space) — and so it reads as typed in raw
36
+ * text. This is not a full Markdown escape: `_under_` can still render as
37
+ * emphasis, and a typed `&copy;` as ©. `a < b`, `[pdf]`, and `snake_case` are
38
+ * left unchanged.
39
+ */
40
+ export function escapeInline(text) {
41
+ return text.replace(LINE_BREAKS, ' ').replace(INLINE_SPECIAL, '\\$&');
42
+ }
43
+ /** {@link escapeInline} for a field quoted in `"…"`, where a `"` would end the quote. */
44
+ export function escapeQuoted(text) {
45
+ return text.replace(LINE_BREAKS, ' ').replace(QUOTED_INLINE_SPECIAL, '\\$&');
46
+ }
47
+ /**
48
+ * Escape an Algolia title highlight for the search footer, leaving its `<em>`
49
+ * and `</em>` markers as markup. `|` is escaped too, since the footer separates
50
+ * its segments with ` | ` and a title reading `x | terms: y` would otherwise
51
+ * imitate one. A literal `<em>` typed into the title is indistinguishable from
52
+ * a marker and passes through the same way.
53
+ */
54
+ export function escapeHighlight(text) {
55
+ return text
56
+ .replace(LINE_BREAKS, ' ')
57
+ .split(HIGHLIGHT_MARKER)
58
+ .map((part, i) => (i % 2 === 1 ? part : part.replace(FOOTER_INLINE_SPECIAL, '\\$&')))
59
+ .join('');
60
+ }
61
+ /**
62
+ * Quote an upstream body: every line gets `> ` after `indent`, and an empty line
63
+ * a bare `>`, so no line of the body can start a server-authored line. The only
64
+ * escape inside the body is the `[` of a link reference definition, which would
65
+ * otherwise reach past the quote; everything else, code included, stays
66
+ * verbatim. A quote absorbs the next non-blank line through lazy continuation,
67
+ * so the caller follows the body with a blank line whenever server text comes
68
+ * after it.
69
+ */
70
+ export function quoteBody(text, indent = '') {
71
+ return text
72
+ .split(LINE_BREAK)
73
+ .map((line) => line ? `${indent}> ${line.replace(REFERENCE_DEFINITION, '$1\\[')}` : `${indent}>`)
74
+ .join('\n');
75
+ }
76
+ //# sourceMappingURL=markdown-escape.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"markdown-escape.js","sourceRoot":"","sources":["../../../src/mcp-server/tools/markdown-escape.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,sFAAsF;AACtF,MAAM,cAAc,GAAG,mCAAmC,CAAC;AAE3D,2EAA2E;AAC3E,MAAM,qBAAqB,GAAG,oCAAoC,CAAC;AAEnE,4FAA4F;AAC5F,MAAM,qBAAqB,GAAG,oCAAoC,CAAC;AAEnE,wDAAwD;AACxD,MAAM,gBAAgB,GAAG,WAAW,CAAC;AAErC,+CAA+C;AAC/C,MAAM,UAAU,GAAG,YAAY,CAAC;AAChC,MAAM,WAAW,GAAG,aAAa,CAAC;AAElC;;;;;;;;;;GAUG;AACH,MAAM,oBAAoB,GAAG,oEAAoE,CAAC;AAElG;;;;;;;GAOG;AACH,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,cAAc,EAAE,MAAM,CAAC,CAAC;AACxE,CAAC;AAED,yFAAyF;AACzF,MAAM,UAAU,YAAY,CAAC,IAAY;IACvC,OAAO,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC;AAC/E,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,eAAe,CAAC,IAAY;IAC1C,OAAO,IAAI;SACR,OAAO,CAAC,WAAW,EAAE,GAAG,CAAC;SACzB,KAAK,CAAC,gBAAgB,CAAC;SACvB,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAC,CAAC;SACpF,IAAI,CAAC,EAAE,CAAC,CAAC;AACd,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,SAAS,CAAC,IAAY,EAAE,MAAM,GAAG,EAAE;IACjD,OAAO,IAAI;SACR,KAAK,CAAC,UAAU,CAAC;SACjB,GAAG,CAAC,CAAC,IAAI,EAAE,EAAE,CACZ,IAAI,CAAC,CAAC,CAAC,GAAG,MAAM,KAAK,IAAI,CAAC,OAAO,CAAC,oBAAoB,EAAE,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC,GAAG,MAAM,GAAG,CAClF;SACA,IAAI,CAAC,IAAI,CAAC,CAAC;AAChB,CAAC"}
@@ -3,15 +3,23 @@
3
3
  * @module services/hn/hn-service
4
4
  */
5
5
  import type { Context } from '@cyanheads/mcp-ts-core';
6
+ import { McpError } from '@cyanheads/mcp-ts-core/errors';
6
7
  import type { AlgoliaResponse, HnFeedType, HnItem, HnUser } from './types.js';
7
- /** Decode numeric and named HTML entities. */
8
+ /** Decode numeric and named HTML entities. An undeclared name stays as typed. */
8
9
  export declare function decodeHtmlEntities(text: string): string;
9
- /** Strip HN HTML to plain text. Preserves code blocks and link URLs. */
10
+ /**
11
+ * Strip an HN HTML body (`text`, `about`, and Algolia's `comment_text` /
12
+ * `story_text`) to plain text: `<p>` becomes a blank line, code blocks are kept
13
+ * verbatim, each link renders once as its full URL — or as `text (url)` when
14
+ * the text is something else — other tags are removed, and entities are
15
+ * decoded exactly once. Titles are not HTML, though some arrive entity-encoded:
16
+ * they take {@link decodeHtmlEntities} alone and never pass through here.
17
+ */
10
18
  export declare function stripHtml(html: string): string;
11
19
  /**
12
- * Strip HN HTML but preserve `<em>…</em>` markers — used to clean Algolia
13
- * highlight snippets, which contain the original field HTML with `<em>` tags
14
- * inserted around matched terms. Other tags are removed by `stripHtml`.
20
+ * {@link stripHtml} for an Algolia highlight snippet, which is the field's HTML
21
+ * with `<em>` inserted around matched terms: the `<em>…</em>` markers survive,
22
+ * including inside a link collapsed to its href.
15
23
  */
16
24
  export declare function stripHtmlPreservingEm(html: string): string;
17
25
  /** Normalize empty URL strings to undefined. */
@@ -22,13 +30,54 @@ export declare function normalizeUrl(url?: string | null): string | undefined;
22
30
  */
23
31
  export declare function extractDomain(url: string | undefined): string | undefined;
24
32
  /**
25
- * Convert a validated ISO 8601 date bound to Unix seconds. A date-time without
26
- * a `Z` or `±hh:mm` offset is read as UTC — the same as a date-only value, and
27
- * unlike JS's own parsing, which reads it in the host's local time zone.
33
+ * Convert a validated ISO 8601 date bound to its exact instant in Unix
34
+ * milliseconds. A date-time without a `Z` or `±hh:mm` offset is read as UTC —
35
+ * the same as a date-only value, and unlike JS's own parsing, which reads it in
36
+ * the host's local time zone.
37
+ */
38
+ export declare function dateBoundToEpochMs(bound: string): number;
39
+ /**
40
+ * Convert a validated ISO 8601 date bound to Unix seconds, read as
41
+ * {@link dateBoundToEpochMs} reads it.
42
+ *
43
+ * A fractional second rounds down by default, which suits an exclusive start.
44
+ * An exclusive end over whole-second timestamps passes `'ceil'`: an end at
45
+ * `10:00:00.5` must still admit an item created at `10:00:00`.
46
+ */
47
+ export declare function dateBoundToEpochSeconds(bound: string, rounding?: 'floor' | 'ceil'): number;
48
+ /**
49
+ * One slot of a {@link HnService.fetchItems} batch, in input order.
50
+ *
51
+ * - `item` — HN returned the item. It may be dead or deleted; callers filter.
52
+ * - `absent` — HN answered `null`: no item exists under this ID.
53
+ * - `failed` — the fetch failed after retries, or never started because an
54
+ * earlier slot was rate-limited. `error` is the classified failure. A later
55
+ * call may succeed, so a caller reports the ID rather than dropping it.
56
+ */
57
+ export type ItemSlot = {
58
+ kind: 'item';
59
+ id: number;
60
+ item: HnItem;
61
+ } | {
62
+ kind: 'absent';
63
+ id: number;
64
+ } | {
65
+ kind: 'failed';
66
+ id: number;
67
+ error: unknown;
68
+ };
69
+ /**
70
+ * Settle one page of a batch for the paged tools: the live items in input
71
+ * order, and the IDs whose fetch failed. Dead, deleted, and absent slots drop
72
+ * out of both. When every slot failed, throws the first failure's classified
73
+ * error, since an empty success would read as a page with nothing on it.
28
74
  */
29
- export declare function dateBoundToEpochSeconds(bound: string): number;
30
- /** Filter out dead, deleted, and null items. */
31
- export declare function filterLiveItems(items: (HnItem | null)[]): HnItem[];
75
+ export declare function settlePage(slots: readonly ItemSlot[]): {
76
+ items: HnItem[];
77
+ failedIds: number[];
78
+ };
79
+ /** True for the classified 429 `getJson` throws once retries are spent or the wait outlasts them. */
80
+ export declare function isRateLimited(err: unknown): err is McpError;
32
81
  export declare class HnService {
33
82
  private readonly concurrencyLimit;
34
83
  constructor(concurrencyLimit: number);
@@ -50,13 +99,19 @@ export declare class HnService {
50
99
  /** Fetch a feed's ID array. Throws on upstream failure after retries. */
51
100
  fetchFeed(type: HnFeedType, ctx: Context): Promise<number[]>;
52
101
  /**
53
- * Batch-fetch items with concurrency limiting. Preserves input order.
54
- * Per-item failures after exhausted retries are logged and yield `null`
55
- * so a single bad item does not fail the whole batch. A caller abort is the
56
- * one failure that is not per-item: it rethrows, ending the batch instead of
57
- * spending the rest of the id list on fetches nobody is waiting for.
102
+ * Batch-fetch items with concurrency limiting: one {@link ItemSlot} per ID,
103
+ * in input order. A per-item failure after exhausted retries fills a
104
+ * `failed` slot, so one bad item does not fail the batch. Two failures are
105
+ * not per-item:
106
+ *
107
+ * - A caller abort rethrows, ending the batch instead of spending the rest of
108
+ * the ID list on fetches nobody is waiting for.
109
+ * - An `upstream_rate_limited` failure stops the batch. Fetches already in
110
+ * flight settle, and every slot not yet started is reported `failed` with
111
+ * that error, rather than each running its own retry ladder against a
112
+ * throttled upstream.
58
113
  */
59
- fetchItems(ids: number[], ctx: Context): Promise<(HnItem | null)[]>;
114
+ fetchItems(ids: readonly number[], ctx: Context): Promise<ItemSlot[]>;
60
115
  /**
61
116
  * Search HN via Algolia. Throws on upstream failure after retries. An omitted
62
117
  * `query` sends no `query` param, making a filter-only search; the tags are
@@ -1 +1 @@
1
- {"version":3,"file":"hn-service.d.ts","sourceRoot":"","sources":["../../../src/services/hn/hn-service.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AAWtD,OAAO,KAAK,EAAE,eAAe,EAAE,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAmB9E,8CAA8C;AAC9C,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAMvD;AAED,wEAAwE;AACxE,wBAAgB,SAAS,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAyB9C;AAED;;;;GAIG;AACH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAM1D;AAED,gDAAgD;AAChD,wBAAgB,YAAY,CAAC,GAAG,CAAC,EAAE,MAAM,GAAG,IAAI,GAAG,MAAM,GAAG,SAAS,CAEpE;AAED;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,SAAS,GAAG,MAAM,GAAG,SAAS,CAOzE;AAED;;;;GAIG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAG7D;AAED,gDAAgD;AAChD,wBAAgB,eAAe,CAAC,KAAK,EAAE,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,GAAG,MAAM,EAAE,CAElE;AA4HD,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAS;IAE1C,YAAY,gBAAgB,EAAE,MAAM,EAEnC;IAED;;;;OAIG;IACH,OAAO,CAAC,OAAO;IAmBf,mFAAmF;IACnF,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAE1D;IAED;;;;;OAKG;IACH,SAAS,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOhE;IAED,yEAAyE;IACzE,SAAS,CAAC,IAAI,EAAE,UAAU,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAG3D;IAED;;;;;;OAMG;IACG,UAAU,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,GAAG,EAAE,OAAO,GAAG,OAAO,CAAC,CAAC,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CA0BxE;IAED;;;;OAIG;IACH,MAAM,CACJ,MAAM,EAAE;QACN,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC1B,MAAM,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC5B,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC7B,IAAI,EAAE,WAAW,GAAG,MAAM,CAAC;QAC3B,SAAS,CAAC,EAAE;YAAE,KAAK,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;YAAC,GAAG,CAAC,EAAE,MAAM,GAAG,SAAS,CAAA;SAAE,GAAG,SAAS,CAAC;QACjF,SAAS,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;QAC/B,KAAK,EAAE,MAAM,CAAC;QACd,IAAI,EAAE,MAAM,CAAC;KACd,EACD,GAAG,EAAE,OAAO,GACX,OAAO,CAAC,eAAe,CAAC,CAyB1B;CACF;AAQD,wBAAgB,aAAa,IAAI,IAAI,CAGpC;AAED,wBAAgB,YAAY,IAAI,SAAS,CAGxC"}
1
+ {"version":3,"file":"hn-service.d.ts","sourceRoot":"","sources":["../../../src/services/hn/hn-service.ts"],"names":[],"mappings":"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"}
@@ -11,56 +11,170 @@ const REQUEST_TIMEOUT_MS = 10_000;
11
11
  // ---------------------------------------------------------------------------
12
12
  // HTML utilities
13
13
  // ---------------------------------------------------------------------------
14
- const HTML_ENTITIES = {
15
- amp: '&',
16
- lt: '<',
17
- gt: '>',
18
- quot: '"',
19
- apos: "'",
20
- nbsp: ' ',
21
- };
22
- /** Decode numeric and named HTML entities. */
14
+ /** The named entities HN emits. A `Map`, so a name like `constructor` finds nothing inherited. */
15
+ const HTML_ENTITIES = new Map([
16
+ ['amp', '&'],
17
+ ['lt', '<'],
18
+ ['gt', '>'],
19
+ ['quot', '"'],
20
+ ['apos', "'"],
21
+ ['nbsp', ' '],
22
+ ]);
23
+ /**
24
+ * A numeric reference's character. NUL, surrogates, and values past U+10FFFF
25
+ * decode to U+FFFD, as in HTML, and so does U+0001 — so decoding never yields
26
+ * either character the strip masks are built on, and an out-of-range value
27
+ * never throws.
28
+ */
29
+ function fromCodePoint(codePoint) {
30
+ const replaced = codePoint <= 1 || codePoint > 0x10ffff || (codePoint >= 0xd800 && codePoint <= 0xdfff);
31
+ return String.fromCodePoint(replaced ? 0xfffd : codePoint);
32
+ }
33
+ /** Decode numeric and named HTML entities. An undeclared name stays as typed. */
23
34
  export function decodeHtmlEntities(text) {
24
35
  return text.replace(/&(?:#x([0-9a-fA-F]+)|#(\d+)|(\w+));/g, (match, hex, dec, named) => {
25
36
  if (hex)
26
- return String.fromCodePoint(parseInt(hex, 16));
37
+ return fromCodePoint(parseInt(hex, 16));
27
38
  if (dec)
28
- return String.fromCodePoint(parseInt(dec, 10));
29
- return HTML_ENTITIES[named] ?? match;
39
+ return fromCodePoint(parseInt(dec, 10));
40
+ return HTML_ENTITIES.get(named) ?? match;
30
41
  });
31
42
  }
32
- /** Strip HN HTML to plain text. Preserves code blocks and link URLs. */
33
- export function stripHtml(html) {
43
+ /**
44
+ * Masks that hold a code block's place, or a highlight marker's, while the rest
45
+ * of the HTML is rewritten. Each opens with U+0000 and closes with U+0001, so
46
+ * text between two adjacent masks cannot borrow the close of one and the open
47
+ * of the next to spell a third. The strip removes both characters from its
48
+ * input before masking, and {@link decodeHtmlEntities} never produces either,
49
+ * so no upstream text can spell a mask.
50
+ */
51
+ const MASK_OPEN = '\u0000';
52
+ const MASK_CLOSE = '\u0001';
53
+ const EM_OPEN = `${MASK_OPEN}EM_OPEN${MASK_CLOSE}`;
54
+ const EM_CLOSE = `${MASK_OPEN}EM_CLOSE${MASK_CLOSE}`;
55
+ const EM_MASK = new RegExp(`${EM_OPEN}|${EM_CLOSE}`, 'g');
56
+ const CODE_MASK = new RegExp(`${MASK_OPEN}CODE_(\\d+)${MASK_CLOSE}`, 'g');
57
+ const MASK_CHARACTERS = new RegExp(`[${MASK_OPEN}${MASK_CLOSE}]`, 'g');
58
+ const CODE_OPEN = /<pre><code>/gi;
59
+ const CODE_CLOSE = /<\/code><\/pre>/gi;
60
+ const LINK_OPEN = /<a\s+href="([^"]*)"[^>]*>/gi;
61
+ const LINK_CLOSE = /<\/a>/gi;
62
+ /** A trailing entity a truncation cut short, such as the `&#3` left of `&#38;`. */
63
+ const PARTIAL_ENTITY = /&#?[0-9A-Za-z]*$/;
64
+ /**
65
+ * Replace each `open … close` span, leftmost opener first and the nearest closer
66
+ * after it, with `render(opener, inner)`. An opener with no closer after it ends
67
+ * the scan — no later opener can find one either — so every search runs forward
68
+ * once and a pass stays linear, where a lazy `open([\s\S]*?)close` regex rescans
69
+ * to the end for each unclosed opener.
70
+ */
71
+ function replaceSpans(text, open, close, render) {
72
+ let out = '';
73
+ let last = 0;
74
+ open.lastIndex = 0;
75
+ for (let opener = open.exec(text); opener; opener = open.exec(text)) {
76
+ close.lastIndex = open.lastIndex;
77
+ const closer = close.exec(text);
78
+ if (!closer)
79
+ break;
80
+ out +=
81
+ text.slice(last, opener.index) + render(opener, text.slice(open.lastIndex, closer.index));
82
+ last = open.lastIndex = close.lastIndex;
83
+ }
84
+ return out + text.slice(last);
85
+ }
86
+ /**
87
+ * Apply `rewrite` to the text up to its last `>`. No tag can close past that
88
+ * point, and leaving it out keeps a regex from rescanning to the end of the
89
+ * string for every unmatched `<` there.
90
+ */
91
+ function throughLastTag(text, rewrite) {
92
+ const end = text.lastIndexOf('>') + 1;
93
+ return rewrite(text.slice(0, end)) + text.slice(end);
94
+ }
95
+ /**
96
+ * Remove every tag. One pass is complete: a `<` the pass leaves is followed
97
+ * directly by `>` or by no `>` at all, and removing a tag changes neither.
98
+ */
99
+ function stripTags(text) {
100
+ return throughLastTag(text, (head) => head.replace(/<[^>]+>/g, ''));
101
+ }
102
+ /**
103
+ * Render one link. HN cuts long link text to a prefix ending in `...`, and older
104
+ * items encode `/` in the text but not the href, so the two are compared
105
+ * decoded, with highlight markers set aside. When the text is the href, or a
106
+ * `...`-cut prefix of it (less any entity the cut left partial), the href
107
+ * renders alone, carrying the text's markers on the same characters. Any other
108
+ * link renders as `text (href)`.
109
+ *
110
+ * The collapsed href goes back re-encoded (`&`, `<`, `>`), so the strip's one
111
+ * decoding pass restores it exactly and its tag strip never reads it as markup.
112
+ */
113
+ function renderLink(rawHref, rawText) {
114
+ const href = decodeHtmlEntities(rawHref);
115
+ const markers = [];
116
+ let text = '';
117
+ let from = 0;
118
+ for (const match of rawText.matchAll(EM_MASK)) {
119
+ text += decodeHtmlEntities(stripTags(rawText.slice(from, match.index)));
120
+ markers.push({ at: text.length, marker: match[0] });
121
+ from = match.index + match[0].length;
122
+ }
123
+ text += decodeHtmlEntities(stripTags(rawText.slice(from)));
124
+ const prefix = text === href
125
+ ? href
126
+ : text.endsWith('...')
127
+ ? text.slice(0, -3).replace(PARTIAL_ENTITY, '')
128
+ : undefined;
129
+ if (prefix === undefined || !href.startsWith(prefix))
130
+ return `${rawText} (${rawHref})`;
131
+ let rendered = '';
132
+ let cut = 0;
133
+ for (const { at, marker } of markers) {
134
+ const position = Math.min(at, prefix.length);
135
+ rendered += href.slice(cut, position) + marker;
136
+ cut = position;
137
+ }
138
+ rendered += href.slice(cut);
139
+ return rendered.replaceAll('&', '&amp;').replaceAll('<', '&lt;').replaceAll('>', '&gt;');
140
+ }
141
+ /** The strip both public entry points share; `keepEm` carries Algolia's highlight markers through. */
142
+ function toPlainText(html, keepEm) {
34
143
  if (!html)
35
144
  return '';
36
- // Preserve code blocks
145
+ let text = html.replace(MASK_CHARACTERS, '');
146
+ if (keepEm)
147
+ text = text.replaceAll('<em>', EM_OPEN).replaceAll('</em>', EM_CLOSE);
37
148
  const codeBlocks = [];
38
- let text = html.replace(/<pre><code>([\s\S]*?)<\/code><\/pre>/gi, (_, code) => {
149
+ text = replaceSpans(text, CODE_OPEN, CODE_CLOSE, (_opener, code) => {
39
150
  codeBlocks.push(code);
40
- return `@@CODE_${codeBlocks.length - 1}@@`;
151
+ return `${MASK_OPEN}CODE_${codeBlocks.length - 1}${MASK_CLOSE}`;
41
152
  });
42
- // Paragraphs → double newline
43
153
  text = text.replace(/<p>/gi, '\n\n');
44
- // Links → text (URL)
45
- text = text.replace(/<a\s+href="([^"]*)"[^>]*>([\s\S]*?)<\/a>/gi, (_, url, linkText) => linkText === url ? url : `${linkText} (${url})`);
46
- // Strip all remaining tags
47
- text = text.replace(/<[^>]+>/g, '');
48
- // Restore code blocks
49
- text = text.replace(/@@CODE_(\d+)@@/g, (_, i) => codeBlocks[Number(i)] ?? '');
50
- return decodeHtmlEntities(text).trim();
154
+ text = throughLastTag(text, (head) => replaceSpans(head, LINK_OPEN, LINK_CLOSE, (opener, inner) => renderLink(opener[1] ?? '', inner)));
155
+ text = stripTags(text);
156
+ text = text.replace(CODE_MASK, (_, i) => codeBlocks[Number(i)] ?? '');
157
+ text = decodeHtmlEntities(text).trim();
158
+ return keepEm ? text.replaceAll(EM_OPEN, '<em>').replaceAll(EM_CLOSE, '</em>') : text;
159
+ }
160
+ /**
161
+ * Strip an HN HTML body (`text`, `about`, and Algolia's `comment_text` /
162
+ * `story_text`) to plain text: `<p>` becomes a blank line, code blocks are kept
163
+ * verbatim, each link renders once as its full URL — or as `text (url)` when
164
+ * the text is something else — other tags are removed, and entities are
165
+ * decoded exactly once. Titles are not HTML, though some arrive entity-encoded:
166
+ * they take {@link decodeHtmlEntities} alone and never pass through here.
167
+ */
168
+ export function stripHtml(html) {
169
+ return toPlainText(html, false);
51
170
  }
52
171
  /**
53
- * Strip HN HTML but preserve `<em>…</em>` markers — used to clean Algolia
54
- * highlight snippets, which contain the original field HTML with `<em>` tags
55
- * inserted around matched terms. Other tags are removed by `stripHtml`.
172
+ * {@link stripHtml} for an Algolia highlight snippet, which is the field's HTML
173
+ * with `<em>` inserted around matched terms: the `<em>…</em>` markers survive,
174
+ * including inside a link collapsed to its href.
56
175
  */
57
176
  export function stripHtmlPreservingEm(html) {
58
- if (!html)
59
- return '';
60
- const masked = html.replace(/<em>/g, '@@EM_OPEN@@').replace(/<\/em>/g, '@@EM_CLOSE@@');
61
- return stripHtml(masked)
62
- .replace(/@@EM_OPEN@@/g, '<em>')
63
- .replace(/@@EM_CLOSE@@/g, '</em>');
177
+ return toPlainText(html, true);
64
178
  }
65
179
  /** Normalize empty URL strings to undefined. */
66
180
  export function normalizeUrl(url) {
@@ -81,17 +195,52 @@ export function extractDomain(url) {
81
195
  }
82
196
  }
83
197
  /**
84
- * Convert a validated ISO 8601 date bound to Unix seconds. A date-time without
85
- * a `Z` or `±hh:mm` offset is read as UTC — the same as a date-only value, and
86
- * unlike JS's own parsing, which reads it in the host's local time zone.
198
+ * Convert a validated ISO 8601 date bound to its exact instant in Unix
199
+ * milliseconds. A date-time without a `Z` or `±hh:mm` offset is read as UTC —
200
+ * the same as a date-only value, and unlike JS's own parsing, which reads it in
201
+ * the host's local time zone.
87
202
  */
88
- export function dateBoundToEpochSeconds(bound) {
203
+ export function dateBoundToEpochMs(bound) {
89
204
  const offsetless = bound.includes('T') && !/(?:Z|[+-]\d{2}:\d{2})$/.test(bound);
90
- return Math.floor(Date.parse(offsetless ? `${bound}Z` : bound) / 1000);
205
+ return Date.parse(offsetless ? `${bound}Z` : bound);
206
+ }
207
+ /**
208
+ * Convert a validated ISO 8601 date bound to Unix seconds, read as
209
+ * {@link dateBoundToEpochMs} reads it.
210
+ *
211
+ * A fractional second rounds down by default, which suits an exclusive start.
212
+ * An exclusive end over whole-second timestamps passes `'ceil'`: an end at
213
+ * `10:00:00.5` must still admit an item created at `10:00:00`.
214
+ */
215
+ export function dateBoundToEpochSeconds(bound, rounding = 'floor') {
216
+ return Math[rounding](dateBoundToEpochMs(bound) / 1000);
217
+ }
218
+ /**
219
+ * Settle one page of a batch for the paged tools: the live items in input
220
+ * order, and the IDs whose fetch failed. Dead, deleted, and absent slots drop
221
+ * out of both. When every slot failed, throws the first failure's classified
222
+ * error, since an empty success would read as a page with nothing on it.
223
+ */
224
+ export function settlePage(slots) {
225
+ const items = [];
226
+ const failedIds = [];
227
+ let firstFailure;
228
+ for (const slot of slots) {
229
+ if (slot.kind === 'failed') {
230
+ failedIds.push(slot.id);
231
+ firstFailure ??= slot;
232
+ }
233
+ else if (slot.kind === 'item' && !slot.item.deleted && !slot.item.dead) {
234
+ items.push(slot.item);
235
+ }
236
+ }
237
+ if (firstFailure && failedIds.length === slots.length)
238
+ throw firstFailure.error;
239
+ return { items, failedIds };
91
240
  }
92
- /** Filter out dead, deleted, and null items. */
93
- export function filterLiveItems(items) {
94
- return items.filter((item) => item != null && !item.deleted && !item.dead);
241
+ /** True for the classified 429 `getJson` throws once retries are spent or the wait outlasts them. */
242
+ export function isRateLimited(err) {
243
+ return err instanceof McpError && err.data?.reason === 'upstream_rate_limited';
95
244
  }
96
245
  /** Detect HTML error bodies returned by upstream APIs under rate limiting or maintenance. */
97
246
  function isHtmlErrorBody(text) {
@@ -138,15 +287,26 @@ function parseJsonBody(text, upstream) {
138
287
  * across several codes — HN answers an unknown path with 401, and a 504 would
139
288
  * arrive as `Timeout`, blurring "this server's own fetch timed out" with an
140
289
  * upstream that is merely down. The exact status stays on `data.status`.
290
+ *
291
+ * A 429's raw `Retry-After` header (delta-seconds or an HTTP-date), which
292
+ * `fetchWithTimeout` leaves on the cause, is copied to `data.retryAfter`
293
+ * unchanged and named in the hint, so the caller can wait exactly the interval
294
+ * the upstream asked for.
141
295
  */
142
296
  function upstreamFailureFor(upstream, status, cause) {
143
297
  if (status === 429) {
298
+ const header = cause.data?.retryAfter;
299
+ const retryAfter = typeof header === 'string' && header.trim() !== '' ? header : undefined;
300
+ const wait = retryAfter && (/^\d+$/.test(retryAfter) ? `${retryAfter} seconds` : retryAfter);
144
301
  return rateLimited(`${upstream} returned HTTP ${status}.`, {
145
302
  upstream,
146
303
  status,
147
304
  reason: 'upstream_rate_limited',
305
+ ...(retryAfter && { retryAfter }),
148
306
  recovery: {
149
- hint: `${upstream} is rate-limiting this server. Wait several seconds before retrying the same call, and reduce how often it is called.`,
307
+ hint: wait
308
+ ? `${upstream} is rate-limiting this server and asked it to retry after ${wait}. Wait that long before retrying the same call, and reduce how often it is called.`
309
+ : `${upstream} is rate-limiting this server. Wait several seconds before retrying the same call, and reduce how often it is called.`,
150
310
  },
151
311
  }, { cause });
152
312
  }
@@ -234,39 +394,55 @@ export class HnService {
234
394
  return this.getJson('HN API', 'hn.fetchFeed', `${HN_API}/${endpoint}.json`, ctx);
235
395
  }
236
396
  /**
237
- * Batch-fetch items with concurrency limiting. Preserves input order.
238
- * Per-item failures after exhausted retries are logged and yield `null`
239
- * so a single bad item does not fail the whole batch. A caller abort is the
240
- * one failure that is not per-item: it rethrows, ending the batch instead of
241
- * spending the rest of the id list on fetches nobody is waiting for.
397
+ * Batch-fetch items with concurrency limiting: one {@link ItemSlot} per ID,
398
+ * in input order. A per-item failure after exhausted retries fills a
399
+ * `failed` slot, so one bad item does not fail the batch. Two failures are
400
+ * not per-item:
401
+ *
402
+ * - A caller abort rethrows, ending the batch instead of spending the rest of
403
+ * the ID list on fetches nobody is waiting for.
404
+ * - An `upstream_rate_limited` failure stops the batch. Fetches already in
405
+ * flight settle, and every slot not yet started is reported `failed` with
406
+ * that error, rather than each running its own retry ladder against a
407
+ * throttled upstream.
242
408
  */
243
409
  async fetchItems(ids, ctx) {
244
- if (ids.length === 0)
245
- return [];
246
- const results = new Array(ids.length).fill(null);
410
+ const slots = new Array(ids.length);
411
+ let rateLimit;
247
412
  let next = 0;
248
413
  const worker = async () => {
249
- while (next < ids.length) {
414
+ while (!rateLimit && next < ids.length) {
250
415
  const i = next++;
251
416
  const id = ids[i];
252
417
  if (id == null)
253
418
  continue;
254
419
  try {
255
- results[i] = await this.fetchItem(id, ctx);
420
+ const item = await this.fetchItem(id, ctx);
421
+ slots[i] = item ? { kind: 'item', id, item } : { kind: 'absent', id };
256
422
  }
257
- catch (err) {
258
- if (err instanceof McpError && err.code === JsonRpcErrorCode.RequestCancelled)
259
- throw err;
423
+ catch (error) {
424
+ if (error instanceof McpError && error.code === JsonRpcErrorCode.RequestCancelled) {
425
+ throw error;
426
+ }
427
+ slots[i] = { kind: 'failed', id, error };
428
+ if (isRateLimited(error))
429
+ rateLimit ??= error;
260
430
  ctx.log.warning('Batch item fetch failed after retries', {
261
431
  id,
262
- error: err instanceof Error ? err.message : String(err),
432
+ error: error instanceof Error ? error.message : String(error),
263
433
  });
264
434
  }
265
435
  }
266
436
  };
267
437
  const workerCount = Math.min(this.concurrencyLimit, ids.length);
268
438
  await Promise.all(Array.from({ length: workerCount }, worker));
269
- return results;
439
+ const skipped = ids.length - next;
440
+ if (rateLimit && skipped > 0) {
441
+ ctx.log.warning('Batch stopped: upstream rate-limited, remaining items not fetched', {
442
+ skipped,
443
+ });
444
+ }
445
+ return ids.map((id, i) => slots[i] ?? { kind: 'failed', id, error: rateLimit });
270
446
  }
271
447
  /**
272
448
  * Search HN via Algolia. Throws on upstream failure after retries. An omitted
@@ -296,7 +472,7 @@ export class HnService {
296
472
  numericFilters.push(`created_at_i>${dateBoundToEpochSeconds(params.dateRange.start)}`);
297
473
  }
298
474
  if (params.dateRange?.end) {
299
- numericFilters.push(`created_at_i<${dateBoundToEpochSeconds(params.dateRange.end)}`);
475
+ numericFilters.push(`created_at_i<${dateBoundToEpochSeconds(params.dateRange.end, 'ceil')}`);
300
476
  }
301
477
  if (numericFilters.length)
302
478
  url.searchParams.set('numericFilters', numericFilters.join(','));
@@ -1 +1 @@
1
- {"version":3,"file":"hn-service.js","sourceRoot":"","sources":["../../../src/services/hn/hn-service.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"hn-service.js","sourceRoot":"","sources":["../../../src/services/hn/hn-service.ts"],"names":[],"mappings":"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"}