@shreyash1601/oopsify 1.0.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.
- package/README.md +157 -0
- package/bin/index.js +198 -0
- package/package.json +28 -0
- package/sounds/Aayein.wav +0 -0
- package/sounds/Arey_kehna_kya_chahte_ho.wav +0 -0
- package/sounds/Majnu(Welcome_movie_meme).wav +0 -0
- package/sounds/chin_tapak_dum_dum.wav +0 -0
- package/sounds/faaah.wav +0 -0
- package/sounds/moye_moye.wav +0 -0
package/README.md
ADDED
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
# 🔊 Oopsify
|
|
2
|
+
|
|
3
|
+
**Oopsify** is a fun CLI tool that plays meme sounds automatically whenever your terminal command fails.
|
|
4
|
+
|
|
5
|
+
Turn boring errors into entertaining moments 😄
|
|
6
|
+
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## 🚀 Features
|
|
10
|
+
|
|
11
|
+
* 🔊 Play sound on terminal errors automatically
|
|
12
|
+
* 🎧 Choose your favorite meme sound
|
|
13
|
+
* 🎯 Interactive CLI with arrow-key selection
|
|
14
|
+
* ⚡ Works with PowerShell, bash, and zsh
|
|
15
|
+
* 🎨 Fun error message with styled output
|
|
16
|
+
|
|
17
|
+
---
|
|
18
|
+
|
|
19
|
+
## 📦 Installation
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
npm install -g oopsify
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
---
|
|
26
|
+
|
|
27
|
+
## ⚙️ Setup (Required)
|
|
28
|
+
|
|
29
|
+
Run:
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
oopsify setup
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
Then restart your terminal.
|
|
36
|
+
|
|
37
|
+
👉 This enables automatic error detection.
|
|
38
|
+
|
|
39
|
+
---
|
|
40
|
+
|
|
41
|
+
## 🎧 Usage
|
|
42
|
+
|
|
43
|
+
### List available sounds
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
oopsify list
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
---
|
|
50
|
+
|
|
51
|
+
### Set default sound
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
oopsify set
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Use arrow keys ⬆️⬇️ and press Enter.
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### Play sound manually
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
oopsify
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
---
|
|
68
|
+
|
|
69
|
+
## 💥 Automatic Mode
|
|
70
|
+
|
|
71
|
+
After setup, any failed command will trigger:
|
|
72
|
+
|
|
73
|
+
* 🔊 A meme sound
|
|
74
|
+
* 😵 A fun error message
|
|
75
|
+
|
|
76
|
+
---
|
|
77
|
+
|
|
78
|
+
### Example
|
|
79
|
+
|
|
80
|
+
```bash
|
|
81
|
+
dir randomfolder
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
Output:
|
|
85
|
+
|
|
86
|
+
```
|
|
87
|
+
dir: cannot find path...
|
|
88
|
+
🔊
|
|
89
|
+
😵 Oops! That didn’t go as planned
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
---
|
|
93
|
+
|
|
94
|
+
## 🧠 How it works
|
|
95
|
+
|
|
96
|
+
Oopsify integrates with your shell by modifying your profile configuration:
|
|
97
|
+
|
|
98
|
+
* PowerShell → `$PROFILE`
|
|
99
|
+
* bash/zsh → `.bashrc` / `.zshrc`
|
|
100
|
+
|
|
101
|
+
It detects command failures and triggers sound playback automatically.
|
|
102
|
+
|
|
103
|
+
---
|
|
104
|
+
|
|
105
|
+
## ⚠️ Notes
|
|
106
|
+
|
|
107
|
+
* You must run `oopsify setup` once after installation
|
|
108
|
+
* Restart your terminal after setup
|
|
109
|
+
* Works best in modern terminals (VS Code, Windows Terminal, etc.)
|
|
110
|
+
|
|
111
|
+
---
|
|
112
|
+
|
|
113
|
+
## 🛠️ Tech Stack
|
|
114
|
+
|
|
115
|
+
* Node.js
|
|
116
|
+
* Enquirer (CLI UI)
|
|
117
|
+
* Chalk (styling)
|
|
118
|
+
* node-wav-player (audio)
|
|
119
|
+
|
|
120
|
+
---
|
|
121
|
+
|
|
122
|
+
## 📁 Project Structure
|
|
123
|
+
|
|
124
|
+
```
|
|
125
|
+
oopsify/
|
|
126
|
+
bin/
|
|
127
|
+
index.js
|
|
128
|
+
sounds/
|
|
129
|
+
*.wav
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
---
|
|
133
|
+
|
|
134
|
+
## 🚀 Roadmap
|
|
135
|
+
|
|
136
|
+
* 🎲 Random sound mode
|
|
137
|
+
* 🎛️ Volume control
|
|
138
|
+
* 🎨 Themes
|
|
139
|
+
* 🧠 Smart error detection
|
|
140
|
+
|
|
141
|
+
---
|
|
142
|
+
|
|
143
|
+
## 👨💻 Author
|
|
144
|
+
|
|
145
|
+
**Shreyash Shrivastava**
|
|
146
|
+
|
|
147
|
+
---
|
|
148
|
+
|
|
149
|
+
## ⭐ Support
|
|
150
|
+
|
|
151
|
+
If you like this project, consider giving it a star ⭐ on GitHub (if you host it).
|
|
152
|
+
|
|
153
|
+
---
|
|
154
|
+
|
|
155
|
+
## 📄 License
|
|
156
|
+
|
|
157
|
+
MIT License
|
package/bin/index.js
ADDED
|
@@ -0,0 +1,198 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
const player = require('node-wav-player');
|
|
6
|
+
const os = require('os');
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
(async () => {
|
|
10
|
+
// 👉 ESM imports
|
|
11
|
+
const inquirer = (await import('inquirer')).default;
|
|
12
|
+
const chalkImport = await import('chalk');
|
|
13
|
+
const chalk = new chalkImport.Chalk({ level: 3 });
|
|
14
|
+
|
|
15
|
+
const soundsDir = path.join(__dirname, '../sounds');
|
|
16
|
+
const configPath = path.join(os.homedir(), '.oopsifyrc');
|
|
17
|
+
|
|
18
|
+
const command = process.argv[2];
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
if (command === 'setup') {
|
|
22
|
+
|
|
23
|
+
const home = os.homedir();
|
|
24
|
+
const isWindows = process.platform === 'win32';
|
|
25
|
+
|
|
26
|
+
if (isWindows) {
|
|
27
|
+
const profilePath = path.join(
|
|
28
|
+
home,
|
|
29
|
+
'Documents',
|
|
30
|
+
'PowerShell',
|
|
31
|
+
'Microsoft.PowerShell_profile.ps1'
|
|
32
|
+
);
|
|
33
|
+
|
|
34
|
+
const config = String.raw`
|
|
35
|
+
# >>> oopsify setup >>>
|
|
36
|
+
$global:lastOopsifyTime = 0
|
|
37
|
+
$global:isFirstRun = $true
|
|
38
|
+
|
|
39
|
+
function global:prompt {
|
|
40
|
+
$currentTime = [int](Get-Date -UFormat %s)
|
|
41
|
+
|
|
42
|
+
if (-not $global:isFirstRun) {
|
|
43
|
+
|
|
44
|
+
$shouldTrigger = $false
|
|
45
|
+
|
|
46
|
+
if (-not $global:isFirstRun) {
|
|
47
|
+
|
|
48
|
+
$shouldTrigger = $false
|
|
49
|
+
|
|
50
|
+
if (-not $?) {
|
|
51
|
+
$shouldTrigger = $true
|
|
52
|
+
} elseif ($LASTEXITCODE -ne 0) {
|
|
53
|
+
$shouldTrigger = $true
|
|
54
|
+
} elseif ($Error.Count -gt 0) {
|
|
55
|
+
$shouldTrigger = $true
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
if ($shouldTrigger) {
|
|
59
|
+
if ($currentTime - $global:lastOopsifyTime -gt 2) {
|
|
60
|
+
oopsify
|
|
61
|
+
$global:lastOopsifyTime = $currentTime
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
$Error.Clear()
|
|
66
|
+
}}
|
|
67
|
+
|
|
68
|
+
$global:isFirstRun = $false
|
|
69
|
+
$global:LASTEXITCODE = 0
|
|
70
|
+
|
|
71
|
+
"\`nPS " + (Get-Location) + "> "
|
|
72
|
+
}
|
|
73
|
+
# <<< oopsify setup <<<
|
|
74
|
+
`;
|
|
75
|
+
|
|
76
|
+
fs.mkdirSync(path.dirname(profilePath), { recursive: true });
|
|
77
|
+
|
|
78
|
+
let existing = '';
|
|
79
|
+
if (fs.existsSync(profilePath)) {
|
|
80
|
+
existing = fs.readFileSync(profilePath, 'utf-8');
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
if (!existing.includes('oopsify setup')) {
|
|
84
|
+
fs.appendFileSync(profilePath, config);
|
|
85
|
+
console.log('✅ Oopsify configured successfully for PowerShell!');
|
|
86
|
+
console.log('👉 Restart your terminal.');
|
|
87
|
+
} else {
|
|
88
|
+
console.log('⚠️ Oopsify already configured.');
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
} else {
|
|
92
|
+
const bashrc = path.join(home, '.bashrc');
|
|
93
|
+
|
|
94
|
+
const config = `
|
|
95
|
+
# >>> oopsify setup >>>
|
|
96
|
+
oopsify_run() {
|
|
97
|
+
"$@"
|
|
98
|
+
if [ $? -ne 0 ]; then
|
|
99
|
+
oopsify
|
|
100
|
+
fi
|
|
101
|
+
}
|
|
102
|
+
alias run="oopsify_run"
|
|
103
|
+
# <<< oopsify setup <<<
|
|
104
|
+
`;
|
|
105
|
+
|
|
106
|
+
let existing = '';
|
|
107
|
+
if (fs.existsSync(bashrc)) {
|
|
108
|
+
existing = fs.readFileSync(bashrc, 'utf-8');
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (!existing.includes('oopsify setup')) {
|
|
112
|
+
fs.appendFileSync(bashrc, config);
|
|
113
|
+
console.log('✅ Oopsify configured for bash!');
|
|
114
|
+
console.log('👉 Run: source ~/.bashrc');
|
|
115
|
+
} else {
|
|
116
|
+
console.log('⚠️ Already configured.');
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
// 👉 LIST COMMAND
|
|
123
|
+
if (command === 'list') {
|
|
124
|
+
const files = fs.readdirSync(soundsDir);
|
|
125
|
+
const sounds = files.map(file => file.replace('.wav', ''));
|
|
126
|
+
|
|
127
|
+
console.log(
|
|
128
|
+
chalk.bgGreen.white.bold(' 🎧 Available Sounds ')
|
|
129
|
+
);
|
|
130
|
+
|
|
131
|
+
sounds.forEach(sound => {
|
|
132
|
+
console.log(
|
|
133
|
+
chalk.bgGreen.white(` ${sound} `)
|
|
134
|
+
);
|
|
135
|
+
});
|
|
136
|
+
|
|
137
|
+
return;
|
|
138
|
+
}
|
|
139
|
+
|
|
140
|
+
// 👉 SET DEFAULT SOUND (interactive)
|
|
141
|
+
if (command === 'set') {
|
|
142
|
+
const enquirer = await import('enquirer');
|
|
143
|
+
const { Select } = enquirer.default;
|
|
144
|
+
|
|
145
|
+
const files = fs.readdirSync(soundsDir);
|
|
146
|
+
const sounds = files.map(file => file.replace('.wav', ''));
|
|
147
|
+
|
|
148
|
+
console.log(
|
|
149
|
+
chalk.bgGreen.white.bold(' 🎧 Select your default sound \n')
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
const prompt = new Select({
|
|
153
|
+
name: 'sound',
|
|
154
|
+
message: chalk.green('Use arrow keys and press Enter'),
|
|
155
|
+
choices: sounds,
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
try {
|
|
159
|
+
const answer = await prompt.run();
|
|
160
|
+
|
|
161
|
+
fs.writeFileSync(
|
|
162
|
+
configPath,
|
|
163
|
+
JSON.stringify({ defaultSound: answer }, null, 2)
|
|
164
|
+
);
|
|
165
|
+
|
|
166
|
+
console.log(
|
|
167
|
+
chalk.bgGreen.white(` ✅ Default sound set to "${answer}" `)
|
|
168
|
+
);
|
|
169
|
+
} catch (err) {
|
|
170
|
+
console.log(chalk.red('❌ Selection cancelled'));
|
|
171
|
+
}
|
|
172
|
+
|
|
173
|
+
return;
|
|
174
|
+
}
|
|
175
|
+
// 👉 PLAY SOUND
|
|
176
|
+
let soundName = command;
|
|
177
|
+
|
|
178
|
+
if (!soundName) {
|
|
179
|
+
if (fs.existsSync(configPath)) {
|
|
180
|
+
const config = JSON.parse(fs.readFileSync(configPath));
|
|
181
|
+
soundName = config.defaultSound;
|
|
182
|
+
} else {
|
|
183
|
+
soundName = 'moye_moye';
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
const soundPath = path.join(soundsDir, `${soundName}.wav`);
|
|
188
|
+
|
|
189
|
+
player.play({
|
|
190
|
+
path: soundPath,
|
|
191
|
+
}).then(async () => {
|
|
192
|
+
|
|
193
|
+
console.log('\x1b[103m\x1b[31m\x1b[1m 😵 Oops! That didn’t go as planned \x1b[0m\r\n\n');
|
|
194
|
+
}).catch(() => {
|
|
195
|
+
console.error(`❌ Sound "${soundName}" not found`);
|
|
196
|
+
});
|
|
197
|
+
|
|
198
|
+
})();
|
package/package.json
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@shreyash1601/oopsify",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "Play meme sounds automatically on terminal errors 🔊",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"bin": {
|
|
7
|
+
"oopsify": "bin/index.js"
|
|
8
|
+
},
|
|
9
|
+
"keywords": [
|
|
10
|
+
"cli",
|
|
11
|
+
"terminal",
|
|
12
|
+
"sound",
|
|
13
|
+
"developer",
|
|
14
|
+
"fun",
|
|
15
|
+
"error"
|
|
16
|
+
],
|
|
17
|
+
"author": "Shreyash Shrivastava",
|
|
18
|
+
"license": "MIT",
|
|
19
|
+
"dependencies": {
|
|
20
|
+
"chalk": "^5.0.0",
|
|
21
|
+
"enquirer": "^2.4.1",
|
|
22
|
+
"node-wav-player": "^1.0.0"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"bin",
|
|
26
|
+
"sounds"
|
|
27
|
+
]
|
|
28
|
+
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
package/sounds/faaah.wav
ADDED
|
Binary file
|
|
Binary file
|