@pipeworx/mcp-guam-code 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -3,7 +3,7 @@
3
3
  Guam Code Annotated (GCA) — Guam territorial statutes, by citation and by
4
4
  topic/keyword search. Keyless.
5
5
 
6
- Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1763+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
6
+ Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1784+ live data sources. This is an independent, unofficial integration — not affiliated with, endorsed by, or published by the upstream provider.
7
7
 
8
8
  ## Tools
9
9
 
@@ -75,23 +75,28 @@ length); it is resolved by picking the longest known chapter number, for the
75
75
  given Title, that is a literal prefix of the citation — correct in every
76
76
  case sampled.
77
77
 
78
- ## `shared/src/pdf-text.ts` needed real fixes, forked pack-local instead
78
+ ## `shared/src/pdf-text.ts` needed real fixes — folded in, fork deleted (fleet #2904)
79
79
 
80
- Guam's chapter PDFs defeated the shared extractor in ways it did not yet
81
- handle, and this pack was built the same week another pack (#2884, New
82
- Mexico) was independently editing that shared file — so the fixes live in
83
- `src/gu-pdf-extract.ts`, a pack-local fork of `shared/src/pdf-text.ts`, with
84
- a loud header comment for whoever next touches the shared extractor to fold
85
- them in (nothing about them is Guam-specific):
80
+ Guam's chapter PDFs originally defeated the shared extractor in ways it did
81
+ not yet handle, and this pack was built the same week another pack (#2884,
82
+ New Mexico) was independently editing that shared file — so the fixes
83
+ initially lived in `src/gu-pdf-extract.ts`, a pack-local fork of
84
+ `shared/src/pdf-text.ts`, with a loud header comment for whoever next
85
+ touched the shared extractor to fold them in (nothing about them was
86
+ Guam-specific). That fold-in happened in fleet #2904: the fork is gone, this
87
+ pack now calls `extractPdfText` from `@pipeworx/shared` directly, and all
88
+ three fixes below live in `shared/src/pdf-text.ts` itself, benefiting every
89
+ other PDF pack (kentucky-code, north-dakota-code, wyoming-code,
90
+ new-mexico-code), not just this one:
86
91
 
87
92
  1. **Literal strings weren't routed through the font decoder.** Guam's
88
93
  producer (Neevia Document Converter, from Word) writes some non-WinAnsi
89
94
  subset fonts' text as parenthesized LITERAL strings (`(abc)Tj`) rather
90
- than hex (`<...>Tj`). The shared extractor's `decodeRun` passes a literal
95
+ than hex (`<...>Tj`). The shared extractor's `decodeRun` passed a literal
91
96
  run through unchanged — correct for WinAnsi, but for these fonts the raw
92
97
  bytes are a tiny, arbitrary code space meaningful only via the font's own
93
- `/ToUnicode` CMap, which the shared code already has the machinery for
94
- (built for North Dakota) but only wires to the HEX-string path. Confirmed
98
+ `/ToUnicode` CMap, which the shared code already had the machinery for
99
+ (built for North Dakota) but only wired to the HEX-string path. Confirmed
95
100
  live: unfixed, `§ 16.10` extracted as control-character noise; fixed, it
96
101
  reads correctly.
97
102
  2. **A declared `/Length` a few bytes long.** Several older chapter PDFs
@@ -99,26 +104,31 @@ them in (nothing about them is Guam-specific):
99
104
  Neevia-converted ones above) declare a `/Length` 1+ bytes longer than
100
105
  their actual deflate stream. Python's zlib tolerates the trailing byte
101
106
  silently; Node/Workers' strict `DecompressionStream` throws
102
- `ERR_TRAILING_JUNK_AFTER_STREAM_END`. Retried with the stream's tail
107
+ `ERR_TRAILING_JUNK_AFTER_STREAM_END`. Now retried with the stream's tail
103
108
  trimmed a byte at a time (up to 4) before giving up.
104
- 3. **A quote-glyph CMap that is wrong in the source file.** One embedded
105
- symbol font per chapter PDF (`...+WPTypographicSymbols`, used only for
106
- curly quotes) carries a `/ToUnicode` CMap that maps its two codes to
107
- U+0041 ('A') and U+0040 ('@') instead of the left/right curly quote it
108
- visually renders as. Confirmed by eye: "ADirector of Public Safety@" in
109
- raw extraction is "“Director of Public Safety”" with those two codes
110
- substituted back — the obviously intended reading, reproduced by any PDF
111
- viewer's own copy-paste. Overridden by font name, since no general rule
112
- could derive it.
113
- 4. **Crash-adjacent, found while baking the section index.** The shared
109
+ 3. **Crash-adjacent, found while baking the section index.** The shared
114
110
  `inflate()` helper's two stream writes were fire-and-forget
115
111
  (`void writer.write(...)`); a malformed deflate stream (the same PDFs #2
116
112
  above describes) rejected that promise as an UNHANDLED rejection,
117
113
  invisible to any caller's try/catch and fatal to the whole process —
118
114
  crashed `scripts/bake-sections.mjs` outright, mid-run. Fixed by attaching
119
115
  a no-op `.catch()` to each write/close; the real failure still surfaces
120
- through `reader.read()`, which the caller already handles. Worth
121
- checking whether `shared/src/pdf-text.ts` has the same exposure.
116
+ through `reader.read()`, which the caller already handles.
117
+
118
+ **One delta stayed pack-local, in `src/gu-font-cmap-fix.ts`, because it
119
+ genuinely IS Guam-specific:** one embedded symbol font per chapter PDF
120
+ (`...+WPTypographicSymbols`, used only for curly quotes) carries a
121
+ `/ToUnicode` CMap that maps its two codes to U+0041 ('A') and U+0040 ('@')
122
+ instead of the left/right curly quote it visually renders as. Confirmed by
123
+ eye: "ADirector of Public Safety@" in raw extraction is "“Director of Public
124
+ Safety”" with those two codes substituted back — the obviously intended
125
+ reading, reproduced by any PDF viewer's own copy-paste. This is a defect in
126
+ Guam's own published PDF, not something a general-purpose extractor could
127
+ derive, so it is passed into `extractPdfText` via its new `fontCMapOverride`
128
+ option — a generic hook (match a font's own dictionary text, optionally
129
+ return a replacement `/ToUnicode` map) with nothing Guam-specific about the
130
+ mechanism itself, available to any future pack that hits a similarly broken
131
+ source PDF.
122
132
 
123
133
  ## Four capabilities — two available, two are not
124
134
 
@@ -214,7 +224,7 @@ directly, instead of just this one's:
214
224
  }
215
225
  ```
216
226
 
217
- Both URLs reach the same gateway and the same 1763+ data sources. The
227
+ Both URLs reach the same gateway and the same 1784+ data sources. The
218
228
  only difference is which pack's tools are listed **directly**; `ask_pipeworx`
219
229
  reaches all of them from either one.
220
230
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pipeworx/mcp-guam-code",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "Guam Code Annotated (GCA) — section lookup and search. Fleet #2888.",
5
5
  "type": "module",
6
6
  "main": "src/index.ts",
@@ -26,7 +26,7 @@
26
26
  "@cloudflare/workers-types": "^4.20260405.1"
27
27
  },
28
28
  "pipeworx": {
29
- "sourceHash": "v1-528944ed480fcb0b07e7646725576e69ad019ebc4e97aa1753f64ffdb7dcea81",
30
- "sourceCommit": "051ee2039fc96224cb5b7358fd69d525bced13a6"
29
+ "sourceHash": "v1-964fe40aed9923b374141088f42860d68ffb5efa97b3c7c3fc37b9902c46c79f",
30
+ "sourceCommit": "3723e46c6d115bd4a1fd2175e6bf758555e7cb50"
31
31
  }
32
32
  }
package/server.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "name": "io.github.pipeworx-io/guam-code",
4
4
  "title": "Guam Code",
5
5
  "description": "Guam Code Annotated (GCA) — section lookup and search. Fleet #2888.",
6
- "version": "0.1.0",
6
+ "version": "0.1.1",
7
7
  "websiteUrl": "https://pipeworx.io/packs/guam-code",
8
8
  "repository": {
9
9
  "url": "https://github.com/pipeworx-io/mcp-guam-code",
@@ -0,0 +1,34 @@
1
+ /**
2
+ * The ONE Guam-specific delta kept after folding this pack's pdf-text.ts
3
+ * fork into the shared extractor (fleet #2888 -> #2904). Everything else
4
+ * `gu-pdf-extract.ts` used to carry — literal strings routed through a
5
+ * font's /ToUnicode map, the overlong-/Length retry against trailing junk,
6
+ * and the fire-and-forget `inflate()` unhandled rejection — was folded into
7
+ * `shared/src/pdf-text.ts` itself because none of it was actually
8
+ * Guam-specific. This one piece genuinely is, so it has nowhere else to
9
+ * live:
10
+ *
11
+ * One embedded symbol font per chapter PDF (`...+WPTypographicSymbols`,
12
+ * used only for that chapter's curly quote marks) carries a `/ToUnicode`
13
+ * CMap that is itself WRONG in Guam's own published source file — code 1
14
+ * (meant to be a left double curly quote) maps to U+0041 ('A') and code 2
15
+ * (right curly quote) maps to U+0040 ('@'). Confirmed by eye against
16
+ * surrounding text: "ADirector of Public Safety@" in a raw extraction is
17
+ * exactly "“Director of Public Safety”" with those two codes substituted
18
+ * back — the unmistakably intended reading, reproduced by any PDF viewer's
19
+ * own copy-paste. This is a defect in the SOURCE PDF, not something a
20
+ * general-purpose extractor could detect from first principles, so it is
21
+ * corrected here by font name rather than generalized into the shared file.
22
+ *
23
+ * Pass this as `shared/src/pdf-text.ts`'s `fontCMapOverride` option — it is
24
+ * called with every font's own dictionary text and its freshly parsed
25
+ * `/ToUnicode` map, right before that map is used to decode any text, and
26
+ * may return a replacement map to override specific codes.
27
+ */
28
+ export function guamFontCMapOverride(fontDict: string, map: Map<number, number>): Map<number, number> | void {
29
+ if (!/WPTypographicSymbols/.test(fontDict)) return;
30
+ const fixed = new Map(map);
31
+ fixed.set(1, 0x201c);
32
+ fixed.set(2, 0x201d);
33
+ return fixed;
34
+ }