@vd7/eyecli 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/.git-personal-enforced +4 -0
- package/README.md +74 -0
- package/bin/eye.js +183 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
# 👁️ eyecli
|
|
2
|
+
|
|
3
|
+
**The Eye sees EVERYTHING.** A powerful search CLI wrapping ripgrep and fd with smart defaults.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install -g eyecli
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
### Requirements
|
|
12
|
+
|
|
13
|
+
- [ripgrep](https://github.com/BurntSushi/ripgrep) - for content search
|
|
14
|
+
- [fd](https://github.com/sharkdp/fd) - for filename search
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
# macOS
|
|
18
|
+
brew install ripgrep fd
|
|
19
|
+
|
|
20
|
+
# Ubuntu/Debian
|
|
21
|
+
apt install ripgrep fd-find
|
|
22
|
+
|
|
23
|
+
# Windows
|
|
24
|
+
choco install ripgrep fd
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
## Usage
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
# Search file contents
|
|
31
|
+
eye "pattern" [path]
|
|
32
|
+
|
|
33
|
+
# Search filenames
|
|
34
|
+
eye -f "pattern" [path]
|
|
35
|
+
|
|
36
|
+
# Find by extension
|
|
37
|
+
eye :json .
|
|
38
|
+
eye :ts,tsx ~/code
|
|
39
|
+
|
|
40
|
+
# Options
|
|
41
|
+
eye -c "pattern" . # Count matches
|
|
42
|
+
eye -t :json . # Tree view
|
|
43
|
+
eye -E node_modules "TODO" . # Exclude paths
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Examples
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# Find all TODOs in current directory
|
|
50
|
+
eye "TODO" .
|
|
51
|
+
|
|
52
|
+
# Find config files
|
|
53
|
+
eye -f "config" ~/projects
|
|
54
|
+
|
|
55
|
+
# Find all JSON files
|
|
56
|
+
eye :json ~/projects
|
|
57
|
+
|
|
58
|
+
# Count TypeScript files
|
|
59
|
+
eye :ts,tsx src -c
|
|
60
|
+
|
|
61
|
+
# Search excluding node_modules
|
|
62
|
+
eye -E node_modules "import" .
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
## Why?
|
|
66
|
+
|
|
67
|
+
- 🔍 **Smart defaults** - hidden files included, case-insensitive, no .gitignore restrictions
|
|
68
|
+
- 🚀 **Fast** - powered by ripgrep and fd
|
|
69
|
+
- 📁 **Extension filter** - `:json`, `:ts,tsx` syntax for quick file type filtering
|
|
70
|
+
- 🌳 **Tree view** - visualize results as directory tree
|
|
71
|
+
|
|
72
|
+
## License
|
|
73
|
+
|
|
74
|
+
MIT
|
package/bin/eye.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const { spawn } = require('child_process');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
// Default flags (mirrors ~/.zshrc RG_DEFAULTS and FD_DEFAULTS)
|
|
7
|
+
const RG_DEFAULTS = ['--hidden', '--no-follow', '--no-ignore', '-i'];
|
|
8
|
+
const FD_DEFAULTS = ['-H', '-L', '--no-ignore'];
|
|
9
|
+
|
|
10
|
+
// Parse arguments
|
|
11
|
+
const args = process.argv.slice(2);
|
|
12
|
+
|
|
13
|
+
// Help
|
|
14
|
+
if (args.includes('--help') || args.includes('-h') || args.length === 0) {
|
|
15
|
+
console.log(`
|
|
16
|
+
👁️ EYE - The Eye sees EVERYTHING
|
|
17
|
+
|
|
18
|
+
Usage:
|
|
19
|
+
eye <pattern> [path] Search file contents (via ripgrep)
|
|
20
|
+
eye -f <pattern> [path] Search filenames (via fd)
|
|
21
|
+
eye :ext [path] Find files by extension (e.g., eye :json .)
|
|
22
|
+
eye :ext1,ext2 [path] Multiple extensions (e.g., eye :js,ts ~/code)
|
|
23
|
+
|
|
24
|
+
Options:
|
|
25
|
+
-f, --files Search filenames instead of content
|
|
26
|
+
-a, --all Include binary files
|
|
27
|
+
-c, --count Count results
|
|
28
|
+
-t, --tree Show results as tree
|
|
29
|
+
-E <glob> Exclude paths matching glob (repeatable)
|
|
30
|
+
-h, --help Show this help
|
|
31
|
+
|
|
32
|
+
Examples:
|
|
33
|
+
eye "TODO" . Find TODO in current directory
|
|
34
|
+
eye "function" ~/code Search for "function" in ~/code
|
|
35
|
+
eye -f "config" ~/projects Find files named "config"
|
|
36
|
+
eye :json ~/projects Find all .json files
|
|
37
|
+
eye :ts,tsx src -c Count TypeScript files in src
|
|
38
|
+
|
|
39
|
+
Requirements:
|
|
40
|
+
- ripgrep (rg) for content search
|
|
41
|
+
- fd for filename search
|
|
42
|
+
|
|
43
|
+
Install dependencies:
|
|
44
|
+
brew install ripgrep fd # macOS
|
|
45
|
+
apt install ripgrep fd-find # Ubuntu/Debian
|
|
46
|
+
`);
|
|
47
|
+
process.exit(0);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
// Check for required tools
|
|
51
|
+
function checkTool(name, altName) {
|
|
52
|
+
const { execSync } = require('child_process');
|
|
53
|
+
try {
|
|
54
|
+
execSync(`which ${name}`, { stdio: 'ignore' });
|
|
55
|
+
return name;
|
|
56
|
+
} catch {
|
|
57
|
+
if (altName) {
|
|
58
|
+
try {
|
|
59
|
+
execSync(`which ${altName}`, { stdio: 'ignore' });
|
|
60
|
+
return altName;
|
|
61
|
+
} catch {
|
|
62
|
+
return null;
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return null;
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
// Parse arguments
|
|
70
|
+
let mode = 'content';
|
|
71
|
+
let includeBinary = false;
|
|
72
|
+
let countMode = false;
|
|
73
|
+
let treeMode = false;
|
|
74
|
+
let pattern = null;
|
|
75
|
+
let searchPath = '.';
|
|
76
|
+
let excludes = [];
|
|
77
|
+
let extensions = [];
|
|
78
|
+
|
|
79
|
+
let i = 0;
|
|
80
|
+
while (i < args.length) {
|
|
81
|
+
const arg = args[i];
|
|
82
|
+
|
|
83
|
+
if (arg === '-f' || arg === '--files') {
|
|
84
|
+
mode = 'files';
|
|
85
|
+
} else if (arg === '-a' || arg === '--all') {
|
|
86
|
+
includeBinary = true;
|
|
87
|
+
} else if (arg === '-c' || arg === '--count') {
|
|
88
|
+
countMode = true;
|
|
89
|
+
} else if (arg === '-t' || arg === '--tree') {
|
|
90
|
+
treeMode = true;
|
|
91
|
+
} else if (arg === '-E' || arg === '--exclude') {
|
|
92
|
+
i++;
|
|
93
|
+
if (args[i]) excludes.push(args[i]);
|
|
94
|
+
} else if (arg.startsWith(':')) {
|
|
95
|
+
// Extension filter :json or :js,ts
|
|
96
|
+
const exts = arg.slice(1).replace(/\s/g, '').split(',');
|
|
97
|
+
extensions.push(...exts.filter(e => e));
|
|
98
|
+
} else if (!pattern && extensions.length === 0) {
|
|
99
|
+
// Only set pattern if no extensions (extensions don't need a pattern)
|
|
100
|
+
pattern = arg;
|
|
101
|
+
} else {
|
|
102
|
+
searchPath = arg;
|
|
103
|
+
}
|
|
104
|
+
i++;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// If only extensions specified, use match-all pattern
|
|
108
|
+
if (extensions.length > 0 && !pattern) {
|
|
109
|
+
pattern = '.';
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
if (!pattern && extensions.length === 0) {
|
|
113
|
+
console.error('Error: No pattern specified. Use --help for usage.');
|
|
114
|
+
process.exit(1);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// Build command
|
|
118
|
+
let cmd, cmdArgs;
|
|
119
|
+
|
|
120
|
+
if (mode === 'files' || extensions.length > 0) {
|
|
121
|
+
// Filename search via fd
|
|
122
|
+
const fdCmd = checkTool('fd', 'fdfind');
|
|
123
|
+
if (!fdCmd) {
|
|
124
|
+
console.error('Error: fd not found. Install with: brew install fd');
|
|
125
|
+
process.exit(1);
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
cmd = fdCmd;
|
|
129
|
+
cmdArgs = [...FD_DEFAULTS];
|
|
130
|
+
|
|
131
|
+
// Add extensions
|
|
132
|
+
for (const ext of extensions) {
|
|
133
|
+
cmdArgs.push('-e', ext);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Add excludes
|
|
137
|
+
for (const ex of excludes) {
|
|
138
|
+
cmdArgs.push('--exclude', `*${ex}*`);
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
// Add pattern (use '.' as match-all if only extensions specified)
|
|
142
|
+
if (extensions.length > 0) {
|
|
143
|
+
cmdArgs.push('.');
|
|
144
|
+
} else if (pattern) {
|
|
145
|
+
cmdArgs.push(pattern);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
// Add search path
|
|
149
|
+
cmdArgs.push(searchPath);
|
|
150
|
+
|
|
151
|
+
} else {
|
|
152
|
+
// Content search via rg
|
|
153
|
+
const rgCmd = checkTool('rg');
|
|
154
|
+
if (!rgCmd) {
|
|
155
|
+
console.error('Error: ripgrep not found. Install with: brew install ripgrep');
|
|
156
|
+
process.exit(1);
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
cmd = rgCmd;
|
|
160
|
+
cmdArgs = [...RG_DEFAULTS];
|
|
161
|
+
|
|
162
|
+
if (includeBinary) cmdArgs.push('-a');
|
|
163
|
+
if (countMode) cmdArgs.push('-c');
|
|
164
|
+
|
|
165
|
+
// Add excludes
|
|
166
|
+
for (const ex of excludes) {
|
|
167
|
+
cmdArgs.push('--glob', `!**/${ex}/**`);
|
|
168
|
+
}
|
|
169
|
+
|
|
170
|
+
cmdArgs.push(pattern, searchPath);
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
// Execute
|
|
174
|
+
const child = spawn(cmd, cmdArgs, { stdio: 'inherit' });
|
|
175
|
+
|
|
176
|
+
child.on('error', (err) => {
|
|
177
|
+
console.error(`Error: ${err.message}`);
|
|
178
|
+
process.exit(1);
|
|
179
|
+
});
|
|
180
|
+
|
|
181
|
+
child.on('close', (code) => {
|
|
182
|
+
process.exit(code || 0);
|
|
183
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vd7/eyecli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "The Eye sees EVERYTHING. A powerful search CLI wrapping ripgrep and fd with smart defaults.",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"eye": "./bin/eye.js"
|
|
8
|
+
},
|
|
9
|
+
"scripts": {
|
|
10
|
+
"test": "node bin/eye.js --help"
|
|
11
|
+
},
|
|
12
|
+
"keywords": [
|
|
13
|
+
"search",
|
|
14
|
+
"ripgrep",
|
|
15
|
+
"fd",
|
|
16
|
+
"find",
|
|
17
|
+
"grep",
|
|
18
|
+
"cli",
|
|
19
|
+
"files",
|
|
20
|
+
"content"
|
|
21
|
+
],
|
|
22
|
+
"author": "vdutts",
|
|
23
|
+
"license": "MIT",
|
|
24
|
+
"repository": {
|
|
25
|
+
"type": "git",
|
|
26
|
+
"url": "https://github.com/vdutts/eyecli.git"
|
|
27
|
+
},
|
|
28
|
+
"engines": {
|
|
29
|
+
"node": ">=16.0.0"
|
|
30
|
+
},
|
|
31
|
+
"dependencies": {},
|
|
32
|
+
"peerDependencies": {
|
|
33
|
+
"ripgrep": "*",
|
|
34
|
+
"fd-find": "*"
|
|
35
|
+
},
|
|
36
|
+
"peerDependenciesMeta": {
|
|
37
|
+
"ripgrep": {
|
|
38
|
+
"optional": true
|
|
39
|
+
},
|
|
40
|
+
"fd-find": {
|
|
41
|
+
"optional": true
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
}
|