@paparats/shared 2.1.1 → 2.2.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.
package/dist/index.d.ts CHANGED
@@ -2,6 +2,7 @@ export { validateIndexingPaths } from './path-validation.js';
2
2
  export { normalizeExcludePatterns } from './exclude-patterns.js';
3
3
  export { LANGUAGE_EXCLUDE_DEFAULTS, COMMON_EXCLUDE, DEFAULT_EXCLUDE_BARE, getDefaultExcludeForLanguages, } from './language-excludes.js';
4
4
  export { createGitignoreFilter, filterFilesByGitignore } from './gitignore.js';
5
+ export { detectNonSource, type NonSourceVerdict } from './non-source-detect.js';
5
6
  export { detectLanguageByPath, detectProjectLanguage } from './language-detect.js';
6
7
  export { DEFAULT_GROUP } from './group.js';
7
8
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAE,KAAK,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
package/dist/index.js CHANGED
@@ -2,6 +2,7 @@ export { validateIndexingPaths } from './path-validation.js';
2
2
  export { normalizeExcludePatterns } from './exclude-patterns.js';
3
3
  export { LANGUAGE_EXCLUDE_DEFAULTS, COMMON_EXCLUDE, DEFAULT_EXCLUDE_BARE, getDefaultExcludeForLanguages, } from './language-excludes.js';
4
4
  export { createGitignoreFilter, filterFilesByGitignore } from './gitignore.js';
5
+ export { detectNonSource } from './non-source-detect.js';
5
6
  export { detectLanguageByPath, detectProjectLanguage } from './language-detect.js';
6
7
  export { DEFAULT_GROUP } from './group.js';
7
8
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AAC7D,OAAO,EAAE,wBAAwB,EAAE,MAAM,uBAAuB,CAAC;AACjE,OAAO,EACL,yBAAyB,EACzB,cAAc,EACd,oBAAoB,EACpB,6BAA6B,GAC9B,MAAM,wBAAwB,CAAC;AAChC,OAAO,EAAE,qBAAqB,EAAE,sBAAsB,EAAE,MAAM,gBAAgB,CAAC;AAC/E,OAAO,EAAE,eAAe,EAAyB,MAAM,wBAAwB,CAAC;AAChF,OAAO,EAAE,oBAAoB,EAAE,qBAAqB,EAAE,MAAM,sBAAsB,CAAC;AACnF,OAAO,EAAE,aAAa,EAAE,MAAM,YAAY,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"language-excludes.d.ts","sourceRoot":"","sources":["../src/language-excludes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAgH9D,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UAiBhC,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAW3E"}
1
+ {"version":3,"file":"language-excludes.d.ts","sourceRoot":"","sources":["../src/language-excludes.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,eAAO,MAAM,yBAAyB,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CA6H9D,CAAC;AAEF,eAAO,MAAM,cAAc,UAAW,CAAC;AAEvC;;;GAGG;AACH,eAAO,MAAM,oBAAoB,UAiBhC,CAAC;AAEF,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,MAAM,EAAE,GAAG,MAAM,EAAE,CAW3E"}
@@ -33,6 +33,16 @@ export const LANGUAGE_EXCLUDE_DEFAULTS = {
33
33
  '.vercel',
34
34
  '.swc',
35
35
  '*.tsbuildinfo',
36
+ // Machine-generated / bundled artifacts: source-file extensions but no
37
+ // source structure (minified bundles, base64 asset blobs). A dense wall of
38
+ // tokens is worthless for retrieval and pathological for the embedder. The
39
+ // structural detector (non-source-detect.ts) is the content-based backstop;
40
+ // these globs skip the obvious classes without reading the file.
41
+ '**/*.min.js',
42
+ '**/*.min.css',
43
+ '**/*.bundle.js',
44
+ '**/*.data.ts',
45
+ '**/*.data.js',
36
46
  ],
37
47
  javascript: [
38
48
  'node_modules',
@@ -44,6 +54,9 @@ export const LANGUAGE_EXCLUDE_DEFAULTS = {
44
54
  'out',
45
55
  '.nuxt',
46
56
  '.output',
57
+ '**/*.min.js',
58
+ '**/*.min.css',
59
+ '**/*.bundle.js',
47
60
  ],
48
61
  python: [
49
62
  'venv',
@@ -1 +1 @@
1
- {"version":3,"file":"language-excludes.js","sourceRoot":"","sources":["../src/language-excludes.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"language-excludes.js","sourceRoot":"","sources":["../src/language-excludes.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ /**
2
+ * Heuristic detection of non-source content — base64/data-URI blobs, minified
3
+ * bundles, and other machine-generated text that has a source-file extension but
4
+ * no source-file structure.
5
+ *
6
+ * Why this exists: files like `convex/export/pptx/assets/bg.data.ts` are `.ts`
7
+ * by name (so language detection routes them to the AST/embedding path) but hold
8
+ * a single multi-hundred-KB base64 string literal. Embedding that is worthless
9
+ * for retrieval and pathological for the model — a dense wall of high-entropy
10
+ * tokens drives llama-server into timeouts/OOM. We detect and skip such content
11
+ * BEFORE it ever reaches the embedder.
12
+ *
13
+ * The signal is structural, not name-based (name globs are a separate, coarser
14
+ * defence in language-excludes.ts): real source code has short lines, plenty of
15
+ * whitespace, and a modest alphabet; machine blobs have enormous lines, little
16
+ * whitespace, and a base64-dominated character distribution. Pure function so it
17
+ * is trivially testable and identical for the file-level and chunk-level checks.
18
+ */
19
+ /** Why a piece of content was judged non-source — surfaced in logs/telemetry. */
20
+ export interface NonSourceVerdict {
21
+ /** True when the content looks machine-generated / non-source. */
22
+ isNonSource: boolean;
23
+ /** Human-readable reason (e.g. "max line 780191 chars"). Empty when source. */
24
+ reason: string;
25
+ }
26
+ /**
27
+ * Judge whether `content` is non-source machine data unsuitable for embedding.
28
+ *
29
+ * Applies to both a whole file (pre-chunking) and an individual chunk
30
+ * (pre-embedding). Short inputs are always treated as source — the statistics
31
+ * are unreliable below {@link MIN_LENGTH_TO_ANALYZE} and a false positive there
32
+ * would drop legitimate small files.
33
+ */
34
+ export declare function detectNonSource(content: string): NonSourceVerdict;
35
+ //# sourceMappingURL=non-source-detect.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-source-detect.d.ts","sourceRoot":"","sources":["../src/non-source-detect.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,iFAAiF;AACjF,MAAM,WAAW,gBAAgB;IAC/B,kEAAkE;IAClE,WAAW,EAAE,OAAO,CAAC;IACrB,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;CAChB;AAqBD;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,gBAAgB,CAiDjE"}
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Heuristic detection of non-source content — base64/data-URI blobs, minified
3
+ * bundles, and other machine-generated text that has a source-file extension but
4
+ * no source-file structure.
5
+ *
6
+ * Why this exists: files like `convex/export/pptx/assets/bg.data.ts` are `.ts`
7
+ * by name (so language detection routes them to the AST/embedding path) but hold
8
+ * a single multi-hundred-KB base64 string literal. Embedding that is worthless
9
+ * for retrieval and pathological for the model — a dense wall of high-entropy
10
+ * tokens drives llama-server into timeouts/OOM. We detect and skip such content
11
+ * BEFORE it ever reaches the embedder.
12
+ *
13
+ * The signal is structural, not name-based (name globs are a separate, coarser
14
+ * defence in language-excludes.ts): real source code has short lines, plenty of
15
+ * whitespace, and a modest alphabet; machine blobs have enormous lines, little
16
+ * whitespace, and a base64-dominated character distribution. Pure function so it
17
+ * is trivially testable and identical for the file-level and chunk-level checks.
18
+ */
19
+ // Thresholds. Deliberately conservative: real source (even generated-but-readable
20
+ // code, long JSON fixtures, SVG paths embedded in JSX) must pass. These fire only
21
+ // on genuinely structureless blobs. Tuning notes live next to each constant.
22
+ /** A single line this long is not hand-written source — minified/one-line blob. */
23
+ const MAX_LINE_LENGTH = 5_000;
24
+ /** Average line length above this means almost no line breaks across the file. */
25
+ const MAX_AVG_LINE_LENGTH = 1_000;
26
+ /** Below this whitespace ratio, text is a dense token wall, not code. */
27
+ const MIN_WHITESPACE_RATIO = 0.02;
28
+ /** Above this base64-alphabet ratio (over a long span), it's an encoded blob. */
29
+ const MAX_BASE64_RATIO = 0.95;
30
+ /** Skip the analysis for short content — the ratios are noisy on tiny inputs. */
31
+ const MIN_LENGTH_TO_ANALYZE = 512;
32
+ // [A-Za-z0-9+/=_-] — the base64 / base64url alphabet plus padding.
33
+ const BASE64_CHAR = /[A-Za-z0-9+/=_-]/;
34
+ const WHITESPACE_CHAR = /\s/;
35
+ /**
36
+ * Judge whether `content` is non-source machine data unsuitable for embedding.
37
+ *
38
+ * Applies to both a whole file (pre-chunking) and an individual chunk
39
+ * (pre-embedding). Short inputs are always treated as source — the statistics
40
+ * are unreliable below {@link MIN_LENGTH_TO_ANALYZE} and a false positive there
41
+ * would drop legitimate small files.
42
+ */
43
+ export function detectNonSource(content) {
44
+ const source = () => ({ isNonSource: false, reason: '' });
45
+ if (content.length < MIN_LENGTH_TO_ANALYZE)
46
+ return source();
47
+ // Longest single line — the strongest single signal for minified/one-line blobs.
48
+ let maxLine = 0;
49
+ let cur = 0;
50
+ for (let i = 0; i < content.length; i++) {
51
+ if (content.charCodeAt(i) === 10 /* \n */) {
52
+ if (cur > maxLine)
53
+ maxLine = cur;
54
+ cur = 0;
55
+ }
56
+ else {
57
+ cur++;
58
+ }
59
+ }
60
+ if (cur > maxLine)
61
+ maxLine = cur;
62
+ if (maxLine > MAX_LINE_LENGTH) {
63
+ return { isNonSource: true, reason: `line of ${maxLine} chars (minified/blob)` };
64
+ }
65
+ // Character-distribution pass: whitespace ratio + base64-alphabet dominance.
66
+ let whitespace = 0;
67
+ let base64 = 0;
68
+ for (let i = 0; i < content.length; i++) {
69
+ const ch = content[i];
70
+ if (WHITESPACE_CHAR.test(ch))
71
+ whitespace++;
72
+ else if (BASE64_CHAR.test(ch))
73
+ base64++;
74
+ }
75
+ const len = content.length;
76
+ const whitespaceRatio = whitespace / len;
77
+ const base64Ratio = base64 / len;
78
+ // Average line length: total length divided by line count.
79
+ const lineCount = countLines(content);
80
+ const avgLine = len / lineCount;
81
+ if (whitespaceRatio < MIN_WHITESPACE_RATIO && base64Ratio > MAX_BASE64_RATIO) {
82
+ return {
83
+ isNonSource: true,
84
+ reason: `dense base64 blob (${(base64Ratio * 100).toFixed(0)}% base64, ${(whitespaceRatio * 100).toFixed(1)}% whitespace)`,
85
+ };
86
+ }
87
+ if (avgLine > MAX_AVG_LINE_LENGTH) {
88
+ return { isNonSource: true, reason: `avg line ${avgLine.toFixed(0)} chars (no structure)` };
89
+ }
90
+ return source();
91
+ }
92
+ function countLines(content) {
93
+ let n = 1;
94
+ for (let i = 0; i < content.length; i++) {
95
+ if (content.charCodeAt(i) === 10)
96
+ n++;
97
+ }
98
+ return n;
99
+ }
100
+ //# sourceMappingURL=non-source-detect.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-source-detect.js","sourceRoot":"","sources":["../src/non-source-detect.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=non-source-detect.test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-source-detect.test.d.ts","sourceRoot":"","sources":["../src/non-source-detect.test.ts"],"names":[],"mappings":""}
@@ -0,0 +1,76 @@
1
+ import { describe, it, expect } from 'vitest';
2
+ import { detectNonSource } from './non-source-detect.js';
3
+ // A base64-ish string of the requested length — the shape of the pptx asset
4
+ // blobs that stalled the embedder (convex/export/pptx/assets/*.data.ts).
5
+ function base64Blob(len) {
6
+ const alphabet = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/';
7
+ let out = '';
8
+ for (let i = 0; i < len; i++)
9
+ out += alphabet[i % alphabet.length];
10
+ return out;
11
+ }
12
+ describe('detectNonSource — flags machine/non-source content', () => {
13
+ it('flags a single-line base64 asset blob (the .data.ts case)', () => {
14
+ const content = `export const asset = "${base64Blob(400_000)}";`;
15
+ const v = detectNonSource(content);
16
+ expect(v.isNonSource).toBe(true);
17
+ expect(v.reason).toMatch(/minified|blob|base64|structure/);
18
+ });
19
+ it('flags a data-URI export', () => {
20
+ const content = `export default "data:image/png;base64,${base64Blob(50_000)}";`;
21
+ expect(detectNonSource(content).isNonSource).toBe(true);
22
+ });
23
+ it('flags minified JS (one enormous line)', () => {
24
+ const min = `!function(){var a=${base64Blob(20_000)};return a}();`;
25
+ expect(detectNonSource(min).isNonSource).toBe(true);
26
+ });
27
+ it('flags a dense base64 wall even with occasional newlines', () => {
28
+ // 200 lines of 300 base64 chars each: high base64 ratio, low whitespace,
29
+ // but no single line trips MAX_LINE_LENGTH — the distribution pass catches it.
30
+ const lines = Array.from({ length: 200 }, () => base64Blob(300));
31
+ expect(detectNonSource(lines.join('\n')).isNonSource).toBe(true);
32
+ });
33
+ });
34
+ describe('detectNonSource — passes legitimate source', () => {
35
+ it('passes normal TypeScript', () => {
36
+ const ts = `
37
+ import { foo } from './foo.js';
38
+
39
+ export function greet(name: string): string {
40
+ // Return a friendly greeting.
41
+ return \`Hello, \${name}!\`;
42
+ }
43
+
44
+ export class Service {
45
+ constructor(private readonly deps: Deps) {}
46
+ async run(): Promise<void> {
47
+ for (const item of this.deps.items) {
48
+ await this.process(item);
49
+ }
50
+ }
51
+ }
52
+ `.repeat(10);
53
+ expect(detectNonSource(ts).isNonSource).toBe(false);
54
+ });
55
+ it('passes a large but well-structured JSON fixture', () => {
56
+ const rows = Array.from({ length: 500 }, (_, i) => ` { "id": ${i}, "name": "item ${i}" }`);
57
+ const json = `[\n${rows.join(',\n')}\n]`;
58
+ expect(detectNonSource(json).isNonSource).toBe(false);
59
+ });
60
+ it('passes code with an embedded SVG path (long-ish but whitespaced)', () => {
61
+ const jsx = `
62
+ export const Icon = () => (
63
+ <svg viewBox="0 0 24 24">
64
+ <path d="M12 2L2 7v10l10 5 10-5V7z M12 4.3l6 3v6.4l-6 3-6-3V7.3z" />
65
+ </svg>
66
+ );
67
+ `.repeat(20);
68
+ expect(detectNonSource(jsx).isNonSource).toBe(false);
69
+ });
70
+ it('always treats short content as source (statistics unreliable below threshold)', () => {
71
+ expect(detectNonSource('a').isNonSource).toBe(false);
72
+ expect(detectNonSource(base64Blob(100)).isNonSource).toBe(false);
73
+ expect(detectNonSource('').isNonSource).toBe(false);
74
+ });
75
+ });
76
+ //# sourceMappingURL=non-source-detect.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"non-source-detect.test.js","sourceRoot":"","sources":["../src/non-source-detect.test.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@paparats/shared",
3
- "version": "2.1.1",
3
+ "version": "2.2.0",
4
4
  "type": "module",
5
5
  "description": "Shared utilities for Paparats MCP - path validation, gitignore filtering, language-aware exclude patterns",
6
6
  "license": "MIT",