my-provider-dash-manager 0.6.3 → 0.7.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 CHANGED
@@ -46,14 +46,14 @@ Start Menu and Desktop shortcuts. Your accounts, sessions and saved logins live
46
46
 
47
47
  Three ways, all ending in the same place:
48
48
 
49
- - **Inside the app.** The version is always shown bottom-left in the rail. When a newer release
50
- exists it turns into an **Update x.y.z** button; click it to open the Updates panel on Home, which
51
- shows the release notes and offers **Download** and **Restart & install** with progress. The app
52
- checks quietly on startup and once an hour after that. Nothing is downloaded or installed until you
53
- press the button.
49
+ - **Automatically, inside the app (default).** The app checks on startup and hourly. A newer release
50
+ downloads in the background and installs silently, with no wizard, the next time you close the app;
51
+ the rail badge bottom-left turns into **Restart to update x.y.z** if you would rather do it now.
52
+ Turn **Auto-update** off in the Updates panel on Home and every step waits for a button press
53
+ instead (Check, Download, Restart & update), with release notes and progress shown.
54
54
  - **From the command line.** `npx my-provider-dash-manager` (or `mpdm update` if installed globally)
55
- installs the newest release over the current one. Close the app first, or the running copy keeps
56
- showing the old version until you restart it.
55
+ updates an existing install silently and in place; add `--interactive` if you want the wizard.
56
+ Close the app first, or the running copy keeps showing the old version until you restart it.
57
57
  - **From the release page.** Run the newest installer; it upgrades in place.
58
58
 
59
59
  The repository is public, so updates need no token or account.
@@ -72,7 +72,7 @@ and it is also available as `mpdm`:
72
72
  | `… where` | Print the install and data paths |
73
73
  | `… uninstall` | Run the uninstaller (accounts and sessions are kept) |
74
74
 
75
- Flags: `--silent` (no wizard), `--download-only`, `--force`, `--version`, `--help`.
75
+ Flags: `--silent` (no wizard on a first install), `--interactive` (wizard for an update), `--download-only`, `--force`, `--version`, `--help`.
76
76
  From a checkout of this repository the equivalent is `npm run install:latest`.
77
77
 
78
78
  ### Run from source
@@ -189,10 +189,13 @@ The token field says which credential each service expects. Tokens are validated
189
189
  encrypted with DPAPI, revocable in one click, and never leave the main process.
190
190
 
191
191
  ### Updates
192
- - Version always visible in the rail; an **Update** button appears when a newer release exists.
193
- - Updates panel on Home: installed vs latest, release notes, Check / Download / Restart & install with
194
- progress. Nothing installs itself.
195
- - Startup and hourly checks against the public release feed.
192
+ - **Silent in-place updates** by default: downloaded in the background, installed without a wizard
193
+ when the app closes or on **Restart & update**, relaunched on the new version.
194
+ - **Auto-update toggle** for people who want to press every button themselves.
195
+ - Version always visible in the rail; it becomes **Update x.y.z** / **Restart to update** as the
196
+ release moves through found → downloaded.
197
+ - Updates panel on Home: installed vs latest, release notes, progress. Startup and hourly checks
198
+ against the public release feed. The interactive installer is only for first installs.
196
199
 
197
200
  ### Content
198
201
  - **Ad-blocking** driven by EasyList (~52,000 blocked hosts plus generic cosmetic rules, refreshed
@@ -248,7 +251,7 @@ npm run smoke:restore # sessions survive a restart (real cookies)
248
251
  npm run smoke:tokens # DPAPI round-trip + live fake-token rejection per provider (15)
249
252
  npm run smoke:creds # import, per-account recall, encryption at rest (7)
250
253
  npm run smoke:autofill # real page: form detection, fill, capture, origin guard (10)
251
- npm run smoke:updates # version comparison + real release-feed check (8)
254
+ npm run smoke:updates # version comparison, silent-install mode, auto-update toggle, real release-feed check (11)
252
255
  npm run smoke:services # every built-in login page loads inside an isolated partition (42)
253
256
  npm run capture # screenshot the running shell (--capture-out, --capture-open svc::id, --capture-js)
254
257
  npm run spike # memory benchmark
@@ -258,7 +261,7 @@ npm start -- --print-paths # show the app name, version and data fold
258
261
  npm start -- --open vercel::personal # open an account on launch
259
262
  ```
260
263
 
261
- The suite is 108 checks across seven modes. `MAM_USER_DATA=<dir>` points any command at an isolated
264
+ The suite is 111 checks across seven modes. `MAM_USER_DATA=<dir>` points any command at an isolated
262
265
  profile.
263
266
 
264
267
  Releases are cut by pushing a `v*` tag: GitHub Actions checks the tag against `package.json`, builds
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "my-provider-dash-manager",
3
- "version": "0.6.3",
3
+ "version": "0.7.0",
4
4
  "description": "Manage many accounts per cloud service (Vercel, Netlify, Supabase, Cloudflare, Railway, Render, GitHub) in one desktop app \u2014 isolated persistent sessions, one tab per account.",
5
5
  "main": "src/main.js",
6
6
  "scripts": {
package/scripts/cli.js CHANGED
@@ -9,7 +9,7 @@
9
9
  // npx my-provider-dash-manager uninstall run the app's uninstaller
10
10
  // npx my-provider-dash-manager where print the install and data paths
11
11
  //
12
- // Flags: --silent (no wizard) · --download-only · --version · --help
12
+ // Flags: --silent (no wizard) · --interactive (wizard even for an update) · --download-only · --version · --help
13
13
  const fs = require('fs');
14
14
  const os = require('os');
15
15
  const path = require('path');
@@ -82,11 +82,15 @@ async function install({ launchAfter }) {
82
82
  if (rel.notes) console.log(`\n${rel.notes.split('\n').slice(0, 10).join('\n')}\n`);
83
83
  const dest = await downloadAsset(rel);
84
84
  if (flags.has('--download-only')) { console.log(`\nSaved to ${dest}`); return; }
85
- console.log(`\nRunning the installer${flags.has('--silent') ? ' (silent)' : ''}…`);
86
- const child = spawn(dest, flags.has('--silent') ? ['/S'] : [], { detached: true, stdio: 'ignore' });
85
+ // An update over an existing install runs silently (no wizard) unless --interactive is given;
86
+ // a first install shows the wizard unless --silent is given.
87
+ const silent = flags.has('--silent') || (!!have && !flags.has('--interactive'));
88
+ console.log(`\nRunning the installer${silent ? ' (silent, in place)' : ''}…`);
89
+ if (silent && have) console.log('Close the app if it is running, or the running copy keeps the old version until restarted.');
90
+ const child = spawn(dest, silent ? ['/S'] : [], { detached: true, stdio: 'ignore' });
87
91
  child.unref();
88
- console.log('The installer is unsigned, so SmartScreen may ask you to confirm.');
89
- if (launchAfter && flags.has('--silent')) {
92
+ if (!silent) console.log('The installer is unsigned, so SmartScreen may ask you to confirm.');
93
+ if (launchAfter && silent) {
90
94
  setTimeout(() => { try { launch(); } catch (e) { console.error(e.message); } }, 15000);
91
95
  }
92
96
  }
@@ -131,7 +135,8 @@ function help() {
131
135
  npx my-provider-dash-manager where print install and data paths
132
136
  npx my-provider-dash-manager uninstall run the uninstaller (keeps your data)
133
137
 
134
- Flags: --silent --download-only --force --version --help
138
+ Flags: --silent --interactive --download-only --force --version --help
139
+ Updates over an existing install run silently; first installs show the wizard.
135
140
  Windows only. https://github.com/FiredMosquito831/my-provider-dash-manager`);
136
141
  }
137
142
 
package/src/main.js CHANGED
@@ -48,7 +48,7 @@ const store = {
48
48
  saveSession() { writeJson(userDataPath('session.json'), this.openTabs); },
49
49
  load() {
50
50
  this.accounts = readJson(userDataPath('accounts.json'), []);
51
- this.settings = Object.assign({ warmLimit: 5, groupTabs: false, collapsed: [], stripCollapsed: [], adBlock: true, darkMode: true, forceDark: false, saveLogins: true, autofill: true }, readJson(userDataPath('settings.json'), {}));
51
+ this.settings = Object.assign({ warmLimit: 5, groupTabs: false, collapsed: [], stripCollapsed: [], adBlock: true, darkMode: true, forceDark: false, saveLogins: true, autofill: true, autoUpdate: true }, readJson(userDataPath('settings.json'), {}));
52
52
  this.openTabs = readJson(userDataPath('session.json'), []);
53
53
  this.customServices = readJson(userDataPath('services.json'), []);
54
54
  },
@@ -816,6 +816,9 @@ async function runSmokeUpdates() {
816
816
  const init = updater.init(() => {});
817
817
  check('reports-current-version', init.currentVersion === app.getVersion(), init.currentVersion);
818
818
  check('knows-it-cannot-install-in-dev', init.canDownload === false && init.packaged === false);
819
+ check('update-installs-silently-and-relaunches', updater.INSTALL_MODE.isSilent === true && updater.INSTALL_MODE.isForceRunAfter === true);
820
+ check('auto-update-defaults-on', store.settings.autoUpdate === true && init.autoUpdate === true);
821
+ check('auto-update-toggle', updater.setAutoUpdate(false) === false && updater.snapshot().autoUpdate === false && updater.setAutoUpdate(true) === true);
819
822
 
820
823
  const s = await updater.check();
821
824
  check('check-completes-with-a-verdict', ['available', 'up-to-date', 'error'].includes(s.status), `status=${s.status}`);
@@ -877,7 +880,7 @@ function runInteractive(captureMode = false) {
877
880
  win.loadFile(path.join(__dirname, 'ui.html'));
878
881
  // Update system: version tracking + release info + explicit user-driven download/install.
879
882
  // Nothing downloads or installs on its own; the UI shows what is available and you decide.
880
- updater.init(s => { if (win && win.webContents && !win.webContents.isDestroyed()) win.webContents.send('update-state', s); });
883
+ updater.init(s => { if (win && win.webContents && !win.webContents.isDestroyed()) win.webContents.send('update-state', s); }, { autoUpdate: store.settings.autoUpdate !== false });
881
884
  updater.check().catch(() => {}); // one check at startup
882
885
  setInterval(() => updater.check().catch(() => {}), 60 * 60 * 1000); // and hourly after that
883
886
  const applyBounds = () => {
@@ -1225,8 +1228,9 @@ function runInteractive(captureMode = false) {
1225
1228
  return true;
1226
1229
  });
1227
1230
  ipcMain.handle('set-content-setting', (_e, name, value) => {
1228
- if (!['adBlock', 'darkMode', 'forceDark', 'saveLogins', 'autofill'].includes(name)) throw new Error(`unknown setting: ${name}`);
1231
+ if (!['adBlock', 'darkMode', 'forceDark', 'saveLogins', 'autofill', 'autoUpdate'].includes(name)) throw new Error(`unknown setting: ${name}`);
1229
1232
  store.settings[name] = !!value;
1233
+ if (name === 'autoUpdate') { store.save(); updater.setAutoUpdate(!!value); vm.emitState(); return !!value; }
1230
1234
  // Inverting a page that is already dark produces a washed-out light page, so the two modes
1231
1235
  // are mutually exclusive.
1232
1236
  if (name === 'forceDark' && value) store.settings.darkMode = false;