my-provider-dash-manager 0.6.2 → 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
@@ -10,6 +10,13 @@ source-available licence: free for personal and commercial use</sub>
10
10
 
11
11
  ![Home — the account rail on the left, every account as a card, the installed version bottom-left](docs/screenshots/home.png)
12
12
 
13
+ Further down Home: the **Add an account** picker with every built-in service you are not using yet
14
+ (37 in total, or add any site by URL), the **Updates** panel with the installed version, and the
15
+ saved-login controls. Install with `npx my-provider-dash-manager` or straight from
16
+ [Releases](https://github.com/FiredMosquito831/my-provider-dash-manager/releases) — see [Install](#install).
17
+
18
+ ![Home, scrolled down — the service picker grouped by category, the Updates panel and saved logins](docs/screenshots/services.png)
19
+
13
20
  ![A Gmail account open in the app, with back / forward / reload / dashboard and the address bar in the strip](docs/screenshots/navigation.png)
14
21
 
15
22
  <sub>Screenshots use a demo profile with placeholder account names.</sub>
@@ -39,14 +46,14 @@ Start Menu and Desktop shortcuts. Your accounts, sessions and saved logins live
39
46
 
40
47
  Three ways, all ending in the same place:
41
48
 
42
- - **Inside the app.** The version is always shown bottom-left in the rail. When a newer release
43
- exists it turns into an **Update x.y.z** button; click it to open the Updates panel on Home, which
44
- shows the release notes and offers **Download** and **Restart & install** with progress. The app
45
- checks quietly on startup and once an hour after that. Nothing is downloaded or installed until you
46
- 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.
47
54
  - **From the command line.** `npx my-provider-dash-manager` (or `mpdm update` if installed globally)
48
- installs the newest release over the current one. Close the app first, or the running copy keeps
49
- 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.
50
57
  - **From the release page.** Run the newest installer; it upgrades in place.
51
58
 
52
59
  The repository is public, so updates need no token or account.
@@ -65,7 +72,7 @@ and it is also available as `mpdm`:
65
72
  | `… where` | Print the install and data paths |
66
73
  | `… uninstall` | Run the uninstaller (accounts and sessions are kept) |
67
74
 
68
- 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`.
69
76
  From a checkout of this repository the equivalent is `npm run install:latest`.
70
77
 
71
78
  ### Run from source
@@ -182,10 +189,13 @@ The token field says which credential each service expects. Tokens are validated
182
189
  encrypted with DPAPI, revocable in one click, and never leave the main process.
183
190
 
184
191
  ### Updates
185
- - Version always visible in the rail; an **Update** button appears when a newer release exists.
186
- - Updates panel on Home: installed vs latest, release notes, Check / Download / Restart & install with
187
- progress. Nothing installs itself.
188
- - 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.
189
199
 
190
200
  ### Content
191
201
  - **Ad-blocking** driven by EasyList (~52,000 blocked hosts plus generic cosmetic rules, refreshed
@@ -241,7 +251,7 @@ npm run smoke:restore # sessions survive a restart (real cookies)
241
251
  npm run smoke:tokens # DPAPI round-trip + live fake-token rejection per provider (15)
242
252
  npm run smoke:creds # import, per-account recall, encryption at rest (7)
243
253
  npm run smoke:autofill # real page: form detection, fill, capture, origin guard (10)
244
- 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)
245
255
  npm run smoke:services # every built-in login page loads inside an isolated partition (42)
246
256
  npm run capture # screenshot the running shell (--capture-out, --capture-open svc::id, --capture-js)
247
257
  npm run spike # memory benchmark
@@ -251,7 +261,7 @@ npm start -- --print-paths # show the app name, version and data fold
251
261
  npm start -- --open vercel::personal # open an account on launch
252
262
  ```
253
263
 
254
- 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
255
265
  profile.
256
266
 
257
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.2",
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;