@bobfrankston/msger 0.1.353 → 0.1.355

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.
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@bobfrankston/msger",
3
- "version": "0.1.353",
3
+ "version": "0.1.355",
4
4
  "description": "Fast, lightweight, cross-platform message box - Rust-powered alternative to msgview",
5
5
  "type": "module",
6
6
  "main": "./index.js",
@@ -51,8 +51,7 @@
51
51
  "dependencies": {
52
52
  "@bobfrankston/msgcommon": "^0.1.23",
53
53
  "ansi-to-html": "^0.7.2",
54
- "json5": "^2.2.3",
55
- "rcedit": "^4.0.1"
54
+ "json5": "^2.2.3"
56
55
  },
57
56
  "files": [
58
57
  "*.js",
package/shower.js CHANGED
@@ -2,7 +2,6 @@ import { spawn, execFileSync } from 'child_process';
2
2
  import { platform } from 'os';
3
3
  import path from 'path';
4
4
  import { pathToFileURL } from 'url';
5
- import { createRequire } from 'module';
6
5
  import fs from 'fs';
7
6
  import AnsiToHtml from 'ansi-to-html';
8
7
  // Load package.json for version
@@ -134,56 +133,21 @@ function sweepAsideSiblings(perAppExe) {
134
133
  }
135
134
  catch { /* fall through */ }
136
135
  }
137
- /** Locate the rcedit-<arch>.exe shipped with the `rcedit` npm package
138
- * (Electron-team maintained, published unscoped). Returns null on
139
- * non-Windows or if the package isn't installed. We resolve the path
140
- * manually so we can call the binary with `execFileSync` and keep the
141
- * caller synchronous. */
142
- function findRceditBinary() {
143
- if (platform() !== "win32")
144
- return null;
145
- try {
146
- // The package ships rcedit-x64.exe / rcedit-ia32.exe / rcedit-arm64.exe
147
- // in its `bin/` dir. Resolve via require.resolve('rcedit') → walk up
148
- // to the package root, then into bin/.
149
- const pkgEntry = createRequire(import.meta.url).resolve("rcedit");
150
- const pkgRoot = path.dirname(pkgEntry);
151
- const archMap = {
152
- x64: "rcedit-x64.exe",
153
- ia32: "rcedit-ia32.exe",
154
- arm64: "rcedit-arm64.exe",
155
- };
156
- const exeName = archMap[process.arch] || "rcedit-x64.exe";
157
- const candidates = [
158
- path.join(pkgRoot, "bin", exeName),
159
- path.join(pkgRoot, "..", "bin", exeName),
160
- ];
161
- for (const c of candidates) {
162
- if (fs.existsSync(c))
163
- return c;
164
- }
165
- }
166
- catch { /* not installed — caller will fall back to plain copy */ }
167
- return null;
168
- }
169
136
  /** Inject `.ico` into `exePath` as the IDI_ICON1 / RT_GROUP_ICON resource so
170
137
  * the per-app exe shows the app's own icon in Explorer, Task Manager, the
171
138
  * taskbar, and pinned shortcuts — every Windows context that reads the exe
172
- * resource (which `with_window_icon` doesn't reach). Sync — fires the
173
- * bundled rcedit.exe via `execFileSync`. Returns true on success. Failures
174
- * don't break launch the launcher just runs without the embedded icon. */
175
- function injectIcon(exePath, icoPath) {
176
- const rcedit = findRceditBinary();
177
- if (!rcedit) {
178
- console.error(` msger: rcedit binary not found — per-app icon not injected (install \`rcedit\` npm package)`);
179
- return false;
180
- }
139
+ * resource (which `with_window_icon` doesn't reach). Sync — invokes the
140
+ * shipped `msgernative.exe --update-icon` subcommand (no external deps;
141
+ * msger stays self-contained). Returns true on success. Failures don't
142
+ * break launch — the launcher just runs without the embedded icon. */
143
+ function injectIcon(msgerNative, exePath, icoPath) {
181
144
  try {
182
- execFileSync(rcedit, [exePath, "--set-icon", icoPath], { stdio: "pipe" });
145
+ execFileSync(msgerNative, ["--update-icon", exePath, icoPath], { stdio: "pipe" });
183
146
  return true;
184
147
  }
185
148
  catch (e) {
186
- console.error(` msger: rcedit failed for ${exePath}: ${e?.message || e}`);
149
+ const stderr = (e?.stderr ?? "").toString().trim();
150
+ console.error(` msger: --update-icon failed for ${exePath}: ${e?.message || e}${stderr ? ` (${stderr})` : ""}`);
187
151
  return false;
188
152
  }
189
153
  }
@@ -191,7 +155,7 @@ function injectIcon(exePath, icoPath) {
191
155
  * with the per-app icon resource injected. Two modes:
192
156
  *
193
157
  * - `_appIcon` is set (the per-app-identity case): the per-app exe is a
194
- * *real copy*, not a hardlink, because `rcedit` rewrites the resource
158
+ * *real copy*, not a hardlink, because `--update-icon` rewrites the resource
195
159
  * section and we don't want that change to bleed back into the shared
196
160
  * `msgernative.exe` (which a hardlink would). Staleness compared via
197
161
  * mtime of source exe + mtime of source icon. Refresh uses the
@@ -231,7 +195,7 @@ function ensureFresh(perAppExe, sourceExe) {
231
195
  sweepAsideSiblings(perAppExe);
232
196
  return;
233
197
  }
234
- // Copy + rcedit path. Stale when the per-app exe is missing OR the source
198
+ // Copy + --update-icon path. Stale when the per-app exe is missing OR the source
235
199
  // exe is newer (msger updated) OR the source icon is newer (icon changed).
236
200
  const srcMtime = fs.statSync(sourceExe).mtimeMs;
237
201
  const icoMtime = fs.statSync(_appIcon).mtimeMs;
@@ -243,7 +207,7 @@ function ensureFresh(perAppExe, sourceExe) {
243
207
  if (!stale)
244
208
  return;
245
209
  // Build the new exe out-of-band so a running instance never sees a
246
- // half-rcedit'd file. Sequence: copy → rcedit tmp → rename old aside →
210
+ // half---update-icon'd file. Sequence: copy → --update-icon tmp → rename old aside →
247
211
  // rename tmp into place. All renames work even on locked files; only
248
212
  // delete is blocked, and we defer that to the next launch's sweep.
249
213
  const stamp = Date.now();
@@ -251,14 +215,14 @@ function ensureFresh(perAppExe, sourceExe) {
251
215
  const isIco = _appIcon.toLowerCase().endsWith(".ico");
252
216
  try {
253
217
  fs.copyFileSync(sourceExe, tmpExe);
254
- let rceditOk = false;
218
+ let injected = false;
255
219
  if (isIco) {
256
- rceditOk = injectIcon(tmpExe, _appIcon);
220
+ injected = injectIcon(sourceExe, tmpExe, _appIcon);
257
221
  }
258
- if (!isIco || !rceditOk) {
259
- // No .ico available, or rcedit couldn't inject — fall back to a
260
- // plain copy. Window-icon path still gets set via Tao at launch;
261
- // we just don't get the EXE-level resource.
222
+ if (!isIco || !injected) {
223
+ // No .ico available, or the resource update failed — fall back
224
+ // to a plain copy. Window-icon path still gets set via Tao at
225
+ // launch; we just don't get the EXE-level resource.
262
226
  }
263
227
  if (fs.existsSync(perAppExe)) {
264
228
  try {