@suveren/gateway 0.13.1 → 0.14.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.
@@ -14,7 +14,7 @@
14
14
  <meta name="apple-mobile-web-app-title" content="Suveren" />
15
15
  <meta name="theme-color" content="#111111" />
16
16
  <title>Suveren</title>
17
- <script type="module" crossorigin src="/assets/index-CmLqzgqA.js"></script>
17
+ <script type="module" crossorigin src="/assets/index-Cg6VaGKb.js"></script>
18
18
  <link rel="stylesheet" crossorigin href="/assets/index-y1OFeYnS.css">
19
19
  </head>
20
20
  <body>
@@ -146,8 +146,14 @@ WantedBy=default.target
146
146
  * carry paths containing spaces.
147
147
  *
148
148
  * LogonType=InteractiveToken keeps it in the user's own session with no stored
149
- * password and no admin rights. Hidden + no execution time limit stop it
150
- * flashing a console window or being killed after the default 72 hours.
149
+ * password and no admin rights. No execution time limit stops it being killed
150
+ * after the default 72 hours. `<Hidden>` only hides the task in the Task
151
+ * Scheduler UI — it does NOT hide the console window: a console program
152
+ * (node.exe, or the installer's launcher.cmd) started by an InteractiveToken
153
+ * task gets a visible console for the gateway's whole lifetime (seen on a real
154
+ * Windows 11 VM; closing it stops the gateway). So the action always runs
155
+ * through `conhost.exe --headless`, Windows' own console host without a
156
+ * window; the real command and its arguments follow it.
151
157
  *
152
158
  * `userId` is what makes it unprivileged, and leaving it out is not a cosmetic
153
159
  * omission: a LogonTrigger with no UserId means "at ANY user's logon", which
@@ -167,9 +173,8 @@ WantedBy=default.target
167
173
  * into offline+managed mode too. Routing the scheduled task through the
168
174
  * launcher instead keeps that env scoped to just this one process tree: the
169
175
  * launcher sets it for its own child (server.js) only. Omitted (the npm/dev
170
- * CLI's `service install`, which has no launcher), this renders BYTE-
171
- * IDENTICAL XML to before — this is additive, not a behaviour change for
172
- * any install that isn't the managed Windows one.
176
+ * CLI's `service install`, which has no launcher), the default node.exe
177
+ * action is used. Either way it is wrapped in conhost.exe --headless.
173
178
  */
174
179
  export function buildWindowsTaskXml({ nodePath, serverEntry, author, dataDir, userId, command, args: argsOverride }) {
175
180
  // Task Scheduler requires \Command to be the executable and \Arguments the
@@ -177,8 +182,11 @@ export function buildWindowsTaskXml({ nodePath, serverEntry, author, dataDir, us
177
182
  // Task Scheduler XML carries no environment block, so the marker that this
178
183
  // was a service start has to ride in the arguments (or, for a launcher
179
184
  // command, is the launcher's own job to pass through).
180
- const resolvedCommand = command ?? nodePath;
181
- const args = argsOverride ?? `"${serverEntry}" --autostart`;
185
+ const realCommand = command ?? nodePath;
186
+ const realArgs = argsOverride ?? `"${serverEntry}" --autostart`;
187
+ // No visible console window (see above): conhost.exe --headless "<real command>" <args>.
188
+ const resolvedCommand = '%SystemRoot%\\System32\\conhost.exe';
189
+ const args = `--headless "${realCommand}" ${realArgs}`;
182
190
  const envNote = dataDir ? `Suveren data directory: ${dataDir}` : 'Suveren gateway';
183
191
 
184
192
  // Element order is fixed by the Task Scheduler XSD, and schtasks rejects the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@suveren/gateway",
3
- "version": "0.13.1",
3
+ "version": "0.14.0",
4
4
  "description": "Suveren gateway — local agent gateway built in compliance with the Human Agency Protocol (HAP). Runs the UI, control plane, and MCP server in one Node process.",
5
5
  "type": "module",
6
6
  "main": "server.js",
package/server.js CHANGED
@@ -95,7 +95,7 @@ if (savedCaFile && !process.env.SUVEREN_CA_REEXEC_DONE) {
95
95
  const child = spawn(
96
96
  process.execPath,
97
97
  [THIS_FILE, ...process.argv.slice(2)],
98
- { env: { ...process.env, NODE_EXTRA_CA_CERTS: effectiveCaFile, SUVEREN_CA_REEXEC_DONE: '1' }, stdio: 'inherit' },
98
+ { env: { ...process.env, NODE_EXTRA_CA_CERTS: effectiveCaFile, SUVEREN_CA_REEXEC_DONE: '1' }, stdio: 'inherit', windowsHide: true },
99
99
  );
100
100
  child.on('exit', (code, signal) => {
101
101
  if (combinedDirToClean) {
@@ -206,13 +206,16 @@ const env = {
206
206
  const cp = spawn(
207
207
  process.execPath,
208
208
  [join(__dirname, 'dist', 'control-plane', 'index.mjs')],
209
- { env, stdio: 'inherit' },
209
+ // windowsHide: on Windows 11 ARM (x64 emulation) these children otherwise got
210
+ // their own visible console windows even under a hidden parent — seen in CI
211
+ // and in a real ARM VM. No effect on macOS/Linux; output still goes to stdio.
212
+ { env, stdio: 'inherit', windowsHide: true },
210
213
  );
211
214
 
212
215
  const mcp = spawn(
213
216
  process.execPath,
214
217
  [join(__dirname, 'dist', 'mcp-server', 'http.mjs')],
215
- { env, stdio: 'inherit' },
218
+ { env, stdio: 'inherit', windowsHide: true },
216
219
  );
217
220
 
218
221
  const children = [