Skip to content

Commit 50c3c6e

Browse files
authored
Address initial usage notes to improve DX (#6)
- **Terminology**: Replace all "clone" references with "vlurp" to better reflect that we download tarballs - **Enhanced default filters**: Now includes `*.md` files (excluding common repo files), `/agents` and `/commands` directories. Refactored to use `glob` for cleaner, more reliable pattern matching - **Re-vlurping protection**: Warns when overwriting existing directories, shows file count, can bypass with `--force` flag - **Tree display**: Automatically shows directory structure after vlurping with total file count using ASCII tree. Fixed to show hidden directories like `.claude` - **Use `glob`**: Avoid reinventing the ~wheel~ `glob`
1 parent 4b02af1 commit 50c3c6e

File tree

11 files changed

+313
-67
lines changed

11 files changed

+313
-67
lines changed

.changeset/friendly-bears-dance.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
"vlurp": minor
3+
---
4+
5+
Improve vlurp user experience based on v1.0.0 feedback:
6+
7+
- **Terminology**: Replace all "clone" references with "vlurp" to better reflect that we download tarballs
8+
- **Enhanced default filters**: Now includes `*.md` files (excluding common repo files), `/agents` and `/commands` directories. Refactored to use `glob` for cleaner, more reliable pattern matching
9+
- **Re-vlurping protection**: Warns when overwriting existing directories, shows file count, can bypass with `--force` flag
10+
- **Tree display**: Automatically shows directory structure after vlurping with total file count using ASCII tree. Fixed to show hidden directories like `.claude`

CONTRIBUTING.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ Thank you for your interest in contributing to vlurp! This document provides gui
55
## Development
66

77
```sh
8-
# clone the repository
8+
# Clone the repository
99
git clone git@github.com:indexzero/vlurp.git
1010

1111
# Install dependencies
@@ -124,4 +124,4 @@ Runs on pushes to `main` and handles:
124124

125125
## Questions?
126126

127-
If you have questions about contributing, feel free to open an issue for discussion.
127+
If you have questions about contributing, feel free to open an issue for discussion.

README.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,19 +18,19 @@ npx vlurp <user>/<repo>
1818
## Usage
1919

2020
```sh
21-
# Vlurp a repository using user/repo format
21+
# vlurp a repository using user/repo format
2222
vlurp cool-repo/has-agents
2323
# → Creates ./cool-repo/has-agents
2424

25-
# Vlurp to a specific directory
25+
# vlurp to a specific directory
2626
vlurp cool-repo/has-agents -d ~/projects
2727
# → Creates ~/projects/cool-repo/has-agents
2828

29-
# Vlurp using a GitHub URL
29+
# vlurp using a GitHub URL
3030
vlurp https://github.com/whoever/cool-configs
3131
# → Creates ./whoever/cool-configs
3232

33-
# Vlurp a GitHub Gist
33+
# vlurp a GitHub Gist
3434
vlurp https://gist.github.com/user/abc123def456
3535
# → Creates ./user/abc123def456
3636

@@ -40,10 +40,10 @@ vlurp --help
4040
# Filter files (default: .claude/** and CLAUDE.md)
4141
vlurp cool-repo/has-agents --filter "*.ts" --filter "*.tsx"
4242

43-
# Vlurp only specific directories
43+
# vlurp only specific directories
4444
vlurp whoever/cool-configs --filter "lib/**" --filter "doc/**"
4545

46-
# Vlurp only markdown files
46+
# vlurp only markdown files
4747
vlurp user/repo --filter "*.md"
4848
```
4949

package.json

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
"vlurp": "./bin/vlurp"
99
},
1010
"scripts": {
11-
"test": "node --test",
11+
"test": "node --test test/*.test.js",
1212
"lint": "xo",
1313
"lint:fix": "xo --fix",
1414
"changeset": "changeset"
1515
},
1616
"keywords": [
1717
"cli",
1818
"github",
19-
"clone",
19+
"vlurp",
2020
"download",
2121
"fetch",
2222
"repository",
@@ -29,6 +29,8 @@
2929
},
3030
"packageManager": "pnpm@10.14.0",
3131
"dependencies": {
32+
"archy": "^1.0.0",
33+
"glob": "^11.0.3",
3234
"hosted-git-info": "^9.0.0",
3335
"ink": "^6.1.0",
3436
"ink-spinner": "^5.0.0",

pnpm-lock.yaml

Lines changed: 48 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.js

Lines changed: 14 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,21 +10,24 @@ const j = jack({
1010
.description('A fun CLI tool to quickly fetch GitHub repositories and gists')
1111
.opt({
1212
d: {
13-
description: 'Root directory for cloning',
13+
description: 'Root directory for vlurping',
1414
short: 'd'
1515
}
1616
})
1717
.optList({
1818
filter: {
19-
description: 'Glob patterns to filter files (defaults to .claude/** and CLAUDE.md)',
20-
short: 'f',
21-
default: ['.claude/**', 'CLAUDE.md']
19+
description: 'Glob patterns to filter files (see defaults in help)',
20+
default: ['.claude/**', 'CLAUDE.md', '*.md', '!README.md', '!CONTRIBUTING.md', '!LICENSE.md', '!CHANGELOG.md', '!CODE_OF_CONDUCT.md', 'agents/**', 'commands/**']
2221
}
2322
})
2423
.flag({
2524
help: {
2625
description: 'Show this help message',
2726
short: 'h'
27+
},
28+
force: {
29+
description: 'Force overwrite existing directories without prompting',
30+
short: 'f'
2831
}
2932
});
3033

@@ -40,9 +43,10 @@ Usage:
4043
vlurp <url> -d <root> Fetch to <root>/<user>/<repo>
4144
4245
Examples:
43-
vlurp facebook/react Fetch with default filters (.claude/**, CLAUDE.md)
46+
vlurp facebook/react Fetch with default filters
4447
vlurp nodejs/node --filter "*.js" Fetch only JavaScript files
45-
vlurp user/repo -f "src/**" -f "*.md" Fetch src folder and markdown files
48+
vlurp user/repo --filter "src/**" Fetch src folder
49+
vlurp user/repo --force Force overwrite existing directory
4650
4751
Options:
4852
${j.usage()}`);
@@ -57,5 +61,8 @@ if (positionals.length === 0) {
5761
const source = positionals[0];
5862
const rootDir = values.d;
5963
const filters = values.filter;
64+
const {force} = values;
6065

61-
render(React.createElement(FetchCommand, { source, rootDir, filters }));
66+
render(React.createElement(FetchCommand, {
67+
source, rootDir, filters, force
68+
}));

src/commands/fetch.js

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,13 @@ import Spinner from 'ink-spinner';
66
import { parseSource } from '../parser.js';
77
import { validateUrl } from '../validator.js';
88
import { fetchRepository } from '../fetcher.js';
9+
import { buildTreeString } from '../tree.js';
910

10-
export function FetchCommand({ source, rootDir, filters }) {
11+
export function FetchCommand({ source, rootDir, filters, force }) {
1112
const [status, setStatus] = useState('locating');
1213
const [error, setError] = useState(null);
1314
const [result, setResult] = useState(null);
15+
const [treeOutput, setTreeOutput] = useState(null);
1416

1517
useEffect(() => {
1618
async function performFetch() {
@@ -32,13 +34,18 @@ export function FetchCommand({ source, rootDir, filters }) {
3234

3335
// Vlurp the repository
3436
setStatus('vlurping');
35-
await fetchRepository(parsed.tarballUrl, targetPath, filters);
37+
const { fileCount } = await fetchRepository(parsed.tarballUrl, targetPath, filters, { force });
38+
39+
// Generate tree output
40+
const tree = await buildTreeString(targetPath);
41+
setTreeOutput(tree);
3642

3743
setResult({
3844
user: parsed.user,
3945
repo: parsed.repo,
4046
path: targetPath,
41-
filterCount: filters.length
47+
filterCount: filters.length,
48+
fileCount
4249
});
4350
setStatus('complete');
4451
} catch (err) {
@@ -48,7 +55,7 @@ export function FetchCommand({ source, rootDir, filters }) {
4855
}
4956

5057
performFetch();
51-
}, [source, rootDir, filters]);
58+
}, [source, rootDir, filters, force]);
5259

5360
if (status === 'error') {
5461
return React.createElement(
@@ -62,9 +69,11 @@ export function FetchCommand({ source, rootDir, filters }) {
6269
return React.createElement(
6370
Box,
6471
{ flexDirection: 'column' },
65-
React.createElement(Text, { color: 'green' }, `✓ Successfully cloned ${result.user}/${result.repo}`),
72+
React.createElement(Text, { color: 'green' }, `✓ Successfully vlurped ${result.user}/${result.repo}`),
6673
React.createElement(Text, { color: 'gray' }, ` Location: ${result.path}`),
67-
result.filterCount > 0 && React.createElement(Text, { color: 'gray' }, ` Filters: ${result.filterCount} pattern(s) applied`)
74+
result.filterCount > 0 && React.createElement(Text, { color: 'gray' }, ` Filters: ${result.filterCount} pattern(s) applied`),
75+
treeOutput && React.createElement(Box, { marginTop: 1 }, React.createElement(Text, null, treeOutput)),
76+
React.createElement(Text, { color: 'cyan', marginTop: 1 }, `✨ vlurped ${result.fileCount} files to ${result.path}`)
6877
);
6978
}
7079

@@ -76,7 +85,7 @@ export function FetchCommand({ source, rootDir, filters }) {
7685
null,
7786
React.createElement(Spinner, { type: 'dots' })
7887
),
79-
React.createElement(Text, null, ` ${status === 'parsing' ? 'Parsing input...' : 'Cloning repository...'}`)
88+
React.createElement(Text, null, ` ${status === 'parsing' ? 'Parsing input...' : 'vlurping repository...'}`)
8089
);
8190
}
8291

0 commit comments

Comments
 (0)