francois 0.17.6 → 0.17.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/assets/icon.png +0 -0
- package/lib/desktop.js +42 -1
- package/manifest.json +5 -5
- package/package.json +1 -1
package/assets/icon.png
CHANGED
|
Binary file
|
package/lib/desktop.js
CHANGED
|
@@ -38,10 +38,38 @@ function startMenuShortcut(productName, appData = process.env.APPDATA) {
|
|
|
38
38
|
return path.join(appData, 'Microsoft', 'Windows', 'Start Menu', 'Programs', `${productName}.lnk`);
|
|
39
39
|
}
|
|
40
40
|
|
|
41
|
+
/**
|
|
42
|
+
* Where a launched Francois should START, which is anywhere but its own package.
|
|
43
|
+
*
|
|
44
|
+
* A process's working directory is an open handle on that directory, and it is
|
|
45
|
+
* inherited by everything the app spawns. Pointing it at `…/francois/vendor`
|
|
46
|
+
* meant the self-update helper — a child of the app — held the exact directory
|
|
47
|
+
* npm has to rename during `npm i -g francois@latest`, so every self-update
|
|
48
|
+
* failed with `EBUSY: resource busy or locked, rename '...\francois\vendor'`.
|
|
49
|
+
* The home directory owes nothing to the install and is never replaced.
|
|
50
|
+
*/
|
|
51
|
+
function shortcutWorkingDir(home = os.homedir()) {
|
|
52
|
+
return home;
|
|
53
|
+
}
|
|
54
|
+
|
|
41
55
|
function uninstallRegistryKey(channel) {
|
|
42
56
|
return `HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\${appId(channel)}`;
|
|
43
57
|
}
|
|
44
58
|
|
|
59
|
+
/**
|
|
60
|
+
* The AppUserModelID toast notifications are sent under. Must equal the tauri
|
|
61
|
+
* `identifier` of the channel's config (tauri.conf.json / tauri.dev.conf.json):
|
|
62
|
+
* tauri-plugin-notification tags every toast from an installed app with that
|
|
63
|
+
* identifier, and Windows silently drops toasts whose AUMID it has never seen.
|
|
64
|
+
*/
|
|
65
|
+
function aumid(channel) {
|
|
66
|
+
return channel === 'dev' ? 'com.francois.dev' : 'com.francois.desktop';
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
function aumidRegistryKey(channel) {
|
|
70
|
+
return `HKCU\\Software\\Classes\\AppUserModelId\\${aumid(channel)}`;
|
|
71
|
+
}
|
|
72
|
+
|
|
45
73
|
function desktopEntryPath(channel, home = os.homedir()) {
|
|
46
74
|
return path.join(home, '.local', 'share', 'applications', `${appId(channel)}.desktop`);
|
|
47
75
|
}
|
|
@@ -103,7 +131,7 @@ function installWindows({ executable, productName, channel, appVersion, notes })
|
|
|
103
131
|
[
|
|
104
132
|
'$s = (New-Object -ComObject WScript.Shell).CreateShortcut(' + psQuote(shortcut) + ');',
|
|
105
133
|
'$s.TargetPath = ' + psQuote(executable) + ';',
|
|
106
|
-
'$s.WorkingDirectory = ' + psQuote(
|
|
134
|
+
'$s.WorkingDirectory = ' + psQuote(shortcutWorkingDir()) + ';',
|
|
107
135
|
"$s.Description = 'Mission control for your Claude Code fleet';",
|
|
108
136
|
'$s.Save()',
|
|
109
137
|
].join(' '),
|
|
@@ -127,12 +155,22 @@ function installWindows({ executable, productName, channel, appVersion, notes })
|
|
|
127
155
|
attempt('reg', ['add', key, '/v', name, '/t', type, '/d', data, '/f']),
|
|
128
156
|
);
|
|
129
157
|
if (!wrote) notes.push('could not register the uninstall entry.');
|
|
158
|
+
|
|
159
|
+
// Registering the AUMID is what lets toast notifications through: a
|
|
160
|
+
// WScript.Shell .lnk cannot carry System.AppUserModel.ID, so use the registry
|
|
161
|
+
// route for unpackaged apps (the same one Chrome uses) instead.
|
|
162
|
+
const toastKey = aumidRegistryKey(channel);
|
|
163
|
+
const registered =
|
|
164
|
+
attempt('reg', ['add', toastKey, '/v', 'DisplayName', '/t', 'REG_SZ', '/d', productName, '/f']) &&
|
|
165
|
+
attempt('reg', ['add', toastKey, '/v', 'IconUri', '/t', 'REG_SZ', '/d', ICON_SOURCE, '/f']);
|
|
166
|
+
if (!registered) notes.push('could not register the notification identity — toasts may not show.');
|
|
130
167
|
}
|
|
131
168
|
|
|
132
169
|
function removeWindows({ productName, channel }) {
|
|
133
170
|
const shortcut = startMenuShortcut(productName);
|
|
134
171
|
if (shortcut) fs.rmSync(shortcut, { force: true });
|
|
135
172
|
attempt('reg', ['delete', uninstallRegistryKey(channel), '/f']);
|
|
173
|
+
attempt('reg', ['delete', aumidRegistryKey(channel), '/f']);
|
|
136
174
|
}
|
|
137
175
|
|
|
138
176
|
/** Single-quoted PowerShell literal — no expansion, '' escapes a quote. */
|
|
@@ -244,11 +282,14 @@ module.exports = {
|
|
|
244
282
|
ICON_SOURCE,
|
|
245
283
|
appId,
|
|
246
284
|
applicationsDir,
|
|
285
|
+
aumid,
|
|
286
|
+
aumidRegistryKey,
|
|
247
287
|
desktopEntry,
|
|
248
288
|
desktopEntryPath,
|
|
249
289
|
desktopIconPath,
|
|
250
290
|
install,
|
|
251
291
|
remove,
|
|
292
|
+
shortcutWorkingDir,
|
|
252
293
|
startMenuShortcut,
|
|
253
294
|
uninstallRegistryKey,
|
|
254
295
|
};
|
package/manifest.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"repo": "antoine-gmnz/francois",
|
|
3
|
-
"tag": "v0.17.
|
|
3
|
+
"tag": "v0.17.10",
|
|
4
4
|
"channel": "stable",
|
|
5
|
-
"appVersion": "0.17.
|
|
5
|
+
"appVersion": "0.17.10",
|
|
6
6
|
"productName": "Francois",
|
|
7
7
|
"assets": {
|
|
8
|
-
"darwin-universal": { "name": "francois-darwin-universal.tar.gz", "sha256": "
|
|
9
|
-
"linux-x64": { "name": "francois-linux-x64.tar.gz", "sha256": "
|
|
10
|
-
"win32-x64": { "name": "francois-win32-x64.zip", "sha256": "
|
|
8
|
+
"darwin-universal": { "name": "francois-darwin-universal.tar.gz", "sha256": "6b8d4ca8c8a078cced1837489129f2663bceecc6860b4d498de7500edc351369" },
|
|
9
|
+
"linux-x64": { "name": "francois-linux-x64.tar.gz", "sha256": "5e724448e5f6fa557caf8bc66630426386122588cdaa61221aad26be237096c6" },
|
|
10
|
+
"win32-x64": { "name": "francois-win32-x64.zip", "sha256": "56cedd995a2e470d1ef8ec203db64719477918602dfa84cbf0ac3d30811906dd" }
|
|
11
11
|
}
|
|
12
12
|
}
|
package/package.json
CHANGED