@vibe-agent-toolkit/utils 0.1.0-rc.7
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/README.md +34 -0
- package/dist/file-crawler.d.ts +54 -0
- package/dist/file-crawler.d.ts.map +1 -0
- package/dist/file-crawler.js +177 -0
- package/dist/file-crawler.js.map +1 -0
- package/dist/fs-utils.d.ts +14 -0
- package/dist/fs-utils.d.ts.map +1 -0
- package/dist/fs-utils.js +31 -0
- package/dist/fs-utils.js.map +1 -0
- package/dist/git-utils.d.ts +11 -0
- package/dist/git-utils.d.ts.map +1 -0
- package/dist/git-utils.js +30 -0
- package/dist/git-utils.js.map +1 -0
- package/dist/gitignore-checker.d.ts +30 -0
- package/dist/gitignore-checker.d.ts.map +1 -0
- package/dist/gitignore-checker.js +95 -0
- package/dist/gitignore-checker.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +19 -0
- package/dist/index.js.map +1 -0
- package/dist/path-utils.d.ts +87 -0
- package/dist/path-utils.d.ts.map +1 -0
- package/dist/path-utils.js +112 -0
- package/dist/path-utils.js.map +1 -0
- package/dist/safe-exec.d.ts +206 -0
- package/dist/safe-exec.d.ts.map +1 -0
- package/dist/safe-exec.js +393 -0
- package/dist/safe-exec.js.map +1 -0
- package/package.json +51 -0
package/README.md
ADDED
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# @vibe-agent-toolkit/utils
|
|
2
|
+
|
|
3
|
+
Core shared utilities with no dependencies on other packages.
|
|
4
|
+
|
|
5
|
+
## Philosophy
|
|
6
|
+
|
|
7
|
+
This package provides utilities that are needed by multiple packages in the toolkit. Utilities are **added as real needs arise**, not speculatively.
|
|
8
|
+
|
|
9
|
+
If you need a utility function and multiple packages would benefit from it, add it here. Otherwise, keep it local to the package that needs it.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
bun add @vibe-agent-toolkit/utils
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Usage
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { /* utilities will be added here */ } from '@vibe-agent-toolkit/utils';
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
## Current Utilities
|
|
24
|
+
|
|
25
|
+
Currently minimal - utilities will be added as needed by other packages.
|
|
26
|
+
|
|
27
|
+
Future additions may include:
|
|
28
|
+
- Schema validation utilities (Zod helpers, JSON Schema conversion)
|
|
29
|
+
- Cross-platform helpers (process spawning, file operations)
|
|
30
|
+
- Common type guards and assertions
|
|
31
|
+
|
|
32
|
+
## License
|
|
33
|
+
|
|
34
|
+
MIT
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Options for directory crawling
|
|
3
|
+
*/
|
|
4
|
+
export interface CrawlOptions {
|
|
5
|
+
/** Base directory to start crawl */
|
|
6
|
+
baseDir: string;
|
|
7
|
+
/** Include patterns (glob) - default: ['**\/*'] */
|
|
8
|
+
include?: string[];
|
|
9
|
+
/** Exclude patterns (glob) - default: ['**\/node_modules/**', '**\/.git/**'] */
|
|
10
|
+
exclude?: string[];
|
|
11
|
+
/** Follow symbolic links (default: false) */
|
|
12
|
+
followSymlinks?: boolean;
|
|
13
|
+
/** Return absolute paths in results (default: true) */
|
|
14
|
+
absolute?: boolean;
|
|
15
|
+
/** Only return files (not directories) - default: true */
|
|
16
|
+
filesOnly?: boolean;
|
|
17
|
+
/** Respect .gitignore files (default: true) */
|
|
18
|
+
respectGitignore?: boolean;
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Crawl a directory tree and return matching files (async)
|
|
22
|
+
*
|
|
23
|
+
* Uses picomatch for glob pattern matching (same as Vitest)
|
|
24
|
+
* Cross-platform compatible
|
|
25
|
+
*
|
|
26
|
+
* @param options - Crawl options
|
|
27
|
+
* @returns Promise resolving to array of matching file paths
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* const files = await crawlDirectory({
|
|
31
|
+
* baseDir: '/project',
|
|
32
|
+
* include: ['**\/*.md'],
|
|
33
|
+
* exclude: ['**\/node_modules/**'],
|
|
34
|
+
* });
|
|
35
|
+
*/
|
|
36
|
+
export declare function crawlDirectory(options: CrawlOptions): Promise<string[]>;
|
|
37
|
+
/**
|
|
38
|
+
* Crawl a directory tree and return matching files (synchronous)
|
|
39
|
+
*
|
|
40
|
+
* Uses picomatch for glob pattern matching (same as Vitest)
|
|
41
|
+
* Cross-platform compatible
|
|
42
|
+
*
|
|
43
|
+
* @param options - Crawl options
|
|
44
|
+
* @returns Array of matching file paths
|
|
45
|
+
*
|
|
46
|
+
* @example
|
|
47
|
+
* const files = crawlDirectorySync({
|
|
48
|
+
* baseDir: '/project',
|
|
49
|
+
* include: ['**\/*.md'],
|
|
50
|
+
* exclude: ['**\/node_modules/**'],
|
|
51
|
+
* });
|
|
52
|
+
*/
|
|
53
|
+
export declare function crawlDirectorySync(options: CrawlOptions): string[];
|
|
54
|
+
//# sourceMappingURL=file-crawler.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-crawler.d.ts","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,oCAAoC;IACpC,OAAO,EAAE,MAAM,CAAC;IAChB,mDAAmD;IACnD,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,gFAAgF;IAChF,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,6CAA6C;IAC7C,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,uDAAuD;IACvD,QAAQ,CAAC,EAAE,OAAO,CAAC;IACnB,0DAA0D;IAC1D,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,+CAA+C;IAC/C,gBAAgB,CAAC,EAAE,OAAO,CAAC;CAC5B;AAOD;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,YAAY,GAAG,OAAO,CAAC,MAAM,EAAE,CAAC,CAE7E;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,EAAE,CAgKlE"}
|
|
@@ -0,0 +1,177 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import picomatch from 'picomatch';
|
|
4
|
+
import { findGitRoot, loadGitignoreRules } from './gitignore-checker.js';
|
|
5
|
+
/**
|
|
6
|
+
* Default exclude patterns that are almost always unwanted
|
|
7
|
+
*/
|
|
8
|
+
const DEFAULT_EXCLUDE = ['**/node_modules/**', '**/.git/**', '**/dist/**', '**/coverage/**'];
|
|
9
|
+
/**
|
|
10
|
+
* Crawl a directory tree and return matching files (async)
|
|
11
|
+
*
|
|
12
|
+
* Uses picomatch for glob pattern matching (same as Vitest)
|
|
13
|
+
* Cross-platform compatible
|
|
14
|
+
*
|
|
15
|
+
* @param options - Crawl options
|
|
16
|
+
* @returns Promise resolving to array of matching file paths
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* const files = await crawlDirectory({
|
|
20
|
+
* baseDir: '/project',
|
|
21
|
+
* include: ['**\/*.md'],
|
|
22
|
+
* exclude: ['**\/node_modules/**'],
|
|
23
|
+
* });
|
|
24
|
+
*/
|
|
25
|
+
export async function crawlDirectory(options) {
|
|
26
|
+
return crawlDirectorySync(options);
|
|
27
|
+
}
|
|
28
|
+
/**
|
|
29
|
+
* Crawl a directory tree and return matching files (synchronous)
|
|
30
|
+
*
|
|
31
|
+
* Uses picomatch for glob pattern matching (same as Vitest)
|
|
32
|
+
* Cross-platform compatible
|
|
33
|
+
*
|
|
34
|
+
* @param options - Crawl options
|
|
35
|
+
* @returns Array of matching file paths
|
|
36
|
+
*
|
|
37
|
+
* @example
|
|
38
|
+
* const files = crawlDirectorySync({
|
|
39
|
+
* baseDir: '/project',
|
|
40
|
+
* include: ['**\/*.md'],
|
|
41
|
+
* exclude: ['**\/node_modules/**'],
|
|
42
|
+
* });
|
|
43
|
+
*/
|
|
44
|
+
export function crawlDirectorySync(options) {
|
|
45
|
+
const { baseDir, include = ['**/*'], exclude = DEFAULT_EXCLUDE, followSymlinks = false, absolute = true, filesOnly = true, respectGitignore = true, } = options;
|
|
46
|
+
// Resolve base directory to absolute path
|
|
47
|
+
const resolvedBaseDir = path.resolve(baseDir);
|
|
48
|
+
// Ensure base directory exists
|
|
49
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- baseDir is from controlled config, not user input
|
|
50
|
+
if (!fs.existsSync(resolvedBaseDir)) {
|
|
51
|
+
throw new Error(`Base directory does not exist: ${resolvedBaseDir}`);
|
|
52
|
+
}
|
|
53
|
+
// Ensure base directory is actually a directory
|
|
54
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- resolved path validated above
|
|
55
|
+
const baseStat = fs.statSync(resolvedBaseDir);
|
|
56
|
+
if (!baseStat.isDirectory()) {
|
|
57
|
+
throw new Error(`Base path is not a directory: ${resolvedBaseDir}`);
|
|
58
|
+
}
|
|
59
|
+
// Load gitignore rules if requested
|
|
60
|
+
let gitignoreChecker = null;
|
|
61
|
+
let gitRoot = null;
|
|
62
|
+
if (respectGitignore) {
|
|
63
|
+
gitRoot = findGitRoot(resolvedBaseDir);
|
|
64
|
+
if (gitRoot) {
|
|
65
|
+
gitignoreChecker = loadGitignoreRules(gitRoot, resolvedBaseDir);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
// Compile glob patterns using picomatch
|
|
69
|
+
const isIncluded = picomatch(include);
|
|
70
|
+
const isExcluded = exclude.length > 0 ? picomatch(exclude) : () => false;
|
|
71
|
+
const results = [];
|
|
72
|
+
/**
|
|
73
|
+
* Check if a path should be excluded based on patterns and gitignore
|
|
74
|
+
*/
|
|
75
|
+
function shouldExclude(normalizedPath, fullPath) {
|
|
76
|
+
// Check explicit exclude patterns
|
|
77
|
+
if (isExcluded(normalizedPath) || isExcluded(normalizedPath + '/')) {
|
|
78
|
+
return true;
|
|
79
|
+
}
|
|
80
|
+
// Check gitignore rules if enabled
|
|
81
|
+
if (gitignoreChecker && gitRoot) {
|
|
82
|
+
// Get path relative to git root for gitignore checking
|
|
83
|
+
const relativeToGitRoot = path.relative(gitRoot, fullPath);
|
|
84
|
+
const normalizedGitPath = relativeToGitRoot.split(path.sep).join('/');
|
|
85
|
+
if (gitignoreChecker.ignores(normalizedGitPath)) {
|
|
86
|
+
return true;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
/**
|
|
92
|
+
* Add a path to results if it matches include patterns
|
|
93
|
+
*/
|
|
94
|
+
function addToResults(normalizedPath, fullPath, relativePath) {
|
|
95
|
+
if (isIncluded(normalizedPath)) {
|
|
96
|
+
results.push(absolute ? fullPath : relativePath);
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Process a symbolic link entry
|
|
101
|
+
*/
|
|
102
|
+
function processSymlink(fullPath, normalizedPath, relativePath) {
|
|
103
|
+
if (!followSymlinks) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
// Resolve symlink and check if it's a directory or file
|
|
107
|
+
let targetStat;
|
|
108
|
+
try {
|
|
109
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated baseDir + entries
|
|
110
|
+
targetStat = fs.statSync(fullPath);
|
|
111
|
+
}
|
|
112
|
+
catch {
|
|
113
|
+
// Skip broken symlinks
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
if (targetStat.isDirectory()) {
|
|
117
|
+
walkDirectory(fullPath);
|
|
118
|
+
}
|
|
119
|
+
else if (targetStat.isFile()) {
|
|
120
|
+
addToResults(normalizedPath, fullPath, relativePath);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
/**
|
|
124
|
+
* Process a directory entry
|
|
125
|
+
*/
|
|
126
|
+
function processDirectory(fullPath, normalizedPath, relativePath) {
|
|
127
|
+
// Recurse into subdirectory
|
|
128
|
+
walkDirectory(fullPath);
|
|
129
|
+
// Add directory to results if not filesOnly
|
|
130
|
+
if (!filesOnly) {
|
|
131
|
+
addToResults(normalizedPath, fullPath, relativePath);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* Process a file entry
|
|
136
|
+
*/
|
|
137
|
+
function processFile(normalizedPath, fullPath, relativePath) {
|
|
138
|
+
addToResults(normalizedPath, fullPath, relativePath);
|
|
139
|
+
}
|
|
140
|
+
/**
|
|
141
|
+
* Recursively walk directory tree
|
|
142
|
+
*/
|
|
143
|
+
function walkDirectory(currentDir) {
|
|
144
|
+
let entries;
|
|
145
|
+
try {
|
|
146
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- path constructed from validated baseDir, recursively walking
|
|
147
|
+
entries = fs.readdirSync(currentDir, { withFileTypes: true });
|
|
148
|
+
}
|
|
149
|
+
catch {
|
|
150
|
+
// Skip directories we don't have permission to read
|
|
151
|
+
return;
|
|
152
|
+
}
|
|
153
|
+
for (const entry of entries) {
|
|
154
|
+
const fullPath = path.join(currentDir, entry.name);
|
|
155
|
+
const relativePath = path.relative(resolvedBaseDir, fullPath);
|
|
156
|
+
const normalizedPath = relativePath.split(path.sep).join('/');
|
|
157
|
+
// Skip excluded paths
|
|
158
|
+
if (shouldExclude(normalizedPath, fullPath)) {
|
|
159
|
+
continue;
|
|
160
|
+
}
|
|
161
|
+
// Dispatch to appropriate handler based on entry type
|
|
162
|
+
if (entry.isSymbolicLink()) {
|
|
163
|
+
processSymlink(fullPath, normalizedPath, relativePath);
|
|
164
|
+
}
|
|
165
|
+
else if (entry.isDirectory()) {
|
|
166
|
+
processDirectory(fullPath, normalizedPath, relativePath);
|
|
167
|
+
}
|
|
168
|
+
else if (entry.isFile()) {
|
|
169
|
+
processFile(normalizedPath, fullPath, relativePath);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
}
|
|
173
|
+
// Start recursive walk from base directory
|
|
174
|
+
walkDirectory(resolvedBaseDir);
|
|
175
|
+
return results;
|
|
176
|
+
}
|
|
177
|
+
//# sourceMappingURL=file-crawler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-crawler.js","sourceRoot":"","sources":["../src/file-crawler.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,OAAO,SAAS,MAAM,WAAW,CAAC;AAElC,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAsBzE;;GAEG;AACH,MAAM,eAAe,GAAG,CAAC,oBAAoB,EAAE,YAAY,EAAE,YAAY,EAAE,gBAAgB,CAAC,CAAC;AAE7F;;;;;;;;;;;;;;;GAeG;AACH,MAAM,CAAC,KAAK,UAAU,cAAc,CAAC,OAAqB;IACxD,OAAO,kBAAkB,CAAC,OAAO,CAAC,CAAC;AACrC,CAAC;AAED;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAqB;IACtD,MAAM,EACJ,OAAO,EACP,OAAO,GAAG,CAAC,MAAM,CAAC,EAClB,OAAO,GAAG,eAAe,EACzB,cAAc,GAAG,KAAK,EACtB,QAAQ,GAAG,IAAI,EACf,SAAS,GAAG,IAAI,EAChB,gBAAgB,GAAG,IAAI,GACxB,GAAG,OAAO,CAAC;IAEZ,0CAA0C;IAC1C,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9C,+BAA+B;IAC/B,wHAAwH;IACxH,IAAI,CAAC,EAAE,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QACpC,MAAM,IAAI,KAAK,CAAC,kCAAkC,eAAe,EAAE,CAAC,CAAC;IACvE,CAAC;IAED,gDAAgD;IAChD,oGAAoG;IACpG,MAAM,QAAQ,GAAG,EAAE,CAAC,QAAQ,CAAC,eAAe,CAAC,CAAC;IAC9C,IAAI,CAAC,QAAQ,CAAC,WAAW,EAAE,EAAE,CAAC;QAC5B,MAAM,IAAI,KAAK,CAAC,iCAAiC,eAAe,EAAE,CAAC,CAAC;IACtE,CAAC;IAED,oCAAoC;IACpC,IAAI,gBAAgB,GAAkB,IAAI,CAAC;IAC3C,IAAI,OAAO,GAAkB,IAAI,CAAC;IAElC,IAAI,gBAAgB,EAAE,CAAC;QACrB,OAAO,GAAG,WAAW,CAAC,eAAe,CAAC,CAAC;QACvC,IAAI,OAAO,EAAE,CAAC;YACZ,gBAAgB,GAAG,kBAAkB,CAAC,OAAO,EAAE,eAAe,CAAC,CAAC;QAClE,CAAC;IACH,CAAC;IAED,wCAAwC;IACxC,MAAM,UAAU,GAAG,SAAS,CAAC,OAAO,CAAC,CAAC;IACtC,MAAM,UAAU,GAAG,OAAO,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAY,EAAE,CAAC,KAAK,CAAC;IAElF,MAAM,OAAO,GAAa,EAAE,CAAC;IAE7B;;OAEG;IACH,SAAS,aAAa,CAAC,cAAsB,EAAE,QAAgB;QAC7D,kCAAkC;QAClC,IAAI,UAAU,CAAC,cAAc,CAAC,IAAI,UAAU,CAAC,cAAc,GAAG,GAAG,CAAC,EAAE,CAAC;YACnE,OAAO,IAAI,CAAC;QACd,CAAC;QAED,mCAAmC;QACnC,IAAI,gBAAgB,IAAI,OAAO,EAAE,CAAC;YAChC,uDAAuD;YACvD,MAAM,iBAAiB,GAAG,IAAI,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;YAC3D,MAAM,iBAAiB,GAAG,iBAAiB,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAEtE,IAAI,gBAAgB,CAAC,OAAO,CAAC,iBAAiB,CAAC,EAAE,CAAC;gBAChD,OAAO,IAAI,CAAC;YACd,CAAC;QACH,CAAC;QAED,OAAO,KAAK,CAAC;IACf,CAAC;IAED;;OAEG;IACH,SAAS,YAAY,CAAC,cAAsB,EAAE,QAAgB,EAAE,YAAoB;QAClF,IAAI,UAAU,CAAC,cAAc,CAAC,EAAE,CAAC;YAC/B,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC;QACnD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,cAAc,CAAC,QAAgB,EAAE,cAAsB,EAAE,YAAoB;QACpF,IAAI,CAAC,cAAc,EAAE,CAAC;YACpB,OAAO;QACT,CAAC;QAED,wDAAwD;QACxD,IAAI,UAAoB,CAAC;QACzB,IAAI,CAAC;YACH,wHAAwH;YACxH,UAAU,GAAG,EAAE,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACrC,CAAC;QAAC,MAAM,CAAC;YACP,uBAAuB;YACvB,OAAO;QACT,CAAC;QAED,IAAI,UAAU,CAAC,WAAW,EAAE,EAAE,CAAC;YAC7B,aAAa,CAAC,QAAQ,CAAC,CAAC;QAC1B,CAAC;aAAM,IAAI,UAAU,CAAC,MAAM,EAAE,EAAE,CAAC;YAC/B,YAAY,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,gBAAgB,CAAC,QAAgB,EAAE,cAAsB,EAAE,YAAoB;QACtF,4BAA4B;QAC5B,aAAa,CAAC,QAAQ,CAAC,CAAC;QAExB,4CAA4C;QAC5C,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,YAAY,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;QACvD,CAAC;IACH,CAAC;IAED;;OAEG;IACH,SAAS,WAAW,CAAC,cAAsB,EAAE,QAAgB,EAAE,YAAoB;QACjF,YAAY,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;IACvD,CAAC;IAED;;OAEG;IACH,SAAS,aAAa,CAAC,UAAkB;QACvC,IAAI,OAAoB,CAAC;QAEzB,IAAI,CAAC;YACH,mIAAmI;YACnI,OAAO,GAAG,EAAE,CAAC,WAAW,CAAC,UAAU,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;QAChE,CAAC;QAAC,MAAM,CAAC;YACP,oDAAoD;YACpD,OAAO;QACT,CAAC;QAED,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;YAC5B,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;YACnD,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,eAAe,EAAE,QAAQ,CAAC,CAAC;YAC9D,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YAE9D,sBAAsB;YACtB,IAAI,aAAa,CAAC,cAAc,EAAE,QAAQ,CAAC,EAAE,CAAC;gBAC5C,SAAS;YACX,CAAC;YAED,sDAAsD;YACtD,IAAI,KAAK,CAAC,cAAc,EAAE,EAAE,CAAC;gBAC3B,cAAc,CAAC,QAAQ,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;YACzD,CAAC;iBAAM,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;gBAC/B,gBAAgB,CAAC,QAAQ,EAAE,cAAc,EAAE,YAAY,CAAC,CAAC;YAC3D,CAAC;iBAAM,IAAI,KAAK,CAAC,MAAM,EAAE,EAAE,CAAC;gBAC1B,WAAW,CAAC,cAAc,EAAE,QAAQ,EAAE,YAAY,CAAC,CAAC;YACtD,CAAC;QACH,CAAC;IACH,CAAC;IAED,2CAA2C;IAC3C,aAAa,CAAC,eAAe,CAAC,CAAC;IAE/B,OAAO,OAAO,CAAC;AACjB,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem utilities
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Recursively copy a directory
|
|
6
|
+
*
|
|
7
|
+
* @param src - Source directory path
|
|
8
|
+
* @param dest - Destination directory path
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* await copyDirectory('/source/dir', '/dest/dir');
|
|
12
|
+
*/
|
|
13
|
+
export declare function copyDirectory(src: string, dest: string): Promise<void>;
|
|
14
|
+
//# sourceMappingURL=fs-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-utils.d.ts","sourceRoot":"","sources":["../src/fs-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAKH;;;;;;;;GAQG;AACH,wBAAsB,aAAa,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAgB5E"}
|
package/dist/fs-utils.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Filesystem utilities
|
|
3
|
+
*/
|
|
4
|
+
import fs from 'node:fs/promises';
|
|
5
|
+
import path from 'node:path';
|
|
6
|
+
/**
|
|
7
|
+
* Recursively copy a directory
|
|
8
|
+
*
|
|
9
|
+
* @param src - Source directory path
|
|
10
|
+
* @param dest - Destination directory path
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* await copyDirectory('/source/dir', '/dest/dir');
|
|
14
|
+
*/
|
|
15
|
+
export async function copyDirectory(src, dest) {
|
|
16
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Paths from validated sources
|
|
17
|
+
await fs.mkdir(dest, { recursive: true });
|
|
18
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- Paths from validated sources
|
|
19
|
+
const entries = await fs.readdir(src, { withFileTypes: true });
|
|
20
|
+
for (const entry of entries) {
|
|
21
|
+
const srcPath = path.join(src, entry.name);
|
|
22
|
+
const destPath = path.join(dest, entry.name);
|
|
23
|
+
if (entry.isDirectory()) {
|
|
24
|
+
await copyDirectory(srcPath, destPath);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
await fs.copyFile(srcPath, destPath);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
//# sourceMappingURL=fs-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"fs-utils.js","sourceRoot":"","sources":["../src/fs-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B;;;;;;;;GAQG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAAC,GAAW,EAAE,IAAY;IAC3D,mGAAmG;IACnG,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAC1C,mGAAmG;IACnG,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,CAAC;IAE/D,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QAE7C,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,MAAM,aAAa,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACzC,CAAC;aAAM,CAAC;YACN,MAAM,EAAE,CAAC,QAAQ,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;QACvC,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Check if a file path is ignored by git
|
|
3
|
+
*
|
|
4
|
+
* Uses git check-ignore which respects .gitignore, .git/info/exclude, and global gitignore
|
|
5
|
+
*
|
|
6
|
+
* @param filePath - Absolute or relative path to check
|
|
7
|
+
* @param cwd - Working directory (defaults to process.cwd())
|
|
8
|
+
* @returns true if file is gitignored, false otherwise
|
|
9
|
+
*/
|
|
10
|
+
export declare function isGitIgnored(filePath: string, cwd?: string): boolean;
|
|
11
|
+
//# sourceMappingURL=git-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.d.ts","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"AAIA;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,GAAG,GAAE,MAAsB,GAAG,OAAO,CAkBnF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import { spawnSync } from 'node:child_process';
|
|
2
|
+
import which from 'which';
|
|
3
|
+
/**
|
|
4
|
+
* Check if a file path is ignored by git
|
|
5
|
+
*
|
|
6
|
+
* Uses git check-ignore which respects .gitignore, .git/info/exclude, and global gitignore
|
|
7
|
+
*
|
|
8
|
+
* @param filePath - Absolute or relative path to check
|
|
9
|
+
* @param cwd - Working directory (defaults to process.cwd())
|
|
10
|
+
* @returns true if file is gitignored, false otherwise
|
|
11
|
+
*/
|
|
12
|
+
export function isGitIgnored(filePath, cwd = process.cwd()) {
|
|
13
|
+
try {
|
|
14
|
+
// Resolve git path using which for security (avoids PATH manipulation)
|
|
15
|
+
const gitPath = which.sync('git');
|
|
16
|
+
// git check-ignore returns exit code 0 if file is ignored, 1 if not
|
|
17
|
+
const result = spawnSync(gitPath, ['check-ignore', '-q', filePath], {
|
|
18
|
+
cwd,
|
|
19
|
+
encoding: 'utf-8',
|
|
20
|
+
stdio: 'pipe',
|
|
21
|
+
shell: false, // No shell interpreter for security
|
|
22
|
+
});
|
|
23
|
+
return result.status === 0;
|
|
24
|
+
}
|
|
25
|
+
catch {
|
|
26
|
+
// If git is not available or other error, assume not ignored
|
|
27
|
+
return false;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
//# sourceMappingURL=git-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"git-utils.js","sourceRoot":"","sources":["../src/git-utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAE/C,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B;;;;;;;;GAQG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,MAAc,OAAO,CAAC,GAAG,EAAE;IACxE,IAAI,CAAC;QACH,uEAAuE;QACvE,MAAM,OAAO,GAAG,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAElC,oEAAoE;QACpE,MAAM,MAAM,GAAG,SAAS,CAAC,OAAO,EAAE,CAAC,cAAc,EAAE,IAAI,EAAE,QAAQ,CAAC,EAAE;YAClE,GAAG;YACH,QAAQ,EAAE,OAAO;YACjB,KAAK,EAAE,MAAM;YACb,KAAK,EAAE,KAAK,EAAE,oCAAoC;SACnD,CAAC,CAAC;QAEH,OAAO,MAAM,CAAC,MAAM,KAAK,CAAC,CAAC;IAC7B,CAAC;IAAC,MAAM,CAAC;QACP,6DAA6D;QAC7D,OAAO,KAAK,CAAC;IACf,CAAC;AACH,CAAC"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for checking if files are gitignored.
|
|
3
|
+
* Used by file-crawler and link validation.
|
|
4
|
+
*/
|
|
5
|
+
import { type Ignore } from 'ignore';
|
|
6
|
+
/**
|
|
7
|
+
* Find the git repository root by walking up from the given directory.
|
|
8
|
+
*
|
|
9
|
+
* @param startDir - Directory to start searching from
|
|
10
|
+
* @returns Path to git root, or null if not in a git repository
|
|
11
|
+
*/
|
|
12
|
+
export declare function findGitRoot(startDir: string): string | null;
|
|
13
|
+
/**
|
|
14
|
+
* Load and parse .gitignore files from git root to baseDir.
|
|
15
|
+
* Returns an ignore instance configured with all applicable .gitignore rules.
|
|
16
|
+
*
|
|
17
|
+
* @param gitRoot - Git repository root directory
|
|
18
|
+
* @param baseDir - Base directory being checked (optional, defaults to gitRoot)
|
|
19
|
+
* @returns Configured ignore instance, or null if no gitignore files found
|
|
20
|
+
*/
|
|
21
|
+
export declare function loadGitignoreRules(gitRoot: string, baseDir?: string): Ignore | null;
|
|
22
|
+
/**
|
|
23
|
+
* Check if a file path is ignored by git.
|
|
24
|
+
*
|
|
25
|
+
* @param filePath - Absolute path to check
|
|
26
|
+
* @param gitRoot - Git repository root (optional, will auto-detect if not provided)
|
|
27
|
+
* @returns True if file is gitignored, false otherwise
|
|
28
|
+
*/
|
|
29
|
+
export declare function isGitignored(filePath: string, gitRoot?: string): boolean;
|
|
30
|
+
//# sourceMappingURL=gitignore-checker.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore-checker.d.ts","sourceRoot":"","sources":["../src/gitignore-checker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAKH,OAAe,EAAE,KAAK,MAAM,EAAE,MAAM,QAAQ,CAAC;AAE7C;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAc3D;AAED;;;;;;;GAOG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAqCnF;AAED;;;;;;GAMG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,OAAO,CAsBxE"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for checking if files are gitignored.
|
|
3
|
+
* Used by file-crawler and link validation.
|
|
4
|
+
*/
|
|
5
|
+
import fs from 'node:fs';
|
|
6
|
+
import path from 'node:path';
|
|
7
|
+
import ignore from 'ignore';
|
|
8
|
+
/**
|
|
9
|
+
* Find the git repository root by walking up from the given directory.
|
|
10
|
+
*
|
|
11
|
+
* @param startDir - Directory to start searching from
|
|
12
|
+
* @returns Path to git root, or null if not in a git repository
|
|
13
|
+
*/
|
|
14
|
+
export function findGitRoot(startDir) {
|
|
15
|
+
let currentDir = path.resolve(startDir);
|
|
16
|
+
const root = path.parse(currentDir).root;
|
|
17
|
+
while (currentDir !== root) {
|
|
18
|
+
const gitDir = path.join(currentDir, '.git');
|
|
19
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- walking up from validated startDir
|
|
20
|
+
if (fs.existsSync(gitDir)) {
|
|
21
|
+
return currentDir;
|
|
22
|
+
}
|
|
23
|
+
currentDir = path.dirname(currentDir);
|
|
24
|
+
}
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Load and parse .gitignore files from git root to baseDir.
|
|
29
|
+
* Returns an ignore instance configured with all applicable .gitignore rules.
|
|
30
|
+
*
|
|
31
|
+
* @param gitRoot - Git repository root directory
|
|
32
|
+
* @param baseDir - Base directory being checked (optional, defaults to gitRoot)
|
|
33
|
+
* @returns Configured ignore instance, or null if no gitignore files found
|
|
34
|
+
*/
|
|
35
|
+
export function loadGitignoreRules(gitRoot, baseDir) {
|
|
36
|
+
const ig = ignore();
|
|
37
|
+
let hasRules = false;
|
|
38
|
+
// Always ignore .git directory
|
|
39
|
+
ig.add('.git');
|
|
40
|
+
hasRules = true;
|
|
41
|
+
// Collect all directories from gitRoot to baseDir
|
|
42
|
+
const dirsToCheck = [];
|
|
43
|
+
let currentDir = path.resolve(baseDir ?? gitRoot);
|
|
44
|
+
const resolvedGitRoot = path.resolve(gitRoot);
|
|
45
|
+
while (currentDir.startsWith(resolvedGitRoot)) {
|
|
46
|
+
dirsToCheck.unshift(currentDir);
|
|
47
|
+
if (currentDir === resolvedGitRoot) {
|
|
48
|
+
break;
|
|
49
|
+
}
|
|
50
|
+
currentDir = path.dirname(currentDir);
|
|
51
|
+
}
|
|
52
|
+
// Load .gitignore files from git root down to baseDir
|
|
53
|
+
for (const dir of dirsToCheck) {
|
|
54
|
+
const gitignorePath = path.join(dir, '.gitignore');
|
|
55
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- constructed from validated gitRoot and baseDir
|
|
56
|
+
if (fs.existsSync(gitignorePath)) {
|
|
57
|
+
try {
|
|
58
|
+
// eslint-disable-next-line security/detect-non-literal-fs-filename -- validated above
|
|
59
|
+
const content = fs.readFileSync(gitignorePath, 'utf-8');
|
|
60
|
+
ig.add(content);
|
|
61
|
+
}
|
|
62
|
+
catch {
|
|
63
|
+
// Skip gitignore files we can't read
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return hasRules ? ig : null;
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Check if a file path is ignored by git.
|
|
71
|
+
*
|
|
72
|
+
* @param filePath - Absolute path to check
|
|
73
|
+
* @param gitRoot - Git repository root (optional, will auto-detect if not provided)
|
|
74
|
+
* @returns True if file is gitignored, false otherwise
|
|
75
|
+
*/
|
|
76
|
+
export function isGitignored(filePath, gitRoot) {
|
|
77
|
+
const resolvedPath = path.resolve(filePath);
|
|
78
|
+
// Find git root if not provided
|
|
79
|
+
const root = gitRoot ?? findGitRoot(resolvedPath);
|
|
80
|
+
if (!root) {
|
|
81
|
+
// Not in a git repository
|
|
82
|
+
return false;
|
|
83
|
+
}
|
|
84
|
+
// Load gitignore rules
|
|
85
|
+
const ig = loadGitignoreRules(root);
|
|
86
|
+
if (!ig) {
|
|
87
|
+
// No gitignore rules
|
|
88
|
+
return false;
|
|
89
|
+
}
|
|
90
|
+
// Get path relative to git root
|
|
91
|
+
const relativePath = path.relative(root, resolvedPath);
|
|
92
|
+
const normalizedPath = relativePath.split(path.sep).join('/');
|
|
93
|
+
return ig.ignores(normalizedPath);
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=gitignore-checker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"gitignore-checker.js","sourceRoot":"","sources":["../src/gitignore-checker.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,EAAE,MAAM,SAAS,CAAC;AACzB,OAAO,IAAI,MAAM,WAAW,CAAC;AAE7B,OAAO,MAAuB,MAAM,QAAQ,CAAC;AAE7C;;;;;GAKG;AACH,MAAM,UAAU,WAAW,CAAC,QAAgB;IAC1C,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IACxC,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC;IAEzC,OAAO,UAAU,KAAK,IAAI,EAAE,CAAC;QAC3B,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;QAC7C,yGAAyG;QACzG,IAAI,EAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC1B,OAAO,UAAU,CAAC;QACpB,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,kBAAkB,CAAC,OAAe,EAAE,OAAgB;IAClE,MAAM,EAAE,GAAG,MAAM,EAAE,CAAC;IACpB,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,+BAA+B;IAC/B,EAAE,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;IACf,QAAQ,GAAG,IAAI,CAAC;IAEhB,kDAAkD;IAClD,MAAM,WAAW,GAAa,EAAE,CAAC;IACjC,IAAI,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,IAAI,OAAO,CAAC,CAAC;IAClD,MAAM,eAAe,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC;IAE9C,OAAO,UAAU,CAAC,UAAU,CAAC,eAAe,CAAC,EAAE,CAAC;QAC9C,WAAW,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;QAChC,IAAI,UAAU,KAAK,eAAe,EAAE,CAAC;YACnC,MAAM;QACR,CAAC;QACD,UAAU,GAAG,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC;IACxC,CAAC;IAED,sDAAsD;IACtD,KAAK,MAAM,GAAG,IAAI,WAAW,EAAE,CAAC;QAC9B,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,GAAG,EAAE,YAAY,CAAC,CAAC;QACnD,qHAAqH;QACrH,IAAI,EAAE,CAAC,UAAU,CAAC,aAAa,CAAC,EAAE,CAAC;YACjC,IAAI,CAAC;gBACH,sFAAsF;gBACtF,MAAM,OAAO,GAAG,EAAE,CAAC,YAAY,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;gBACxD,EAAE,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC;YAClB,CAAC;YAAC,MAAM,CAAC;gBACP,qCAAqC;YACvC,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;AAC9B,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,YAAY,CAAC,QAAgB,EAAE,OAAgB;IAC7D,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;IAE5C,gCAAgC;IAChC,MAAM,IAAI,GAAG,OAAO,IAAI,WAAW,CAAC,YAAY,CAAC,CAAC;IAClD,IAAI,CAAC,IAAI,EAAE,CAAC;QACV,0BAA0B;QAC1B,OAAO,KAAK,CAAC;IACf,CAAC;IAED,uBAAuB;IACvB,MAAM,EAAE,GAAG,kBAAkB,CAAC,IAAI,CAAC,CAAC;IACpC,IAAI,CAAC,EAAE,EAAE,CAAC;QACR,qBAAqB;QACrB,OAAO,KAAK,CAAC;IACf,CAAC;IAED,gCAAgC;IAChC,MAAM,YAAY,GAAG,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAC,CAAC;IACvD,MAAM,cAAc,GAAG,YAAY,CAAC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IAE9D,OAAO,EAAE,CAAC,OAAO,CAAC,cAAc,CAAC,CAAC;AACpC,CAAC"}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vibe-agent-toolkit/utils
|
|
3
|
+
* Core shared utilities with no dependencies on other packages
|
|
4
|
+
*
|
|
5
|
+
* Utilities are added as needed by other packages, not speculatively.
|
|
6
|
+
*/
|
|
7
|
+
export * from './safe-exec.js';
|
|
8
|
+
export * from './path-utils.js';
|
|
9
|
+
export * from './fs-utils.js';
|
|
10
|
+
export * from './file-crawler.js';
|
|
11
|
+
export * from './gitignore-checker.js';
|
|
12
|
+
export * from './git-utils.js';
|
|
13
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,cAAc,gBAAgB,CAAC;AAG/B,cAAc,iBAAiB,CAAC;AAGhC,cAAc,eAAe,CAAC;AAG9B,cAAc,mBAAmB,CAAC;AAGlC,cAAc,wBAAwB,CAAC;AAGvC,cAAc,gBAAgB,CAAC"}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @vibe-agent-toolkit/utils
|
|
3
|
+
* Core shared utilities with no dependencies on other packages
|
|
4
|
+
*
|
|
5
|
+
* Utilities are added as needed by other packages, not speculatively.
|
|
6
|
+
*/
|
|
7
|
+
// Safe command execution (cross-platform, no shell injection)
|
|
8
|
+
export * from './safe-exec.js';
|
|
9
|
+
// Cross-platform path utilities
|
|
10
|
+
export * from './path-utils.js';
|
|
11
|
+
// Filesystem utilities
|
|
12
|
+
export * from './fs-utils.js';
|
|
13
|
+
// Directory crawling with glob patterns
|
|
14
|
+
export * from './file-crawler.js';
|
|
15
|
+
// Git ignore checking
|
|
16
|
+
export * from './gitignore-checker.js';
|
|
17
|
+
// Git utilities (using git commands directly)
|
|
18
|
+
export * from './git-utils.js';
|
|
19
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,8DAA8D;AAC9D,cAAc,gBAAgB,CAAC;AAE/B,gCAAgC;AAChC,cAAc,iBAAiB,CAAC;AAEhC,uBAAuB;AACvB,cAAc,eAAe,CAAC;AAE9B,wCAAwC;AACxC,cAAc,mBAAmB,CAAC;AAElC,sBAAsB;AACtB,cAAc,wBAAwB,CAAC;AAEvC,8CAA8C;AAC9C,cAAc,gBAAgB,CAAC"}
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Normalize a path for cross-platform comparison
|
|
3
|
+
*
|
|
4
|
+
* - Converts to absolute path (if baseDir provided)
|
|
5
|
+
* - Normalizes separators (/ vs \)
|
|
6
|
+
* - Resolves . and ..
|
|
7
|
+
* - Removes trailing slashes
|
|
8
|
+
*
|
|
9
|
+
* @param p - Path to normalize
|
|
10
|
+
* @param baseDir - Optional base directory for relative path resolution
|
|
11
|
+
* @returns Normalized absolute path
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* normalizePath('./docs/../README.md', '/project')
|
|
15
|
+
* // Returns: '/project/README.md'
|
|
16
|
+
*/
|
|
17
|
+
export declare function normalizePath(p: string, baseDir?: string): string;
|
|
18
|
+
/**
|
|
19
|
+
* Check if a path is absolute
|
|
20
|
+
*
|
|
21
|
+
* Cross-platform detection of absolute paths:
|
|
22
|
+
* - Unix: /path/to/file
|
|
23
|
+
* - Windows: C:\path\to\file or C:/path/to/file
|
|
24
|
+
*
|
|
25
|
+
* @param p - Path to check
|
|
26
|
+
* @returns True if path is absolute
|
|
27
|
+
*
|
|
28
|
+
* @example
|
|
29
|
+
* isAbsolutePath('/path/to/file') // true
|
|
30
|
+
* isAbsolutePath('./relative') // false
|
|
31
|
+
* isAbsolutePath('C:/Windows') // true (Windows)
|
|
32
|
+
*/
|
|
33
|
+
export declare function isAbsolutePath(p: string): boolean;
|
|
34
|
+
/**
|
|
35
|
+
* Convert a relative path to absolute
|
|
36
|
+
*
|
|
37
|
+
* If path is already absolute, returns it normalized.
|
|
38
|
+
* Otherwise resolves relative to baseDir.
|
|
39
|
+
*
|
|
40
|
+
* @param p - Path to convert
|
|
41
|
+
* @param baseDir - Base directory for resolution
|
|
42
|
+
* @returns Absolute path
|
|
43
|
+
*
|
|
44
|
+
* @example
|
|
45
|
+
* toAbsolutePath('./docs/README.md', '/project')
|
|
46
|
+
* // Returns: '/project/docs/README.md'
|
|
47
|
+
*
|
|
48
|
+
* toAbsolutePath('/absolute/path.md', '/project')
|
|
49
|
+
* // Returns: '/absolute/path.md'
|
|
50
|
+
*/
|
|
51
|
+
export declare function toAbsolutePath(p: string, baseDir: string): string;
|
|
52
|
+
/**
|
|
53
|
+
* Get the relative path from one file to another
|
|
54
|
+
*
|
|
55
|
+
* Useful for generating relative links between markdown files.
|
|
56
|
+
*
|
|
57
|
+
* @param from - Source file path (absolute)
|
|
58
|
+
* @param to - Target file path (absolute)
|
|
59
|
+
* @returns Relative path from source to target
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* getRelativePath('/project/docs/guide.md', '/project/README.md')
|
|
63
|
+
* // Returns: '../README.md'
|
|
64
|
+
*
|
|
65
|
+
* getRelativePath('/project/README.md', '/project/docs/api.md')
|
|
66
|
+
* // Returns: 'docs/api.md'
|
|
67
|
+
*/
|
|
68
|
+
export declare function getRelativePath(from: string, to: string): string;
|
|
69
|
+
/**
|
|
70
|
+
* Convert a path to Unix-style forward slashes
|
|
71
|
+
*
|
|
72
|
+
* Useful for glob pattern matching, which expects forward slashes.
|
|
73
|
+
* On Windows, path.resolve() and path.normalize() return backslashes,
|
|
74
|
+
* but glob matchers like picomatch expect forward slashes by default.
|
|
75
|
+
*
|
|
76
|
+
* @param p - Path to convert
|
|
77
|
+
* @returns Path with forward slashes
|
|
78
|
+
*
|
|
79
|
+
* @example
|
|
80
|
+
* toUnixPath('C:\\Users\\docs\\README.md')
|
|
81
|
+
* // Returns: 'C:/Users/docs/README.md'
|
|
82
|
+
*
|
|
83
|
+
* toUnixPath('/project/docs/README.md')
|
|
84
|
+
* // Returns: '/project/docs/README.md' (unchanged on Unix)
|
|
85
|
+
*/
|
|
86
|
+
export declare function toUnixPath(p: string): string;
|
|
87
|
+
//# sourceMappingURL=path-utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path-utils.d.ts","sourceRoot":"","sources":["../src/path-utils.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,aAAa,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,GAAG,MAAM,CAWjE;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAEjD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,CAAC,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,GAAG,MAAM,CAKjE;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,GAAG,MAAM,CAMhE;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,UAAU,CAAC,CAAC,EAAE,MAAM,GAAG,MAAM,CAE5C"}
|