@pipeworx/mcp-guam-code 0.1.1 → 0.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/package.json +3 -3
- package/server.json +1 -1
- package/src/index.ts +71 -1
- package/src/server.ts +1 -1
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
|
|
6
|
+
Part of [Pipeworx](https://pipeworx.io) — an MCP gateway connecting AI agents to 1815+ 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
|
|
|
@@ -224,7 +224,7 @@ directly, instead of just this one's:
|
|
|
224
224
|
}
|
|
225
225
|
```
|
|
226
226
|
|
|
227
|
-
Both URLs reach the same gateway and the same
|
|
227
|
+
Both URLs reach the same gateway and the same 1815+ data sources. The
|
|
228
228
|
only difference is which pack's tools are listed **directly**; `ask_pipeworx`
|
|
229
229
|
reaches all of them from either one.
|
|
230
230
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@pipeworx/mcp-guam-code",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
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-
|
|
30
|
-
"sourceCommit": "
|
|
29
|
+
"sourceHash": "v1-0e8b06ad75d31b79367ea7bccec933bfae1665a234e87b2fd47a9220c214f878",
|
|
30
|
+
"sourceCommit": "fe38188882d0fe91e5a45d82b7b989b4aae1e8b6"
|
|
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.
|
|
6
|
+
"version": "0.1.2",
|
|
7
7
|
"websiteUrl": "https://pipeworx.io/packs/guam-code",
|
|
8
8
|
"repository": {
|
|
9
9
|
"url": "https://github.com/pipeworx-io/mcp-guam-code",
|
package/src/index.ts
CHANGED
|
@@ -935,6 +935,48 @@ function unescapePdfLiteral(s: string): string {
|
|
|
935
935
|
return out;
|
|
936
936
|
}
|
|
937
937
|
|
|
938
|
+
/**
|
|
939
|
+
* Recover the ORIGINAL raw byte (0-255) that `new TextDecoder('latin1')`
|
|
940
|
+
* produced a given codepoint for. This exists because the WHATWG Encoding
|
|
941
|
+
* Standard makes "latin1" an ALIAS for "windows-1252", not true ISO-8859-1 —
|
|
942
|
+
* every browser and Node's TextDecoder follow that spec. Bytes 0x00-0x7F and
|
|
943
|
+
* 0xA0-0xFF decode as identity either way, but bytes 0x80-0x9F come back as
|
|
944
|
+
* windows-1252's typographic symbols (0x99 -> U+2122 "™", 0x87 -> U+2021
|
|
945
|
+
* "‡", …) instead of themselves — so `charCodeAt(i) & 0xff`, used everywhere
|
|
946
|
+
* else in this file to recover a raw byte from a decoded string, silently
|
|
947
|
+
* returns the WRONG byte for any of those 32 codepoints (U+2122 & 0xff is
|
|
948
|
+
* 0x22, not the real 0x99).
|
|
949
|
+
*
|
|
950
|
+
* This only matters where the decoded character is being used as DATA (a
|
|
951
|
+
* CID half-byte, a `mapped1` font's 1-byte code) rather than as the actual
|
|
952
|
+
* text it renders (a true WinAnsi-encoded character, where the windows-1252
|
|
953
|
+
* reading IS the correct glyph — see `fontDecoderFor`'s `'winansi'` kind,
|
|
954
|
+
* which returns the decoded string unchanged on purpose and must NOT be
|
|
955
|
+
* routed through this function). Found on mainland China's NPC/MOJ law PDFs
|
|
956
|
+
* (cn-law, fleet #3136): Founder PDFGenerator (方正) writes CJK body text as
|
|
957
|
+
* LITERAL strings under a Type0/Identity-H CID font, and roughly an eighth
|
|
958
|
+
* of all 2-byte CIDs have at least one half-byte landing in 0x80-0x9F —
|
|
959
|
+
* `合` (U+5408, CID 0x0F87) was coming back as `骨` (U+9AA8) because its low
|
|
960
|
+
* byte 0x87 decoded to U+2021, and `U+2021 & 0xff` (0x21) is a different,
|
|
961
|
+
* also-valid CID that happens to mean `骨` in the same font.
|
|
962
|
+
*/
|
|
963
|
+
function rawByteFromLatin1Char(code: number): number {
|
|
964
|
+
const b = WIN1252_HIGH_TO_BYTE.get(code);
|
|
965
|
+
return b !== undefined ? b : code & 0xff;
|
|
966
|
+
}
|
|
967
|
+
// windows-1252's 0x80-0x9F table (the WHATWG "windows-1252" index), inverted
|
|
968
|
+
// codepoint -> original byte. 0x81/0x8D/0x8F/0x90/0x9D are undefined in that
|
|
969
|
+
// table and decode as themselves (identity), so they need no entry here.
|
|
970
|
+
const WIN1252_HIGH_TO_BYTE = new Map<number, number>([
|
|
971
|
+
[0x20ac, 0x80], [0x201a, 0x82], [0x0192, 0x83], [0x201e, 0x84],
|
|
972
|
+
[0x2026, 0x85], [0x2020, 0x86], [0x2021, 0x87], [0x02c6, 0x88],
|
|
973
|
+
[0x2030, 0x89], [0x0160, 0x8a], [0x2039, 0x8b], [0x0152, 0x8c],
|
|
974
|
+
[0x017d, 0x8e], [0x2018, 0x91], [0x2019, 0x92], [0x201c, 0x93],
|
|
975
|
+
[0x201d, 0x94], [0x2022, 0x95], [0x2013, 0x96], [0x2014, 0x97],
|
|
976
|
+
[0x02dc, 0x98], [0x2122, 0x99], [0x0161, 0x9a], [0x203a, 0x9b],
|
|
977
|
+
[0x0153, 0x9c], [0x017e, 0x9e], [0x0178, 0x9f],
|
|
978
|
+
]);
|
|
979
|
+
|
|
938
980
|
interface RawObject {
|
|
939
981
|
dict: string;
|
|
940
982
|
streamBytes: Uint8Array | null;
|
|
@@ -1298,10 +1340,38 @@ async function extractPdfText(buf: ArrayBuffer, options?: PdfExtractOptions): Pr
|
|
|
1298
1340
|
// font's /ToUnicode map entirely and produces line-noise control
|
|
1299
1341
|
// characters instead of the real character -- route it through the
|
|
1300
1342
|
// SAME decoder a hex run below already uses.
|
|
1343
|
+
//
|
|
1344
|
+
// 'cid' (Type0/Identity-H) is a 2-BYTE code space, same as the hex-
|
|
1345
|
+
// string path below -- a literal string's BYTES must be paired up
|
|
1346
|
+
// big-endian into one CID per pair, not looked up one byte at a time.
|
|
1347
|
+
// Found on mainland China's NPC/MOJ law PDFs (cn-law, fleet #3136):
|
|
1348
|
+
// Founder PDFGenerator (方正), the producer behind flk.npc.gov.cn's
|
|
1349
|
+
// and xzfg.moj.gov.cn's statute PDFs, writes most CJK body text as
|
|
1350
|
+
// literal strings like `(\000I)Tj` under a Type0 CID font rather than
|
|
1351
|
+
// as hex strings -- the shape this branch was missing. Decoding each
|
|
1352
|
+
// byte separately (the pre-fix behavior) looks up CID 0x00 and CID
|
|
1353
|
+
// 0x49 independently instead of the real CID 0x0049, so virtually
|
|
1354
|
+
// every CJK glyph misses its ToUnicode entry and comes back as
|
|
1355
|
+
// U+FFFD -- silently: no warning, a non-empty result, just wrong.
|
|
1356
|
+
// Measured against 中华人民共和国个人信息保护法 (PIPL)'s official
|
|
1357
|
+
// gazette PDF: 18,929 of 19,858 extracted characters were U+FFFD
|
|
1358
|
+
// before this fix (95%), 0 after, and `第十三条` (Article 13) and its
|
|
1359
|
+
// neighbors read correctly. If the literal string has an odd byte
|
|
1360
|
+
// count (shouldn't happen for a well-formed 2-byte-code run), the
|
|
1361
|
+
// trailing lone byte is silently dropped rather than guessed at.
|
|
1301
1362
|
if (dec.kind === 'winansi') return unescaped;
|
|
1363
|
+
if (dec.kind === 'cid') {
|
|
1364
|
+
let out = '';
|
|
1365
|
+
for (let i = 0; i + 2 <= unescaped.length; i += 2) {
|
|
1366
|
+
const code =
|
|
1367
|
+
(rawByteFromLatin1Char(unescaped.charCodeAt(i)) << 8) | rawByteFromLatin1Char(unescaped.charCodeAt(i + 1));
|
|
1368
|
+
out += String.fromCodePoint(dec.map.get(code) ?? 0xfffd);
|
|
1369
|
+
}
|
|
1370
|
+
return out;
|
|
1371
|
+
}
|
|
1302
1372
|
let out = '';
|
|
1303
1373
|
for (let i = 0; i < unescaped.length; i++) {
|
|
1304
|
-
const code = unescaped.charCodeAt(i)
|
|
1374
|
+
const code = rawByteFromLatin1Char(unescaped.charCodeAt(i));
|
|
1305
1375
|
out += String.fromCodePoint(dec.map.get(code) ?? 0xfffd);
|
|
1306
1376
|
}
|
|
1307
1377
|
return out;
|
package/src/server.ts
CHANGED
|
@@ -11,7 +11,7 @@ import * as bakedIndexModule from './gu-baked-data.js';
|
|
|
11
11
|
const bakedIndex = Object.fromEntries(Object.entries(bakedIndexModule));
|
|
12
12
|
|
|
13
13
|
const server = new Server(
|
|
14
|
-
{ name: '@pipeworx/mcp-guam-code', version: '0.1.
|
|
14
|
+
{ name: '@pipeworx/mcp-guam-code', version: '0.1.2' },
|
|
15
15
|
{ capabilities: { tools: {} } },
|
|
16
16
|
);
|
|
17
17
|
|