@fredlackey/devutils 0.0.19 → 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.
Files changed (122) hide show
  1. package/README.md +223 -32
  2. package/package.json +7 -5
  3. package/src/api/loader.js +229 -0
  4. package/src/api/registry.json +62 -0
  5. package/src/cli.js +305 -0
  6. package/src/commands/ai/index.js +16 -0
  7. package/src/commands/ai/launch.js +112 -0
  8. package/src/commands/ai/list.js +54 -0
  9. package/src/commands/ai/resume.js +70 -0
  10. package/src/commands/ai/sessions.js +121 -0
  11. package/src/commands/ai/set.js +131 -0
  12. package/src/commands/ai/show.js +74 -0
  13. package/src/commands/ai/tools.js +46 -0
  14. package/src/commands/alias/add.js +93 -0
  15. package/src/commands/alias/helpers.js +107 -0
  16. package/src/commands/alias/index.js +14 -0
  17. package/src/commands/alias/list.js +55 -0
  18. package/src/commands/alias/remove.js +62 -0
  19. package/src/commands/alias/sync.js +109 -0
  20. package/src/commands/api/disable.js +73 -0
  21. package/src/commands/api/enable.js +148 -0
  22. package/src/commands/api/index.js +15 -0
  23. package/src/commands/api/list.js +66 -0
  24. package/src/commands/api/update.js +87 -0
  25. package/src/commands/auth/index.js +15 -0
  26. package/src/commands/auth/list.js +49 -0
  27. package/src/commands/auth/login.js +384 -0
  28. package/src/commands/auth/logout.js +111 -0
  29. package/src/commands/auth/refresh.js +184 -0
  30. package/src/commands/auth/services.js +169 -0
  31. package/src/commands/auth/status.js +104 -0
  32. package/src/commands/config/export.js +224 -0
  33. package/src/commands/config/get.js +52 -0
  34. package/src/commands/config/import.js +308 -0
  35. package/src/commands/config/index.js +17 -0
  36. package/src/commands/config/init.js +143 -0
  37. package/src/commands/config/reset.js +57 -0
  38. package/src/commands/config/set.js +93 -0
  39. package/src/commands/config/show.js +35 -0
  40. package/src/commands/help.js +338 -0
  41. package/src/commands/identity/add.js +133 -0
  42. package/src/commands/identity/index.js +17 -0
  43. package/src/commands/identity/link.js +76 -0
  44. package/src/commands/identity/list.js +48 -0
  45. package/src/commands/identity/remove.js +72 -0
  46. package/src/commands/identity/show.js +65 -0
  47. package/src/commands/identity/sync.js +172 -0
  48. package/src/commands/identity/unlink.js +57 -0
  49. package/src/commands/ignore/add.js +165 -0
  50. package/src/commands/ignore/index.js +14 -0
  51. package/src/commands/ignore/list.js +89 -0
  52. package/src/commands/ignore/markers.js +43 -0
  53. package/src/commands/ignore/remove.js +164 -0
  54. package/src/commands/ignore/show.js +169 -0
  55. package/src/commands/machine/detect.js +122 -0
  56. package/src/commands/machine/index.js +14 -0
  57. package/src/commands/machine/list.js +74 -0
  58. package/src/commands/machine/set.js +106 -0
  59. package/src/commands/machine/show.js +35 -0
  60. package/src/commands/schema.js +152 -0
  61. package/src/commands/search/collections.js +134 -0
  62. package/src/commands/search/get.js +71 -0
  63. package/src/commands/search/index-cmd.js +54 -0
  64. package/src/commands/search/index.js +21 -0
  65. package/src/commands/search/keyword.js +60 -0
  66. package/src/commands/search/qmd.js +70 -0
  67. package/src/commands/search/query.js +64 -0
  68. package/src/commands/search/semantic.js +62 -0
  69. package/src/commands/search/status.js +46 -0
  70. package/src/commands/status.js +276 -0
  71. package/src/commands/tools/check.js +79 -0
  72. package/src/commands/tools/index.js +14 -0
  73. package/src/commands/tools/install.js +110 -0
  74. package/src/commands/tools/list.js +91 -0
  75. package/src/commands/tools/search.js +60 -0
  76. package/src/commands/update.js +113 -0
  77. package/src/commands/util/add.js +151 -0
  78. package/src/commands/util/index.js +15 -0
  79. package/src/commands/util/list.js +97 -0
  80. package/src/commands/util/remove.js +76 -0
  81. package/src/commands/util/run.js +79 -0
  82. package/src/commands/util/show.js +67 -0
  83. package/src/commands/version.js +33 -0
  84. package/src/installers/_template.js +104 -0
  85. package/src/installers/git.js +150 -0
  86. package/src/installers/homebrew.js +190 -0
  87. package/src/installers/node.js +223 -0
  88. package/src/installers/registry.json +29 -0
  89. package/src/lib/config.js +125 -0
  90. package/src/lib/detect.js +74 -0
  91. package/src/lib/errors.js +114 -0
  92. package/src/lib/github.js +315 -0
  93. package/src/lib/installer.js +225 -0
  94. package/src/lib/output.js +239 -0
  95. package/src/lib/platform.js +112 -0
  96. package/src/lib/platforms/amazon-linux.js +41 -0
  97. package/src/lib/platforms/gitbash.js +46 -0
  98. package/src/lib/platforms/macos.js +45 -0
  99. package/src/lib/platforms/raspbian.js +41 -0
  100. package/src/lib/platforms/ubuntu.js +39 -0
  101. package/src/lib/platforms/windows.js +45 -0
  102. package/src/lib/prompt.js +161 -0
  103. package/src/lib/schema.js +211 -0
  104. package/src/lib/shell.js +75 -0
  105. package/src/patterns/gitignore/claude-code.txt +25 -0
  106. package/src/patterns/gitignore/docker.txt +15 -0
  107. package/src/patterns/gitignore/go.txt +24 -0
  108. package/src/patterns/gitignore/java.txt +38 -0
  109. package/src/patterns/gitignore/jetbrains.txt +26 -0
  110. package/src/patterns/gitignore/linux.txt +18 -0
  111. package/src/patterns/gitignore/macos.txt +27 -0
  112. package/src/patterns/gitignore/node.txt +51 -0
  113. package/src/patterns/gitignore/python.txt +55 -0
  114. package/src/patterns/gitignore/rust.txt +14 -0
  115. package/src/patterns/gitignore/terraform.txt +30 -0
  116. package/src/patterns/gitignore/vscode.txt +15 -0
  117. package/src/patterns/gitignore/windows.txt +25 -0
  118. package/src/utils/clone/index.js +165 -0
  119. package/src/utils/git-push/index.js +230 -0
  120. package/src/utils/git-status/index.js +116 -0
  121. package/src/utils/git-status/unix.sh +75 -0
  122. package/src/utils/registry.json +41 -0
@@ -0,0 +1,116 @@
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const fs = require('fs');
5
+
6
+ const meta = {
7
+ name: 'git-status',
8
+ description: 'Scan directories for git repos and show a color-coded status summary',
9
+ platforms: ['macos', 'ubuntu', 'raspbian', 'amazon-linux', 'windows', 'gitbash'],
10
+ arguments: [
11
+ { name: 'path', required: false, description: 'Directory to scan (defaults to current directory)' },
12
+ ],
13
+ flags: [
14
+ { name: 'depth', type: 'number', description: 'How many levels deep to scan for repos (default: 1)' },
15
+ ],
16
+ };
17
+
18
+ /**
19
+ * Run the Unix bash script for git status scanning.
20
+ * @param {string} dir - The directory to scan.
21
+ */
22
+ async function runUnixScript(dir) {
23
+ const shell = require('../../lib/shell');
24
+ const scriptPath = path.join(__dirname, 'unix.sh');
25
+
26
+ const result = await shell.exec(`bash "${scriptPath}" "${dir}"`);
27
+
28
+ if (result.exitCode !== 0) {
29
+ console.error(result.stderr || 'git-status script failed');
30
+ return;
31
+ }
32
+
33
+ if (result.stdout) {
34
+ console.log(result.stdout);
35
+ }
36
+ }
37
+
38
+ /**
39
+ * Pure JavaScript fallback for platforms without bash (Windows, Git Bash).
40
+ * @param {string} dir - The directory to scan.
41
+ */
42
+ async function runJsFallback(dir) {
43
+ const shell = require('../../lib/shell');
44
+
45
+ const entries = fs.readdirSync(dir, { withFileTypes: true });
46
+ const repos = entries
47
+ .filter(e => e.isDirectory() && fs.existsSync(path.join(dir, e.name, '.git')))
48
+ .map(e => ({ name: e.name, path: path.join(dir, e.name) }));
49
+
50
+ if (repos.length === 0) {
51
+ console.log('No git repositories found in ' + dir);
52
+ return;
53
+ }
54
+
55
+ for (const repo of repos) {
56
+ const opts = { cwd: repo.path };
57
+
58
+ // Get branch
59
+ let branch = shell.execSync('git symbolic-ref --short HEAD', opts);
60
+ if (branch === null) branch = 'detached';
61
+
62
+ // Get dirty count
63
+ const porcelain = shell.execSync('git status --porcelain', opts) || '';
64
+ const dirtyCount = porcelain ? porcelain.split('\n').filter(Boolean).length : 0;
65
+
66
+ // Get stash count
67
+ const stashList = shell.execSync('git stash list', opts) || '';
68
+ const stashCount = stashList ? stashList.split('\n').filter(Boolean).length : 0;
69
+
70
+ // Get ahead/behind
71
+ let ahead = 0;
72
+ let behind = 0;
73
+ const tracking = shell.execSync('git rev-parse --abbrev-ref @{upstream}', opts);
74
+ if (tracking) {
75
+ const counts = shell.execSync('git rev-list --left-right --count HEAD...@{upstream}', opts);
76
+ if (counts) {
77
+ const parts = counts.split(/\s+/);
78
+ ahead = parseInt(parts[0], 10) || 0;
79
+ behind = parseInt(parts[1], 10) || 0;
80
+ }
81
+ }
82
+
83
+ // Build status string
84
+ const statusParts = [];
85
+ if (dirtyCount > 0) statusParts.push(`${dirtyCount} dirty`);
86
+ if (ahead > 0) statusParts.push(`+${ahead}`);
87
+ if (behind > 0) statusParts.push(`-${behind}`);
88
+ if (stashCount > 0) statusParts.push(`${stashCount} stash`);
89
+ if (statusParts.length === 0) statusParts.push('clean');
90
+
91
+ const nameCol = repo.name.padEnd(30);
92
+ const branchCol = branch.padEnd(20);
93
+ console.log(`${nameCol} ${branchCol} ${statusParts.join(' ')}`);
94
+ }
95
+ }
96
+
97
+ async function run(args) {
98
+ const platform = require('../../lib/platform').detect();
99
+ const targetDir = args[0] || process.cwd();
100
+ const resolvedDir = path.resolve(targetDir);
101
+
102
+ if (!fs.existsSync(resolvedDir)) {
103
+ console.error(`Directory not found: ${resolvedDir}`);
104
+ return;
105
+ }
106
+
107
+ const unixPlatforms = ['macos', 'ubuntu', 'raspbian', 'amazon-linux'];
108
+
109
+ if (unixPlatforms.includes(platform.type)) {
110
+ await runUnixScript(resolvedDir);
111
+ } else {
112
+ await runJsFallback(resolvedDir);
113
+ }
114
+ }
115
+
116
+ module.exports = { meta, run };
@@ -0,0 +1,75 @@
1
+ #!/bin/bash
2
+ # git-status: Scan directory for git repos and show status summary
3
+
4
+ TARGET_DIR="${1:-.}"
5
+
6
+ # Colors
7
+ RED='\033[0;31m'
8
+ GREEN='\033[0;32m'
9
+ YELLOW='\033[0;33m'
10
+ CYAN='\033[0;36m'
11
+ NC='\033[0m' # No Color
12
+ BOLD='\033[1m'
13
+
14
+ # Find git repos (immediate subdirectories with .git folders)
15
+ for dir in "$TARGET_DIR"/*/; do
16
+ if [ ! -d "$dir/.git" ]; then
17
+ continue
18
+ fi
19
+
20
+ repo_name=$(basename "$dir")
21
+
22
+ # Get branch name
23
+ branch=$(git -C "$dir" symbolic-ref --short HEAD 2>/dev/null)
24
+ if [ -z "$branch" ]; then
25
+ branch="detached"
26
+ fi
27
+
28
+ # Get dirty file count
29
+ dirty_count=$(git -C "$dir" status --porcelain 2>/dev/null | wc -l | tr -d ' ')
30
+
31
+ # Get stash count
32
+ stash_count=$(git -C "$dir" stash list 2>/dev/null | wc -l | tr -d ' ')
33
+
34
+ # Get ahead/behind counts
35
+ ahead=0
36
+ behind=0
37
+ tracking=$(git -C "$dir" rev-parse --abbrev-ref '@{upstream}' 2>/dev/null)
38
+ if [ -n "$tracking" ]; then
39
+ counts=$(git -C "$dir" rev-list --left-right --count HEAD...'@{upstream}' 2>/dev/null)
40
+ if [ -n "$counts" ]; then
41
+ ahead=$(echo "$counts" | awk '{print $1}')
42
+ behind=$(echo "$counts" | awk '{print $2}')
43
+ fi
44
+ fi
45
+
46
+ # Determine color based on status
47
+ color="$GREEN"
48
+ if [ "$dirty_count" -gt 0 ]; then
49
+ color="$YELLOW"
50
+ fi
51
+ if [ "$behind" -gt 0 ]; then
52
+ color="$RED"
53
+ fi
54
+
55
+ # Build status string
56
+ status_parts=""
57
+ if [ "$dirty_count" -gt 0 ]; then
58
+ status_parts="${status_parts} ${YELLOW}${dirty_count} dirty${NC}"
59
+ fi
60
+ if [ "$ahead" -gt 0 ]; then
61
+ status_parts="${status_parts} ${GREEN}+${ahead}${NC}"
62
+ fi
63
+ if [ "$behind" -gt 0 ]; then
64
+ status_parts="${status_parts} ${RED}-${behind}${NC}"
65
+ fi
66
+ if [ "$stash_count" -gt 0 ]; then
67
+ status_parts="${status_parts} ${CYAN}${stash_count} stash${NC}"
68
+ fi
69
+ if [ -z "$status_parts" ]; then
70
+ status_parts=" ${GREEN}clean${NC}"
71
+ fi
72
+
73
+ # Print the line
74
+ printf "${color}${BOLD}%-30s${NC} ${CYAN}%-20s${NC}%s\n" "$repo_name" "$branch" "$status_parts"
75
+ done
@@ -0,0 +1,41 @@
1
+ {
2
+ "_comment": "Built-in utility metadata. Name, description, supported platforms, and arguments for each utility.",
3
+ "utilities": [
4
+ {
5
+ "name": "git-status",
6
+ "description": "Scan directories for git repos and show a color-coded status summary",
7
+ "type": "built-in",
8
+ "platforms": ["macos", "ubuntu", "raspbian", "amazon-linux", "windows", "gitbash"],
9
+ "arguments": [
10
+ { "name": "path", "required": false, "description": "Directory to scan (defaults to current directory)" }
11
+ ],
12
+ "flags": [
13
+ { "name": "depth", "type": "number", "description": "How many levels deep to scan for repos (default: 1)" }
14
+ ]
15
+ },
16
+ {
17
+ "name": "clone",
18
+ "description": "Clone a git repo and auto-install dependencies using the detected package manager",
19
+ "type": "built-in",
20
+ "platforms": ["macos", "ubuntu", "raspbian", "amazon-linux", "windows", "gitbash"],
21
+ "arguments": [
22
+ { "name": "url", "required": true, "description": "Git repository URL (SSH or HTTPS)" },
23
+ { "name": "directory", "required": false, "description": "Target directory name (defaults to repo name)" }
24
+ ],
25
+ "flags": []
26
+ },
27
+ {
28
+ "name": "git-push",
29
+ "description": "Safer git push: shows what will be pushed, confirms before pushing, and protects main/master",
30
+ "type": "built-in",
31
+ "platforms": ["macos", "ubuntu", "raspbian", "amazon-linux", "windows", "gitbash"],
32
+ "arguments": [
33
+ { "name": "message", "required": true, "description": "Commit message" }
34
+ ],
35
+ "flags": [
36
+ { "name": "force", "type": "boolean", "description": "Allow pushing to protected branches" },
37
+ { "name": "yes", "type": "boolean", "description": "Skip confirmation prompt" }
38
+ ]
39
+ }
40
+ ]
41
+ }