just-bash 2.5.0 → 2.5.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/chunks/chunk-CTLU5QUH.js +17 -0
- package/dist/bin/chunks/{grep-WDHYDUUD.js → grep-QCXXYC54.js} +1 -1
- package/dist/bin/chunks/rg-GVIT6FTE.js +33 -0
- package/dist/bin/just-bash.js +99 -99
- package/dist/bin/shell/chunks/chunk-CTLU5QUH.js +17 -0
- package/dist/bin/shell/chunks/{grep-WDHYDUUD.js → grep-QCXXYC54.js} +1 -1
- package/dist/bin/shell/chunks/rg-GVIT6FTE.js +33 -0
- package/dist/bin/shell/shell.js +33 -33
- package/dist/bundle/browser.js +379 -375
- package/dist/bundle/chunks/chunk-OHJS5H37.js +16 -0
- package/dist/bundle/chunks/{grep-QVR5G7SC.js → grep-TUWLGQC2.js} +1 -1
- package/dist/bundle/chunks/rg-KTCMPGU6.js +32 -0
- package/dist/bundle/index.js +116 -116
- package/dist/commands/rg/file-types.d.ts +33 -7
- package/dist/commands/rg/gitignore.d.ts +32 -3
- package/dist/commands/rg/rg-options.d.ts +14 -0
- package/dist/commands/search-engine/index.d.ts +1 -1
- package/dist/commands/search-engine/regex.d.ts +10 -0
- package/dist/fs/in-memory-fs/in-memory-fs.d.ts +51 -0
- package/dist/fs/in-memory-fs/index.d.ts +1 -0
- package/dist/fs/init.d.ts +12 -0
- package/dist/fs/interface.d.ts +203 -0
- package/dist/fs/mountable-fs/index.d.ts +1 -0
- package/dist/fs/mountable-fs/mountable-fs.d.ts +108 -0
- package/dist/fs/overlay-fs/index.d.ts +1 -0
- package/dist/fs/overlay-fs/overlay-fs.d.ts +107 -0
- package/dist/fs/read-write-fs/index.d.ts +1 -0
- package/dist/fs/read-write-fs/read-write-fs.d.ts +47 -0
- package/dist/fs/utils.d.ts +17 -0
- package/package.json +2 -3
- package/dist/bin/chunks/chunk-X4WRNADE.js +0 -17
- package/dist/bin/chunks/rg-ALK3CYAN.js +0 -29
- package/dist/bin/shell/chunks/chunk-X4WRNADE.js +0 -17
- package/dist/bin/shell/chunks/rg-ALK3CYAN.js +0 -29
- package/dist/bundle/chunks/chunk-7VH6U2UX.js +0 -16
- package/dist/bundle/chunks/rg-43HLKW4V.js +0 -28
|
@@ -9,14 +9,40 @@ export interface FileType {
|
|
|
9
9
|
globs: string[];
|
|
10
10
|
}
|
|
11
11
|
/**
|
|
12
|
-
*
|
|
13
|
-
*
|
|
12
|
+
* Mutable file type registry for runtime type modifications
|
|
13
|
+
* Supports --type-add and --type-clear flags
|
|
14
14
|
*/
|
|
15
|
-
export declare
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
15
|
+
export declare class FileTypeRegistry {
|
|
16
|
+
private types;
|
|
17
|
+
constructor();
|
|
18
|
+
/**
|
|
19
|
+
* Add a type definition
|
|
20
|
+
* Format: "name:pattern" where pattern can be:
|
|
21
|
+
* - "*.ext" - glob pattern
|
|
22
|
+
* - "include:other" - include patterns from another type
|
|
23
|
+
*/
|
|
24
|
+
addType(spec: string): void;
|
|
25
|
+
/**
|
|
26
|
+
* Clear all patterns from a type
|
|
27
|
+
*/
|
|
28
|
+
clearType(name: string): void;
|
|
29
|
+
/**
|
|
30
|
+
* Get a type by name
|
|
31
|
+
*/
|
|
32
|
+
getType(name: string): FileType | undefined;
|
|
33
|
+
/**
|
|
34
|
+
* Get all type names
|
|
35
|
+
*/
|
|
36
|
+
getAllTypes(): Map<string, FileType>;
|
|
37
|
+
/**
|
|
38
|
+
* Check if a filename matches any of the specified types
|
|
39
|
+
*/
|
|
40
|
+
matchesType(filename: string, typeNames: string[]): boolean;
|
|
41
|
+
/**
|
|
42
|
+
* Check if a filename matches any recognized type
|
|
43
|
+
*/
|
|
44
|
+
private matchesAnyType;
|
|
45
|
+
}
|
|
20
46
|
/**
|
|
21
47
|
* Format type list for --type-list output
|
|
22
48
|
*/
|
|
@@ -29,6 +29,14 @@ export declare class GitignoreParser {
|
|
|
29
29
|
* @returns true if the path should be ignored
|
|
30
30
|
*/
|
|
31
31
|
matches(relativePath: string, isDirectory: boolean): boolean;
|
|
32
|
+
/**
|
|
33
|
+
* Check if a path is explicitly whitelisted by a negation pattern
|
|
34
|
+
*
|
|
35
|
+
* @param relativePath Path relative to the gitignore location
|
|
36
|
+
* @param isDirectory Whether the path is a directory
|
|
37
|
+
* @returns true if the path is whitelisted by a negation pattern
|
|
38
|
+
*/
|
|
39
|
+
isWhitelisted(relativePath: string, isDirectory: boolean): boolean;
|
|
32
40
|
/**
|
|
33
41
|
* Get the base path for this gitignore
|
|
34
42
|
*/
|
|
@@ -43,12 +51,24 @@ export declare class GitignoreParser {
|
|
|
43
51
|
export declare class GitignoreManager {
|
|
44
52
|
private parsers;
|
|
45
53
|
private fs;
|
|
46
|
-
private
|
|
47
|
-
|
|
54
|
+
private skipDotIgnore;
|
|
55
|
+
private skipVcsIgnore;
|
|
56
|
+
private loadedDirs;
|
|
57
|
+
constructor(fs: IFileSystem, _rootPath: string, skipDotIgnore?: boolean, skipVcsIgnore?: boolean);
|
|
48
58
|
/**
|
|
49
59
|
* Load all .gitignore and .ignore files from root to the specified path
|
|
50
60
|
*/
|
|
51
61
|
load(targetPath: string): Promise<void>;
|
|
62
|
+
/**
|
|
63
|
+
* Load ignore files for a directory during traversal.
|
|
64
|
+
* Only loads if the directory hasn't been loaded before.
|
|
65
|
+
*/
|
|
66
|
+
loadForDirectory(dir: string): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Add patterns from raw content at the specified base path.
|
|
69
|
+
* Used for --ignore-file flag.
|
|
70
|
+
*/
|
|
71
|
+
addPatternsFromContent(content: string, basePath: string): void;
|
|
52
72
|
/**
|
|
53
73
|
* Check if a path should be ignored
|
|
54
74
|
*
|
|
@@ -57,6 +77,15 @@ export declare class GitignoreManager {
|
|
|
57
77
|
* @returns true if the path should be ignored
|
|
58
78
|
*/
|
|
59
79
|
matches(absolutePath: string, isDirectory: boolean): boolean;
|
|
80
|
+
/**
|
|
81
|
+
* Check if a path is explicitly whitelisted by a negation pattern.
|
|
82
|
+
* Used to include hidden files that have negation patterns like "!.foo"
|
|
83
|
+
*
|
|
84
|
+
* @param absolutePath Absolute path to check
|
|
85
|
+
* @param isDirectory Whether the path is a directory
|
|
86
|
+
* @returns true if the path is whitelisted by a negation pattern
|
|
87
|
+
*/
|
|
88
|
+
isWhitelisted(absolutePath: string, isDirectory: boolean): boolean;
|
|
60
89
|
/**
|
|
61
90
|
* Quick check for common ignored directories
|
|
62
91
|
* Used for early pruning during traversal
|
|
@@ -66,4 +95,4 @@ export declare class GitignoreManager {
|
|
|
66
95
|
/**
|
|
67
96
|
* Load gitignore files for a search starting at the given path
|
|
68
97
|
*/
|
|
69
|
-
export declare function loadGitignores(fs: IFileSystem, startPath: string): Promise<GitignoreManager>;
|
|
98
|
+
export declare function loadGitignores(fs: IFileSystem, startPath: string, skipDotIgnore?: boolean, skipVcsIgnore?: boolean, customIgnoreFiles?: string[]): Promise<GitignoreManager>;
|
|
@@ -10,16 +10,20 @@ export interface RgOptions {
|
|
|
10
10
|
lineRegexp: boolean;
|
|
11
11
|
invertMatch: boolean;
|
|
12
12
|
multiline: boolean;
|
|
13
|
+
multilineDotall: boolean;
|
|
13
14
|
patterns: string[];
|
|
14
15
|
patternFiles: string[];
|
|
15
16
|
count: boolean;
|
|
16
17
|
countMatches: boolean;
|
|
18
|
+
files: boolean;
|
|
17
19
|
filesWithMatches: boolean;
|
|
18
20
|
filesWithoutMatch: boolean;
|
|
21
|
+
stats: boolean;
|
|
19
22
|
onlyMatching: boolean;
|
|
20
23
|
maxCount: number;
|
|
21
24
|
lineNumber: boolean;
|
|
22
25
|
noFilename: boolean;
|
|
26
|
+
withFilename: boolean;
|
|
23
27
|
nullSeparator: boolean;
|
|
24
28
|
byteOffset: boolean;
|
|
25
29
|
column: boolean;
|
|
@@ -35,13 +39,23 @@ export interface RgOptions {
|
|
|
35
39
|
sort: "path" | "none";
|
|
36
40
|
json: boolean;
|
|
37
41
|
globs: string[];
|
|
42
|
+
iglobs: string[];
|
|
43
|
+
globCaseInsensitive: boolean;
|
|
38
44
|
types: string[];
|
|
39
45
|
typesNot: string[];
|
|
46
|
+
typeAdd: string[];
|
|
47
|
+
typeClear: string[];
|
|
40
48
|
hidden: boolean;
|
|
41
49
|
noIgnore: boolean;
|
|
50
|
+
noIgnoreDot: boolean;
|
|
51
|
+
noIgnoreVcs: boolean;
|
|
52
|
+
ignoreFiles: string[];
|
|
42
53
|
maxDepth: number;
|
|
54
|
+
maxFilesize: number;
|
|
43
55
|
followSymlinks: boolean;
|
|
44
56
|
searchZip: boolean;
|
|
45
57
|
searchBinary: boolean;
|
|
58
|
+
preprocessor: string | null;
|
|
59
|
+
preprocessorGlobs: string[];
|
|
46
60
|
}
|
|
47
61
|
export declare function createDefaultOptions(): RgOptions;
|
|
@@ -7,4 +7,4 @@
|
|
|
7
7
|
* - Regex building for different modes (basic, extended, fixed, perl)
|
|
8
8
|
*/
|
|
9
9
|
export { type SearchOptions, type SearchResult, searchContent, } from "./matcher.js";
|
|
10
|
-
export { buildRegex, type RegexMode, type RegexOptions } from "./regex.js";
|
|
10
|
+
export { buildRegex, convertReplacement, type RegexMode, type RegexOptions, } from "./regex.js";
|
|
@@ -15,3 +15,13 @@ export interface RegexOptions {
|
|
|
15
15
|
* Build a JavaScript RegExp from a pattern with the specified mode
|
|
16
16
|
*/
|
|
17
17
|
export declare function buildRegex(pattern: string, options: RegexOptions): RegExp;
|
|
18
|
+
/**
|
|
19
|
+
* Convert replacement string syntax to JavaScript's String.replace format
|
|
20
|
+
*
|
|
21
|
+
* Conversions:
|
|
22
|
+
* - $0 and ${0} -> $& (full match)
|
|
23
|
+
* - $name -> $<name> (named capture groups)
|
|
24
|
+
* - ${name} -> $<name> (braced named capture groups)
|
|
25
|
+
* - Preserves $1, $2, etc. for numbered groups
|
|
26
|
+
*/
|
|
27
|
+
export declare function convertReplacement(replacement: string): string;
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
import type { BufferEncoding, CpOptions, DirectoryEntry, DirentEntry, FileContent, FileEntry, FsEntry, FsStat, IFileSystem, InitialFiles, MkdirOptions, ReadFileOptions, RmOptions, SymlinkEntry, WriteFileOptions } from "../interface.js";
|
|
2
|
+
export type { BufferEncoding, FileContent, FileEntry, DirectoryEntry, SymlinkEntry, FsEntry, FsStat, IFileSystem, };
|
|
3
|
+
export interface FsData {
|
|
4
|
+
[path: string]: FsEntry;
|
|
5
|
+
}
|
|
6
|
+
export declare class InMemoryFs implements IFileSystem {
|
|
7
|
+
private data;
|
|
8
|
+
constructor(initialFiles?: InitialFiles);
|
|
9
|
+
private normalizePath;
|
|
10
|
+
private dirname;
|
|
11
|
+
private ensureParentDirs;
|
|
12
|
+
writeFileSync(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding, metadata?: {
|
|
13
|
+
mode?: number;
|
|
14
|
+
mtime?: Date;
|
|
15
|
+
}): void;
|
|
16
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
17
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
18
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
19
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
20
|
+
exists(path: string): Promise<boolean>;
|
|
21
|
+
stat(path: string): Promise<FsStat>;
|
|
22
|
+
lstat(path: string): Promise<FsStat>;
|
|
23
|
+
private resolveSymlink;
|
|
24
|
+
/**
|
|
25
|
+
* Resolve symlinks in intermediate path components only (not the final component).
|
|
26
|
+
* Used by lstat which should not follow the final symlink.
|
|
27
|
+
*/
|
|
28
|
+
private resolveIntermediateSymlinks;
|
|
29
|
+
/**
|
|
30
|
+
* Resolve all symlinks in a path, including intermediate components.
|
|
31
|
+
* For example: /home/user/linkdir/file.txt where linkdir is a symlink to "subdir"
|
|
32
|
+
* would resolve to /home/user/subdir/file.txt
|
|
33
|
+
*/
|
|
34
|
+
private resolvePathWithSymlinks;
|
|
35
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
36
|
+
/**
|
|
37
|
+
* Synchronous version of mkdir
|
|
38
|
+
*/
|
|
39
|
+
mkdirSync(path: string, options?: MkdirOptions): void;
|
|
40
|
+
readdir(path: string): Promise<string[]>;
|
|
41
|
+
readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
|
|
42
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
43
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
44
|
+
mv(src: string, dest: string): Promise<void>;
|
|
45
|
+
getAllPaths(): string[];
|
|
46
|
+
resolvePath(base: string, path: string): string;
|
|
47
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
48
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
49
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
50
|
+
readlink(path: string): Promise<string>;
|
|
51
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { InMemoryFs } from "./in-memory-fs.js";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem Initialization
|
|
3
|
+
*
|
|
4
|
+
* Sets up the default filesystem structure for the bash environment
|
|
5
|
+
* including /dev, /proc, and common directories.
|
|
6
|
+
*/
|
|
7
|
+
import type { IFileSystem } from "./interface.js";
|
|
8
|
+
/**
|
|
9
|
+
* Initialize the filesystem with standard directories and files
|
|
10
|
+
* Works with both InMemoryFs and OverlayFs (both write to memory)
|
|
11
|
+
*/
|
|
12
|
+
export declare function initFilesystem(fs: IFileSystem, useDefaultLayout: boolean): void;
|
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported buffer encodings
|
|
3
|
+
*/
|
|
4
|
+
export type BufferEncoding = "utf8" | "utf-8" | "ascii" | "binary" | "base64" | "hex" | "latin1";
|
|
5
|
+
/**
|
|
6
|
+
* File content can be string or Buffer
|
|
7
|
+
*/
|
|
8
|
+
export type FileContent = string | Uint8Array;
|
|
9
|
+
/**
|
|
10
|
+
* Options for reading files
|
|
11
|
+
*/
|
|
12
|
+
export interface ReadFileOptions {
|
|
13
|
+
encoding?: BufferEncoding | null;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Options for writing files
|
|
17
|
+
*/
|
|
18
|
+
export interface WriteFileOptions {
|
|
19
|
+
encoding?: BufferEncoding;
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* File system entry types
|
|
23
|
+
*/
|
|
24
|
+
export interface FileEntry {
|
|
25
|
+
type: "file";
|
|
26
|
+
content: string | Uint8Array;
|
|
27
|
+
mode: number;
|
|
28
|
+
mtime: Date;
|
|
29
|
+
}
|
|
30
|
+
export interface DirectoryEntry {
|
|
31
|
+
type: "directory";
|
|
32
|
+
mode: number;
|
|
33
|
+
mtime: Date;
|
|
34
|
+
}
|
|
35
|
+
export interface SymlinkEntry {
|
|
36
|
+
type: "symlink";
|
|
37
|
+
target: string;
|
|
38
|
+
mode: number;
|
|
39
|
+
mtime: Date;
|
|
40
|
+
}
|
|
41
|
+
export type FsEntry = FileEntry | DirectoryEntry | SymlinkEntry;
|
|
42
|
+
/**
|
|
43
|
+
* Directory entry with type information (similar to Node's Dirent)
|
|
44
|
+
* Used by readdirWithFileTypes for efficient directory listing without stat calls
|
|
45
|
+
*/
|
|
46
|
+
export interface DirentEntry {
|
|
47
|
+
name: string;
|
|
48
|
+
isFile: boolean;
|
|
49
|
+
isDirectory: boolean;
|
|
50
|
+
isSymbolicLink: boolean;
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Stat result from the filesystem
|
|
54
|
+
*/
|
|
55
|
+
export interface FsStat {
|
|
56
|
+
isFile: boolean;
|
|
57
|
+
isDirectory: boolean;
|
|
58
|
+
isSymbolicLink: boolean;
|
|
59
|
+
mode: number;
|
|
60
|
+
size: number;
|
|
61
|
+
mtime: Date;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* Options for mkdir operation
|
|
65
|
+
*/
|
|
66
|
+
export interface MkdirOptions {
|
|
67
|
+
recursive?: boolean;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Options for rm operation
|
|
71
|
+
*/
|
|
72
|
+
export interface RmOptions {
|
|
73
|
+
recursive?: boolean;
|
|
74
|
+
force?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Options for cp operation
|
|
78
|
+
*/
|
|
79
|
+
export interface CpOptions {
|
|
80
|
+
recursive?: boolean;
|
|
81
|
+
}
|
|
82
|
+
/**
|
|
83
|
+
* Abstract filesystem interface that can be implemented by different backends.
|
|
84
|
+
* This allows BashEnv to work with:
|
|
85
|
+
* - InMemoryFs (in-memory, default)
|
|
86
|
+
* - Real filesystem (via node:fs)
|
|
87
|
+
* - Custom implementations (e.g., remote storage, browser IndexedDB)
|
|
88
|
+
*/
|
|
89
|
+
export interface IFileSystem {
|
|
90
|
+
/**
|
|
91
|
+
* Read the contents of a file as a string (default: utf8)
|
|
92
|
+
* @throws Error if file doesn't exist or is a directory
|
|
93
|
+
*/
|
|
94
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
95
|
+
/**
|
|
96
|
+
* Read the contents of a file as a Uint8Array (binary)
|
|
97
|
+
* @throws Error if file doesn't exist or is a directory
|
|
98
|
+
*/
|
|
99
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
100
|
+
/**
|
|
101
|
+
* Write content to a file, creating it if it doesn't exist
|
|
102
|
+
*/
|
|
103
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
104
|
+
/**
|
|
105
|
+
* Append content to a file, creating it if it doesn't exist
|
|
106
|
+
*/
|
|
107
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
108
|
+
/**
|
|
109
|
+
* Check if a path exists
|
|
110
|
+
*/
|
|
111
|
+
exists(path: string): Promise<boolean>;
|
|
112
|
+
/**
|
|
113
|
+
* Get file/directory information
|
|
114
|
+
* @throws Error if path doesn't exist
|
|
115
|
+
*/
|
|
116
|
+
stat(path: string): Promise<FsStat>;
|
|
117
|
+
/**
|
|
118
|
+
* Create a directory
|
|
119
|
+
* @throws Error if parent doesn't exist (unless recursive) or path exists
|
|
120
|
+
*/
|
|
121
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
122
|
+
/**
|
|
123
|
+
* Read directory contents
|
|
124
|
+
* @returns Array of entry names (not full paths)
|
|
125
|
+
* @throws Error if path doesn't exist or is not a directory
|
|
126
|
+
*/
|
|
127
|
+
readdir(path: string): Promise<string[]>;
|
|
128
|
+
/**
|
|
129
|
+
* Read directory contents with file type information (optional)
|
|
130
|
+
* This is more efficient than readdir + stat for each entry
|
|
131
|
+
* @returns Array of DirentEntry objects with name and type
|
|
132
|
+
* @throws Error if path doesn't exist or is not a directory
|
|
133
|
+
*/
|
|
134
|
+
readdirWithFileTypes?(path: string): Promise<DirentEntry[]>;
|
|
135
|
+
/**
|
|
136
|
+
* Remove a file or directory
|
|
137
|
+
* @throws Error if path doesn't exist (unless force) or directory not empty (unless recursive)
|
|
138
|
+
*/
|
|
139
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
140
|
+
/**
|
|
141
|
+
* Copy a file or directory
|
|
142
|
+
* @throws Error if source doesn't exist or trying to copy directory without recursive
|
|
143
|
+
*/
|
|
144
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
145
|
+
/**
|
|
146
|
+
* Move/rename a file or directory
|
|
147
|
+
*/
|
|
148
|
+
mv(src: string, dest: string): Promise<void>;
|
|
149
|
+
/**
|
|
150
|
+
* Resolve a relative path against a base path
|
|
151
|
+
*/
|
|
152
|
+
resolvePath(base: string, path: string): string;
|
|
153
|
+
/**
|
|
154
|
+
* Get all paths in the filesystem (useful for glob matching)
|
|
155
|
+
* Optional - implementations may return empty array if not supported
|
|
156
|
+
*/
|
|
157
|
+
getAllPaths(): string[];
|
|
158
|
+
/**
|
|
159
|
+
* Change file/directory permissions
|
|
160
|
+
* @throws Error if path doesn't exist
|
|
161
|
+
*/
|
|
162
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
163
|
+
/**
|
|
164
|
+
* Create a symbolic link
|
|
165
|
+
* @param target - The path the symlink should point to
|
|
166
|
+
* @param linkPath - The path where the symlink will be created
|
|
167
|
+
* @throws Error if linkPath already exists
|
|
168
|
+
*/
|
|
169
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
170
|
+
/**
|
|
171
|
+
* Create a hard link
|
|
172
|
+
* @param existingPath - The existing file to link to
|
|
173
|
+
* @param newPath - The path where the new link will be created
|
|
174
|
+
* @throws Error if existingPath doesn't exist or newPath already exists
|
|
175
|
+
*/
|
|
176
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
177
|
+
/**
|
|
178
|
+
* Read the target of a symbolic link
|
|
179
|
+
* @throws Error if path doesn't exist or is not a symlink
|
|
180
|
+
*/
|
|
181
|
+
readlink(path: string): Promise<string>;
|
|
182
|
+
/**
|
|
183
|
+
* Get file/directory information without following symlinks
|
|
184
|
+
* @throws Error if path doesn't exist
|
|
185
|
+
*/
|
|
186
|
+
lstat(path: string): Promise<FsStat>;
|
|
187
|
+
}
|
|
188
|
+
/**
|
|
189
|
+
* Extended file initialization options with optional metadata
|
|
190
|
+
*/
|
|
191
|
+
export interface FileInit {
|
|
192
|
+
content: FileContent;
|
|
193
|
+
mode?: number;
|
|
194
|
+
mtime?: Date;
|
|
195
|
+
}
|
|
196
|
+
/**
|
|
197
|
+
* Initial files can be simple content or extended options with metadata
|
|
198
|
+
*/
|
|
199
|
+
export type InitialFiles = Record<string, FileContent | FileInit>;
|
|
200
|
+
/**
|
|
201
|
+
* Factory function type for creating filesystem instances
|
|
202
|
+
*/
|
|
203
|
+
export type FileSystemFactory = (initialFiles?: InitialFiles) => IFileSystem;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { MountableFs, type MountableFsOptions, type MountConfig, } from "./mountable-fs.js";
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import type { BufferEncoding, CpOptions, FileContent, FsStat, IFileSystem, MkdirOptions, ReadFileOptions, RmOptions, WriteFileOptions } from "../interface.js";
|
|
2
|
+
/**
|
|
3
|
+
* Configuration for a mount point
|
|
4
|
+
*/
|
|
5
|
+
export interface MountConfig {
|
|
6
|
+
/** Virtual path where the filesystem is mounted */
|
|
7
|
+
mountPoint: string;
|
|
8
|
+
/** The filesystem to mount at this path */
|
|
9
|
+
filesystem: IFileSystem;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Options for creating a MountableFs
|
|
13
|
+
*/
|
|
14
|
+
export interface MountableFsOptions {
|
|
15
|
+
/** Base filesystem used for unmounted paths (defaults to InMemoryFs) */
|
|
16
|
+
base?: IFileSystem;
|
|
17
|
+
/** Initial mounts to configure */
|
|
18
|
+
mounts?: MountConfig[];
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* A filesystem that supports mounting other filesystems at specific paths.
|
|
22
|
+
*
|
|
23
|
+
* This allows combining multiple filesystem backends into a unified namespace.
|
|
24
|
+
* For example, mounting a read-only knowledge base at /mnt/knowledge and a
|
|
25
|
+
* read-write workspace at /home/agent.
|
|
26
|
+
*
|
|
27
|
+
* @example
|
|
28
|
+
* ```typescript
|
|
29
|
+
* const fs = new MountableFs({ base: new InMemoryFs() });
|
|
30
|
+
* fs.mount('/mnt/knowledge', new OverlayFs({ root: "/path/to/knowledge", readOnly: true }));
|
|
31
|
+
* fs.mount('/home/agent', new ReadWriteFs({ root: "/path/to/workspace" }));
|
|
32
|
+
* ```
|
|
33
|
+
*/
|
|
34
|
+
export declare class MountableFs implements IFileSystem {
|
|
35
|
+
private baseFs;
|
|
36
|
+
private mounts;
|
|
37
|
+
constructor(options?: MountableFsOptions);
|
|
38
|
+
/**
|
|
39
|
+
* Mount a filesystem at the specified virtual path.
|
|
40
|
+
*
|
|
41
|
+
* @param mountPoint - The virtual path where the filesystem will be accessible
|
|
42
|
+
* @param filesystem - The filesystem to mount
|
|
43
|
+
* @throws Error if mounting at root '/' or inside an existing mount
|
|
44
|
+
*/
|
|
45
|
+
mount(mountPoint: string, filesystem: IFileSystem): void;
|
|
46
|
+
/**
|
|
47
|
+
* Unmount the filesystem at the specified path.
|
|
48
|
+
*
|
|
49
|
+
* @param mountPoint - The virtual path to unmount
|
|
50
|
+
* @throws Error if no filesystem is mounted at this path
|
|
51
|
+
*/
|
|
52
|
+
unmount(mountPoint: string): void;
|
|
53
|
+
/**
|
|
54
|
+
* Get all current mounts.
|
|
55
|
+
*/
|
|
56
|
+
getMounts(): ReadonlyArray<{
|
|
57
|
+
mountPoint: string;
|
|
58
|
+
filesystem: IFileSystem;
|
|
59
|
+
}>;
|
|
60
|
+
/**
|
|
61
|
+
* Check if a path is exactly a mount point.
|
|
62
|
+
*/
|
|
63
|
+
isMountPoint(path: string): boolean;
|
|
64
|
+
/**
|
|
65
|
+
* Validate mount path format before normalization.
|
|
66
|
+
* Rejects paths containing . or .. segments.
|
|
67
|
+
*/
|
|
68
|
+
private validateMountPath;
|
|
69
|
+
/**
|
|
70
|
+
* Validate that a mount point is allowed.
|
|
71
|
+
*/
|
|
72
|
+
private validateMount;
|
|
73
|
+
/**
|
|
74
|
+
* Normalize a path to a consistent format.
|
|
75
|
+
*/
|
|
76
|
+
private normalizePath;
|
|
77
|
+
/**
|
|
78
|
+
* Route a path to the appropriate filesystem.
|
|
79
|
+
* Returns the filesystem and the relative path within that filesystem.
|
|
80
|
+
*/
|
|
81
|
+
private routePath;
|
|
82
|
+
/**
|
|
83
|
+
* Get mount points that are immediate children of a directory.
|
|
84
|
+
*/
|
|
85
|
+
private getChildMountPoints;
|
|
86
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
87
|
+
readFileBuffer(path: string): Promise<Uint8Array>;
|
|
88
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
89
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
90
|
+
exists(path: string): Promise<boolean>;
|
|
91
|
+
stat(path: string): Promise<FsStat>;
|
|
92
|
+
lstat(path: string): Promise<FsStat>;
|
|
93
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
94
|
+
readdir(path: string): Promise<string[]>;
|
|
95
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
96
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
97
|
+
mv(src: string, dest: string): Promise<void>;
|
|
98
|
+
resolvePath(base: string, path: string): string;
|
|
99
|
+
getAllPaths(): string[];
|
|
100
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
101
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
102
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
103
|
+
readlink(path: string): Promise<string>;
|
|
104
|
+
/**
|
|
105
|
+
* Perform a cross-mount copy operation.
|
|
106
|
+
*/
|
|
107
|
+
private crossMountCopy;
|
|
108
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { OverlayFs, type OverlayFsOptions } from "./overlay-fs.js";
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OverlayFs - Copy-on-write filesystem backed by a real directory
|
|
3
|
+
*
|
|
4
|
+
* Reads come from the real filesystem, writes go to an in-memory layer.
|
|
5
|
+
* Changes don't persist to disk and can't escape the root directory.
|
|
6
|
+
*/
|
|
7
|
+
import type { CpOptions, DirentEntry, FsStat, IFileSystem, MkdirOptions, ReadFileOptions, RmOptions, WriteFileOptions } from "../interface.js";
|
|
8
|
+
import { type FileContent } from "../utils.js";
|
|
9
|
+
export interface OverlayFsOptions {
|
|
10
|
+
/**
|
|
11
|
+
* The root directory on the real filesystem.
|
|
12
|
+
* All paths are relative to this root and cannot escape it.
|
|
13
|
+
*/
|
|
14
|
+
root: string;
|
|
15
|
+
/**
|
|
16
|
+
* The virtual mount point where the root directory appears.
|
|
17
|
+
* Defaults to "/home/user/project".
|
|
18
|
+
*/
|
|
19
|
+
mountPoint?: string;
|
|
20
|
+
/**
|
|
21
|
+
* If true, all write operations will throw an error.
|
|
22
|
+
* Useful for truly read-only access to the filesystem.
|
|
23
|
+
* Defaults to false.
|
|
24
|
+
*/
|
|
25
|
+
readOnly?: boolean;
|
|
26
|
+
}
|
|
27
|
+
export declare class OverlayFs implements IFileSystem {
|
|
28
|
+
private readonly root;
|
|
29
|
+
private readonly mountPoint;
|
|
30
|
+
private readonly readOnly;
|
|
31
|
+
private readonly memory;
|
|
32
|
+
private readonly deleted;
|
|
33
|
+
constructor(options: OverlayFsOptions);
|
|
34
|
+
/**
|
|
35
|
+
* Throws an error if the filesystem is in read-only mode.
|
|
36
|
+
*/
|
|
37
|
+
private assertWritable;
|
|
38
|
+
/**
|
|
39
|
+
* Create directory entries for the mount point path
|
|
40
|
+
*/
|
|
41
|
+
private createMountPointDirs;
|
|
42
|
+
/**
|
|
43
|
+
* Get the mount point for this overlay
|
|
44
|
+
*/
|
|
45
|
+
getMountPoint(): string;
|
|
46
|
+
/**
|
|
47
|
+
* Create a virtual directory in memory (sync, for initialization)
|
|
48
|
+
*/
|
|
49
|
+
mkdirSync(path: string, _options?: MkdirOptions): void;
|
|
50
|
+
/**
|
|
51
|
+
* Create a virtual file in memory (sync, for initialization)
|
|
52
|
+
*/
|
|
53
|
+
writeFileSync(path: string, content: string | Uint8Array): void;
|
|
54
|
+
private getDirname;
|
|
55
|
+
/**
|
|
56
|
+
* Normalize a virtual path (resolve . and .., ensure starts with /)
|
|
57
|
+
*/
|
|
58
|
+
private normalizePath;
|
|
59
|
+
/**
|
|
60
|
+
* Check if a normalized virtual path is under the mount point.
|
|
61
|
+
* Returns the relative path within the mount point, or null if not under it.
|
|
62
|
+
*/
|
|
63
|
+
private getRelativeToMount;
|
|
64
|
+
/**
|
|
65
|
+
* Convert a virtual path to a real filesystem path.
|
|
66
|
+
* Returns null if the path is not under the mount point or would escape the root.
|
|
67
|
+
*/
|
|
68
|
+
private toRealPath;
|
|
69
|
+
private dirname;
|
|
70
|
+
private ensureParentDirs;
|
|
71
|
+
/**
|
|
72
|
+
* Check if a path exists in the overlay (memory + real fs - deleted)
|
|
73
|
+
*/
|
|
74
|
+
private existsInOverlay;
|
|
75
|
+
readFile(path: string, options?: ReadFileOptions | BufferEncoding): Promise<string>;
|
|
76
|
+
readFileBuffer(path: string, seen?: Set<string>): Promise<Uint8Array>;
|
|
77
|
+
writeFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
78
|
+
appendFile(path: string, content: FileContent, options?: WriteFileOptions | BufferEncoding): Promise<void>;
|
|
79
|
+
exists(path: string): Promise<boolean>;
|
|
80
|
+
stat(path: string, seen?: Set<string>): Promise<FsStat>;
|
|
81
|
+
lstat(path: string): Promise<FsStat>;
|
|
82
|
+
private resolveSymlink;
|
|
83
|
+
mkdir(path: string, options?: MkdirOptions): Promise<void>;
|
|
84
|
+
/**
|
|
85
|
+
* Core readdir implementation that returns entries with file types.
|
|
86
|
+
* Both readdir and readdirWithFileTypes use this shared implementation.
|
|
87
|
+
*/
|
|
88
|
+
private readdirCore;
|
|
89
|
+
/**
|
|
90
|
+
* Follow symlinks to resolve the final directory path.
|
|
91
|
+
* Returns outsideOverlay: true if the symlink points outside the overlay or
|
|
92
|
+
* the resolved target doesn't exist (security - broken symlinks return []).
|
|
93
|
+
*/
|
|
94
|
+
private resolveForReaddir;
|
|
95
|
+
readdir(path: string): Promise<string[]>;
|
|
96
|
+
readdirWithFileTypes(path: string): Promise<DirentEntry[]>;
|
|
97
|
+
rm(path: string, options?: RmOptions): Promise<void>;
|
|
98
|
+
cp(src: string, dest: string, options?: CpOptions): Promise<void>;
|
|
99
|
+
mv(src: string, dest: string): Promise<void>;
|
|
100
|
+
resolvePath(base: string, path: string): string;
|
|
101
|
+
getAllPaths(): string[];
|
|
102
|
+
private scanRealFs;
|
|
103
|
+
chmod(path: string, mode: number): Promise<void>;
|
|
104
|
+
symlink(target: string, linkPath: string): Promise<void>;
|
|
105
|
+
link(existingPath: string, newPath: string): Promise<void>;
|
|
106
|
+
readlink(path: string): Promise<string>;
|
|
107
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { ReadWriteFs, type ReadWriteFsOptions } from "./read-write-fs.js";
|