theamify-cli 2.2.2 → 2.2.5

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 CHANGED
@@ -40,6 +40,29 @@ theamify help # show all commands
40
40
 
41
41
  ---
42
42
 
43
+ ## ✨ What's New (v2.2.5 — doc refresh & command parity)
44
+
45
+ | Feature | Details |
46
+ |---|---|
47
+ | 📖 **README synced** | Every command + alias documented and verified against the live CLI: `list`/`ls`, `info`/`show`, `get`/`fetch`/`download`, `use`/`apply`/`set`, `remove`/`rm`/`uncache`, `add`/`del`/`delete`, `update`, `open`, `status`, `doctor`, `upgrade`/`self-update`, `repair`, `browse`/`wizard`/`install`, `uninstall`, `clean`/`purge-cache`, `version`, `help` |
48
+ | 🗑️ **Uninstall contract** | After `theamify uninstall`, `theamify` reports `command not found` (new terminal) — clear the current shell's cache with `hash -r` |
49
+
50
+ ## ✨ What's New (v2.2.4 — command-not-found clarity)
51
+
52
+ | Feature | Details |
53
+ |---|---|
54
+ | 💡 **Current-terminal hint** | After uninstall, `theamify` is fully deleted — a **new terminal** reports `bash: theamify: command not found`. If your *current* shell still says `No such file or directory`, that's bash's cached command path — clear it with `hash -r` |
55
+ | 🗑️ **Still removes everything** | Every runtime, theme, GRUB theme, npm package, `~/.local/bin/theamify` shadow and PATH marker |
56
+
57
+ ## ✨ What's New (v2.2.3 — complete uninstall)
58
+
59
+ | Feature | Details |
60
+ |---|---|
61
+ | 🗑️ **Uninstall removes EVERYTHING** | `theamify uninstall` now removes **every** runtime tree (`~/.local/share/theamify` AND `/usr/local/share/theamify`), all downloaded themes, the applied GRUB theme, the `theamify-cli` npm package **and** `~/.local/bin/theamify` (legacy shadow, file or symlink) plus every PATH marker from `~/.bashrc`/`~/.zshrc` |
62
+ | ✅ **`command not found` guaranteed** | After uninstall, `theamify` shadows nothing on PATH — typing it returns `bash: theamify: command not found`, exactly like any tool you never installed |
63
+ | 🔒 **One confirmation** | A single confirmation covers the whole removal (no more piecemeal "keep the npm package?" prompts) |
64
+ | 🩹 **Regression-tested** | `removeUserBin` (symlink + real-file shadow), runtime-tree removal and rc cleanup are all covered by tests |
65
+
43
66
  ## ✨ What's New (v2.2.2 — uninstall crash hotfix)
44
67
 
45
68
  | Feature | Details |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "theamify-cli",
3
- "version": "2.2.2",
3
+ "version": "2.2.5",
4
4
  "description": "theamify — GRUB theme manager & interactive browser wizard. Browse, preview, download and apply GRUB boot themes from the terminal.",
5
5
  "type": "module",
6
6
  "main": "src/cli.js",
@@ -5,8 +5,10 @@ import pc from 'picocolors';
5
5
  import { execa, execaSync } from 'execa';
6
6
  import {
7
7
  findInstalledRuntime,
8
+ SYSTEM_DIR,
8
9
  USER_DIR,
9
- removeShadowBin,
10
+ BIN_NAME,
11
+ removeUserBin,
10
12
  repairRuntime,
11
13
  resolveEngine,
12
14
  } from '../core/engine.js';
@@ -160,46 +162,52 @@ export async function resetGrubTheme({ grubFile = '/etc/default/grub', asRoot =
160
162
  return res.exitCode === 0;
161
163
  }
162
164
 
163
- /** `theamify uninstall` — removes theamify, ALL downloaded themes, and resets GRUB to default. */
165
+ /** `theamify uninstall` — remove EVERY trace of theamify so the command vanishes. */
164
166
  export async function runUninstallWizard() {
165
167
  p.intro(pc.bgRed(pc.black(' theamify Uninstaller ')));
168
+
166
169
  const found = findInstalledRuntime();
167
- if (!found) p.log.info('No installed theamify runtime found (nothing to remove).');
168
-
169
- let removed = false;
170
- if (found) {
171
- const confirm = await p.confirm({
172
- message: `Remove theamify files at ${found.dir}/? (this deletes ALL downloaded themes)`,
173
- initialValue: true,
174
- });
175
- if (!p.isCancel(confirm) && confirm) {
176
- removed = await removeRuntimeDir(found.dir);
177
- if (removed) removeShadowBin();
178
- else p.log.warn(`Could not remove ${found.dir}.`);
179
- }
180
- }
170
+ if (found) p.note(found.dir, 'Installed runtime detected');
181
171
 
182
- // Reset the boot menu back to the default (remove the applied GRUB theme).
183
- const resetGrub = await p.confirm({
184
- message: 'Remove your applied GRUB theme and reset to the default boot menu?',
172
+ const confirm = await p.confirm({
173
+ message: 'Uninstall theamify completely? This removes the runtime, ALL downloaded themes, the applied GRUB theme, the theamify-cli npm package, ~/.local/bin/theamify and every PATH marker.',
185
174
  initialValue: true,
186
175
  });
187
- if (p.isCancel(resetGrub)) { p.cancel('Aborted.'); process.exit(0); }
188
- const grubReset = resetGrub ? await resetGrubTheme() : false;
176
+ if (p.isCancel(confirm)) { p.cancel('Aborted.'); process.exit(0); }
177
+ if (!confirm) { p.outro('Nothing was removed.'); return; }
178
+
179
+ // 1. Remove EVERY runtime tree — user AND system. (removeRuntimeDir uses
180
+ // sudo automatically for root-owned dirs like /usr/local/share/theamify.)
181
+ let removedCount = 0;
182
+ for (const dir of [SYSTEM_DIR, USER_DIR]) {
183
+ if (fs.existsSync(path.join(dir, BIN_NAME))) {
184
+ if (await removeRuntimeDir(dir)) removedCount++;
185
+ else p.log.warn(`Could not remove ${dir}.`);
186
+ }
187
+ }
188
+
189
+ // 2. Remove any legacy `~/.local/bin/theamify` shadow — symlink OR real file.
190
+ // This is what KEEPS the command alive when `~/.local/bin` is on PATH.
191
+ if (removeUserBin()) p.log.success('Removed ~/.local/bin/theamify.');
192
+
193
+ // 3. Reset the boot menu back to the default (remove the applied GRUB theme).
194
+ const grubReset = await resetGrubTheme();
189
195
 
190
- // Remove the npm package so the `theamify` command actually disappears.
196
+ // 4. Remove the npm package so the `theamify` command truly disappears.
191
197
  const npmRemoved = await selfUninstall();
192
198
 
193
- // Remove leftover PATH markers from ~/.bashrc / ~/.zshrc so zero traces remain.
199
+ // 5. Remove leftover PATH markers from ~/.bashrc / ~/.zshrc so zero traces remain.
194
200
  await cleanRcMarkers();
195
201
 
196
202
  // Companion tools (chafa, grub-customizer) are intentionally LEFT in place —
197
- // the user may want them for later; uninstall only removes theamify itself.
203
+ // they are not theamify; uninstall only removes theamify itself.
198
204
  const themeNote = grubReset
199
205
  ? 'Boot menu reset to the default theme.'
200
- : (resetGrub ? 'GRUB reset could not be completed — remove GRUB_THEME= from /etc/default/grub and rebuild.' : 'Your applied GRUB theme was left in place.');
206
+ : 'GRUB reset could not be completed — remove GRUB_THEME= from /etc/default/grub and rebuild.';
201
207
 
202
208
  p.outro(pc.green(
203
- `Uninstalled.${removed ? ' Runtime + all downloaded themes removed.' : ''} ${themeNote} ${npmRemoved ? 'theamify npm package removed — command no longer available.' : 'theamify npm package kept.'} Companion tools (chafa, grub-customizer) were kept for your use.`,
209
+ `Uninstalled.${removedCount ? ` ${removedCount} runtime tree(s) + all downloaded themes removed.` : ''} ${themeNote} ${npmRemoved ? 'theamify-cli npm package removed — the theamify command is gone.' : 'theamify-cli npm package could not be removed automatically — run: npm uninstall -g theamify-cli'} Companion tools (chafa, grub-customizer) were kept for your use.`,
204
210
  ));
211
+ p.log.message(pc.dim('After uninstall, `theamify` reports: bash: theamify: command not found'));
212
+ p.log.message(pc.dim('If this terminal still shows "No such file or directory", clear bash\'s cached command path with: hash -r (or open a new terminal).'));
205
213
  }
@@ -44,6 +44,24 @@ export function removeShadowBin() {
44
44
  } catch { /* nothing to remove */ }
45
45
  }
46
46
 
47
+ /**
48
+ * Remove anything at `~/.local/bin/theamify` — a legacy shadow executable that
49
+ * keeps the `theamify` command alive and SHADOWS the npm CLI after uninstall
50
+ * (because `~/.local/bin` precedes the npm global bin on PATH). Removes BOTH a
51
+ * symlink and a plain-file engine copy left behind by old installs.
52
+ * @param {string} [binPath] override the path (used by tests)
53
+ * @returns {boolean} true when something was removed
54
+ */
55
+ export function removeUserBin(binPath = USER_BIN_LINK) {
56
+ try {
57
+ if (fs.existsSync(binPath) || fs.lstatSync(binPath)) {
58
+ fs.rmSync(binPath, { force: true });
59
+ return !fs.existsSync(binPath);
60
+ }
61
+ } catch { /* nothing to remove */ }
62
+ return false;
63
+ }
64
+
47
65
  /** Copy the vendored engine script + shared libs into a runtime dir. */
48
66
  function copyEngineTo(dir) {
49
67
  fs.mkdirSync(path.join(dir, 'lib'), { recursive: true });
package/src/lib/self.js CHANGED
@@ -101,18 +101,12 @@ export async function promptSelfUpdate() {
101
101
 
102
102
  /**
103
103
  * Fully remove the npm package so the `theamify` command disappears from PATH.
104
+ * Uninstall is non-interactive about this — removing the npm package is a core
105
+ * part of "remove everything", not an optional extra.
104
106
  * @returns {Promise<boolean>} true when uninstalled
105
107
  */
106
108
  export async function selfUninstall() {
107
109
  const p = await import('@clack/prompts');
108
- const want = await p.confirm({
109
- message: `Also remove the ${NPM_NAME} npm package, so the ${pc.cyan(BIN_NAME)} command is gone from your system?`,
110
- initialValue: true,
111
- });
112
- if (p.isCancel(want) || !want) {
113
- p.log.message(pc.dim(`Keeping the npm package — the ${BIN_NAME} command will remain.`));
114
- return false;
115
- }
116
110
  console.log();
117
111
  const res = await execa('npm', ['uninstall', '-g', NPM_NAME], { stdio: 'inherit', reject: false });
118
112
  if (res.exitCode === 0) {
package/vendor/theamify CHANGED
@@ -10,7 +10,7 @@ set -euo pipefail
10
10
  # -----------------------------------------------------------------------------
11
11
  # VERSION & TOOL NAME
12
12
  # -----------------------------------------------------------------------------
13
- readonly VERSION="2.2.2"
13
+ readonly VERSION="2.2.5"
14
14
  readonly TOOL="theamify"
15
15
 
16
16
  # -----------------------------------------------------------------------------