@caplab/read 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 (132) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +189 -0
  3. package/dist/cjs/errors/structured.d.ts +12 -0
  4. package/dist/cjs/errors/structured.d.ts.map +1 -0
  5. package/dist/cjs/errors/structured.js +124 -0
  6. package/dist/cjs/errors/structured.js.map +1 -0
  7. package/dist/cjs/factory.d.ts +3 -0
  8. package/dist/cjs/factory.d.ts.map +1 -0
  9. package/dist/cjs/factory.js +92 -0
  10. package/dist/cjs/factory.js.map +1 -0
  11. package/dist/cjs/fs/binary.d.ts +4 -0
  12. package/dist/cjs/fs/binary.d.ts.map +1 -0
  13. package/dist/cjs/fs/binary.js +116 -0
  14. package/dist/cjs/fs/binary.js.map +1 -0
  15. package/dist/cjs/fs/directory.d.ts +3 -0
  16. package/dist/cjs/fs/directory.d.ts.map +1 -0
  17. package/dist/cjs/fs/directory.js +163 -0
  18. package/dist/cjs/fs/directory.js.map +1 -0
  19. package/dist/cjs/fs/reader.d.ts +3 -0
  20. package/dist/cjs/fs/reader.d.ts.map +1 -0
  21. package/dist/cjs/fs/reader.js +145 -0
  22. package/dist/cjs/fs/reader.js.map +1 -0
  23. package/dist/cjs/index.d.ts +3 -0
  24. package/dist/cjs/index.d.ts.map +1 -0
  25. package/dist/cjs/index.js +7 -0
  26. package/dist/cjs/index.js.map +1 -0
  27. package/dist/cjs/output/formatter.d.ts +4 -0
  28. package/dist/cjs/output/formatter.d.ts.map +1 -0
  29. package/dist/cjs/output/formatter.js +26 -0
  30. package/dist/cjs/output/formatter.js.map +1 -0
  31. package/dist/cjs/output/truncation.d.ts +5 -0
  32. package/dist/cjs/output/truncation.d.ts.map +1 -0
  33. package/dist/cjs/output/truncation.js +10 -0
  34. package/dist/cjs/output/truncation.js.map +1 -0
  35. package/dist/cjs/package.json +1 -0
  36. package/dist/cjs/path/guard.d.ts +5 -0
  37. package/dist/cjs/path/guard.d.ts.map +1 -0
  38. package/dist/cjs/path/guard.js +91 -0
  39. package/dist/cjs/path/guard.js.map +1 -0
  40. package/dist/cjs/path/normalizer.d.ts +3 -0
  41. package/dist/cjs/path/normalizer.d.ts.map +1 -0
  42. package/dist/cjs/path/normalizer.js +47 -0
  43. package/dist/cjs/path/normalizer.js.map +1 -0
  44. package/dist/cjs/path/resolver.d.ts +5 -0
  45. package/dist/cjs/path/resolver.d.ts.map +1 -0
  46. package/dist/cjs/path/resolver.js +73 -0
  47. package/dist/cjs/path/resolver.js.map +1 -0
  48. package/dist/cjs/read/encoding.d.ts +5 -0
  49. package/dist/cjs/read/encoding.d.ts.map +1 -0
  50. package/dist/cjs/read/encoding.js +29 -0
  51. package/dist/cjs/read/encoding.js.map +1 -0
  52. package/dist/cjs/read/multi-file.d.ts +4 -0
  53. package/dist/cjs/read/multi-file.d.ts.map +1 -0
  54. package/dist/cjs/read/multi-file.js +293 -0
  55. package/dist/cjs/read/multi-file.js.map +1 -0
  56. package/dist/cjs/search/adapter.d.ts +3 -0
  57. package/dist/cjs/search/adapter.d.ts.map +1 -0
  58. package/dist/cjs/search/adapter.js +34 -0
  59. package/dist/cjs/search/adapter.js.map +1 -0
  60. package/dist/cjs/types/internal.d.ts +24 -0
  61. package/dist/cjs/types/internal.d.ts.map +1 -0
  62. package/dist/cjs/types/internal.js +4 -0
  63. package/dist/cjs/types/internal.js.map +1 -0
  64. package/dist/cjs/types/public.d.ts +87 -0
  65. package/dist/cjs/types/public.d.ts.map +1 -0
  66. package/dist/cjs/types/public.js +4 -0
  67. package/dist/cjs/types/public.js.map +1 -0
  68. package/dist/errors/structured.d.ts +12 -0
  69. package/dist/errors/structured.d.ts.map +1 -0
  70. package/dist/errors/structured.js +79 -0
  71. package/dist/errors/structured.js.map +1 -0
  72. package/dist/factory.d.ts +3 -0
  73. package/dist/factory.d.ts.map +1 -0
  74. package/dist/factory.js +89 -0
  75. package/dist/factory.js.map +1 -0
  76. package/dist/fs/binary.d.ts +4 -0
  77. package/dist/fs/binary.d.ts.map +1 -0
  78. package/dist/fs/binary.js +79 -0
  79. package/dist/fs/binary.js.map +1 -0
  80. package/dist/fs/directory.d.ts +3 -0
  81. package/dist/fs/directory.d.ts.map +1 -0
  82. package/dist/fs/directory.js +127 -0
  83. package/dist/fs/directory.js.map +1 -0
  84. package/dist/fs/reader.d.ts +3 -0
  85. package/dist/fs/reader.d.ts.map +1 -0
  86. package/dist/fs/reader.js +109 -0
  87. package/dist/fs/reader.js.map +1 -0
  88. package/dist/index.d.ts +3 -0
  89. package/dist/index.d.ts.map +1 -0
  90. package/dist/index.js +3 -0
  91. package/dist/index.js.map +1 -0
  92. package/dist/output/formatter.d.ts +4 -0
  93. package/dist/output/formatter.d.ts.map +1 -0
  94. package/dist/output/formatter.js +22 -0
  95. package/dist/output/formatter.js.map +1 -0
  96. package/dist/output/truncation.d.ts +5 -0
  97. package/dist/output/truncation.d.ts.map +1 -0
  98. package/dist/output/truncation.js +7 -0
  99. package/dist/output/truncation.js.map +1 -0
  100. package/dist/path/guard.d.ts +5 -0
  101. package/dist/path/guard.d.ts.map +1 -0
  102. package/dist/path/guard.js +55 -0
  103. package/dist/path/guard.js.map +1 -0
  104. package/dist/path/normalizer.d.ts +3 -0
  105. package/dist/path/normalizer.d.ts.map +1 -0
  106. package/dist/path/normalizer.js +10 -0
  107. package/dist/path/normalizer.js.map +1 -0
  108. package/dist/path/resolver.d.ts +5 -0
  109. package/dist/path/resolver.d.ts.map +1 -0
  110. package/dist/path/resolver.js +35 -0
  111. package/dist/path/resolver.js.map +1 -0
  112. package/dist/read/encoding.d.ts +5 -0
  113. package/dist/read/encoding.d.ts.map +1 -0
  114. package/dist/read/encoding.js +26 -0
  115. package/dist/read/encoding.js.map +1 -0
  116. package/dist/read/multi-file.d.ts +4 -0
  117. package/dist/read/multi-file.d.ts.map +1 -0
  118. package/dist/read/multi-file.js +257 -0
  119. package/dist/read/multi-file.js.map +1 -0
  120. package/dist/search/adapter.d.ts +3 -0
  121. package/dist/search/adapter.d.ts.map +1 -0
  122. package/dist/search/adapter.js +31 -0
  123. package/dist/search/adapter.js.map +1 -0
  124. package/dist/types/internal.d.ts +24 -0
  125. package/dist/types/internal.d.ts.map +1 -0
  126. package/dist/types/internal.js +3 -0
  127. package/dist/types/internal.js.map +1 -0
  128. package/dist/types/public.d.ts +87 -0
  129. package/dist/types/public.d.ts.map +1 -0
  130. package/dist/types/public.js +3 -0
  131. package/dist/types/public.js.map +1 -0
  132. package/package.json +62 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.d.ts","sourceRoot":"","sources":["../../src/path/guard.ts"],"names":[],"mappings":"AAGA,wBAAsB,oBAAoB,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC;IAAE,KAAK,EAAE,OAAO,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,GAAG,mBAAmB,CAAA;CAAE,CAAC,CA4D9J"}
@@ -0,0 +1,55 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs/promises';
3
+ export async function validatePathBoundary(absolutePath, workspaceRoot) {
4
+ // First check if the resolved path is within the workspace root
5
+ // This must happen before checking if the path exists
6
+ const resolvedPath = path.resolve(absolutePath);
7
+ const resolvedRoot = path.resolve(workspaceRoot);
8
+ // On Windows, check if paths are on different drives
9
+ if (process.platform === 'win32') {
10
+ const pathDrive = resolvedPath.split(path.sep)[0];
11
+ const rootDrive = resolvedRoot.split(path.sep)[0];
12
+ if (pathDrive.toLowerCase() !== rootDrive.toLowerCase()) {
13
+ return { valid: false, error: undefined };
14
+ }
15
+ }
16
+ const relativePath = path.relative(resolvedRoot, resolvedPath);
17
+ // If relative path starts with '..', it's outside the workspace
18
+ if (relativePath.startsWith('..')) {
19
+ return { valid: false, error: undefined };
20
+ }
21
+ try {
22
+ // Check if path exists to distinguish error types
23
+ await fs.stat(absolutePath);
24
+ // Resolve symlinks to prevent escape via symlinks
25
+ const realPath = await fs.realpath(absolutePath);
26
+ const realWorkspaceRoot = await fs.realpath(workspaceRoot);
27
+ const realResolvedPath = path.resolve(realPath);
28
+ const realResolvedRoot = path.resolve(realWorkspaceRoot);
29
+ // On Windows, check if resolved paths are on different drives
30
+ if (process.platform === 'win32') {
31
+ const realPathDrive = realResolvedPath.split(path.sep)[0];
32
+ const realRootDrive = realResolvedRoot.split(path.sep)[0];
33
+ if (realPathDrive.toLowerCase() !== realRootDrive.toLowerCase()) {
34
+ return { valid: false, error: undefined };
35
+ }
36
+ }
37
+ // Check if the resolved path is within the workspace root (after symlink resolution)
38
+ const realRelativePath = path.relative(realResolvedRoot, realResolvedPath);
39
+ // If relative path starts with '..', it's outside the workspace
40
+ if (realRelativePath.startsWith('..')) {
41
+ return { valid: false, error: undefined };
42
+ }
43
+ return { valid: true };
44
+ }
45
+ catch (error) {
46
+ if (error.code === 'ENOENT') {
47
+ return { valid: false, error: 'not_found' };
48
+ }
49
+ if (error.code === 'EACCES' || error.code === 'EPERM') {
50
+ return { valid: false, error: 'permission_denied' };
51
+ }
52
+ return { valid: false, error: undefined };
53
+ }
54
+ }
55
+ //# sourceMappingURL=guard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"guard.js","sourceRoot":"","sources":["../../src/path/guard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ export declare function normalizePath(inputPath: string): string;
2
+ export declare function isAbsolute(inputPath: string): boolean;
3
+ //# sourceMappingURL=normalizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.d.ts","sourceRoot":"","sources":["../../src/path/normalizer.ts"],"names":[],"mappings":"AAEA,wBAAgB,aAAa,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAIvD;AAED,wBAAgB,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAErD"}
@@ -0,0 +1,10 @@
1
+ import * as path from 'node:path';
2
+ export function normalizePath(inputPath) {
3
+ const normalized = path.normalize(inputPath);
4
+ // Convert backslashes to forward slashes for consistency
5
+ return normalized.split(path.sep).join('/');
6
+ }
7
+ export function isAbsolute(inputPath) {
8
+ return path.isAbsolute(inputPath);
9
+ }
10
+ //# sourceMappingURL=normalizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalizer.js","sourceRoot":"","sources":["../../src/path/normalizer.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAElC,MAAM,UAAU,aAAa,CAAC,SAAiB;IAC7C,MAAM,UAAU,GAAG,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,CAAC;IAC7C,yDAAyD;IACzD,OAAO,UAAU,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC9C,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAAiB;IAC1C,OAAO,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC;AACpC,CAAC"}
@@ -0,0 +1,5 @@
1
+ import type { WorkspaceConfig } from '../types/internal.js';
2
+ export declare function validateWorkspaceRoot(workspaceRoot: string): Promise<WorkspaceConfig | null>;
3
+ export declare function resolvePath(inputPath: string, workspaceRoot: string): string;
4
+ export declare function getRelativePath(absolutePath: string, workspaceRoot: string): string;
5
+ //# sourceMappingURL=resolver.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.d.ts","sourceRoot":"","sources":["../../src/path/resolver.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,wBAAsB,qBAAqB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,GAAG,IAAI,CAAC,CAqBlG;AAED,wBAAgB,WAAW,CAAC,SAAS,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAK5E;AAED,wBAAgB,eAAe,CAAC,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,GAAG,MAAM,CAInF"}
@@ -0,0 +1,35 @@
1
+ import * as path from 'node:path';
2
+ import * as fs from 'node:fs/promises';
3
+ export async function validateWorkspaceRoot(workspaceRoot) {
4
+ try {
5
+ const stat = await fs.stat(workspaceRoot);
6
+ if (!stat.isDirectory()) {
7
+ return null;
8
+ }
9
+ const resolvedRoot = path.resolve(workspaceRoot);
10
+ return {
11
+ workspaceRoot: resolvedRoot,
12
+ maxBytes: 262144,
13
+ maxLines: 2000,
14
+ maxFiles: 20,
15
+ maxTotalBytes: 1048576,
16
+ maxEntries: 1000,
17
+ maxSearchResults: 200,
18
+ };
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ export function resolvePath(inputPath, workspaceRoot) {
25
+ if (path.isAbsolute(inputPath)) {
26
+ return path.resolve(inputPath);
27
+ }
28
+ return path.resolve(workspaceRoot, inputPath);
29
+ }
30
+ export function getRelativePath(absolutePath, workspaceRoot) {
31
+ const relative = path.relative(workspaceRoot, absolutePath);
32
+ // Normalize to forward slashes for consistency
33
+ return relative.split(path.sep).join('/');
34
+ }
35
+ //# sourceMappingURL=resolver.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resolver.js","sourceRoot":"","sources":["../../src/path/resolver.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,IAAI,MAAM,WAAW,CAAC;AAClC,OAAO,KAAK,EAAE,MAAM,kBAAkB,CAAC;AAGvC,MAAM,CAAC,KAAK,UAAU,qBAAqB,CAAC,aAAqB;IAC/D,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QAC1C,IAAI,CAAC,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,OAAO,IAAI,CAAC;QACd,CAAC;QAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,aAAa,CAAC,CAAC;QAEjD,OAAO;YACL,aAAa,EAAE,YAAY;YAC3B,QAAQ,EAAE,MAAM;YAChB,QAAQ,EAAE,IAAI;YACd,QAAQ,EAAE,EAAE;YACZ,aAAa,EAAE,OAAO;YACtB,UAAU,EAAE,IAAI;YAChB,gBAAgB,EAAE,GAAG;SACtB,CAAC;IACJ,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,SAAiB,EAAE,aAAqB;IAClE,IAAI,IAAI,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;IACjC,CAAC;IACD,OAAO,IAAI,CAAC,OAAO,CAAC,aAAa,EAAE,SAAS,CAAC,CAAC;AAChD,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,YAAoB,EAAE,aAAqB;IACzE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,aAAa,EAAE,YAAY,CAAC,CAAC;IAC5D,+CAA+C;IAC/C,OAAO,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAC5C,CAAC"}
@@ -0,0 +1,5 @@
1
+ export declare function detectFileEncoding(filePath: string, requestedEncoding?: 'utf-8' | 'utf-16le' | 'utf-16be' | 'auto'): Promise<{
2
+ encoding: 'utf-8' | 'utf-16le' | 'utf-16be' | 'unknown';
3
+ error?: string;
4
+ }>;
5
+ //# sourceMappingURL=encoding.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.d.ts","sourceRoot":"","sources":["../../src/read/encoding.ts"],"names":[],"mappings":"AAEA,wBAAsB,kBAAkB,CACtC,QAAQ,EAAE,MAAM,EAChB,iBAAiB,CAAC,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,MAAM,GAC7D,OAAO,CAAC;IAAE,QAAQ,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAyBtF"}
@@ -0,0 +1,26 @@
1
+ import { detectEncoding } from '../fs/binary.js';
2
+ export async function detectFileEncoding(filePath, requestedEncoding) {
3
+ if (requestedEncoding && requestedEncoding !== 'auto') {
4
+ // Validate that the requested encoding is supported
5
+ if (requestedEncoding !== 'utf-8' && requestedEncoding !== 'utf-16le' && requestedEncoding !== 'utf-16be') {
6
+ return {
7
+ encoding: 'unknown',
8
+ error: 'unsupported_encoding',
9
+ };
10
+ }
11
+ return {
12
+ encoding: requestedEncoding,
13
+ };
14
+ }
15
+ const detection = await detectEncoding(filePath);
16
+ if (detection.encoding === 'unknown') {
17
+ return {
18
+ encoding: 'unknown',
19
+ error: 'unsupported_encoding',
20
+ };
21
+ }
22
+ return {
23
+ encoding: detection.encoding,
24
+ };
25
+ }
26
+ //# sourceMappingURL=encoding.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"encoding.js","sourceRoot":"","sources":["../../src/read/encoding.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAEjD,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,QAAgB,EAChB,iBAA8D;IAE9D,IAAI,iBAAiB,IAAI,iBAAiB,KAAK,MAAM,EAAE,CAAC;QACtD,oDAAoD;QACpD,IAAI,iBAAiB,KAAK,OAAO,IAAI,iBAAiB,KAAK,UAAU,IAAI,iBAAiB,KAAK,UAAU,EAAE,CAAC;YAC1G,OAAO;gBACL,QAAQ,EAAE,SAAS;gBACnB,KAAK,EAAE,sBAAsB;aAC9B,CAAC;QACJ,CAAC;QACD,OAAO;YACL,QAAQ,EAAE,iBAAiB;SAC5B,CAAC;IACJ,CAAC;IAED,MAAM,SAAS,GAAG,MAAM,cAAc,CAAC,QAAQ,CAAC,CAAC;IACjD,IAAI,SAAS,CAAC,QAAQ,KAAK,SAAS,EAAE,CAAC;QACrC,OAAO;YACL,QAAQ,EAAE,SAAS;YACnB,KAAK,EAAE,sBAAsB;SAC9B,CAAC;IACJ,CAAC;IAED,OAAO;QACL,QAAQ,EAAE,SAAS,CAAC,QAAQ;KAC7B,CAAC;AACJ,CAAC"}
@@ -0,0 +1,4 @@
1
+ import type { MultiFileResult, ReadMultipleFilesOptions } from '../types/public.js';
2
+ import type { WorkspaceConfig } from '../types/internal.js';
3
+ export declare function readMultipleFiles(paths: string[], workspaceConfig: WorkspaceConfig, options?: ReadMultipleFilesOptions): Promise<MultiFileResult>;
4
+ //# sourceMappingURL=multi-file.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-file.d.ts","sourceRoot":"","sources":["../../src/read/multi-file.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,eAAe,EAAkB,wBAAwB,EAAE,MAAM,oBAAoB,CAAC;AACpG,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAc5D,wBAAsB,iBAAiB,CACrC,KAAK,EAAE,MAAM,EAAE,EACf,eAAe,EAAE,eAAe,EAChC,OAAO,GAAE,wBAA6B,GACrC,OAAO,CAAC,eAAe,CAAC,CA0Q1B"}
@@ -0,0 +1,257 @@
1
+ import * as fs from 'node:fs/promises';
2
+ import * as path from 'node:path';
3
+ import { readFileWithBudget } from '../fs/reader.js';
4
+ import { validatePathBoundary } from '../path/guard.js';
5
+ import { getRelativePath } from '../path/resolver.js';
6
+ export async function readMultipleFiles(paths, workspaceConfig, options = {}) {
7
+ const maxFiles = options.maxFiles ?? workspaceConfig.maxFiles;
8
+ const maxBytes = options.maxBytes ?? workspaceConfig.maxBytes;
9
+ const maxTotalBytes = options.maxTotalBytes ?? workspaceConfig.maxTotalBytes;
10
+ const maxConcurrency = options.maxConcurrency ?? 5;
11
+ // Validate maxConcurrency to prevent deadlock
12
+ if (!Number.isFinite(maxConcurrency) || maxConcurrency <= 0) {
13
+ throw new Error('maxConcurrency must be a positive finite number');
14
+ }
15
+ const results = [];
16
+ let totalBytesRead = 0;
17
+ let totalBytesSkipped = 0;
18
+ // Phase 1: Stat all files in input order (sequential, deterministic)
19
+ const fileStats = [];
20
+ for (const inputPath of paths) {
21
+ const absolutePath = path.resolve(workspaceConfig.workspaceRoot, inputPath);
22
+ const relativePath = getRelativePath(absolutePath, workspaceConfig.workspaceRoot);
23
+ // Check path boundary
24
+ const boundaryCheck = await validatePathBoundary(absolutePath, workspaceConfig.workspaceRoot);
25
+ if (!boundaryCheck.valid) {
26
+ if (boundaryCheck.error === 'not_found') {
27
+ fileStats.push({
28
+ path: absolutePath,
29
+ relativePath,
30
+ size: 0,
31
+ exists: false,
32
+ accessible: false,
33
+ outsideWorkspace: false,
34
+ });
35
+ }
36
+ else if (boundaryCheck.error === 'permission_denied') {
37
+ fileStats.push({
38
+ path: absolutePath,
39
+ relativePath,
40
+ size: 0,
41
+ exists: true,
42
+ accessible: false,
43
+ outsideWorkspace: false,
44
+ });
45
+ }
46
+ else {
47
+ // Outside workspace
48
+ fileStats.push({
49
+ path: absolutePath,
50
+ relativePath,
51
+ size: 0,
52
+ exists: false,
53
+ accessible: false,
54
+ outsideWorkspace: true,
55
+ });
56
+ }
57
+ continue;
58
+ }
59
+ try {
60
+ const stats = await fs.stat(absolutePath);
61
+ fileStats.push({
62
+ path: absolutePath,
63
+ relativePath,
64
+ size: stats.size,
65
+ exists: true,
66
+ accessible: true,
67
+ outsideWorkspace: false,
68
+ });
69
+ }
70
+ catch (error) {
71
+ const isNotFound = error.code === 'ENOENT';
72
+ const isPermissionDenied = error.code === 'EACCES' || error.code === 'EPERM';
73
+ fileStats.push({
74
+ path: absolutePath,
75
+ relativePath,
76
+ size: 0,
77
+ exists: !isNotFound,
78
+ accessible: !isPermissionDenied,
79
+ outsideWorkspace: false,
80
+ });
81
+ }
82
+ }
83
+ // Phase 2: Apply maxFiles limit after stat-phase failures
84
+ let admittedFiles = fileStats.filter(f => f.exists && f.accessible);
85
+ const maxFilesSkipped = fileStats.filter(f => f.exists && f.accessible).slice(maxFiles);
86
+ admittedFiles = admittedFiles.slice(0, maxFiles);
87
+ // Phase 3: Reserve budget based on min(stat.size, effectiveMaxBytes)
88
+ let budgetReserved = 0;
89
+ const admittedWithBudget = [];
90
+ const budgetSkipped = [];
91
+ for (const fileInfo of admittedFiles) {
92
+ const effectiveMaxBytes = Math.min(fileInfo.size, maxBytes);
93
+ if (budgetReserved + effectiveMaxBytes <= maxTotalBytes) {
94
+ budgetReserved += effectiveMaxBytes;
95
+ admittedWithBudget.push(fileInfo);
96
+ }
97
+ else {
98
+ budgetSkipped.push(fileInfo);
99
+ }
100
+ }
101
+ // Phase 4: Read admitted files with bounded parallelism
102
+ const readPromises = [];
103
+ const activePromises = [];
104
+ let index = 0;
105
+ const processNext = async () => {
106
+ while (index < admittedWithBudget.length || activePromises.length > 0) {
107
+ // Fill up to maxConcurrency
108
+ while (index < admittedWithBudget.length && activePromises.length < maxConcurrency) {
109
+ const fileInfo = admittedWithBudget[index++];
110
+ const promise = (async () => {
111
+ try {
112
+ const result = await readFileWithBudget(fileInfo.path, maxBytes, workspaceConfig.maxLines, 'auto', workspaceConfig.workspaceRoot);
113
+ results.push({
114
+ path: fileInfo.path,
115
+ relativePath: fileInfo.relativePath,
116
+ result,
117
+ });
118
+ if (result.success) {
119
+ totalBytesRead += result.bytesRead;
120
+ }
121
+ }
122
+ catch (error) {
123
+ // Re-throw unexpected errors (e.g., RangeError from invalid API usage)
124
+ if (error instanceof RangeError || error instanceof TypeError) {
125
+ throw error;
126
+ }
127
+ // Only map known I/O errors to permission_denied
128
+ results.push({
129
+ path: fileInfo.path,
130
+ relativePath: fileInfo.relativePath,
131
+ result: {
132
+ success: false,
133
+ error: 'permission_denied',
134
+ path: fileInfo.path,
135
+ relativePath: fileInfo.relativePath,
136
+ },
137
+ });
138
+ }
139
+ })();
140
+ activePromises.push(promise);
141
+ readPromises.push(promise);
142
+ // Remove from active when done
143
+ promise.then(() => {
144
+ const idx = activePromises.indexOf(promise);
145
+ if (idx !== -1) {
146
+ activePromises.splice(idx, 1);
147
+ }
148
+ }).catch(() => {
149
+ // Ignore errors here - they're already handled in the worker
150
+ const idx = activePromises.indexOf(promise);
151
+ if (idx !== -1) {
152
+ activePromises.splice(idx, 1);
153
+ }
154
+ });
155
+ }
156
+ // Wait for at least one to complete if we're at capacity
157
+ if (activePromises.length >= maxConcurrency) {
158
+ await Promise.race(activePromises);
159
+ }
160
+ else if (index >= admittedWithBudget.length && activePromises.length > 0) {
161
+ // No more to enqueue, wait for remaining
162
+ await Promise.all(activePromises);
163
+ }
164
+ else {
165
+ // Break if nothing to do
166
+ if (index >= admittedWithBudget.length && activePromises.length === 0) {
167
+ break;
168
+ }
169
+ // Small delay to avoid busy-wait
170
+ await new Promise(resolve => setImmediate(resolve));
171
+ }
172
+ }
173
+ };
174
+ await processNext();
175
+ await Promise.all(readPromises);
176
+ // Add stat-phase failures
177
+ for (const fileInfo of fileStats) {
178
+ if (fileInfo.outsideWorkspace) {
179
+ results.push({
180
+ path: fileInfo.path,
181
+ relativePath: fileInfo.relativePath,
182
+ result: {
183
+ success: false,
184
+ error: 'path_outside_workspace',
185
+ path: fileInfo.path,
186
+ relativePath: fileInfo.relativePath,
187
+ },
188
+ });
189
+ }
190
+ else if (!fileInfo.exists) {
191
+ results.push({
192
+ path: fileInfo.path,
193
+ relativePath: fileInfo.relativePath,
194
+ result: {
195
+ success: false,
196
+ error: 'file_not_found',
197
+ path: fileInfo.path,
198
+ relativePath: fileInfo.relativePath,
199
+ },
200
+ });
201
+ }
202
+ else if (!fileInfo.accessible) {
203
+ results.push({
204
+ path: fileInfo.path,
205
+ relativePath: fileInfo.relativePath,
206
+ result: {
207
+ success: false,
208
+ error: 'permission_denied',
209
+ path: fileInfo.path,
210
+ relativePath: fileInfo.relativePath,
211
+ },
212
+ });
213
+ }
214
+ }
215
+ // Add maxFiles skipped files
216
+ for (const fileInfo of maxFilesSkipped) {
217
+ results.push({
218
+ path: fileInfo.path,
219
+ relativePath: fileInfo.relativePath,
220
+ result: {
221
+ success: false,
222
+ error: 'skipped_due_to_max_files',
223
+ path: fileInfo.path,
224
+ relativePath: fileInfo.relativePath,
225
+ },
226
+ });
227
+ }
228
+ // Add budget-skipped files
229
+ for (const fileInfo of budgetSkipped) {
230
+ const effectiveMaxBytes = Math.min(fileInfo.size, maxBytes);
231
+ totalBytesSkipped += effectiveMaxBytes;
232
+ results.push({
233
+ path: fileInfo.path,
234
+ relativePath: fileInfo.relativePath,
235
+ result: {
236
+ success: false,
237
+ error: 'skipped_due_to_budget',
238
+ path: fileInfo.path,
239
+ relativePath: fileInfo.relativePath,
240
+ },
241
+ });
242
+ }
243
+ // Sort results to preserve input order
244
+ const pathToIndex = new Map(paths.map((p, i) => [path.resolve(workspaceConfig.workspaceRoot, p), i]));
245
+ results.sort((a, b) => {
246
+ const indexA = pathToIndex.get(a.path) ?? Infinity;
247
+ const indexB = pathToIndex.get(b.path) ?? Infinity;
248
+ return indexA - indexB;
249
+ });
250
+ return {
251
+ success: true,
252
+ results,
253
+ totalBytesRead,
254
+ totalBytesSkipped,
255
+ };
256
+ }
257
+ //# sourceMappingURL=multi-file.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"multi-file.js","sourceRoot":"","sources":["../../src/read/multi-file.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,3 @@
1
+ import type { WorkspaceConfig } from '../types/internal.js';
2
+ export declare function fileSearch(query: string, workspaceConfig: WorkspaceConfig, options?: any): AsyncGenerator<any, void, unknown>;
3
+ //# sourceMappingURL=adapter.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.d.ts","sourceRoot":"","sources":["../../src/search/adapter.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAE5D,wBAAgB,UAAU,CACxB,KAAK,EAAE,MAAM,EACb,eAAe,EAAE,eAAe,EAChC,OAAO,CAAC,EAAE,GAAG,GACZ,cAAc,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,CAAC,CAqBpC"}
@@ -0,0 +1,31 @@
1
+ import { grepSearch } from '@caplab/grep-search';
2
+ export function fileSearch(query, workspaceConfig, options) {
3
+ // Use allowlist of safe options to prevent workspace boundary escape
4
+ const safeOptions = {
5
+ query,
6
+ cwd: workspaceConfig.workspaceRoot,
7
+ };
8
+ // Only forward specific safe options, not cwd or other boundary-related options
9
+ if (options?.regex !== undefined)
10
+ safeOptions.regex = options.regex;
11
+ if (options?.caseSensitive !== undefined)
12
+ safeOptions.caseSensitive = options.caseSensitive;
13
+ if (options?.wholeWord !== undefined)
14
+ safeOptions.wholeWord = options.wholeWord;
15
+ if (options?.multiline !== undefined)
16
+ safeOptions.multiline = options.multiline;
17
+ if (options?.extensions !== undefined)
18
+ safeOptions.extensions = options.extensions;
19
+ if (options?.ignore !== undefined)
20
+ safeOptions.ignore = options.ignore;
21
+ if (options?.beforeContext !== undefined)
22
+ safeOptions.beforeContext = options.beforeContext;
23
+ if (options?.afterContext !== undefined)
24
+ safeOptions.afterContext = options.afterContext;
25
+ if (options?.maxDepth !== undefined)
26
+ safeOptions.maxDepth = options.maxDepth;
27
+ // Always apply default maxResults from workspaceConfig
28
+ safeOptions.maxResults = options?.maxResults ?? workspaceConfig.maxSearchResults;
29
+ return grepSearch(safeOptions);
30
+ }
31
+ //# sourceMappingURL=adapter.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"adapter.js","sourceRoot":"","sources":["../../src/search/adapter.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,qBAAqB,CAAC;AAGjD,MAAM,UAAU,UAAU,CACxB,KAAa,EACb,eAAgC,EAChC,OAAa;IAEb,qEAAqE;IACrE,MAAM,WAAW,GAAQ;QACvB,KAAK;QACL,GAAG,EAAE,eAAe,CAAC,aAAa;KACnC,CAAC;IAEF,gFAAgF;IAChF,IAAI,OAAO,EAAE,KAAK,KAAK,SAAS;QAAE,WAAW,CAAC,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC;IACpE,IAAI,OAAO,EAAE,aAAa,KAAK,SAAS;QAAE,WAAW,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC5F,IAAI,OAAO,EAAE,SAAS,KAAK,SAAS;QAAE,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAChF,IAAI,OAAO,EAAE,SAAS,KAAK,SAAS;QAAE,WAAW,CAAC,SAAS,GAAG,OAAO,CAAC,SAAS,CAAC;IAChF,IAAI,OAAO,EAAE,UAAU,KAAK,SAAS;QAAE,WAAW,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;IACnF,IAAI,OAAO,EAAE,MAAM,KAAK,SAAS;QAAE,WAAW,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACvE,IAAI,OAAO,EAAE,aAAa,KAAK,SAAS;QAAE,WAAW,CAAC,aAAa,GAAG,OAAO,CAAC,aAAa,CAAC;IAC5F,IAAI,OAAO,EAAE,YAAY,KAAK,SAAS;QAAE,WAAW,CAAC,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IACzF,IAAI,OAAO,EAAE,QAAQ,KAAK,SAAS;QAAE,WAAW,CAAC,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAC;IAC7E,uDAAuD;IACvD,WAAW,CAAC,UAAU,GAAG,OAAO,EAAE,UAAU,IAAI,eAAe,CAAC,gBAAgB,CAAC;IAEjF,OAAO,UAAU,CAAC,WAAW,CAAC,CAAC;AACjC,CAAC"}
@@ -0,0 +1,24 @@
1
+ export interface WorkspaceConfig {
2
+ workspaceRoot: string;
3
+ maxBytes: number;
4
+ maxLines: number;
5
+ maxFiles: number;
6
+ maxTotalBytes: number;
7
+ maxEntries: number;
8
+ maxSearchResults: number;
9
+ }
10
+ export interface FileStat {
11
+ size: number;
12
+ isFile: boolean;
13
+ isDirectory: boolean;
14
+ }
15
+ export interface EncodingDetectionResult {
16
+ encoding: 'utf-8' | 'utf-16le' | 'utf-16be' | 'unknown';
17
+ bom: boolean;
18
+ }
19
+ export interface AdmissionResult {
20
+ admitted: boolean;
21
+ reason?: 'budget_exhausted' | 'max_files_exceeded' | 'stat_failed';
22
+ reservedBytes: number;
23
+ }
24
+ //# sourceMappingURL=internal.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.d.ts","sourceRoot":"","sources":["../../src/types/internal.ts"],"names":[],"mappings":"AAEA,MAAM,WAAW,eAAe;IAC9B,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,EAAE,MAAM,CAAC;IACnB,gBAAgB,EAAE,MAAM,CAAC;CAC1B;AAED,MAAM,WAAW,QAAQ;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,OAAO,CAAC;IAChB,WAAW,EAAE,OAAO,CAAC;CACtB;AAED,MAAM,WAAW,uBAAuB;IACtC,QAAQ,EAAE,OAAO,GAAG,UAAU,GAAG,UAAU,GAAG,SAAS,CAAC;IACxD,GAAG,EAAE,OAAO,CAAC;CACd;AAED,MAAM,WAAW,eAAe;IAC9B,QAAQ,EAAE,OAAO,CAAC;IAClB,MAAM,CAAC,EAAE,kBAAkB,GAAG,oBAAoB,GAAG,aAAa,CAAC;IACnE,aAAa,EAAE,MAAM,CAAC;CACvB"}
@@ -0,0 +1,3 @@
1
+ // Internal implementation types
2
+ export {};
3
+ //# sourceMappingURL=internal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"internal.js","sourceRoot":"","sources":["../../src/types/internal.ts"],"names":[],"mappings":"AAAA,gCAAgC"}
@@ -0,0 +1,87 @@
1
+ export interface WorkspaceReaderOptions {
2
+ workspaceRoot: string;
3
+ maxBytes?: number;
4
+ maxLines?: number;
5
+ maxFiles?: number;
6
+ maxTotalBytes?: number;
7
+ maxEntries?: number;
8
+ maxSearchResults?: number;
9
+ }
10
+ export interface ListDirectoryOptions {
11
+ maxDepth?: number;
12
+ includeHidden?: boolean;
13
+ include?: string[];
14
+ exclude?: string[];
15
+ maxEntries?: number;
16
+ }
17
+ export type DirectoryResult = {
18
+ success: true;
19
+ entries: DirectoryEntry[];
20
+ truncated: boolean;
21
+ } | {
22
+ success: false;
23
+ error: "path_not_found" | "permission_denied" | "path_outside_workspace";
24
+ path: string;
25
+ };
26
+ export interface DirectoryEntry {
27
+ path: string;
28
+ relativePath: string;
29
+ type: "file" | "directory";
30
+ size?: number;
31
+ }
32
+ export interface ReadFileOptions {
33
+ maxBytes?: number;
34
+ maxLines?: number;
35
+ encoding?: "utf-8" | "utf-16le" | "utf-16be" | "auto";
36
+ }
37
+ export type FileReadResult = {
38
+ success: true;
39
+ path: string;
40
+ relativePath: string;
41
+ content: string;
42
+ encoding: string;
43
+ truncatedBytes: boolean;
44
+ truncatedLines: boolean;
45
+ bytesRead: number;
46
+ linesRead: number;
47
+ } | {
48
+ success: false;
49
+ error: "file_not_found" | "permission_denied" | "binary_file" | "unsupported_encoding" | "path_outside_workspace" | "skipped_due_to_budget" | "skipped_due_to_max_files";
50
+ path: string;
51
+ relativePath: string;
52
+ };
53
+ export interface ReadMultipleFilesOptions {
54
+ maxFiles?: number;
55
+ maxBytes?: number;
56
+ maxTotalBytes?: number;
57
+ maxConcurrency?: number;
58
+ }
59
+ export interface MultiFileResult {
60
+ success: true;
61
+ results: Array<{
62
+ path: string;
63
+ relativePath: string;
64
+ result: FileReadResult;
65
+ }>;
66
+ totalBytesRead: number;
67
+ totalBytesSkipped: number;
68
+ }
69
+ export interface FileSearchOptions {
70
+ regex?: boolean;
71
+ wholeWord?: boolean;
72
+ caseSensitive?: boolean;
73
+ multiline?: boolean;
74
+ extensions?: string[];
75
+ ignore?: string[];
76
+ maxDepth?: number;
77
+ beforeContext?: number;
78
+ afterContext?: number;
79
+ maxResults?: number;
80
+ }
81
+ export interface WorkspaceReader {
82
+ listDirectory(path: string, options?: ListDirectoryOptions): Promise<DirectoryResult>;
83
+ readFile(path: string, options?: ReadFileOptions): Promise<FileReadResult>;
84
+ readMultipleFiles(paths: string[], options?: ReadMultipleFilesOptions): Promise<MultiFileResult>;
85
+ fileSearch(query: string, options?: FileSearchOptions): AsyncGenerator<import("@caplab/grep-search").SearchMatch, void, unknown>;
86
+ }
87
+ //# sourceMappingURL=public.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"public.d.ts","sourceRoot":"","sources":["../../src/types/public.ts"],"names":[],"mappings":"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"}