@fredlackey/devutils 0.0.1
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 +156 -0
- package/bin/dev.js +16 -0
- package/files/README.md +0 -0
- package/files/claude/.claude/commands/setup-context.md +3 -0
- package/files/monorepos/_archive/README.md +36 -0
- package/files/monorepos/_legacy/README.md +36 -0
- package/files/monorepos/ai-docs/README.md +33 -0
- package/files/monorepos/apps/README.md +24 -0
- package/files/monorepos/docs/README.md +40 -0
- package/files/monorepos/packages/README.md +25 -0
- package/files/monorepos/research/README.md +29 -0
- package/files/monorepos/scripts/README.md +24 -0
- package/package.json +39 -0
- package/src/cli.js +68 -0
- package/src/commands/README.md +41 -0
- package/src/commands/configure.js +199 -0
- package/src/commands/identity.js +1630 -0
- package/src/commands/ignore.js +247 -0
- package/src/commands/install.js +173 -0
- package/src/commands/setup.js +212 -0
- package/src/commands/status.js +223 -0
- package/src/completion.js +284 -0
- package/src/constants.js +45 -0
- package/src/ignore/claude-code.txt +10 -0
- package/src/ignore/docker.txt +18 -0
- package/src/ignore/linux.txt +23 -0
- package/src/ignore/macos.txt +36 -0
- package/src/ignore/node.txt +55 -0
- package/src/ignore/terraform.txt +37 -0
- package/src/ignore/vscode.txt +18 -0
- package/src/ignore/windows.txt +35 -0
- package/src/index.js +0 -0
- package/src/installs/README.md +399 -0
- package/src/installs/adobe-creative-cloud.js +44 -0
- package/src/installs/appcleaner.js +44 -0
- package/src/installs/atomicparsley.js +44 -0
- package/src/installs/aws-cli.js +44 -0
- package/src/installs/balena-etcher.js +44 -0
- package/src/installs/bambu-studio.js +44 -0
- package/src/installs/bash-completion.js +44 -0
- package/src/installs/bash.js +44 -0
- package/src/installs/beyond-compare.js +44 -0
- package/src/installs/build-essential.js +44 -0
- package/src/installs/caffeine.js +44 -0
- package/src/installs/camtasia.js +44 -0
- package/src/installs/chatgpt.js +44 -0
- package/src/installs/chrome-canary.js +44 -0
- package/src/installs/chromium.js +44 -0
- package/src/installs/claude-code.js +44 -0
- package/src/installs/curl.js +44 -0
- package/src/installs/cursor.js +44 -0
- package/src/installs/dbschema.js +44 -0
- package/src/installs/docker.js +44 -0
- package/src/installs/drawio.js +44 -0
- package/src/installs/elmedia-player.js +44 -0
- package/src/installs/ffmpeg.js +44 -0
- package/src/installs/gemini-cli.js +44 -0
- package/src/installs/git.js +44 -0
- package/src/installs/gitego.js +44 -0
- package/src/installs/go.js +44 -0
- package/src/installs/google-chrome.js +44 -0
- package/src/installs/gpg.js +141 -0
- package/src/installs/homebrew.js +44 -0
- package/src/installs/imageoptim.js +44 -0
- package/src/installs/jq.js +44 -0
- package/src/installs/keyboard-maestro.js +44 -0
- package/src/installs/latex.js +44 -0
- package/src/installs/lftp.js +44 -0
- package/src/installs/messenger.js +44 -0
- package/src/installs/microsoft-office.js +44 -0
- package/src/installs/microsoft-teams.js +44 -0
- package/src/installs/node.js +44 -0
- package/src/installs/nordpass.js +44 -0
- package/src/installs/nvm.js +44 -0
- package/src/installs/openssh.js +134 -0
- package/src/installs/pandoc.js +44 -0
- package/src/installs/pinentry.js +44 -0
- package/src/installs/pngyu.js +44 -0
- package/src/installs/postman.js +44 -0
- package/src/installs/safari-tech-preview.js +44 -0
- package/src/installs/sfnt2woff.js +44 -0
- package/src/installs/shellcheck.js +44 -0
- package/src/installs/slack.js +44 -0
- package/src/installs/snagit.js +44 -0
- package/src/installs/spotify.js +44 -0
- package/src/installs/studio-3t.js +44 -0
- package/src/installs/sublime-text.js +44 -0
- package/src/installs/superwhisper.js +44 -0
- package/src/installs/tailscale.js +44 -0
- package/src/installs/termius.js +44 -0
- package/src/installs/terraform.js +44 -0
- package/src/installs/tidal.js +44 -0
- package/src/installs/tmux.js +44 -0
- package/src/installs/tree.js +44 -0
- package/src/installs/vim.js +44 -0
- package/src/installs/vlc.js +44 -0
- package/src/installs/vscode.js +44 -0
- package/src/installs/whatsapp.js +44 -0
- package/src/installs/woff2.js +44 -0
- package/src/installs/xcode.js +44 -0
- package/src/installs/yarn.js +44 -0
- package/src/installs/yq.js +44 -0
- package/src/installs/yt-dlp.js +44 -0
- package/src/installs/zoom.js +44 -0
- package/src/scripts/README.md +95 -0
- package/src/scripts/afk.js +23 -0
- package/src/scripts/backup-all.js +24 -0
- package/src/scripts/backup-source.js +24 -0
- package/src/scripts/brewd.js +23 -0
- package/src/scripts/brewi.js +24 -0
- package/src/scripts/brewr.js +24 -0
- package/src/scripts/brews.js +24 -0
- package/src/scripts/brewu.js +23 -0
- package/src/scripts/c.js +23 -0
- package/src/scripts/ccurl.js +24 -0
- package/src/scripts/certbot-crontab-init.js +24 -0
- package/src/scripts/certbot-init.js +25 -0
- package/src/scripts/ch.js +23 -0
- package/src/scripts/claude-danger.js +23 -0
- package/src/scripts/clean-dev.js +24 -0
- package/src/scripts/clear-dns-cache.js +23 -0
- package/src/scripts/clone.js +25 -0
- package/src/scripts/code-all.js +24 -0
- package/src/scripts/count-files.js +24 -0
- package/src/scripts/count-folders.js +24 -0
- package/src/scripts/count.js +24 -0
- package/src/scripts/d.js +23 -0
- package/src/scripts/datauri.js +24 -0
- package/src/scripts/delete-files.js +24 -0
- package/src/scripts/docker-clean.js +24 -0
- package/src/scripts/dp.js +23 -0
- package/src/scripts/e.js +24 -0
- package/src/scripts/empty-trash.js +23 -0
- package/src/scripts/evm.js +25 -0
- package/src/scripts/fetch-github-repos.js +25 -0
- package/src/scripts/get-channel.js +24 -0
- package/src/scripts/get-course.js +26 -0
- package/src/scripts/get-dependencies.js +25 -0
- package/src/scripts/get-folder.js +26 -0
- package/src/scripts/get-tunes.js +25 -0
- package/src/scripts/get-video.js +24 -0
- package/src/scripts/git-backup.js +25 -0
- package/src/scripts/git-clone.js +25 -0
- package/src/scripts/git-pup.js +23 -0
- package/src/scripts/git-push.js +24 -0
- package/src/scripts/h.js +24 -0
- package/src/scripts/hide-desktop-icons.js +23 -0
- package/src/scripts/hide-hidden-files.js +23 -0
- package/src/scripts/install-dependencies-from.js +25 -0
- package/src/scripts/ips.js +26 -0
- package/src/scripts/iso.js +24 -0
- package/src/scripts/killni.js +23 -0
- package/src/scripts/ll.js +24 -0
- package/src/scripts/local-ip.js +23 -0
- package/src/scripts/m.js +24 -0
- package/src/scripts/map.js +24 -0
- package/src/scripts/mkd.js +24 -0
- package/src/scripts/ncu-update-all.js +24 -0
- package/src/scripts/nginx-init.js +28 -0
- package/src/scripts/npmi.js +23 -0
- package/src/scripts/o.js +24 -0
- package/src/scripts/org-by-date.js +24 -0
- package/src/scripts/p.js +23 -0
- package/src/scripts/packages.js +25 -0
- package/src/scripts/path.js +23 -0
- package/src/scripts/ports.js +23 -0
- package/src/scripts/q.js +23 -0
- package/src/scripts/refresh-files.js +26 -0
- package/src/scripts/remove-smaller-files.js +24 -0
- package/src/scripts/rename-files-with-date.js +25 -0
- package/src/scripts/resize-image.js +25 -0
- package/src/scripts/rm-safe.js +24 -0
- package/src/scripts/s.js +24 -0
- package/src/scripts/set-git-public.js +23 -0
- package/src/scripts/show-desktop-icons.js +23 -0
- package/src/scripts/show-hidden-files.js +23 -0
- package/src/scripts/tpa.js +23 -0
- package/src/scripts/tpo.js +23 -0
- package/src/scripts/u.js +23 -0
- package/src/scripts/vpush.js +23 -0
- package/src/scripts/y.js +23 -0
- package/src/utils/README.md +95 -0
- package/src/utils/common/apps.js +143 -0
- package/src/utils/common/display.js +157 -0
- package/src/utils/common/network.js +185 -0
- package/src/utils/common/os.js +202 -0
- package/src/utils/common/package-manager.js +301 -0
- package/src/utils/common/privileges.js +138 -0
- package/src/utils/common/shell.js +195 -0
- package/src/utils/macos/apps.js +228 -0
- package/src/utils/macos/brew.js +315 -0
- package/src/utils/ubuntu/apt.js +301 -0
- package/src/utils/ubuntu/desktop.js +292 -0
- package/src/utils/ubuntu/snap.js +302 -0
- package/src/utils/ubuntu/systemd.js +286 -0
- package/src/utils/windows/choco.js +327 -0
- package/src/utils/windows/env.js +246 -0
- package/src/utils/windows/registry.js +269 -0
- package/src/utils/windows/shell.js +240 -0
- package/src/utils/windows/winget.js +378 -0
|
@@ -0,0 +1,223 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Status command - Display current configuration and environment health.
|
|
5
|
+
*/
|
|
6
|
+
|
|
7
|
+
const { Command } = require('commander');
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
const { execSync } = require('child_process');
|
|
11
|
+
|
|
12
|
+
const CONFIG_FILE = path.join(process.env.HOME || process.env.USERPROFILE, '.devutils');
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* Load existing configuration
|
|
16
|
+
* @returns {object|null}
|
|
17
|
+
*/
|
|
18
|
+
function loadConfig() {
|
|
19
|
+
try {
|
|
20
|
+
if (fs.existsSync(CONFIG_FILE)) {
|
|
21
|
+
const content = fs.readFileSync(CONFIG_FILE, 'utf8');
|
|
22
|
+
return JSON.parse(content);
|
|
23
|
+
}
|
|
24
|
+
} catch {
|
|
25
|
+
return null;
|
|
26
|
+
}
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
/**
|
|
31
|
+
* Check if current directory is inside a git repository
|
|
32
|
+
* @returns {string|null} Path to git root or null
|
|
33
|
+
*/
|
|
34
|
+
function getGitRoot() {
|
|
35
|
+
try {
|
|
36
|
+
const result = execSync('git rev-parse --show-toplevel', {
|
|
37
|
+
encoding: 'utf8',
|
|
38
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
39
|
+
});
|
|
40
|
+
return result.trim();
|
|
41
|
+
} catch {
|
|
42
|
+
return null;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
/**
|
|
47
|
+
* Get current git branch
|
|
48
|
+
* @returns {string|null}
|
|
49
|
+
*/
|
|
50
|
+
function getGitBranch() {
|
|
51
|
+
try {
|
|
52
|
+
const result = execSync('git branch --show-current', {
|
|
53
|
+
encoding: 'utf8',
|
|
54
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
55
|
+
});
|
|
56
|
+
return result.trim();
|
|
57
|
+
} catch {
|
|
58
|
+
return null;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* Get Node.js version
|
|
64
|
+
* @returns {string|null}
|
|
65
|
+
*/
|
|
66
|
+
function getNodeVersion() {
|
|
67
|
+
try {
|
|
68
|
+
return process.version;
|
|
69
|
+
} catch {
|
|
70
|
+
return null;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
/**
|
|
75
|
+
* Get npm version
|
|
76
|
+
* @returns {string|null}
|
|
77
|
+
*/
|
|
78
|
+
function getNpmVersion() {
|
|
79
|
+
try {
|
|
80
|
+
return execSync('npm --version', {
|
|
81
|
+
encoding: 'utf8',
|
|
82
|
+
stdio: ['pipe', 'pipe', 'pipe']
|
|
83
|
+
}).trim();
|
|
84
|
+
} catch {
|
|
85
|
+
return null;
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
/**
|
|
90
|
+
* Detect operating system
|
|
91
|
+
* @returns {string}
|
|
92
|
+
*/
|
|
93
|
+
function getOS() {
|
|
94
|
+
switch (process.platform) {
|
|
95
|
+
case 'darwin':
|
|
96
|
+
return 'macOS';
|
|
97
|
+
case 'win32':
|
|
98
|
+
return 'Windows';
|
|
99
|
+
case 'linux':
|
|
100
|
+
return 'Linux';
|
|
101
|
+
default:
|
|
102
|
+
return process.platform;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
/**
|
|
107
|
+
* Check if a command exists
|
|
108
|
+
* @param {string} cmd - Command to check
|
|
109
|
+
* @returns {boolean}
|
|
110
|
+
*/
|
|
111
|
+
function commandExists(cmd) {
|
|
112
|
+
try {
|
|
113
|
+
const checkCmd = process.platform === 'win32' ? `where ${cmd}` : `which ${cmd}`;
|
|
114
|
+
execSync(checkCmd, { stdio: ['pipe', 'pipe', 'pipe'] });
|
|
115
|
+
return true;
|
|
116
|
+
} catch {
|
|
117
|
+
return false;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Display status information
|
|
123
|
+
* @param {object} options - Command options
|
|
124
|
+
*/
|
|
125
|
+
function runStatus(options) {
|
|
126
|
+
const config = loadConfig();
|
|
127
|
+
const warnings = [];
|
|
128
|
+
|
|
129
|
+
console.log('\n=== DevUtils CLI Status ===\n');
|
|
130
|
+
|
|
131
|
+
// Configuration Status
|
|
132
|
+
console.log('Configuration:');
|
|
133
|
+
console.log('─'.repeat(40));
|
|
134
|
+
|
|
135
|
+
if (config) {
|
|
136
|
+
console.log(` File: ${CONFIG_FILE}`);
|
|
137
|
+
console.log(' Status: Valid');
|
|
138
|
+
|
|
139
|
+
if (config.user) {
|
|
140
|
+
console.log(` User: ${config.user.name} <${config.user.email}>`);
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
if (config.updated) {
|
|
144
|
+
console.log(` Updated: ${new Date(config.updated).toLocaleString()}`);
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Check for issues
|
|
148
|
+
if (!config.user?.name || !config.user?.email) {
|
|
149
|
+
warnings.push('User name or email not configured');
|
|
150
|
+
}
|
|
151
|
+
} else {
|
|
152
|
+
console.log(` File: ${CONFIG_FILE}`);
|
|
153
|
+
console.log(' Status: Not found');
|
|
154
|
+
warnings.push(`Configuration file not found. Run 'dev configure' to create it.`);
|
|
155
|
+
}
|
|
156
|
+
|
|
157
|
+
// Environment
|
|
158
|
+
console.log('\nEnvironment:');
|
|
159
|
+
console.log('─'.repeat(40));
|
|
160
|
+
console.log(` OS: ${getOS()}`);
|
|
161
|
+
console.log(` Node: ${getNodeVersion() || 'Not found'}`);
|
|
162
|
+
console.log(` npm: ${getNpmVersion() || 'Not found'}`);
|
|
163
|
+
console.log(` CWD: ${process.cwd()}`);
|
|
164
|
+
|
|
165
|
+
// Git Repository
|
|
166
|
+
const gitRoot = getGitRoot();
|
|
167
|
+
console.log('\nGit Repository:');
|
|
168
|
+
console.log('─'.repeat(40));
|
|
169
|
+
|
|
170
|
+
if (gitRoot) {
|
|
171
|
+
console.log(` Root: ${gitRoot}`);
|
|
172
|
+
console.log(` Branch: ${getGitBranch() || 'Unknown'}`);
|
|
173
|
+
} else {
|
|
174
|
+
console.log(' Status: Not in a git repository');
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
// Available Tools
|
|
178
|
+
console.log('\nAvailable Tools:');
|
|
179
|
+
console.log('─'.repeat(40));
|
|
180
|
+
|
|
181
|
+
const tools = [
|
|
182
|
+
{ name: 'git', label: 'Git' },
|
|
183
|
+
{ name: 'docker', label: 'Docker' },
|
|
184
|
+
{ name: 'code', label: 'VS Code' },
|
|
185
|
+
{ name: 'brew', label: 'Homebrew' },
|
|
186
|
+
{ name: 'choco', label: 'Chocolatey' },
|
|
187
|
+
{ name: 'winget', label: 'winget' }
|
|
188
|
+
];
|
|
189
|
+
|
|
190
|
+
for (const tool of tools) {
|
|
191
|
+
const exists = commandExists(tool.name);
|
|
192
|
+
const status = exists ? 'Installed' : 'Not found';
|
|
193
|
+
console.log(` ${tool.label.padEnd(12)} ${status}`);
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
// Identities
|
|
197
|
+
if (config?.identities && Object.keys(config.identities).length > 0) {
|
|
198
|
+
console.log('\nIdentities:');
|
|
199
|
+
console.log('─'.repeat(40));
|
|
200
|
+
for (const [name, identity] of Object.entries(config.identities)) {
|
|
201
|
+
console.log(` ${name}: ${identity.email || identity.name || '(incomplete)'}`);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Warnings
|
|
206
|
+
if (warnings.length > 0) {
|
|
207
|
+
console.log('\nWarnings:');
|
|
208
|
+
console.log('─'.repeat(40));
|
|
209
|
+
for (const warning of warnings) {
|
|
210
|
+
console.log(` ! ${warning}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
console.log('');
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
// Create and configure the command
|
|
218
|
+
const status = new Command('status')
|
|
219
|
+
.description('Display current configuration and environment health')
|
|
220
|
+
.option('--verbose', 'Show detailed information')
|
|
221
|
+
.action(runStatus);
|
|
222
|
+
|
|
223
|
+
module.exports = status;
|
|
@@ -0,0 +1,284 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @fileoverview Tab completion handler for the dev CLI.
|
|
5
|
+
* Provides shell completion for bash, zsh, and fish.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
const fs = require('fs');
|
|
9
|
+
const path = require('path');
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* Command completion definitions
|
|
13
|
+
* Maps parent commands to their available subcommands
|
|
14
|
+
*/
|
|
15
|
+
const COMMANDS = {
|
|
16
|
+
'': ['configure', 'status', 'identity', 'ignore', 'install', 'completion'],
|
|
17
|
+
'dev': ['configure', 'status', 'identity', 'ignore', 'install', 'completion'],
|
|
18
|
+
'identity': ['add', 'remove', 'link'],
|
|
19
|
+
'completion': ['install', 'uninstall']
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Command descriptions for enhanced completion (zsh/fish)
|
|
24
|
+
*/
|
|
25
|
+
const DESCRIPTIONS = {
|
|
26
|
+
'configure': 'Interactive configuration wizard',
|
|
27
|
+
'status': 'Display current configuration',
|
|
28
|
+
'identity': 'Manage identity profiles',
|
|
29
|
+
'ignore': 'Append patterns to .gitignore',
|
|
30
|
+
'install': 'Install development tools',
|
|
31
|
+
'completion': 'Manage shell completion',
|
|
32
|
+
'add': 'Add a new identity profile',
|
|
33
|
+
'remove': 'Remove an identity profile',
|
|
34
|
+
'link': 'Link identity to a source folder'
|
|
35
|
+
};
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* Get available ignore technologies by scanning src/ignore directory
|
|
39
|
+
* @returns {string[]} Array of technology names
|
|
40
|
+
*/
|
|
41
|
+
function getIgnoreTechnologies() {
|
|
42
|
+
try {
|
|
43
|
+
const ignoreDir = path.join(__dirname, 'ignore');
|
|
44
|
+
if (!fs.existsSync(ignoreDir)) {
|
|
45
|
+
return [];
|
|
46
|
+
}
|
|
47
|
+
return fs.readdirSync(ignoreDir)
|
|
48
|
+
.filter(file => file.endsWith('.txt'))
|
|
49
|
+
.map(file => file.replace('.txt', ''));
|
|
50
|
+
} catch {
|
|
51
|
+
return [];
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/**
|
|
56
|
+
* Get available install scripts by scanning src/installs directory
|
|
57
|
+
* @returns {string[]} Array of install script names
|
|
58
|
+
*/
|
|
59
|
+
function getInstallScripts() {
|
|
60
|
+
try {
|
|
61
|
+
const installsDir = path.join(__dirname, 'installs');
|
|
62
|
+
if (!fs.existsSync(installsDir)) {
|
|
63
|
+
return [];
|
|
64
|
+
}
|
|
65
|
+
return fs.readdirSync(installsDir)
|
|
66
|
+
.filter(file => file.endsWith('.js'))
|
|
67
|
+
.map(file => file.replace('.js', ''));
|
|
68
|
+
} catch {
|
|
69
|
+
return [];
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/**
|
|
74
|
+
* Parse completion environment variables
|
|
75
|
+
* @returns {object} Parsed environment with line, words, prev, etc.
|
|
76
|
+
*/
|
|
77
|
+
function parseEnv() {
|
|
78
|
+
const line = process.env.COMP_LINE || '';
|
|
79
|
+
const point = parseInt(process.env.COMP_POINT || line.length, 10);
|
|
80
|
+
const partial = line.slice(0, point);
|
|
81
|
+
const words = partial.split(/\s+/).filter(Boolean);
|
|
82
|
+
const lastPartial = partial.endsWith(' ') ? '' : (words[words.length - 1] || '');
|
|
83
|
+
const prev = words.length > 1 ? words[words.length - (partial.endsWith(' ') ? 1 : 2)] : '';
|
|
84
|
+
|
|
85
|
+
return {
|
|
86
|
+
line,
|
|
87
|
+
point,
|
|
88
|
+
words,
|
|
89
|
+
prev,
|
|
90
|
+
lastPartial,
|
|
91
|
+
wordCount: words.length
|
|
92
|
+
};
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/**
|
|
96
|
+
* Output completions in the format expected by shells
|
|
97
|
+
* @param {string[]|object[]} completions - Array of completion strings or objects with name/description
|
|
98
|
+
*/
|
|
99
|
+
function logCompletions(completions) {
|
|
100
|
+
completions.forEach(item => {
|
|
101
|
+
if (typeof item === 'string') {
|
|
102
|
+
console.log(item);
|
|
103
|
+
} else {
|
|
104
|
+
// For zsh/fish: name:description format
|
|
105
|
+
console.log(`${item.name}:${item.description || ''}`);
|
|
106
|
+
}
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Handle tab completion request
|
|
112
|
+
* Called when COMP_LINE environment variable is present
|
|
113
|
+
*/
|
|
114
|
+
function handleCompletion() {
|
|
115
|
+
const env = parseEnv();
|
|
116
|
+
let completions = [];
|
|
117
|
+
|
|
118
|
+
// Determine what completions to provide based on context
|
|
119
|
+
if (env.prev === 'ignore') {
|
|
120
|
+
completions = getIgnoreTechnologies();
|
|
121
|
+
} else if (env.prev === 'install') {
|
|
122
|
+
completions = getInstallScripts();
|
|
123
|
+
} else if (COMMANDS[env.prev]) {
|
|
124
|
+
completions = COMMANDS[env.prev];
|
|
125
|
+
} else if (env.wordCount <= 2) {
|
|
126
|
+
completions = COMMANDS['dev'];
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
// Filter completions by partial match
|
|
130
|
+
if (env.lastPartial && !env.line.endsWith(' ')) {
|
|
131
|
+
completions = completions.filter(c =>
|
|
132
|
+
c.toLowerCase().startsWith(env.lastPartial.toLowerCase())
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
// Add descriptions if available
|
|
137
|
+
const withDescriptions = completions.map(name => ({
|
|
138
|
+
name,
|
|
139
|
+
description: DESCRIPTIONS[name] || ''
|
|
140
|
+
}));
|
|
141
|
+
|
|
142
|
+
logCompletions(withDescriptions);
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
/**
|
|
146
|
+
* Install shell tab completion
|
|
147
|
+
* Adds completion script to user's shell configuration
|
|
148
|
+
*/
|
|
149
|
+
async function installCompletion() {
|
|
150
|
+
const shell = process.env.SHELL || '';
|
|
151
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
152
|
+
|
|
153
|
+
let rcFile;
|
|
154
|
+
let completionScript;
|
|
155
|
+
|
|
156
|
+
if (shell.includes('zsh')) {
|
|
157
|
+
rcFile = path.join(home, '.zshrc');
|
|
158
|
+
completionScript = `
|
|
159
|
+
# @fredlackey/devutils completion
|
|
160
|
+
_dev_completions() {
|
|
161
|
+
local IFS=$'\\n'
|
|
162
|
+
COMPREPLY=($(COMP_LINE="$COMP_LINE" COMP_POINT="$COMP_POINT" dev))
|
|
163
|
+
}
|
|
164
|
+
complete -F _dev_completions dev
|
|
165
|
+
`;
|
|
166
|
+
} else if (shell.includes('bash')) {
|
|
167
|
+
rcFile = path.join(home, '.bashrc');
|
|
168
|
+
completionScript = `
|
|
169
|
+
# @fredlackey/devutils completion
|
|
170
|
+
_dev_completions() {
|
|
171
|
+
local IFS=$'\\n'
|
|
172
|
+
COMPREPLY=($(COMP_LINE="$COMP_LINE" COMP_POINT="$COMP_POINT" dev))
|
|
173
|
+
}
|
|
174
|
+
complete -F _dev_completions dev
|
|
175
|
+
`;
|
|
176
|
+
} else if (shell.includes('fish')) {
|
|
177
|
+
rcFile = path.join(home, '.config', 'fish', 'config.fish');
|
|
178
|
+
completionScript = `
|
|
179
|
+
# @fredlackey/devutils completion
|
|
180
|
+
complete -c dev -f -a "(COMP_LINE=(commandline) COMP_POINT=(commandline -C) dev)"
|
|
181
|
+
`;
|
|
182
|
+
} else {
|
|
183
|
+
console.error('Unsupported shell. Supported shells: bash, zsh, fish');
|
|
184
|
+
process.exit(1);
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
try {
|
|
188
|
+
// Check if completion is already installed
|
|
189
|
+
if (fs.existsSync(rcFile)) {
|
|
190
|
+
const content = fs.readFileSync(rcFile, 'utf8');
|
|
191
|
+
if (content.includes('@fredlackey/devutils completion')) {
|
|
192
|
+
console.log('Tab completion is already installed.');
|
|
193
|
+
return;
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
// Append completion script
|
|
198
|
+
fs.appendFileSync(rcFile, '\n' + completionScript);
|
|
199
|
+
console.log(`Tab completion installed in ${rcFile}`);
|
|
200
|
+
console.log('Restart your shell or run:');
|
|
201
|
+
console.log(` source ${rcFile}`);
|
|
202
|
+
} catch (err) {
|
|
203
|
+
console.error('Failed to install completion:', err.message);
|
|
204
|
+
process.exit(1);
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
/**
|
|
209
|
+
* Uninstall shell tab completion
|
|
210
|
+
* Removes completion script from user's shell configuration
|
|
211
|
+
*/
|
|
212
|
+
async function uninstallCompletion() {
|
|
213
|
+
const shell = process.env.SHELL || '';
|
|
214
|
+
const home = process.env.HOME || process.env.USERPROFILE;
|
|
215
|
+
|
|
216
|
+
let rcFile;
|
|
217
|
+
if (shell.includes('zsh')) {
|
|
218
|
+
rcFile = path.join(home, '.zshrc');
|
|
219
|
+
} else if (shell.includes('bash')) {
|
|
220
|
+
rcFile = path.join(home, '.bashrc');
|
|
221
|
+
} else if (shell.includes('fish')) {
|
|
222
|
+
rcFile = path.join(home, '.config', 'fish', 'config.fish');
|
|
223
|
+
} else {
|
|
224
|
+
console.error('Unsupported shell. Supported shells: bash, zsh, fish');
|
|
225
|
+
process.exit(1);
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
try {
|
|
229
|
+
if (!fs.existsSync(rcFile)) {
|
|
230
|
+
console.log('Shell configuration file not found.');
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
let content = fs.readFileSync(rcFile, 'utf8');
|
|
235
|
+
|
|
236
|
+
// Remove completion block
|
|
237
|
+
const startMarker = '# @fredlackey/devutils completion';
|
|
238
|
+
if (!content.includes(startMarker)) {
|
|
239
|
+
console.log('Tab completion is not installed.');
|
|
240
|
+
return;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Remove the completion section (handles multi-line blocks)
|
|
244
|
+
const lines = content.split('\n');
|
|
245
|
+
const filteredLines = [];
|
|
246
|
+
let inCompletionBlock = false;
|
|
247
|
+
let braceCount = 0;
|
|
248
|
+
|
|
249
|
+
for (const line of lines) {
|
|
250
|
+
if (line.includes(startMarker)) {
|
|
251
|
+
inCompletionBlock = true;
|
|
252
|
+
continue;
|
|
253
|
+
}
|
|
254
|
+
if (inCompletionBlock) {
|
|
255
|
+
if (line.includes('{')) braceCount++;
|
|
256
|
+
if (line.includes('}')) braceCount--;
|
|
257
|
+
if (line.includes('complete') && braceCount === 0) {
|
|
258
|
+
inCompletionBlock = false;
|
|
259
|
+
continue;
|
|
260
|
+
}
|
|
261
|
+
if (braceCount === 0 && line.trim() === '') {
|
|
262
|
+
inCompletionBlock = false;
|
|
263
|
+
}
|
|
264
|
+
continue;
|
|
265
|
+
}
|
|
266
|
+
filteredLines.push(line);
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
fs.writeFileSync(rcFile, filteredLines.join('\n'));
|
|
270
|
+
console.log(`Tab completion removed from ${rcFile}`);
|
|
271
|
+
console.log('Restart your shell for changes to take effect.');
|
|
272
|
+
} catch (err) {
|
|
273
|
+
console.error('Failed to uninstall completion:', err.message);
|
|
274
|
+
process.exit(1);
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
module.exports = {
|
|
279
|
+
handleCompletion,
|
|
280
|
+
installCompletion,
|
|
281
|
+
uninstallCompletion,
|
|
282
|
+
getIgnoreTechnologies,
|
|
283
|
+
getInstallScripts
|
|
284
|
+
};
|
package/src/constants.js
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
const INSTALLS = [
|
|
2
|
+
{
|
|
3
|
+
name: "Debian",
|
|
4
|
+
environment: "debian",
|
|
5
|
+
description: "Installs generic to any Debian-based Linux distribution.",
|
|
6
|
+
packages: [
|
|
7
|
+
{
|
|
8
|
+
name: "Git",
|
|
9
|
+
description: "Git command line tool.",
|
|
10
|
+
command: "apt-get install -y git",
|
|
11
|
+
priority: 1,
|
|
12
|
+
}
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
{
|
|
16
|
+
name: "Debian WSL",
|
|
17
|
+
environment: "debian_wsl",
|
|
18
|
+
description: "Installs generic to any Debian-based Linux distribution running in WSL.",
|
|
19
|
+
},
|
|
20
|
+
{
|
|
21
|
+
name: "Ubuntu",
|
|
22
|
+
environment: "ubuntu",
|
|
23
|
+
description: "Installs generic to any Ubuntu-based Linux distribution.",
|
|
24
|
+
},
|
|
25
|
+
{
|
|
26
|
+
name: "Ubuntu WSL",
|
|
27
|
+
environment: "ubuntu_wsl",
|
|
28
|
+
description: "Installs generic to any Ubuntu-based Linux distribution running in WSL.",
|
|
29
|
+
},
|
|
30
|
+
{
|
|
31
|
+
name: "macOS",
|
|
32
|
+
environment: "macos",
|
|
33
|
+
description: "Installs for macOS systems.",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
name: "Windows",
|
|
37
|
+
environment: "windows",
|
|
38
|
+
description: "Installs for Windows systems.",
|
|
39
|
+
},
|
|
40
|
+
{
|
|
41
|
+
name: "Git Bash",
|
|
42
|
+
environment: "gitbash",
|
|
43
|
+
description: "Installs within the Git Bash environment.",
|
|
44
|
+
},
|
|
45
|
+
]
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# ##############################################################################
|
|
2
|
+
# CLAUDE CODE
|
|
3
|
+
# Generated by DevUtils CLI (https://github.com/fredlackey/devutils-cli)
|
|
4
|
+
# ##############################################################################
|
|
5
|
+
|
|
6
|
+
# Claude Code local files
|
|
7
|
+
.claude/
|
|
8
|
+
.claude-context
|
|
9
|
+
.claude_memory/
|
|
10
|
+
claude-output/
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# ##############################################################################
|
|
2
|
+
# DOCKER
|
|
3
|
+
# Generated by DevUtils CLI (https://github.com/fredlackey/devutils-cli)
|
|
4
|
+
# ##############################################################################
|
|
5
|
+
|
|
6
|
+
# Docker configuration
|
|
7
|
+
.docker/
|
|
8
|
+
docker-compose.override.yml
|
|
9
|
+
docker-compose.local.yml
|
|
10
|
+
.dockerignore
|
|
11
|
+
|
|
12
|
+
# Docker data volumes
|
|
13
|
+
data/
|
|
14
|
+
volumes/
|
|
15
|
+
|
|
16
|
+
# Docker environment files
|
|
17
|
+
.env.docker
|
|
18
|
+
.env.docker.local
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# ##############################################################################
|
|
2
|
+
# LINUX
|
|
3
|
+
# Generated by DevUtils CLI (https://github.com/fredlackey/devutils-cli)
|
|
4
|
+
# ##############################################################################
|
|
5
|
+
|
|
6
|
+
# Backup files
|
|
7
|
+
*~
|
|
8
|
+
*.bak
|
|
9
|
+
*.backup
|
|
10
|
+
|
|
11
|
+
# Swap files
|
|
12
|
+
*.swp
|
|
13
|
+
*.swo
|
|
14
|
+
|
|
15
|
+
# Temporary files
|
|
16
|
+
.fuse_hidden*
|
|
17
|
+
.nfs*
|
|
18
|
+
|
|
19
|
+
# Trash
|
|
20
|
+
.Trash-*
|
|
21
|
+
|
|
22
|
+
# KDE directory preferences
|
|
23
|
+
.directory
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# ##############################################################################
|
|
2
|
+
# MACOS
|
|
3
|
+
# Generated by DevUtils CLI (https://github.com/fredlackey/devutils-cli)
|
|
4
|
+
# ##############################################################################
|
|
5
|
+
|
|
6
|
+
# Finder metadata
|
|
7
|
+
.DS_Store
|
|
8
|
+
.AppleDouble
|
|
9
|
+
.LSOverride
|
|
10
|
+
|
|
11
|
+
# Icon must end with two \r
|
|
12
|
+
Icon
|
|
13
|
+
|
|
14
|
+
# Thumbnails
|
|
15
|
+
._*
|
|
16
|
+
|
|
17
|
+
# Volume files
|
|
18
|
+
.DocumentRevisions-V100
|
|
19
|
+
.fseventsd
|
|
20
|
+
.Spotlight-V100
|
|
21
|
+
.TemporaryItems
|
|
22
|
+
.Trashes
|
|
23
|
+
.VolumeIcon.icns
|
|
24
|
+
.com.apple.timemachine.donotpresent
|
|
25
|
+
|
|
26
|
+
# AFP share files
|
|
27
|
+
.AppleDB
|
|
28
|
+
.AppleDesktop
|
|
29
|
+
Network Trash Folder
|
|
30
|
+
Temporary Items
|
|
31
|
+
.apdisk
|
|
32
|
+
|
|
33
|
+
# Xcode
|
|
34
|
+
xcuserdata/
|
|
35
|
+
*.xcscmblueprint
|
|
36
|
+
*.xccheckout
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# ##############################################################################
|
|
2
|
+
# NODE.JS
|
|
3
|
+
# Generated by DevUtils CLI (https://github.com/fredlackey/devutils-cli)
|
|
4
|
+
# ##############################################################################
|
|
5
|
+
|
|
6
|
+
# Dependencies
|
|
7
|
+
node_modules/
|
|
8
|
+
jspm_packages/
|
|
9
|
+
bower_components/
|
|
10
|
+
|
|
11
|
+
# Debug logs
|
|
12
|
+
npm-debug.log*
|
|
13
|
+
yarn-debug.log*
|
|
14
|
+
yarn-error.log*
|
|
15
|
+
lerna-debug.log*
|
|
16
|
+
.pnpm-debug.log*
|
|
17
|
+
|
|
18
|
+
# Runtime data
|
|
19
|
+
pids/
|
|
20
|
+
*.pid
|
|
21
|
+
*.seed
|
|
22
|
+
*.pid.lock
|
|
23
|
+
|
|
24
|
+
# Coverage
|
|
25
|
+
coverage/
|
|
26
|
+
*.lcov
|
|
27
|
+
.nyc_output/
|
|
28
|
+
|
|
29
|
+
# Build output
|
|
30
|
+
dist/
|
|
31
|
+
build/
|
|
32
|
+
out/
|
|
33
|
+
|
|
34
|
+
# TypeScript
|
|
35
|
+
*.tsbuildinfo
|
|
36
|
+
|
|
37
|
+
# Optional caches
|
|
38
|
+
.npm/
|
|
39
|
+
.eslintcache
|
|
40
|
+
.stylelintcache
|
|
41
|
+
|
|
42
|
+
# Yarn
|
|
43
|
+
.yarn/cache
|
|
44
|
+
.yarn/unplugged
|
|
45
|
+
.yarn/build-state.yml
|
|
46
|
+
.yarn/install-state.gz
|
|
47
|
+
.pnp.*
|
|
48
|
+
|
|
49
|
+
# pnpm
|
|
50
|
+
.pnpm-store/
|
|
51
|
+
|
|
52
|
+
# Environment files
|
|
53
|
+
.env
|
|
54
|
+
.env.local
|
|
55
|
+
.env.*.local
|