francois 0.12.0-dev.9 → 0.13.0-dev.10

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
@@ -23,9 +23,12 @@ with your desktop.
23
23
  | **macOS** | the app bundle in `~/Applications` — Spotlight, Launchpad and the Dock all find it |
24
24
  | **Linux** | a `.desktop` launcher and icon under `~/.local/share` |
25
25
 
26
- All per-user: no administrator rights, no elevation prompt. `npm uninstall -g
27
- francois` removes them again, and `francois shortcut --remove` is the manual
28
- escape hatch.
26
+ All per-user: no administrator rights, no elevation prompt. Run `francois
27
+ uninstall` to remove them again current npm (v7+) doesn't run the
28
+ `preuninstall` hook a plain `npm uninstall -g francois` would need, so that
29
+ alone leaves the app behind in `~/Applications` (or the Start Menu / `.desktop`
30
+ entry). `francois shortcut --remove` unregisters just the desktop entry,
31
+ without touching the npm package.
29
32
 
30
33
  ## Why install this way
31
34
 
@@ -54,6 +57,7 @@ Prebuilt for macOS (universal), Windows x64 and Linux x64. On anything else,
54
57
  | `francois --version` | print the app + package versions |
55
58
  | `francois shortcut` | re-register the desktop entry (after deleting it, or a headless install) |
56
59
  | `francois shortcut --remove` | unregister it |
60
+ | `francois uninstall` | unregister the desktop entry, then remove the npm package — the supported way to uninstall |
57
61
  | `francois --help` | usage |
58
62
 
59
63
  Environment: `FRANCOIS_SKIP_DOWNLOAD=1` skips the postinstall download,
package/bin/francois.js CHANGED
@@ -29,6 +29,7 @@ Usage
29
29
  francois --version print the app + package versions
30
30
  francois shortcut re-register the Start Menu / Launchpad / menu entry
31
31
  francois shortcut --remove unregister it
32
+ francois uninstall unregister the desktop entry, then npm-uninstall this package
32
33
  francois --help this message
33
34
 
34
35
  Anything else is forwarded to the app.
@@ -95,6 +96,25 @@ function main() {
95
96
  return;
96
97
  }
97
98
 
99
+ // Current npm (v7+) never runs preuninstall/postuninstall for `npm uninstall
100
+ // -g` — a long-standing, unfixed npm regression — so uninstall.js's preuninstall
101
+ // hook (still useful under yarn/pnpm, which do honor it) cannot be relied on
102
+ // with npm. This is the reliable path: remove the desktop entry (and, on
103
+ // macOS, the ~/Applications bundle) while the install record still exists,
104
+ // THEN hand off to npm — after which the record and this very script are gone.
105
+ if (argv[0] === 'uninstall') {
106
+ const record = readInstallRecord();
107
+ if (record) {
108
+ desktop.remove(record);
109
+ process.stdout.write(`francois: removed the ${record.productName} shortcut.\n`);
110
+ }
111
+ const pkg = require('../package.json');
112
+ process.stdout.write('francois: removing the npm package…\n');
113
+ const npmCmd = process.platform === 'win32' ? 'npm.cmd' : 'npm';
114
+ const result = spawnSync(npmCmd, ['uninstall', '-g', pkg.name], { stdio: 'inherit' });
115
+ process.exit(result.status === null ? 1 : result.status);
116
+ }
117
+
98
118
  const executable = resolveExecutable();
99
119
  if (!executable) {
100
120
  if (!assetKey()) {
package/manifest.json CHANGED
@@ -2,11 +2,11 @@
2
2
  "repo": "antoine-gmnz/francois",
3
3
  "tag": "dev",
4
4
  "channel": "dev",
5
- "appVersion": "0.12.0",
5
+ "appVersion": "0.13.0",
6
6
  "productName": "Francois Dev",
7
7
  "assets": {
8
- "darwin-universal": { "name": "francois-darwin-universal.tar.gz", "sha256": "7bd79eeb0627034d78918301fa9a97b075bf65b662d03693ef610328d0d195b5" },
9
- "linux-x64": { "name": "francois-linux-x64.tar.gz", "sha256": "2d0282446db9d13cb12dd9e268265e72b18373811edb51fd9d641a0671e4036c" },
10
- "win32-x64": { "name": "francois-win32-x64.zip", "sha256": "1ae55c7b18b4f216fb4cf86436d06e4e351a3dc43c500a8bb623e4e38109e0df" }
8
+ "darwin-universal": { "name": "francois-darwin-universal.tar.gz", "sha256": "48e9909027ca0cd10e64ecf8ed4fa9f6a7807904bc326d6f5ae7184d6998b877" },
9
+ "linux-x64": { "name": "francois-linux-x64.tar.gz", "sha256": "d14bcce1a61bed460bbd0c065e21a97962031e34b25db4de41b01e9cc779c77e" },
10
+ "win32-x64": { "name": "francois-win32-x64.zip", "sha256": "9234fbf1805b5657e82a9ce5dcd2b2f797813e51887ce479fd6246bab6e656bd" }
11
11
  }
12
12
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "francois",
3
- "version": "0.12.0-dev.9",
3
+ "version": "0.13.0-dev.10",
4
4
  "description": "Mission control for your Claude Code fleet — installs the Francois desktop app without an installer.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "author": "Antoine Gimenez",
package/uninstall.js CHANGED
@@ -2,15 +2,18 @@
2
2
  'use strict';
3
3
 
4
4
  /**
5
- * preuninstall — unregister the desktop integration before npm deletes the
6
- * package directory.
5
+ * preuninstall — unregister the desktop integration before the package
6
+ * directory is deleted.
7
7
  *
8
8
  * This matters most on macOS, where the .app was moved out to ~/Applications and
9
- * would otherwise survive `npm uninstall -g francois` as an orphan.
9
+ * would otherwise survive an uninstall as an orphan.
10
10
  *
11
- * npm's uninstall lifecycle does not fire in every situation (a manually deleted
12
- * global folder, some CI teardowns), so `francois shortcut --remove` exists as
13
- * the explicit escape hatch. Never fails the uninstall.
11
+ * Current npm (v7+) never actually runs this a long-standing, unfixed
12
+ * regression where `npm uninstall -g` skips preuninstall/postuninstall
13
+ * entirely so `francois uninstall` (bin/francois.js) is the command that
14
+ * reliably does this cleanup with npm. This script still earns its keep under
15
+ * package managers that do honor the hook (yarn, pnpm). Never fails the
16
+ * uninstall either way.
14
17
  */
15
18
 
16
19
  const desktop = require('./lib/desktop.js');