@johannes.latzel/llm-chat-file 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.
- package/LICENSE +7 -0
- package/README.md +34 -0
- package/dist/index.d.ts +15 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/lib/config.d.ts +89 -0
- package/dist/lib/config.d.ts.map +1 -0
- package/dist/lib/config.js +155 -0
- package/dist/lib/config.js.map +1 -0
- package/dist/lib/helpers.d.ts +9 -0
- package/dist/lib/helpers.d.ts.map +1 -0
- package/dist/lib/helpers.js +17 -0
- package/dist/lib/helpers.js.map +1 -0
- package/dist/lib/types.d.ts +23 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +9 -0
- package/dist/lib/types.js.map +1 -0
- package/dist/lib/workspace.d.ts +75 -0
- package/dist/lib/workspace.d.ts.map +1 -0
- package/dist/lib/workspace.js +168 -0
- package/dist/lib/workspace.js.map +1 -0
- package/dist/tools/create-folder.d.ts +12 -0
- package/dist/tools/create-folder.d.ts.map +1 -0
- package/dist/tools/create-folder.js +39 -0
- package/dist/tools/create-folder.js.map +1 -0
- package/dist/tools/delete-file.d.ts +12 -0
- package/dist/tools/delete-file.d.ts.map +1 -0
- package/dist/tools/delete-file.js +54 -0
- package/dist/tools/delete-file.js.map +1 -0
- package/dist/tools/entry-info.d.ts +9 -0
- package/dist/tools/entry-info.d.ts.map +1 -0
- package/dist/tools/entry-info.js +107 -0
- package/dist/tools/entry-info.js.map +1 -0
- package/dist/tools/file-access-info.d.ts +12 -0
- package/dist/tools/file-access-info.d.ts.map +1 -0
- package/dist/tools/file-access-info.js +23 -0
- package/dist/tools/file-access-info.js.map +1 -0
- package/dist/tools/list-directory.d.ts +15 -0
- package/dist/tools/list-directory.d.ts.map +1 -0
- package/dist/tools/list-directory.js +120 -0
- package/dist/tools/list-directory.js.map +1 -0
- package/dist/tools/move-file.d.ts +12 -0
- package/dist/tools/move-file.d.ts.map +1 -0
- package/dist/tools/move-file.js +71 -0
- package/dist/tools/move-file.js.map +1 -0
- package/dist/tools/read-file.d.ts +14 -0
- package/dist/tools/read-file.d.ts.map +1 -0
- package/dist/tools/read-file.js +86 -0
- package/dist/tools/read-file.js.map +1 -0
- package/dist/tools/search.d.ts +17 -0
- package/dist/tools/search.d.ts.map +1 -0
- package/dist/tools/search.js +237 -0
- package/dist/tools/search.js.map +1 -0
- package/dist/tools/switch-workspace.d.ts +12 -0
- package/dist/tools/switch-workspace.d.ts.map +1 -0
- package/dist/tools/switch-workspace.js +34 -0
- package/dist/tools/switch-workspace.js.map +1 -0
- package/dist/tools/write-file.d.ts +15 -0
- package/dist/tools/write-file.d.ts.map +1 -0
- package/dist/tools/write-file.js +56 -0
- package/dist/tools/write-file.js.map +1 -0
- package/package.json +88 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
Copyright (c) 2026 Johannes B. Latzel
|
|
2
|
+
|
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
|
4
|
+
|
|
5
|
+
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
|
6
|
+
|
|
7
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# LLM Chat File
|
|
2
|
+
|
|
3
|
+
[](https://opensource.org/licenses/MIT)
|
|
4
|
+
[](https://www.npmjs.com/package/@johannes.latzel/llm-chat-file)
|
|
5
|
+
[](https://github.com/johanneslatzel/llm-chat-file/releases)
|
|
6
|
+
[](https://www.typescriptlang.org/)
|
|
7
|
+
[](https://github.com/johanneslatzel/llm-chat-file/pulls)
|
|
8
|
+
[](https://codecov.io/gh/johanneslatzel/llm-chat-file)
|
|
9
|
+
[](https://github.com/johanneslatzel/llm-chat-file/actions/workflows/ci.yml)
|
|
10
|
+
[](https://badge.socket.dev/npm/package/@johannes.latzel/llm-chat-file/latest)
|
|
11
|
+
|
|
12
|
+
llm-chat tools for filesystem operations.
|
|
13
|
+
|
|
14
|
+
## Prerequisites
|
|
15
|
+
|
|
16
|
+
- Node.js >= 18
|
|
17
|
+
|
|
18
|
+
## Installation
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
npm install @johannes.latzel/llm-chat-file
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Documentation
|
|
25
|
+
|
|
26
|
+
Full documentation at **[johanneslatzel.github.io/llm-chat-file/](https://johanneslatzel.github.io/llm-chat-file/)**
|
|
27
|
+
|
|
28
|
+
## License
|
|
29
|
+
|
|
30
|
+
MIT — see [`LICENSE`](LICENSE).
|
|
31
|
+
|
|
32
|
+
## Contributing
|
|
33
|
+
|
|
34
|
+
Issues and PRs welcome at [github.com/johanneslatzel/llm-chat-file](https://github.com/johanneslatzel/llm-chat-file).
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
export { SearchConfiguration, FileConfiguration, DirectoryConfiguration } from './lib/config.js';
|
|
2
|
+
export { AccessType } from './lib/types.js';
|
|
3
|
+
export type { Access, WalkEntry } from './lib/types.js';
|
|
4
|
+
export { Workspace } from './lib/workspace.js';
|
|
5
|
+
export { ReadFileTool } from './tools/read-file.js';
|
|
6
|
+
export { WriteFileTool } from './tools/write-file.js';
|
|
7
|
+
export { SearchEntriesTool } from './tools/search.js';
|
|
8
|
+
export { ListDirectoryTool } from './tools/list-directory.js';
|
|
9
|
+
export { CreateFolderTool } from './tools/create-folder.js';
|
|
10
|
+
export { DeleteFileTool } from './tools/delete-file.js';
|
|
11
|
+
export { MoveFileTool } from './tools/move-file.js';
|
|
12
|
+
export { SwitchWorkspaceTool } from './tools/switch-workspace.js';
|
|
13
|
+
export { FileAccessInfoTool } from './tools/file-access-info.js';
|
|
14
|
+
export { EntryInfoTool } from './tools/entry-info.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACxD,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export { SearchConfiguration, FileConfiguration, DirectoryConfiguration } from './lib/config.js';
|
|
2
|
+
export { AccessType } from './lib/types.js';
|
|
3
|
+
export { Workspace } from './lib/workspace.js';
|
|
4
|
+
export { ReadFileTool } from './tools/read-file.js';
|
|
5
|
+
export { WriteFileTool } from './tools/write-file.js';
|
|
6
|
+
export { SearchEntriesTool } from './tools/search.js';
|
|
7
|
+
export { ListDirectoryTool } from './tools/list-directory.js';
|
|
8
|
+
export { CreateFolderTool } from './tools/create-folder.js';
|
|
9
|
+
export { DeleteFileTool } from './tools/delete-file.js';
|
|
10
|
+
export { MoveFileTool } from './tools/move-file.js';
|
|
11
|
+
export { SwitchWorkspaceTool } from './tools/switch-workspace.js';
|
|
12
|
+
export { FileAccessInfoTool } from './tools/file-access-info.js';
|
|
13
|
+
export { EntryInfoTool } from './tools/entry-info.js';
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,mBAAmB,EAAE,iBAAiB,EAAE,sBAAsB,EAAE,MAAM,iBAAiB,CAAC;AACjG,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAE5C,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAC/C,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,mBAAmB,CAAC;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,2BAA2B,CAAC;AAC9D,OAAO,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AACxD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,mBAAmB,EAAE,MAAM,6BAA6B,CAAC;AAClE,OAAO,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC;AACjE,OAAO,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { AccessType } from './types.js';
|
|
2
|
+
/** Configuration for file search operations (content search, name search, timestamp search, etc.). */
|
|
3
|
+
export declare class SearchConfiguration {
|
|
4
|
+
/**
|
|
5
|
+
* Maximum number of search results to return.
|
|
6
|
+
* Falls back to the `LLM_CHAT_FS_MAX_SEARCH_RESULTS` environment variable, or `50` if not set.
|
|
7
|
+
*/
|
|
8
|
+
maxSearchResults: number;
|
|
9
|
+
/**
|
|
10
|
+
* Threshold above which results are returned as a count summary instead of individual paths.
|
|
11
|
+
* Falls back to `LLM_CHAT_FS_MAX_DISPLAY_ENTRIES` or `200`.
|
|
12
|
+
*/
|
|
13
|
+
maxDisplayEntries: number;
|
|
14
|
+
/**
|
|
15
|
+
* Hard limit on total entries to traverse. Returns an error if exceeded.
|
|
16
|
+
* Falls back to `LLM_CHAT_FS_MAX_TOTAL_ENTRIES` or `5000`.
|
|
17
|
+
*/
|
|
18
|
+
maxTotalEntries: number;
|
|
19
|
+
/**
|
|
20
|
+
* Total search timeout in milliseconds. The search returns partial results if this is exceeded.
|
|
21
|
+
* Falls back to `LLM_CHAT_FS_SEARCH_TIMEOUT` or `10000`.
|
|
22
|
+
*/
|
|
23
|
+
timeoutMs: number;
|
|
24
|
+
/**
|
|
25
|
+
* @param maxSearchResults - Maximum results. Defaults to env `LLM_CHAT_FS_MAX_SEARCH_RESULTS` or `50`.
|
|
26
|
+
* @param maxDisplayEntries - Display threshold. Defaults to env `LLM_CHAT_FS_MAX_DISPLAY_ENTRIES` or `200`.
|
|
27
|
+
* @param maxTotalEntries - Hard traversal limit. Defaults to env `LLM_CHAT_FS_MAX_TOTAL_ENTRIES` or `5000`.
|
|
28
|
+
* @param timeoutMs - Total search timeout. Defaults to env `LLM_CHAT_FS_SEARCH_TIMEOUT` or `10000`.
|
|
29
|
+
*/
|
|
30
|
+
constructor(maxSearchResults?: number, maxDisplayEntries?: number, maxTotalEntries?: number, timeoutMs?: number);
|
|
31
|
+
}
|
|
32
|
+
/** Configuration that defines which directories are accessible and at what permission level. */
|
|
33
|
+
export declare class DirectoryConfiguration {
|
|
34
|
+
/** List of access entries. Must contain at least one entry. */
|
|
35
|
+
accesses: {
|
|
36
|
+
type: AccessType;
|
|
37
|
+
path: string;
|
|
38
|
+
}[];
|
|
39
|
+
/** Directory names to skip when walking directory trees (e.g. `node_modules`, `.git`). */
|
|
40
|
+
skipDirs: string[];
|
|
41
|
+
/**
|
|
42
|
+
* When `true`, resolves symlinks via `fs.realpathSync.native()` before access checks.
|
|
43
|
+
* This prevents symlink-based path traversal outside configured directories.
|
|
44
|
+
* Defaults to `false` (symlinks are followed as-is).
|
|
45
|
+
*/
|
|
46
|
+
resolveSymlinks: boolean;
|
|
47
|
+
/** The default workspace path. Used as the initial `currentPath` in the Workspace. */
|
|
48
|
+
workspacePath?: string | undefined;
|
|
49
|
+
/**
|
|
50
|
+
* Constructs a directory configuration. When called with no arguments,
|
|
51
|
+
* all values are read from environment variables. Pass specific arguments
|
|
52
|
+
* to override individual values.
|
|
53
|
+
*
|
|
54
|
+
* @param accesses - Access entries. Omit or pass `undefined` to read from env vars.
|
|
55
|
+
* @param skipDirs - Directory names to skip. Defaults to `[]` when accesses are explicitly provided.
|
|
56
|
+
* @param resolveSymlinks - Resolve symlinks before access checks. Defaults to `false` when accesses are explicitly provided.
|
|
57
|
+
* @param workspacePath - Default workspace path. Defaults to resolved `LLM_CHAT_FS_WORKSPACE` or `cwd` when reading from env.
|
|
58
|
+
*/
|
|
59
|
+
constructor(accesses?: {
|
|
60
|
+
type: AccessType;
|
|
61
|
+
path: string;
|
|
62
|
+
}[], skipDirs?: string[], resolveSymlinks?: boolean, workspacePath?: string);
|
|
63
|
+
/**
|
|
64
|
+
* Deduplicates directory accesses: for any path that appears multiple times,
|
|
65
|
+
* write access takes precedence over read access. Exact duplicates are removed.
|
|
66
|
+
*
|
|
67
|
+
* @returns A new directory configuration with deduplicated accesses.
|
|
68
|
+
*/
|
|
69
|
+
deduplicate(): DirectoryConfiguration;
|
|
70
|
+
}
|
|
71
|
+
/** Configuration for file read/write operations (character limits, etc.). */
|
|
72
|
+
export declare class FileConfiguration {
|
|
73
|
+
/**
|
|
74
|
+
* Maximum number of characters allowed per file read or write.
|
|
75
|
+
* Falls back to the `LLM_CHAT_FS_MAX_CHARS_PER_FILE` environment variable, or `10000` if not set.
|
|
76
|
+
*/
|
|
77
|
+
maxCharsPerFile: number;
|
|
78
|
+
/**
|
|
79
|
+
* Maximum file size in bytes allowed for read operations.
|
|
80
|
+
* Falls back to the `LLM_CHAT_FS_MAX_FILE_SIZE` environment variable, or `10485760` (10 MB) if not set.
|
|
81
|
+
*/
|
|
82
|
+
maxFileSize: number;
|
|
83
|
+
/**
|
|
84
|
+
* @param maxCharsPerFile - Maximum chars. Defaults to env `LLM_CHAT_FS_MAX_CHARS_PER_FILE` or `10000`.
|
|
85
|
+
* @param maxFileSize - Maximum file size in bytes. Defaults to env `LLM_CHAT_FS_MAX_FILE_SIZE` or `10485760` (10 MB).
|
|
86
|
+
*/
|
|
87
|
+
constructor(maxCharsPerFile?: number, maxFileSize?: number);
|
|
88
|
+
}
|
|
89
|
+
//# sourceMappingURL=config.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAExC,sGAAsG;AACtG,qBAAa,mBAAmB;IAC5B;;;OAGG;IACH,gBAAgB,EAAE,MAAM,CAAC;IAEzB;;;OAGG;IACH,iBAAiB,EAAE,MAAM,CAAC;IAE1B;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,SAAS,EAAE,MAAM,CAAC;IAElB;;;;;OAKG;gBAEC,gBAAgB,CAAC,EAAE,MAAM,EACzB,iBAAiB,CAAC,EAAE,MAAM,EAC1B,eAAe,CAAC,EAAE,MAAM,EACxB,SAAS,CAAC,EAAE,MAAM;CAUzB;AAED,gGAAgG;AAChG,qBAAa,sBAAsB;IAC/B,+DAA+D;IAC/D,QAAQ,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAE/C,0FAA0F;IAC1F,QAAQ,EAAE,MAAM,EAAE,CAAC;IAEnB;;;;OAIG;IACH,eAAe,EAAE,OAAO,CAAC;IAEzB,sFAAsF;IACtF,aAAa,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAEnC;;;;;;;;;OASG;gBAEC,QAAQ,CAAC,EAAE;QAAE,IAAI,EAAE,UAAU,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE,EAC/C,QAAQ,CAAC,EAAE,MAAM,EAAE,EACnB,eAAe,CAAC,EAAE,OAAO,EACzB,aAAa,CAAC,EAAE,MAAM;IA8B1B;;;;;OAKG;IACH,WAAW,IAAI,sBAAsB;CAgBxC;AAED,6EAA6E;AAC7E,qBAAa,iBAAiB;IAC1B;;;OAGG;IACH,eAAe,EAAE,MAAM,CAAC;IAExB;;;OAGG;IACH,WAAW,EAAE,MAAM,CAAC;IAEpB;;;OAGG;gBACS,eAAe,CAAC,EAAE,MAAM,EAAE,WAAW,CAAC,EAAE,MAAM;CAM7D"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import * as path from 'node:path';
|
|
2
|
+
import { AccessType } from './types.js';
|
|
3
|
+
/** Configuration for file search operations (content search, name search, timestamp search, etc.). */
|
|
4
|
+
export class SearchConfiguration {
|
|
5
|
+
/**
|
|
6
|
+
* Maximum number of search results to return.
|
|
7
|
+
* Falls back to the `LLM_CHAT_FS_MAX_SEARCH_RESULTS` environment variable, or `50` if not set.
|
|
8
|
+
*/
|
|
9
|
+
maxSearchResults;
|
|
10
|
+
/**
|
|
11
|
+
* Threshold above which results are returned as a count summary instead of individual paths.
|
|
12
|
+
* Falls back to `LLM_CHAT_FS_MAX_DISPLAY_ENTRIES` or `200`.
|
|
13
|
+
*/
|
|
14
|
+
maxDisplayEntries;
|
|
15
|
+
/**
|
|
16
|
+
* Hard limit on total entries to traverse. Returns an error if exceeded.
|
|
17
|
+
* Falls back to `LLM_CHAT_FS_MAX_TOTAL_ENTRIES` or `5000`.
|
|
18
|
+
*/
|
|
19
|
+
maxTotalEntries;
|
|
20
|
+
/**
|
|
21
|
+
* Total search timeout in milliseconds. The search returns partial results if this is exceeded.
|
|
22
|
+
* Falls back to `LLM_CHAT_FS_SEARCH_TIMEOUT` or `10000`.
|
|
23
|
+
*/
|
|
24
|
+
timeoutMs;
|
|
25
|
+
/**
|
|
26
|
+
* @param maxSearchResults - Maximum results. Defaults to env `LLM_CHAT_FS_MAX_SEARCH_RESULTS` or `50`.
|
|
27
|
+
* @param maxDisplayEntries - Display threshold. Defaults to env `LLM_CHAT_FS_MAX_DISPLAY_ENTRIES` or `200`.
|
|
28
|
+
* @param maxTotalEntries - Hard traversal limit. Defaults to env `LLM_CHAT_FS_MAX_TOTAL_ENTRIES` or `5000`.
|
|
29
|
+
* @param timeoutMs - Total search timeout. Defaults to env `LLM_CHAT_FS_SEARCH_TIMEOUT` or `10000`.
|
|
30
|
+
*/
|
|
31
|
+
constructor(maxSearchResults, maxDisplayEntries, maxTotalEntries, timeoutMs) {
|
|
32
|
+
this.maxSearchResults =
|
|
33
|
+
maxSearchResults ?? parseEnvInt('LLM_CHAT_FS_MAX_SEARCH_RESULTS', 50);
|
|
34
|
+
this.maxDisplayEntries =
|
|
35
|
+
maxDisplayEntries ?? parseEnvInt('LLM_CHAT_FS_MAX_DISPLAY_ENTRIES', 200);
|
|
36
|
+
this.maxTotalEntries =
|
|
37
|
+
maxTotalEntries ?? parseEnvInt('LLM_CHAT_FS_MAX_TOTAL_ENTRIES', 5000);
|
|
38
|
+
this.timeoutMs = timeoutMs ?? parseEnvInt('LLM_CHAT_FS_SEARCH_TIMEOUT', 10000);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
/** Configuration that defines which directories are accessible and at what permission level. */
|
|
42
|
+
export class DirectoryConfiguration {
|
|
43
|
+
/** List of access entries. Must contain at least one entry. */
|
|
44
|
+
accesses;
|
|
45
|
+
/** Directory names to skip when walking directory trees (e.g. `node_modules`, `.git`). */
|
|
46
|
+
skipDirs;
|
|
47
|
+
/**
|
|
48
|
+
* When `true`, resolves symlinks via `fs.realpathSync.native()` before access checks.
|
|
49
|
+
* This prevents symlink-based path traversal outside configured directories.
|
|
50
|
+
* Defaults to `false` (symlinks are followed as-is).
|
|
51
|
+
*/
|
|
52
|
+
resolveSymlinks;
|
|
53
|
+
/** The default workspace path. Used as the initial `currentPath` in the Workspace. */
|
|
54
|
+
workspacePath;
|
|
55
|
+
/**
|
|
56
|
+
* Constructs a directory configuration. When called with no arguments,
|
|
57
|
+
* all values are read from environment variables. Pass specific arguments
|
|
58
|
+
* to override individual values.
|
|
59
|
+
*
|
|
60
|
+
* @param accesses - Access entries. Omit or pass `undefined` to read from env vars.
|
|
61
|
+
* @param skipDirs - Directory names to skip. Defaults to `[]` when accesses are explicitly provided.
|
|
62
|
+
* @param resolveSymlinks - Resolve symlinks before access checks. Defaults to `false` when accesses are explicitly provided.
|
|
63
|
+
* @param workspacePath - Default workspace path. Defaults to resolved `LLM_CHAT_FS_WORKSPACE` or `cwd` when reading from env.
|
|
64
|
+
*/
|
|
65
|
+
constructor(accesses, skipDirs, resolveSymlinks, workspacePath) {
|
|
66
|
+
if (accesses) {
|
|
67
|
+
this.accesses = accesses;
|
|
68
|
+
this.skipDirs = skipDirs ?? [];
|
|
69
|
+
this.resolveSymlinks = resolveSymlinks ?? false;
|
|
70
|
+
this.workspacePath = workspacePath;
|
|
71
|
+
}
|
|
72
|
+
else {
|
|
73
|
+
const readDirs = parseDirs(process.env.LLM_CHAT_FS_READ_DIRS);
|
|
74
|
+
const writeDirs = parseDirs(process.env.LLM_CHAT_FS_WRITE_DIRS);
|
|
75
|
+
this.accesses = [];
|
|
76
|
+
for (const d of readDirs) {
|
|
77
|
+
this.accesses.push({ type: AccessType.Read, path: path.resolve(d) });
|
|
78
|
+
}
|
|
79
|
+
for (const d of writeDirs) {
|
|
80
|
+
this.accesses.push({ type: AccessType.Write, path: path.resolve(d) });
|
|
81
|
+
}
|
|
82
|
+
const wsPath = path.resolve(process.env.LLM_CHAT_FS_WORKSPACE ?? process.cwd());
|
|
83
|
+
const alreadyWrite = this.accesses.some((a) => a.type === AccessType.Write && a.path === wsPath);
|
|
84
|
+
if (!alreadyWrite) {
|
|
85
|
+
this.accesses.push({ type: AccessType.Write, path: wsPath });
|
|
86
|
+
}
|
|
87
|
+
this.skipDirs = parseDirs(process.env.LLM_CHAT_FS_SKIP_DIRS);
|
|
88
|
+
this.resolveSymlinks = parseEnvBool('LLM_CHAT_FS_RESOLVE_SYMLINKS', false);
|
|
89
|
+
this.workspacePath = wsPath;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Deduplicates directory accesses: for any path that appears multiple times,
|
|
94
|
+
* write access takes precedence over read access. Exact duplicates are removed.
|
|
95
|
+
*
|
|
96
|
+
* @returns A new directory configuration with deduplicated accesses.
|
|
97
|
+
*/
|
|
98
|
+
deduplicate() {
|
|
99
|
+
const seen = new Map();
|
|
100
|
+
for (const a of this.accesses) {
|
|
101
|
+
const existing = seen.get(a.path);
|
|
102
|
+
if (existing === AccessType.Write)
|
|
103
|
+
continue;
|
|
104
|
+
if (a.type === AccessType.Write || !existing) {
|
|
105
|
+
seen.set(a.path, a.type);
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
return new DirectoryConfiguration(Array.from(seen.entries()).map(([path, type]) => ({ type, path })), this.skipDirs, this.resolveSymlinks, this.workspacePath);
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
/** Configuration for file read/write operations (character limits, etc.). */
|
|
112
|
+
export class FileConfiguration {
|
|
113
|
+
/**
|
|
114
|
+
* Maximum number of characters allowed per file read or write.
|
|
115
|
+
* Falls back to the `LLM_CHAT_FS_MAX_CHARS_PER_FILE` environment variable, or `10000` if not set.
|
|
116
|
+
*/
|
|
117
|
+
maxCharsPerFile;
|
|
118
|
+
/**
|
|
119
|
+
* Maximum file size in bytes allowed for read operations.
|
|
120
|
+
* Falls back to the `LLM_CHAT_FS_MAX_FILE_SIZE` environment variable, or `10485760` (10 MB) if not set.
|
|
121
|
+
*/
|
|
122
|
+
maxFileSize;
|
|
123
|
+
/**
|
|
124
|
+
* @param maxCharsPerFile - Maximum chars. Defaults to env `LLM_CHAT_FS_MAX_CHARS_PER_FILE` or `10000`.
|
|
125
|
+
* @param maxFileSize - Maximum file size in bytes. Defaults to env `LLM_CHAT_FS_MAX_FILE_SIZE` or `10485760` (10 MB).
|
|
126
|
+
*/
|
|
127
|
+
constructor(maxCharsPerFile, maxFileSize) {
|
|
128
|
+
this.maxCharsPerFile =
|
|
129
|
+
maxCharsPerFile ?? parseEnvInt('LLM_CHAT_FS_MAX_CHARS_PER_FILE', 10000);
|
|
130
|
+
this.maxFileSize =
|
|
131
|
+
maxFileSize ?? parseEnvInt('LLM_CHAT_FS_MAX_FILE_SIZE', 10 * 1024 * 1024);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function parseEnvInt(key, fallback, min = 1) {
|
|
135
|
+
const raw = process.env[key];
|
|
136
|
+
if (raw === undefined || raw === '')
|
|
137
|
+
return Math.max(min, fallback);
|
|
138
|
+
const parsed = parseInt(raw, 10);
|
|
139
|
+
return Number.isNaN(parsed) ? Math.max(min, fallback) : Math.max(min, parsed);
|
|
140
|
+
}
|
|
141
|
+
function parseDirs(raw) {
|
|
142
|
+
if (!raw)
|
|
143
|
+
return [];
|
|
144
|
+
return raw
|
|
145
|
+
.split(',')
|
|
146
|
+
.map((s) => s.trim())
|
|
147
|
+
.filter(Boolean);
|
|
148
|
+
}
|
|
149
|
+
function parseEnvBool(key, fallback) {
|
|
150
|
+
const raw = process.env[key];
|
|
151
|
+
if (raw === undefined || raw === '')
|
|
152
|
+
return fallback;
|
|
153
|
+
return raw === 'true';
|
|
154
|
+
}
|
|
155
|
+
//# sourceMappingURL=config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Checks whether a file is binary by reading its header bytes.
|
|
3
|
+
* If the check fails (e.g. the file doesn't exist), it returns `true` to err on the side of caution.
|
|
4
|
+
*
|
|
5
|
+
* @param filePath - Path to the file to check.
|
|
6
|
+
* @returns `true` if the file is binary or the check fails, `false` if it appears to be text.
|
|
7
|
+
*/
|
|
8
|
+
export declare function isBinary(filePath: string): Promise<boolean>;
|
|
9
|
+
//# sourceMappingURL=helpers.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/lib/helpers.ts"],"names":[],"mappings":"AAEA;;;;;;GAMG;AACH,wBAAsB,QAAQ,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAMjE"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { isBinaryFile } from 'isbinaryfile';
|
|
2
|
+
/**
|
|
3
|
+
* Checks whether a file is binary by reading its header bytes.
|
|
4
|
+
* If the check fails (e.g. the file doesn't exist), it returns `true` to err on the side of caution.
|
|
5
|
+
*
|
|
6
|
+
* @param filePath - Path to the file to check.
|
|
7
|
+
* @returns `true` if the file is binary or the check fails, `false` if it appears to be text.
|
|
8
|
+
*/
|
|
9
|
+
export async function isBinary(filePath) {
|
|
10
|
+
try {
|
|
11
|
+
return await isBinaryFile(filePath);
|
|
12
|
+
}
|
|
13
|
+
catch {
|
|
14
|
+
return true;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
//# sourceMappingURL=helpers.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"helpers.js","sourceRoot":"","sources":["../../src/lib/helpers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,cAAc,CAAC;AAE5C;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAC,QAAgB;IAC3C,IAAI,CAAC;QACD,OAAO,MAAM,YAAY,CAAC,QAAQ,CAAC,CAAC;IACxC,CAAC;IAAC,MAAM,CAAC;QACL,OAAO,IAAI,CAAC;IAChB,CAAC;AACL,CAAC"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { Dirent } from 'node:fs';
|
|
2
|
+
/** Type of filesystem access (read or write). */
|
|
3
|
+
export declare enum AccessType {
|
|
4
|
+
/** Read-only access — files can be listed and read but not modified. */
|
|
5
|
+
Read = "read",
|
|
6
|
+
/** Read-write access — files can be created, modified and deleted. */
|
|
7
|
+
Write = "write"
|
|
8
|
+
}
|
|
9
|
+
/** A single filesystem access entry granting a type of access to a directory. */
|
|
10
|
+
export interface Access {
|
|
11
|
+
/** Whether this grants read or write access to the directory. */
|
|
12
|
+
type: AccessType;
|
|
13
|
+
/** Absolute path to the directory this access applies to. */
|
|
14
|
+
path: string;
|
|
15
|
+
}
|
|
16
|
+
/** An entry yielded when recursively walking a directory tree. */
|
|
17
|
+
export interface WalkEntry {
|
|
18
|
+
/** Absolute path to the file or directory. */
|
|
19
|
+
filePath: string;
|
|
20
|
+
/** `fs.Dirent` from the directory read operation, providing type and name information. */
|
|
21
|
+
dirent: Dirent;
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,SAAS,CAAC;AAEtC,iDAAiD;AACjD,oBAAY,UAAU;IAClB,wEAAwE;IACxE,IAAI,SAAS;IACb,sEAAsE;IACtE,KAAK,UAAU;CAClB;AAED,iFAAiF;AACjF,MAAM,WAAW,MAAM;IACnB,iEAAiE;IACjE,IAAI,EAAE,UAAU,CAAC;IACjB,6DAA6D;IAC7D,IAAI,EAAE,MAAM,CAAC;CAChB;AAED,kEAAkE;AAClE,MAAM,WAAW,SAAS;IACtB,8CAA8C;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,0FAA0F;IAC1F,MAAM,EAAE,MAAM,CAAC;CAClB"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/** Type of filesystem access (read or write). */
|
|
2
|
+
export var AccessType;
|
|
3
|
+
(function (AccessType) {
|
|
4
|
+
/** Read-only access — files can be listed and read but not modified. */
|
|
5
|
+
AccessType["Read"] = "read";
|
|
6
|
+
/** Read-write access — files can be created, modified and deleted. */
|
|
7
|
+
AccessType["Write"] = "write";
|
|
8
|
+
})(AccessType || (AccessType = {}));
|
|
9
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"AAEA,iDAAiD;AACjD,MAAM,CAAN,IAAY,UAKX;AALD,WAAY,UAAU;IAClB,wEAAwE;IACxE,2BAAa,CAAA;IACb,sEAAsE;IACtE,6BAAe,CAAA;AACnB,CAAC,EALW,UAAU,KAAV,UAAU,QAKrB"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { DirectoryConfiguration } from './config.js';
|
|
2
|
+
/**
|
|
3
|
+
* Manages the current workspace path and enforces access control for all file operations.
|
|
4
|
+
*
|
|
5
|
+
* Tracks which directories are accessible (read and/or write) and provides methods
|
|
6
|
+
* to check permissions, resolve paths, and switch the active workspace directory.
|
|
7
|
+
* Uses a mutex to ensure thread-safe workspace switching.
|
|
8
|
+
*/
|
|
9
|
+
export declare class Workspace {
|
|
10
|
+
/** The currently active workspace directory (absolute path). */
|
|
11
|
+
currentPath: string;
|
|
12
|
+
private cfg;
|
|
13
|
+
private mutex;
|
|
14
|
+
/**
|
|
15
|
+
* @param config - Directory configuration defining accessible paths and their permission levels.
|
|
16
|
+
* @throws {Error} If the configuration contains no access entries.
|
|
17
|
+
*/
|
|
18
|
+
constructor(config: DirectoryConfiguration);
|
|
19
|
+
/**
|
|
20
|
+
* Changes the current workspace path to a new directory, thread-safe with a mutex.
|
|
21
|
+
*
|
|
22
|
+
* @param target - Path to the new workspace directory (may be relative or absolute).
|
|
23
|
+
* @throws {Error} If the target is not within any configured accessible directory.
|
|
24
|
+
*/
|
|
25
|
+
switchWorkspace(target: string): Promise<void>;
|
|
26
|
+
/**
|
|
27
|
+
* Resolves a path against the current workspace. If the input is already absolute, `path.resolve` returns it as-is.
|
|
28
|
+
*
|
|
29
|
+
* @param input - Path to resolve (relative or absolute).
|
|
30
|
+
* @returns The resolved absolute path.
|
|
31
|
+
*/
|
|
32
|
+
normalize(input: string): string;
|
|
33
|
+
/**
|
|
34
|
+
* Checks whether the given absolute path is within any directory configured for read (or write) access.
|
|
35
|
+
*
|
|
36
|
+
* @param absPath - Absolute path to check.
|
|
37
|
+
* @returns `true` if the path is readable.
|
|
38
|
+
*/
|
|
39
|
+
canRead(absPath: string): boolean;
|
|
40
|
+
/**
|
|
41
|
+
* Checks whether the given absolute path is within any directory configured for write access.
|
|
42
|
+
*
|
|
43
|
+
* @param absPath - Absolute path to check.
|
|
44
|
+
* @returns `true` if the path is writable.
|
|
45
|
+
*/
|
|
46
|
+
canWrite(absPath: string): boolean;
|
|
47
|
+
/**
|
|
48
|
+
* Returns the list of configured directory accesses with their types.
|
|
49
|
+
*/
|
|
50
|
+
getAccesses(): {
|
|
51
|
+
type: 'read' | 'write';
|
|
52
|
+
path: string;
|
|
53
|
+
}[];
|
|
54
|
+
/**
|
|
55
|
+
* Returns the list of directory names to skip when walking (e.g. `node_modules`, `.git`).
|
|
56
|
+
*/
|
|
57
|
+
get skipDirs(): string[];
|
|
58
|
+
/** Whether symlink resolution is enabled for access checks. */
|
|
59
|
+
get resolveSymlinks(): boolean;
|
|
60
|
+
private resolvePath;
|
|
61
|
+
/**
|
|
62
|
+
* Recursively walks a directory, yielding entries for files and directories.
|
|
63
|
+
* Skips directories whose names are listed in `cfg.skipDirs`.
|
|
64
|
+
*
|
|
65
|
+
* @param dir - Directory to walk.
|
|
66
|
+
* @param onError - Optional callback invoked when a subdirectory cannot be read.
|
|
67
|
+
* Receives the directory path and the error. The walk continues with other subtrees.
|
|
68
|
+
* @yields {WalkEntry} Entries for each file and subdirectory found.
|
|
69
|
+
*/
|
|
70
|
+
walk(dir: string, onError?: (dirPath: string, error: Error) => void): AsyncGenerator<{
|
|
71
|
+
filePath: string;
|
|
72
|
+
dirent: import('node:fs').Dirent;
|
|
73
|
+
}>;
|
|
74
|
+
}
|
|
75
|
+
//# sourceMappingURL=workspace.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"workspace.d.ts","sourceRoot":"","sources":["../../src/lib/workspace.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAC;AAarD;;;;;;GAMG;AACH,qBAAa,SAAS;IAClB,gEAAgE;IAChE,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,CAAC,GAAG,CAAyB;IACpC,OAAO,CAAC,KAAK,CAAQ;IAErB;;;OAGG;gBACS,MAAM,EAAE,sBAAsB;IAoB1C;;;;;OAKG;IACG,eAAe,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAYpD;;;;;OAKG;IACH,SAAS,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM;IAIhC;;;;;OAKG;IACH,OAAO,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAWjC;;;;;OAKG;IACH,QAAQ,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO;IAQlC;;OAEG;IACH,WAAW,IAAI;QAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,EAAE;IAIzD;;OAEG;IACH,IAAI,QAAQ,IAAI,MAAM,EAAE,CAEvB;IAED,+DAA+D;IAC/D,IAAI,eAAe,IAAI,OAAO,CAE7B;IAED,OAAO,CAAC,WAAW;IAUnB;;;;;;;;OAQG;IACI,IAAI,CACP,GAAG,EAAE,MAAM,EACX,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,KAAK,KAAK,IAAI,GAClD,cAAc,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,SAAS,EAAE,MAAM,CAAA;KAAE,CAAC;CAqB5E"}
|