dsh-autorestart 0.3.4 → 0.3.5

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.
Files changed (2) hide show
  1. package/lib/restart.js +34 -2
  2. package/package.json +1 -1
package/lib/restart.js CHANGED
@@ -100,6 +100,38 @@ export function detectEnvironment({
100
100
  * }} [options]
101
101
  * @returns {string}
102
102
  */
103
+ /**
104
+ * The command that relaunches the host WITHOUT letting it inherit the helper's
105
+ * console.
106
+ *
107
+ * Launching the app with `start "" "<exe>"` attached it to the detached helper's
108
+ * console, and Windows delivers `CTRL_CLOSE_EVENT` to every process attached to a
109
+ * console when that console closes: closing the helper window (or the window going
110
+ * away) therefore killed DSH itself. A hidden PowerShell `Start-Process` goes
111
+ * through ShellExecute instead, so the relaunched host is a console-free process and
112
+ * the helper window can close without touching it.
113
+ *
114
+ * @param {string} exe
115
+ * @returns {string}
116
+ */
117
+ export function relaunchCommandLine(exe) {
118
+ const target = psSingle(typeof exe === 'string' ? exe : '');
119
+ return "start \"\" powershell.exe -WindowStyle Hidden -NoProfile -Command Start-Process -FilePath '"
120
+ + target
121
+ + "'";
122
+ }
123
+
124
+ /**
125
+ * Build the Windows one-liner the detached scheduler runs when no idle-gate script
126
+ * is used: wait, kill, relaunch.
127
+ *
128
+ * @param {{
129
+ * appExePath?: string|null,
130
+ * relaunchDelaySeconds?: number,
131
+ * taskkillImageName?: string,
132
+ * }} [options]
133
+ * @returns {string}
134
+ */
103
135
  export function buildRestartCommand({
104
136
  appExePath = null,
105
137
  relaunchDelaySeconds = DEFAULT_RELAUNCH_DELAY_SECONDS,
@@ -113,7 +145,7 @@ export function buildRestartCommand({
113
145
  const exe = typeof appExePath === 'string' ? appExePath : '';
114
146
  // `ping -n N` where N = seconds + 1: one packet is sent immediately, so a
115
147
  // 4-second delay needs 5 pings. `>nul` keeps the detached console silent.
116
- return `cmd.exe /c ping -n ${seconds + 1} 127.0.0.1 >nul & taskkill /IM "${image}" /T /F & start "" "${exe}"`;
148
+ return `cmd.exe /c ping -n ${seconds + 1} 127.0.0.1 >nul & taskkill /IM "${image}" /T /F & ${relaunchCommandLine(exe)}`;
117
149
  }
118
150
 
119
151
  /**
@@ -181,7 +213,7 @@ export function buildGateScript({
181
213
  'if errorlevel 1 exit /b 0',
182
214
  'taskkill /IM "' + image + '" /T /F',
183
215
  'ping -n 3 127.0.0.1 >nul',
184
- 'start "" "' + exe + '"',
216
+ relaunchCommandLine(exe),
185
217
  ];
186
218
  if (watch !== null) {
187
219
  lines.push('rem dsh-autorestart: wait for the host to come back; roll the backup back when it does not.');
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-autorestart",
3
- "version": "0.3.4",
3
+ "version": "0.3.5",
4
4
  "type": "module",
5
5
  "description": "DeepSeek Harness plugin: restart without losing work. Waits until every conversation is idle, restarts the host, then automatically resumes the interrupted sessions. AI-generated, not human-reviewed: use with caution.",
6
6
  "license": "MIT",