@vd7/eyecli 0.1.8
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 +3 -0
- package/README.md +173 -0
- package/TODOs.md +10 -0
- package/assets/social-preview.png +0 -0
- package/bin/eye.js +191 -0
- package/package.json +44 -0
package/README.md
ADDED
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
<div align="center">
|
|
2
|
+
|
|
3
|
+
<img src="https://raw.githubusercontent.com/vdutts7/webp/refs/heads/main/eyecli.webp" alt="logo" width="80" height="80" />
|
|
4
|
+
<img src="https://raw.githubusercontent.com/vdutts7/webp/refs/heads/main/npm.webp" alt="logo" width="80" height="80" />
|
|
5
|
+
|
|
6
|
+
<h1 align="center">๐๏ธ eyecli</h1>
|
|
7
|
+
<p align="center"><i><b>The Eye sees EVERYTHING. A powerful search CLI wrapping ripgrep and fd.</b></i></p>
|
|
8
|
+
|
|
9
|
+
[![Github][github]][github-url]
|
|
10
|
+
[![npm][npm]][npm-url]
|
|
11
|
+
|
|
12
|
+
</div>
|
|
13
|
+
|
|
14
|
+
<br/>
|
|
15
|
+
|
|
16
|
+
## Table of Contents
|
|
17
|
+
|
|
18
|
+
<ol>
|
|
19
|
+
<a href="#about">๐ About</a><br/>
|
|
20
|
+
<a href="#install">๐ป Install</a><br/>
|
|
21
|
+
<a href="#usage">๐ Usage</a><br/>
|
|
22
|
+
<a href="#ignore-file">๐ Ignore File</a><br/>
|
|
23
|
+
<a href="#roadmap">๐บ๏ธ Roadmap</a><br/>
|
|
24
|
+
<a href="#tools-used">๐ง Tools used</a><br/>
|
|
25
|
+
<a href="#contact">๐ค Contact</a>
|
|
26
|
+
</ol>
|
|
27
|
+
|
|
28
|
+
<br/>
|
|
29
|
+
|
|
30
|
+
## ๐About
|
|
31
|
+
|
|
32
|
+
Smart defaults for searching. Hidden files included, case-insensitive, no .gitignore restrictions.
|
|
33
|
+
|
|
34
|
+
- **๐ Smart defaults** - hidden files included, case-insensitive, no .gitignore restrictions
|
|
35
|
+
- **๐ Fast** - powered by ripgrep and fd
|
|
36
|
+
- **๐ Extension filter** - `:json`, `:ts,tsx` syntax for quick file type filtering
|
|
37
|
+
- **๐ณ Tree view** - visualize results as directory tree
|
|
38
|
+
- **โ๏ธ Customizable** - `~/.eyeignore` for personal ignore patterns
|
|
39
|
+
|
|
40
|
+
<br/>
|
|
41
|
+
|
|
42
|
+
## ๐ปInstall
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
npm i -g @vd7/eyecli
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
### Requirements
|
|
49
|
+
|
|
50
|
+
- [ripgrep](https://github.com/BurntSushi/ripgrep) - for content search
|
|
51
|
+
- [fd](https://github.com/sharkdp/fd) - for filename search
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# macOS
|
|
55
|
+
brew install ripgrep fd
|
|
56
|
+
|
|
57
|
+
# Ubuntu/Debian
|
|
58
|
+
apt install ripgrep fd-find
|
|
59
|
+
|
|
60
|
+
# Windows
|
|
61
|
+
choco install ripgrep fd
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
<br/>
|
|
65
|
+
|
|
66
|
+
## ๐Usage
|
|
67
|
+
|
|
68
|
+
```bash
|
|
69
|
+
# Search file contents
|
|
70
|
+
eye "pattern" [path]
|
|
71
|
+
|
|
72
|
+
# Search filenames
|
|
73
|
+
eye -f "pattern" [path]
|
|
74
|
+
|
|
75
|
+
# Find by extension
|
|
76
|
+
eye :json .
|
|
77
|
+
eye :ts,tsx ~/code
|
|
78
|
+
|
|
79
|
+
# Options
|
|
80
|
+
eye -c "pattern" . # Count matches
|
|
81
|
+
eye -t :json . # Tree view
|
|
82
|
+
eye -E node_modules "TODO" . # Exclude paths
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
### Examples
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# Find all TODOs in current directory
|
|
89
|
+
eye "TODO" .
|
|
90
|
+
|
|
91
|
+
# Find config files
|
|
92
|
+
eye -f "config" ~/projects
|
|
93
|
+
|
|
94
|
+
# Find all JSON files
|
|
95
|
+
eye :json ~/projects
|
|
96
|
+
|
|
97
|
+
# Count TypeScript files
|
|
98
|
+
eye :ts,tsx src -c
|
|
99
|
+
|
|
100
|
+
# Search excluding node_modules
|
|
101
|
+
eye -E node_modules "import" .
|
|
102
|
+
|
|
103
|
+
# Create ignore file
|
|
104
|
+
eye init
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
<br/>
|
|
108
|
+
|
|
109
|
+
## ๐Ignore File
|
|
110
|
+
|
|
111
|
+
Eye supports a `~/.eyeignore` file to customize what gets searched.
|
|
112
|
+
|
|
113
|
+
```bash
|
|
114
|
+
# Create starter ignore file
|
|
115
|
+
eye init
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
This creates `~/.eyeignore` with sensible defaults (node_modules, .git, build dirs, etc.). Edit it to customize.
|
|
119
|
+
|
|
120
|
+
**Starter template includes:**
|
|
121
|
+
- Version control (.git, .svn)
|
|
122
|
+
- Dependencies (node_modules, vendor)
|
|
123
|
+
- Build output (dist, build, out)
|
|
124
|
+
- Lock files (package-lock.json, yarn.lock)
|
|
125
|
+
- IDE files (.idea, .vscode)
|
|
126
|
+
- Caches (__pycache__, .cache)
|
|
127
|
+
- And more...
|
|
128
|
+
|
|
129
|
+
**Secrets are NOT ignored by default** - uncomment `.env` patterns in `~/.eyeignore` if you want to exclude them.
|
|
130
|
+
|
|
131
|
+
<br/>
|
|
132
|
+
|
|
133
|
+
## ๐บ๏ธRoadmap
|
|
134
|
+
|
|
135
|
+
- [x] Content search with ripgrep
|
|
136
|
+
- [x] Filename search with fd
|
|
137
|
+
- [x] Extension filtering (`:json`, `:ts,tsx`)
|
|
138
|
+
- [x] Tree view output
|
|
139
|
+
- [x] Custom ignore file (`~/.eyeignore`)
|
|
140
|
+
- [ ] Fuzzy matching
|
|
141
|
+
- [ ] Interactive mode
|
|
142
|
+
- [ ] Config file for defaults
|
|
143
|
+
|
|
144
|
+
<br/>
|
|
145
|
+
|
|
146
|
+
## ๐งTools Used
|
|
147
|
+
|
|
148
|
+
[![Node.js][nodejs-badge]][nodejs-url]
|
|
149
|
+
[![ripgrep][rg-badge]][rg-url]
|
|
150
|
+
[![fd][fd-badge]][fd-url]
|
|
151
|
+
|
|
152
|
+
<br/>
|
|
153
|
+
|
|
154
|
+
## ๐คContact
|
|
155
|
+
|
|
156
|
+
[![Email][email]][email-url]
|
|
157
|
+
[![Twitter][twitter]][twitter-url]
|
|
158
|
+
|
|
159
|
+
<!-- BADGES -->
|
|
160
|
+
[github]: https://img.shields.io/badge/๐ป_eyecli-000000?style=for-the-badge
|
|
161
|
+
[github-url]: https://github.com/vdutts7/eyecli
|
|
162
|
+
[npm]: https://img.shields.io/badge/npm-@vd7/eyecli-CB3837?style=for-the-badge&logo=npm
|
|
163
|
+
[npm-url]: https://www.npmjs.com/package/@vd7/eyecli
|
|
164
|
+
[nodejs-badge]: https://img.shields.io/badge/Node.js-339933?style=for-the-badge&logo=nodedotjs&logoColor=white
|
|
165
|
+
[nodejs-url]: https://nodejs.org
|
|
166
|
+
[rg-badge]: https://img.shields.io/badge/ripgrep-4B275F?style=for-the-badge&logo=rust&logoColor=white
|
|
167
|
+
[rg-url]: https://github.com/BurntSushi/ripgrep
|
|
168
|
+
[fd-badge]: https://img.shields.io/badge/fd-4B275F?style=for-the-badge&logo=rust&logoColor=white
|
|
169
|
+
[fd-url]: https://github.com/sharkdp/fd
|
|
170
|
+
[email]: https://img.shields.io/badge/Email-000000?style=for-the-badge&logo=Gmail&logoColor=white
|
|
171
|
+
[email-url]: mailto:me@vd7.io
|
|
172
|
+
[twitter]: https://img.shields.io/badge/Twitter-000000?style=for-the-badge&logo=Twitter&logoColor=white
|
|
173
|
+
[twitter-url]: https://x.com/vdutts7
|
package/TODOs.md
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# TODOs
|
|
2
|
+
|
|
3
|
+
<!-- macos-trace: traces fd can't see (path-only) -->
|
|
4
|
+
- [ ] Keychain (binary; refs in label/service) โ Keychain Access or `security dump-keychain โฆ | strings | grep -i PATTERN`
|
|
5
|
+
- [ ] SQLite/.vscdb/.db (path in column, not filename) โ `rg -i -l PATTERN ~/Library --glob '*.{sqlite,vscdb,db}'`
|
|
6
|
+
- [ ] Plists/caches (path embedded in content) โ `rg -i -l PATTERN ~/Library` (slow)
|
|
7
|
+
- [ ] Add `--content` or keychain/DB pass to trace (or separate script)
|
|
8
|
+
<!-- -->
|
|
9
|
+
|
|
10
|
+
<!-- same for rg as for fd -->
|
|
Binary file
|
package/bin/eye.js
ADDED
|
@@ -0,0 +1,191 @@
|
|
|
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 (handle absolute vs relative paths)
|
|
137
|
+
for (const ex of excludes) {
|
|
138
|
+
if (ex.startsWith('/')) {
|
|
139
|
+
cmdArgs.push('--exclude', ex);
|
|
140
|
+
} else {
|
|
141
|
+
cmdArgs.push('--exclude', `*${ex}*`);
|
|
142
|
+
}
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
// Add pattern (use '.' as match-all if only extensions specified)
|
|
146
|
+
if (extensions.length > 0) {
|
|
147
|
+
cmdArgs.push('.');
|
|
148
|
+
} else if (pattern) {
|
|
149
|
+
cmdArgs.push(pattern);
|
|
150
|
+
}
|
|
151
|
+
|
|
152
|
+
// Add search path
|
|
153
|
+
cmdArgs.push(searchPath);
|
|
154
|
+
|
|
155
|
+
} else {
|
|
156
|
+
// Content search via rg
|
|
157
|
+
const rgCmd = checkTool('rg');
|
|
158
|
+
if (!rgCmd) {
|
|
159
|
+
console.error('Error: ripgrep not found. Install with: brew install ripgrep');
|
|
160
|
+
process.exit(1);
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
cmd = rgCmd;
|
|
164
|
+
cmdArgs = [...RG_DEFAULTS];
|
|
165
|
+
|
|
166
|
+
if (includeBinary) cmdArgs.push('-a');
|
|
167
|
+
if (countMode) cmdArgs.push('-c');
|
|
168
|
+
|
|
169
|
+
// Add excludes (handle absolute vs relative paths)
|
|
170
|
+
for (const ex of excludes) {
|
|
171
|
+
if (ex.startsWith('/')) {
|
|
172
|
+
cmdArgs.push('--glob', `!${ex}/**`);
|
|
173
|
+
} else {
|
|
174
|
+
cmdArgs.push('--glob', `!**/${ex}/**`);
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
cmdArgs.push(pattern, searchPath);
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
// Execute
|
|
182
|
+
const child = spawn(cmd, cmdArgs, { stdio: 'inherit' });
|
|
183
|
+
|
|
184
|
+
child.on('error', (err) => {
|
|
185
|
+
console.error(`Error: ${err.message}`);
|
|
186
|
+
process.exit(1);
|
|
187
|
+
});
|
|
188
|
+
|
|
189
|
+
child.on('close', (code) => {
|
|
190
|
+
process.exit(code || 0);
|
|
191
|
+
});
|
package/package.json
ADDED
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@vd7/eyecli",
|
|
3
|
+
"version": "0.1.8",
|
|
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
|
+
}
|