@tertium/hlpr 0.6.0 → 0.6.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.
@@ -0,0 +1,225 @@
1
+ # Rename Command
2
+
3
+ Recursively rename files and folders according to a specific case style.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ hlpr file rename <directory> <style> [--dry|-n] [--no-update-content]
9
+ ```
10
+
11
+ ### Arguments
12
+
13
+ - `<directory>` - The root directory to recursively process
14
+ - `<style>` - The target case style (see Supported Styles below)
15
+ - `--dry` or `-n` - Optional dry-run mode (preview changes without applying)
16
+ - `--no-update-content` - Skip updating import/require statements in files (content updates are enabled by default)
17
+
18
+ ## Supported Styles
19
+
20
+ | Style | Description | Example |
21
+ |-------|-------------|---------|
22
+ | `title_underscore` | Title case with underscores | `File_Name` |
23
+ | `pascal_underscore` | Pascal-style with underscores (alias `title_underscore`) | `File_Name` |
24
+ | `snake` | Lowercase with underscores | `file_name` |
25
+ | `kebab` | Lowercase with hyphens | `file-name` |
26
+ | `camel` | Lowercase first word, capitalized rest | `fileName` |
27
+ | `pascal` | All words capitalized, no separators | `FileName` |
28
+ | `upper` | Uppercase with underscores | `FILE_NAME` |
29
+ | `lower` | Lowercase with underscores | `file_name` |
30
+
31
+ ## Examples
32
+
33
+ ### Dry Run (Preview Changes)
34
+
35
+ ```bash
36
+ # Preview renaming all files/folders to kebab-case
37
+ hlpr file rename ./my-project kebab --dry
38
+
39
+ # Preview renaming with short flag
40
+ hlpr file rename ./src snake -n
41
+ ```
42
+
43
+ ### Apply Changes
44
+
45
+ ```bash
46
+ # Rename all files/folders to kebab-case
47
+ hlpr file rename ./my-project kebab
48
+
49
+ # Rename to PascalCase
50
+ hlpr file rename ./docs pascal
51
+
52
+ # Rename current directory
53
+ hlpr file rename . snake
54
+ hlpr rename . snake
55
+ ```
56
+
57
+ ## Features
58
+
59
+ ### ✅ Automatic Content Updates
60
+
61
+ **NEW:** By default, the rename command now automatically updates import and require statements in your code files when files are renamed!
62
+
63
+ The tool intelligently detects and updates **all text-based files** by analyzing file content (not just extensions). This includes:
64
+
65
+ - Source code: `.js`, `.ts`, `.jsx`, `.tsx`, `.py`, `.rb`, `.go`, `.rs`, etc.
66
+ - Config files: `.json`, `.yml`, `.yaml`, `.toml`, `.xml`, `.ini`, etc.
67
+ - Documentation: `.md`, `.txt`, `.rst`, etc.
68
+ - Shell scripts: `.sh`, `.bash`, `.zsh`, etc.
69
+ - And any other text file format!
70
+
71
+ Binary files (images, executables, etc.) are automatically skipped.
72
+
73
+ Example:
74
+
75
+ ```javascript
76
+ // Before renaming from kebab-case to snake_case:
77
+ import { helper } from './my-utils'
78
+ const x = require('./my-utils')
79
+
80
+ // After running: hlpr file rename . snake
81
+ import { helper } from './my_utils'
82
+ const x = require('./my_utils')
83
+ ```
84
+
85
+ The feature supports:
86
+
87
+ - Single quotes, double quotes, and backticks
88
+ - Relative paths (`./`, `../`)
89
+ - Files with and without extensions in import statements
90
+ - Both ES6 imports and CommonJS require statements
91
+
92
+ To disable this feature, use the `--no-update-content` flag.
93
+
94
+ ### ✅ Recursive Processing
95
+
96
+ The command walks through all subdirectories, renaming:
97
+
98
+ 1. Files first (so they don't interfere with directory renames)
99
+ 2. Directories after processing their contents
100
+ 3. Updates file content references after renaming (unless disabled)
101
+
102
+ ### ✅ Extension Preservation
103
+
104
+ File extensions are preserved. Only the base name is transformed:
105
+
106
+ - `file-name.md` → `file_name.md` (snake case)
107
+ - `MyComponent.tsx` → `my-component.tsx` (kebab case)
108
+
109
+ ### ✅ Leading Dot Files
110
+
111
+ Files starting with a dot (e.g., `.gitignore`, `.env`) are handled specially:
112
+
113
+ - The leading dot is preserved
114
+ - The rest of the name is transformed
115
+ - `.gitIgnore` → `.git-ignore` (kebab case)
116
+
117
+ ### ✅ Case-Only Renames (Windows)
118
+
119
+ Windows filesystems are case-insensitive, so renaming `File.txt` to `file.txt` requires special handling. The command uses a temporary file strategy to handle this correctly.
120
+
121
+ ### ✅ Conflict Resolution
122
+
123
+ If a renamed file would conflict with an existing file, the command automatically adds a `_N` suffix:
124
+
125
+ - If `file-name.txt` → `file_name.txt` already exists
126
+ - The new file becomes `file_name_1.txt`
127
+
128
+ ### ✅ Dry-Run Mode
129
+
130
+ Use `--dry` or `-n` to preview all changes before applying them:
131
+
132
+ ```bash
133
+ hlpr file rename ./src kebab --dry
134
+ ```
135
+
136
+ Output:
137
+
138
+ ```text
139
+ Dry run - would rename 3 items:
140
+ src/myFile.ts → src/my-file.ts
141
+ src/anotherFile.ts → src/another-file.ts
142
+ src/someFolder → src/some-folder
143
+ ```
144
+
145
+ ## TypeScript API
146
+
147
+ The command can also be used programmatically:
148
+
149
+ ```typescript
150
+ import { renameRecursive, transformBasename } from './commands/rename/rename.js'
151
+
152
+ // Transform a single basename
153
+ const newName = transformBasename('MyFileName', 'kebab')
154
+ // Returns: 'my-file-name'
155
+
156
+ // Recursively rename with dry-run
157
+ const changes = await renameRecursive('./my-project', 'snake', { dryRun: true })
158
+ // Returns: [{ from: '...', to: '...' }, ...]
159
+
160
+ // Apply changes with content updates (default)
161
+ await renameRecursive('./my-project', 'kebab')
162
+
163
+ // Apply changes without updating file contents
164
+ await renameRecursive('./my-project', 'kebab', { updateContent: false })
165
+
166
+ // Combine options
167
+ await renameRecursive('./my-project', 'snake', {
168
+ dryRun: false,
169
+ updateContent: true
170
+ })
171
+ ```
172
+
173
+ ## Technical Details
174
+
175
+ ### Word Splitting
176
+
177
+ The command intelligently splits filenames into words by:
178
+
179
+ 1. Splitting on non-alphanumeric characters (hyphens, underscores, spaces, etc.)
180
+ 2. Splitting on CamelCase boundaries (`myFileName` → `my`, `File`, `Name`)
181
+ 3. Preserving Unicode letters and numbers
182
+
183
+ ### Transformation Algorithm
184
+
185
+ 1. Walk directory tree recursively
186
+ 2. For each file:
187
+ - Extract basename (without extension)
188
+ - Transform basename according to style
189
+ - Append original extension
190
+ - Rename file (handling case-only renames and conflicts)
191
+ 3. For each directory (after processing contents):
192
+ - Transform directory name according to style
193
+ - Rename directory (handling case-only renames and conflicts)
194
+
195
+ ### Error Handling
196
+
197
+ - If a rename fails, the command attempts to revert temporary changes
198
+ - All errors are logged to stderr
199
+ - The command exits with code 1 on failure
200
+
201
+ ## Limitations
202
+
203
+ - Files and directories must be accessible (proper permissions)
204
+ - Very long paths (>260 characters on Windows) may fail
205
+ - Symlinks are not followed (treated as regular files/directories)
206
+
207
+ ## Examples by Style
208
+
209
+ Starting with: `MyTestFile-name_Example.txt`
210
+
211
+ | Style | Result |
212
+ |-------|--------|
213
+ | `title_underscore` | `My_Test_File_Name_Example.txt` |
214
+ | `snake` | `my_test_file_name_example.txt` |
215
+ | `kebab` | `my-test-file-name-example.txt` |
216
+ | `camel` | `myTestFileNameExample.txt` |
217
+ | `pascal` | `MyTestFileNameExample.txt` |
218
+ | `upper` | `MY_TEST_FILE_NAME_EXAMPLE.txt` |
219
+ | `lower` | `my_test_file_name_example.txt` |
220
+
221
+ ## See Also
222
+
223
+ - [Main hlpr README](../../README.md)
224
+ - [TypeScript Implementation](./rename.ts)
225
+ - [Tests](./rename.test.ts)
@@ -0,0 +1,129 @@
1
+ # Git Commands
2
+
3
+ Helpful git utilities for common development workflows.
4
+
5
+ ## Platform Support
6
+
7
+ All Git commands work on:
8
+
9
+ - ✅ **Linux** - Fully supported
10
+ - ✅ **macOS** - Fully supported
11
+ - ✅ **Windows** - Requires Git for Windows (includes Git Bash)
12
+
13
+ ---
14
+
15
+ ## fodd
16
+
17
+ Fetch and update develop branch from origin.
18
+
19
+ **Usage:**
20
+ ```bash
21
+ hlpr git fodd
22
+ ```
23
+
24
+ **What it does:**
25
+ - Fetches the `develop` branch from origin
26
+ - Updates your local `develop` branch to match the remote
27
+
28
+ **When to use:**
29
+ - Before starting work to ensure you have the latest develop branch
30
+ - To sync your local develop with the remote
31
+
32
+ **Command:**
33
+ ```bash
34
+ git fetch origin develop:develop
35
+ ```
36
+
37
+ ---
38
+
39
+ ## precommit
40
+
41
+ Run build and stage binaries before commit.
42
+
43
+ **Usage:**
44
+ ```bash
45
+ hlpr git precommit
46
+ ```
47
+
48
+ **What it does:**
49
+ 1. Runs `bun run build` to compile your project
50
+ 2. Stages the `bin/` directory for commit
51
+
52
+ **When to use:**
53
+ - Before committing changes to ensure binaries are up-to-date
54
+ - As a git pre-commit hook to automate the process
55
+
56
+ **Example workflow:**
57
+ ```bash
58
+ # Make changes to source files
59
+ hlpr git precommit # Build and stage bin/
60
+ git commit -m "feat: add new feature"
61
+ ```
62
+
63
+ ---
64
+
65
+ ## switch-clean
66
+
67
+ Safely switch to a target branch and delete the previous branch (both local and remote).
68
+
69
+ **Usage:**
70
+ ```bash
71
+ hlpr git switch-clean <target-branch>
72
+ ```
73
+
74
+ **What it does:**
75
+
76
+ 1. **Validates current state**
77
+ - Checks you're on a branch (not detached HEAD)
78
+ - Ensures you're not already on the target branch
79
+ - Verifies there are no uncommitted changes
80
+
81
+ 2. **Checks for unpushed commits**
82
+ - Fails if current branch has commits that haven't been pushed
83
+ - Prevents accidental loss of work
84
+
85
+ 3. **Fetches target branch**
86
+ - Runs `git fetch origin <target-branch>:<target-branch>`
87
+ - Updates the target branch to match remote
88
+
89
+ 4. **Switches to target branch**
90
+ - Checks out the target branch
91
+
92
+ 5. **Deletes previous branch**
93
+ - Deletes local branch: `git branch -d <old-branch>`
94
+ - Deletes remote branch (if exists): `git push origin --delete <old-branch>`
95
+
96
+ **Safety Features:**
97
+
98
+ - ✅ **Uncommitted changes check** - Prevents switching if you have uncommitted work
99
+ - ✅ **Unpushed commits check** - Ensures all work is pushed before deletion
100
+ - ✅ **Remote existence check** - Only deletes remote branch if it exists
101
+ - ✅ **Safe branch deletion** - Uses `git branch -d` (not `-D`), refuses to delete unmerged branches
102
+
103
+ **Examples:**
104
+
105
+ ```bash
106
+ # Switch from feature branch to develop and clean up
107
+ hlpr git switch-clean develop
108
+ # ✓ Switched to 'develop' and deleted 'feature/add-auth' (local & remote)
109
+
110
+ # Switch to main
111
+ hlpr git switch-clean main
112
+ # ✓ Switched to 'main' and deleted 'develop' (local only)
113
+ ```
114
+
115
+ **Error Handling:**
116
+
117
+ The command will fail and exit if:
118
+
119
+ - No target branch is specified
120
+ - Not currently on a branch (detached HEAD)
121
+ - Already on the target branch
122
+ - There are uncommitted changes
123
+ - Current branch has unpushed commits
124
+ - Target branch doesn't exist on remote
125
+
126
+ **Solution:**
127
+ - Commit or stash uncommitted changes
128
+ - Push unpushed commits: `git push origin <branch>`
129
+ - Ensure target branch exists on remote
@@ -0,0 +1,35 @@
1
+ # Hello Commands
2
+
3
+ Example/demo commands for testing the hlpr CLI tool.
4
+
5
+ ## Platform Support
6
+
7
+ - ✅ **Linux** - Fully supported
8
+ - ✅ **macOS** - Fully supported
9
+ - ✅ **Windows** - Requires Git Bash or WSL
10
+
11
+ ## world
12
+
13
+ Print a personalized hello world message.
14
+
15
+ ### Usage
16
+
17
+ ```bash
18
+ hlpr hello world
19
+ ```
20
+
21
+ The command will prompt you for a name and then print a personalized greeting.
22
+
23
+ ### Example
24
+
25
+ ```bash
26
+ $ hlpr hello world
27
+ Enter name: Alice
28
+ Hello World, Alice
29
+ ```
30
+
31
+ ### Variables
32
+
33
+ - `name` - Your name (prompted during execution)
34
+
35
+ This command demonstrates the variable substitution feature of hlpr, where `{{name}}` in the script is replaced with user input.
@@ -0,0 +1,55 @@
1
+ # Help Command
2
+
3
+ Displays help information about available commands in the hlpr CLI tool.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ hlpr help
9
+ # or
10
+ hlpr --help
11
+ # or
12
+ hlpr -h
13
+ # or just
14
+ hlpr
15
+ ```
16
+
17
+ ## Description
18
+
19
+ The help command automatically discovers all available commands in the `commands/` directory and displays them in an organized format. It shows:
20
+
21
+ - Command categories (e.g., file, git, ssh, nvm)
22
+ - Command names and full usage
23
+ - Command type (TypeScript or Shell)
24
+ - Command descriptions (when available)
25
+ - Usage examples
26
+
27
+ ## Features
28
+
29
+ - Auto-discovers commands from the commands directory
30
+ - Groups commands by category
31
+ - Shows command types (TypeScript or Shell scripts)
32
+ - Extracts descriptions from:
33
+ - `@description` comments in source files
34
+ - README.md files in command directories
35
+ - Displays formatted help with usage examples
36
+
37
+ ## Examples
38
+
39
+ ```bash
40
+ # Show all available commands
41
+ hlpr help
42
+
43
+ # If no command is provided, help is shown automatically
44
+ hlpr
45
+ ```
46
+
47
+ ## Output
48
+
49
+ The help command displays:
50
+
51
+ 1. **Header** - Tool name and version
52
+ 2. **Usage** - Basic syntax
53
+ 3. **Options** - Available flags (-f, -v, help)
54
+ 4. **Available Commands** - Grouped by category with descriptions
55
+ 5. **Examples** - Common usage patterns
@@ -0,0 +1,90 @@
1
+ # NVM Commands
2
+
3
+ Node Version Manager (nvm) utility commands.
4
+
5
+ ## install
6
+
7
+ Install Node Version Manager (nvm).
8
+
9
+ ### Usage
10
+
11
+ ```bash
12
+ hlpr nvm install
13
+ ```
14
+
15
+ ### Platform Support
16
+
17
+ - ✅ **Linux** - Fully supported
18
+ - ✅ **macOS** - Fully supported
19
+ - ⚠️ **Windows** - Requires Git Bash or WSL (Windows Subsystem for Linux)
20
+ - **Alternative for Windows**: Use [nvm-windows](https://github.com/coreybutler/nvm-windows) instead
21
+
22
+ ### What it does
23
+
24
+ Downloads and installs nvm from the official repository using the installation script:
25
+
26
+ ```bash
27
+ curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.1/install.sh | bash
28
+ ```
29
+
30
+ ### Post-installation
31
+
32
+ After installation, you may need to:
33
+
34
+ 1. Close and reopen your terminal
35
+ 2. Or source your shell profile:
36
+
37
+ ```bash
38
+ source ~/.bashrc # or ~/.zshrc, ~/.bash_profile, etc.
39
+ ```
40
+
41
+ ### Verify installation
42
+
43
+ ```bash
44
+ nvm --version
45
+ ```
46
+
47
+ ## lts
48
+
49
+ Install and use the latest Node.js LTS (Long Term Support) version.
50
+
51
+ ### Platform Support (lts)
52
+
53
+ Same as `install` command - requires nvm to be installed.
54
+
55
+ ### Usage
56
+
57
+ ```bash
58
+ hlpr nvm lts
59
+ ```
60
+
61
+ ### What it does (lts)
62
+
63
+ 1. Downloads and installs the latest LTS version of Node.js
64
+ 2. Switches to use the newly installed LTS version
65
+
66
+ Equivalent to running:
67
+
68
+ ```bash
69
+ nvm install --lts
70
+ nvm use --lts
71
+ ```
72
+
73
+ ### Example
74
+
75
+ ```bash
76
+ $ hlpr nvm lts
77
+ Downloading and installing node v20.11.0...
78
+ Now using node v20.11.0 (npm v10.2.4)
79
+ ```
80
+
81
+ ### Prerequisites
82
+
83
+ - nvm must be installed first (use `hlpr nvm install`)
84
+
85
+ ### Verify (lts)
86
+
87
+ ```bash
88
+ node --version # Should show the LTS version
89
+ npm --version # npm comes with Node.js
90
+ ```
@@ -0,0 +1,49 @@
1
+ # kill-port
2
+
3
+ Kill process(es) running on a specified port. Supports both Windows and Linux/macOS.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ hlpr process kill-port <port> [options]
9
+ ```
10
+
11
+ ## Arguments
12
+
13
+ - `port` - Port number (1-65535)
14
+
15
+ ## Options
16
+
17
+ - `-f, --force` - Force kill (SIGKILL on Linux, /F on Windows)
18
+ - `-v, --verbose` - Show verbose output
19
+ - `-h, --help` - Show help message
20
+
21
+ ## Examples
22
+
23
+ ```bash
24
+ # Kill process on port 3000
25
+ hlpr process kill-port 3000
26
+
27
+ # Force kill with verbose output
28
+ hlpr process kill-port 8080 --force --verbose
29
+
30
+ # Kill process on port 5432
31
+ hlpr process kill-port 5432 -v
32
+ ```
33
+
34
+ ## Platform Support
35
+
36
+ ### Windows
37
+ - Uses `netstat -ano` to find processes
38
+ - Uses `taskkill` to kill processes
39
+ - `-f/--force` flag uses `/F` switch (force termination)
40
+
41
+ ### Linux/macOS
42
+ - Uses `lsof` (preferred) or `netstat` to find processes
43
+ - Uses `kill` command to terminate processes
44
+ - `-f/--force` flag sends SIGKILL instead of SIGTERM
45
+
46
+ ## Exit Codes
47
+
48
+ - `0` - Success (all processes killed or no processes found)
49
+ - `1` - Failure (some processes could not be killed)
@@ -0,0 +1,58 @@
1
+ # list-port
2
+
3
+ List process(es) running on a specified port. Supports both Windows and Linux/macOS.
4
+
5
+ ## Usage
6
+
7
+ ```bash
8
+ hlpr process list-port <port> [options]
9
+ ```
10
+
11
+ ## Arguments
12
+
13
+ - `port` - Port number (1-65535)
14
+
15
+ ## Options
16
+
17
+ - `-v, --verbose` - Show verbose output
18
+ - `-h, --help` - Show help message
19
+
20
+ ## Examples
21
+
22
+ ```bash
23
+ # List processes on port 3000
24
+ hlpr process list-port 3000
25
+
26
+ # List with verbose output
27
+ hlpr process list-port 8080 -v
28
+
29
+ # List processes on port 5432
30
+ hlpr process list-port 5432
31
+ ```
32
+
33
+ ## Output Format
34
+
35
+ Displays a table with:
36
+ - **PID** - Process ID
37
+ - **STATE** - Connection state (LISTENING, ESTABLISHED, etc.)
38
+ - **COMMAND** - Process name/command
39
+
40
+ ## Platform Support
41
+
42
+ ### Windows
43
+ - Uses `netstat -ano` to find processes
44
+ - Uses `tasklist` to get process names
45
+ - Shows PID, state, and command
46
+
47
+ ### Linux/macOS
48
+ - Uses `lsof` (preferred) or `netstat` (fallback) to find processes
49
+ - Shows PID, state, and command name
50
+
51
+ ## Exit Codes
52
+
53
+ - `0` - Success (processes found)
54
+ - `1` - No processes found or error
55
+
56
+ ## See Also
57
+
58
+ - `hlpr process kill-port` - Kill processes on a port
@@ -0,0 +1,80 @@
1
+ # SSH Commands
2
+
3
+ SSH configuration and setup utilities.
4
+
5
+ ## Platform Support
6
+
7
+ - ✅ **Linux** - Fully supported
8
+ - ✅ **macOS** - Fully supported
9
+ - ✅ **Windows** - Requires Git Bash or WSL
10
+ - Git Bash (included with Git for Windows) provides Unix-like `~/.ssh` directory
11
+ - Native Windows SSH uses `%USERPROFILE%\.ssh` instead
12
+
13
+ ## init-dir
14
+
15
+ Initialize SSH directory with proper permissions.
16
+
17
+ ### Usage
18
+
19
+ ```bash
20
+ hlpr ssh init-dir
21
+ ```
22
+
23
+ ### What it does
24
+
25
+ Creates the `~/.ssh` directory and essential SSH configuration files with correct permissions:
26
+
27
+ 1. Creates `~/.ssh` directory (if it doesn't exist)
28
+ 2. Creates `~/.ssh/known_hosts` file
29
+ 3. Creates `~/.ssh/config` file
30
+ 4. Sets directory permissions to 700 (rwx------)
31
+ 5. Sets file permissions to 644 (rw-r--r--)
32
+
33
+ ### Permissions explained
34
+
35
+ - `~/.ssh/` → 700 (only owner can read/write/execute)
36
+ - `~/.ssh/known_hosts` → 644 (owner can write, others can read)
37
+ - `~/.ssh/config` → 644 (owner can write, others can read)
38
+
39
+ These permissions are required by SSH for security. If permissions are incorrect, SSH will refuse to use the files.
40
+
41
+ ### When to use
42
+
43
+ - Setting up SSH on a new system
44
+ - Fixing SSH permission issues
45
+ - After accidentally deleting SSH configuration files
46
+
47
+ ### Example
48
+
49
+ ```bash
50
+ $ hlpr ssh init-dir
51
+ # Creates ~/.ssh/ with proper structure and permissions
52
+ ```
53
+
54
+ ### Verify
55
+
56
+ ```bash
57
+ ls -la ~/.ssh/
58
+ # Should show:
59
+ # drwx------ ~/.ssh/
60
+ # -rw-r--r-- ~/.ssh/config
61
+ # -rw-r--r-- ~/.ssh/known_hosts
62
+ ```
63
+
64
+ ### Note
65
+
66
+ This command will fail if `~/.ssh` already exists. If you need to fix permissions on an existing directory, you can:
67
+
68
+ ```bash
69
+ chmod 700 ~/.ssh
70
+ chmod 644 ~/.ssh/known_hosts
71
+ chmod 644 ~/.ssh/config
72
+ ```
73
+
74
+ ### Next steps
75
+
76
+ After initializing the SSH directory, you typically:
77
+
78
+ 1. Generate SSH keys: `ssh-keygen -t ed25519 -C "your_email@example.com"`
79
+ 2. Add SSH config entries to `~/.ssh/config`
80
+ 3. Add public key to remote servers or services (GitHub, GitLab, etc.)
package/bin/index.js CHANGED
@@ -6,7 +6,6 @@ import { exec } from "node:child_process";
6
6
  import * as path from "node:path";
7
7
  import * as fs from "node:fs";
8
8
  import * as readline from "node:readline";
9
- import * as os from "node:os";
10
9
  import { fileURLToPath } from "node:url";
11
10
  async function getVersion() {
12
11
  try {
@@ -20,13 +19,6 @@ async function getVersion() {
20
19
  return "0.0.0";
21
20
  }
22
21
  }
23
- function detectShell() {
24
- const isWindows = os.platform() === "win32";
25
- if (isWindows) {
26
- return "powershell";
27
- }
28
- return "bash";
29
- }
30
22
  var __filename2 = fileURLToPath(import.meta.url);
31
23
  var __dirname2 = path.dirname(__filename2);
32
24
  var scriptDir = path.join(__dirname2, "..", "src");
@@ -245,7 +237,7 @@ async function main() {
245
237
  }
246
238
  }
247
239
  if (!isTypeScriptCommand && restArgs.length > 0) {
248
- const scriptName = restArgs.join("");
240
+ const scriptName = restArgs[0];
249
241
  let scriptPathCandidate = path.join(scriptDir, "commands", category, `${scriptName}.sh`);
250
242
  if (!fs.existsSync(scriptPathCandidate)) {
251
243
  scriptPathCandidate = path.join(__dirname2, "..", "bin", "commands", category, `${scriptName}.sh`);
@@ -273,8 +265,8 @@ async function main() {
273
265
  const finalCommand = `node "${scriptPath}" ${tsArgs.join(" ")}`;
274
266
  console.log(`Executing command: ${finalCommand}`);
275
267
  const success2 = await executeCommand(finalCommand, {});
276
- const helpFlags = ["-h", "--help", "help", "/h", "/help", "/?"];
277
- const isHelpInvocation = tsArgs.some((arg) => helpFlags.includes(arg));
268
+ const helpFlags2 = ["-h", "--help", "help", "/h", "/help", "/?"];
269
+ const isHelpInvocation = tsArgs.some((arg) => helpFlags2.includes(arg));
278
270
  if (!success2 && !forceFlag && !isHelpInvocation) {
279
271
  console.error("Command failed, stopping execution.");
280
272
  process.exit(1);
@@ -284,6 +276,7 @@ async function main() {
284
276
  return;
285
277
  }
286
278
  const scriptContent = await readFile(scriptPath, "utf-8");
279
+ const scriptArgs = restArgs.slice(1);
287
280
  const variableRegex = /{{([^}]+)}}/g;
288
281
  const variables = {};
289
282
  const uniqueVars = new Set;
@@ -291,9 +284,13 @@ async function main() {
291
284
  while ((match = variableRegex.exec(scriptContent)) !== null) {
292
285
  uniqueVars.add(match[1]);
293
286
  }
294
- for (const varName of uniqueVars) {
295
- const value = await prompt(`Enter ${varName}: `);
296
- variables[varName] = value;
287
+ const helpFlags = ["-h", "--help", "help", "/h", "/help", "/?"];
288
+ const isHelpRequested = scriptArgs.some((arg) => helpFlags.includes(arg));
289
+ if (!isHelpRequested) {
290
+ for (const varName of uniqueVars) {
291
+ const value = await prompt(`Enter ${varName}: `);
292
+ variables[varName] = value;
293
+ }
297
294
  }
298
295
  let processedScript = scriptContent;
299
296
  for (const [key, value] of Object.entries(variables)) {
@@ -301,8 +298,8 @@ async function main() {
301
298
  }
302
299
  const tempScriptPath = path.join(path.dirname(scriptPath), `_temp_${path.basename(scriptPath)}`);
303
300
  fs.writeFileSync(tempScriptPath, processedScript);
304
- const shell = detectShell();
305
- const command = shell === "powershell" ? `powershell -File "${tempScriptPath}"` : `bash "${tempScriptPath}"`;
301
+ const argsStr = scriptArgs.map((arg) => `"${arg}"`).join(" ");
302
+ const command = `bash "${tempScriptPath}" ${argsStr}`;
306
303
  const success = await executeCommand(command, {});
307
304
  fs.unlinkSync(tempScriptPath);
308
305
  if (!success && !forceFlag) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tertium/hlpr",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "description": "Windows and *Nix utility for typical programming activity",
5
5
  "author": "Vitalii Balabanov",
6
6
  "email": "tertiumnon@gmail.com",