amenbo 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (81) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +171 -0
  3. package/dist/adapters/index.d.ts +22 -0
  4. package/dist/adapters/index.js +51 -0
  5. package/dist/adapters/index.js.map +1 -0
  6. package/dist/adapters/types.d.ts +21 -0
  7. package/dist/adapters/types.js +2 -0
  8. package/dist/adapters/types.js.map +1 -0
  9. package/dist/cache.d.ts +90 -0
  10. package/dist/cache.js +286 -0
  11. package/dist/cache.js.map +1 -0
  12. package/dist/cli.d.ts +46 -0
  13. package/dist/cli.js +327 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/core.d.ts +78 -0
  16. package/dist/core.js +649 -0
  17. package/dist/core.js.map +1 -0
  18. package/dist/diff.d.ts +20 -0
  19. package/dist/diff.js +44 -0
  20. package/dist/diff.js.map +1 -0
  21. package/dist/errors.d.ts +97 -0
  22. package/dist/errors.js +209 -0
  23. package/dist/errors.js.map +1 -0
  24. package/dist/extract/dataSources.d.ts +10 -0
  25. package/dist/extract/dataSources.js +115 -0
  26. package/dist/extract/dataSources.js.map +1 -0
  27. package/dist/extract/geometry.d.ts +63 -0
  28. package/dist/extract/geometry.js +77 -0
  29. package/dist/extract/geometry.js.map +1 -0
  30. package/dist/extract/markdown.d.ts +24 -0
  31. package/dist/extract/markdown.js +221 -0
  32. package/dist/extract/markdown.js.map +1 -0
  33. package/dist/extract/outline.d.ts +33 -0
  34. package/dist/extract/outline.js +128 -0
  35. package/dist/extract/outline.js.map +1 -0
  36. package/dist/extract/pdf.d.ts +22 -0
  37. package/dist/extract/pdf.js +95 -0
  38. package/dist/extract/pdf.js.map +1 -0
  39. package/dist/extract/preview.d.ts +19 -0
  40. package/dist/extract/preview.js +94 -0
  41. package/dist/extract/preview.js.map +1 -0
  42. package/dist/extract/pruning.d.ts +61 -0
  43. package/dist/extract/pruning.js +101 -0
  44. package/dist/extract/pruning.js.map +1 -0
  45. package/dist/extract/qualityScore.d.ts +67 -0
  46. package/dist/extract/qualityScore.js +98 -0
  47. package/dist/extract/qualityScore.js.map +1 -0
  48. package/dist/fetcher/browser.d.ts +85 -0
  49. package/dist/fetcher/browser.js +343 -0
  50. package/dist/fetcher/browser.js.map +1 -0
  51. package/dist/fetcher/http.d.ts +105 -0
  52. package/dist/fetcher/http.js +538 -0
  53. package/dist/fetcher/http.js.map +1 -0
  54. package/dist/fetcher/index.d.ts +41 -0
  55. package/dist/fetcher/index.js +92 -0
  56. package/dist/fetcher/index.js.map +1 -0
  57. package/dist/jp/consentBanner.d.ts +27 -0
  58. package/dist/jp/consentBanner.js +48 -0
  59. package/dist/jp/consentBanner.js.map +1 -0
  60. package/dist/jp/normalize.d.ts +30 -0
  61. package/dist/jp/normalize.js +65 -0
  62. package/dist/jp/normalize.js.map +1 -0
  63. package/dist/links.d.ts +20 -0
  64. package/dist/links.js +223 -0
  65. package/dist/links.js.map +1 -0
  66. package/dist/politeness.d.ts +66 -0
  67. package/dist/politeness.js +170 -0
  68. package/dist/politeness.js.map +1 -0
  69. package/dist/screenshot.d.ts +38 -0
  70. package/dist/screenshot.js +90 -0
  71. package/dist/screenshot.js.map +1 -0
  72. package/dist/server.d.ts +3 -0
  73. package/dist/server.js +111 -0
  74. package/dist/server.js.map +1 -0
  75. package/dist/templateLearning.d.ts +11 -0
  76. package/dist/templateLearning.js +42 -0
  77. package/dist/templateLearning.js.map +1 -0
  78. package/dist/tokens.d.ts +47 -0
  79. package/dist/tokens.js +141 -0
  80. package/dist/tokens.js.map +1 -0
  81. package/package.json +61 -0
package/dist/tokens.js ADDED
@@ -0,0 +1,141 @@
1
+ /**
2
+ * J5: CJK対応トークン見積り。
3
+ *
4
+ * 文字クラス別係数(plan.md §2 J5):
5
+ * - ASCII等(半角英数記号): 1トークン ≒ 3.8文字
6
+ * - CJK(かな/カナ/漢字/全角記号等): 1文字 ≒ 0.9トークン
7
+ *
8
+ * 設計判断: plan.mdはASCII/CJKの二区分のみを定義しているため、絵文字・キリル文字等の
9
+ * その他多バイト文字はASCII側の係数で近似する(Phase 1のスコープでは十分な精度と判断)。
10
+ */
11
+ const ASCII_CHARS_PER_TOKEN = 3.8;
12
+ const CJK_TOKENS_PER_CHAR = 0.9;
13
+ /**
14
+ * コードポイントがCJK(日本語表記に使われる文字)かどうかを判定する。
15
+ * ひらがな・カタカナ・漢字(統合漢字+拡張A)・CJK記号(全角スペースを除く)・
16
+ * 全角英数/記号(半角スペースに相当する全角スペースを除く)・半角カタカナを対象とする。
17
+ */
18
+ function isCjkCodePoint(cp) {
19
+ return ((cp >= 0x3040 && cp <= 0x309f) || // ひらがな
20
+ (cp >= 0x30a0 && cp <= 0x30ff) || // カタカナ
21
+ (cp >= 0x3400 && cp <= 0x4dbf) || // CJK統合漢字拡張A
22
+ (cp >= 0x4e00 && cp <= 0x9fff) || // CJK統合漢字
23
+ (cp >= 0xf900 && cp <= 0xfaff) || // CJK互換漢字
24
+ (cp >= 0x3001 && cp <= 0x303f) || // CJK記号(0x3000の全角スペースは除く)
25
+ (cp >= 0xff01 && cp <= 0xffef) // 全角英数/記号・半角カタカナ(0xFF00の全角スペースは除く)
26
+ );
27
+ }
28
+ /** テキストのCJK文字数と非CJK文字数を数える。 */
29
+ function countByClass(text) {
30
+ let cjk = 0;
31
+ let other = 0;
32
+ for (const ch of text) {
33
+ const cp = ch.codePointAt(0);
34
+ if (cp === undefined)
35
+ continue;
36
+ if (isCjkCodePoint(cp)) {
37
+ cjk++;
38
+ }
39
+ else if (!/\s/u.test(ch)) {
40
+ // 空白は係数計算に含めない(トークンをほぼ消費しないため)
41
+ other++;
42
+ }
43
+ }
44
+ return { cjk, other };
45
+ }
46
+ /** テキストの概算トークン数を返す(CJK文字クラス別係数)。 */
47
+ export function estimateTokens(text) {
48
+ if (text.length === 0)
49
+ return 0;
50
+ const { cjk, other } = countByClass(text);
51
+ const tokens = cjk * CJK_TOKENS_PER_CHAR + other / ASCII_CHARS_PER_TOKEN;
52
+ return Math.ceil(tokens);
53
+ }
54
+ /**
55
+ * Markdownをブロック単位(空行区切り)に分割する。
56
+ * フェンスコードブロック(```)内の空行はブロック境界として扱わない。
57
+ * templateLearning.ts(Phase 4定型ブロック除去)からも再利用される共通処理。
58
+ */
59
+ export function splitIntoBlocks(markdown) {
60
+ const lines = markdown.split("\n");
61
+ const blocks = [];
62
+ let current = [];
63
+ let inFence = false;
64
+ const flush = () => {
65
+ if (current.length === 0)
66
+ return;
67
+ const text = current.join("\n").replace(/\n+$/, "");
68
+ if (text.trim().length > 0) {
69
+ blocks.push({ text, isHeading: /^#{1,6}\s/.test(current[0] ?? "") });
70
+ }
71
+ current = [];
72
+ };
73
+ for (const line of lines) {
74
+ if (/^\s*```/.test(line)) {
75
+ inFence = !inFence;
76
+ current.push(line);
77
+ continue;
78
+ }
79
+ if (!inFence && line.trim() === "") {
80
+ flush();
81
+ continue;
82
+ }
83
+ current.push(line);
84
+ }
85
+ flush();
86
+ return blocks;
87
+ }
88
+ const MIN_TOKENS_PER_PAGE = 1;
89
+ /** 見出し直前で改ページを優先する閾値(予算に対する充填率)。 */
90
+ const HEADING_BREAK_FILL_RATIO = 0.6;
91
+ /**
92
+ * J5: max_tokens予算で見出し/段落境界を優先してページ分割する。
93
+ *
94
+ * アルゴリズム:
95
+ * 1. 空行(フェンスコード内を除く)でMarkdownをブロックに分割
96
+ * 2. ブロックを先頭から貪欲に詰め、予算超過前に新しいページへ切り替える
97
+ * 3. 見出しブロックの手前では、既に予算の60%以上を使っていれば先に改ページする
98
+ * (見出しがページ末尾に孤立するのを避けるため)
99
+ * 4. 単一ブロックが予算を超える場合(巨大な表/コード等)は、表・コードを
100
+ * 壊さないためブロックを割らずそのページ単独で返す
101
+ */
102
+ export function paginateMarkdown(markdown, maxTokens, page) {
103
+ const budget = Math.max(MIN_TOKENS_PER_PAGE, maxTokens);
104
+ const blocks = splitIntoBlocks(markdown);
105
+ if (blocks.length === 0) {
106
+ return { content: "", page: 1, totalPages: 1, tokens: 0, exceededBudget: false };
107
+ }
108
+ const pages = [];
109
+ let currentBlocks = [];
110
+ let currentTokens = 0;
111
+ for (const block of blocks) {
112
+ const blockTokens = estimateTokens(block.text);
113
+ const wouldExceed = currentTokens + blockTokens > budget;
114
+ const shouldBreakBeforeHeading = block.isHeading && currentBlocks.length > 0 && currentTokens >= budget * HEADING_BREAK_FILL_RATIO;
115
+ if (currentBlocks.length > 0 && (wouldExceed || shouldBreakBeforeHeading)) {
116
+ pages.push(currentBlocks);
117
+ currentBlocks = [];
118
+ currentTokens = 0;
119
+ }
120
+ currentBlocks.push(block.text);
121
+ currentTokens += blockTokens;
122
+ }
123
+ if (currentBlocks.length > 0) {
124
+ pages.push(currentBlocks);
125
+ }
126
+ const totalPages = pages.length;
127
+ const clampedPage = Math.min(Math.max(1, page), totalPages);
128
+ const selected = pages[clampedPage - 1] ?? [];
129
+ const content = selected.join("\n\n");
130
+ const tokens = estimateTokens(content);
131
+ return {
132
+ content,
133
+ page: clampedPage,
134
+ totalPages,
135
+ tokens,
136
+ // N6: 単一ブロックが予算超過でもページを割らずそのまま返す(paginateMarkdownの仕様)ため、
137
+ // その場合はここでtokens > budgetとなる。呼び出し側(server.ts)が明示的にユーザーへ伝える。
138
+ exceededBudget: tokens > budget,
139
+ };
140
+ }
141
+ //# sourceMappingURL=tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tokens.js","sourceRoot":"","sources":["../src/tokens.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "amenbo",
3
+ "version": "0.1.0",
4
+ "description": "Skims the web without making waves — a Japanese-web-native MCP server for low-impact, token-efficient web collection",
5
+ "type": "module",
6
+ "license": "MIT",
7
+ "author": "Rererr",
8
+ "repository": {
9
+ "type": "git",
10
+ "url": "git+https://github.com/Rererr/amenbo.git"
11
+ },
12
+ "keywords": [
13
+ "mcp",
14
+ "model-context-protocol",
15
+ "web",
16
+ "japanese",
17
+ "markdown",
18
+ "llm"
19
+ ],
20
+ "bin": {
21
+ "amenbo": "dist/cli.js"
22
+ },
23
+ "files": [
24
+ "dist"
25
+ ],
26
+ "engines": {
27
+ "node": ">=20"
28
+ },
29
+ "scripts": {
30
+ "build": "tsc",
31
+ "dev": "tsx src/server.ts",
32
+ "dev:cli": "tsx src/cli.ts",
33
+ "test": "vitest run",
34
+ "typecheck": "tsc --noEmit",
35
+ "postinstall": "playwright install chromium"
36
+ },
37
+ "dependencies": {
38
+ "@joplin/turndown-plugin-gfm": "^1.0.67",
39
+ "@modelcontextprotocol/sdk": "^1.29.0",
40
+ "@mozilla/readability": "^0.6.0",
41
+ "@napi-rs/canvas": "^1.0.2",
42
+ "better-sqlite3": "^12.11.1",
43
+ "encoding-japanese": "^2.2.0",
44
+ "linkedom": "^0.18.13",
45
+ "pdfjs-dist": "^6.1.200",
46
+ "playwright": "^1.61.1",
47
+ "robots-parser": "^3.0.1",
48
+ "turndown": "^7.2.4",
49
+ "undici": "^8.7.0",
50
+ "zod": "^4.4.3"
51
+ },
52
+ "devDependencies": {
53
+ "@types/better-sqlite3": "^7.6.13",
54
+ "@types/encoding-japanese": "^2.2.1",
55
+ "@types/node": "^26.1.1",
56
+ "@types/turndown": "^5.0.6",
57
+ "tsx": "^4.23.0",
58
+ "typescript": "^7.0.2",
59
+ "vitest": "^4.1.10"
60
+ }
61
+ }