@suveren/gateway 0.7.1 → 0.7.2

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.
@@ -323,8 +323,14 @@ function serviceRunning() {
323
323
  return p.status === 0 && /state = running/.test(p.stdout || '');
324
324
  }
325
325
  if (os === 'win32') {
326
- const p = runQuiet('schtasks', ['/Query', '/TN', WIN_TASK_NAME, '/FO', 'LIST']);
327
- return p.status === 0 && /Status:\s+Running/i.test(p.stdout || '');
326
+ // NOT schtasks /Query: its LIST output is localized — a German Windows
327
+ // prints "Wird ausgeführt", so matching the English word "Running" reports
328
+ // every non-English machine as stopped, and restart silently falls back to
329
+ // the manual path. Get-ScheduledTask's State is a .NET enum; its name is
330
+ // English on every locale.
331
+ const p = runQuiet('powershell', ['-NoProfile', '-NonInteractive', '-Command',
332
+ `(Get-ScheduledTask -TaskName '${WIN_TASK_NAME}' -ErrorAction Stop).State`]);
333
+ return p.status === 0 && /^Running/m.test((p.stdout || '').trim());
328
334
  }
329
335
  const p = runQuiet('systemctl', ['--user', 'is-active', SYSTEMD_UNIT]);
330
336
  return (p.stdout || '').trim() === 'active';
@@ -344,7 +350,16 @@ function serviceRestart() {
344
350
  if (os === 'darwin') {
345
351
  runQuiet('launchctl', ['kickstart', '-k', `gui/${process.getuid()}/${LAUNCH_AGENT_LABEL}`]);
346
352
  } else if (os === 'win32') {
347
- runQuiet('schtasks', ['/End', '/TN', WIN_TASK_NAME]);
353
+ // NOT schtasks /End: it TerminateProcess()es only the task's ROOT process
354
+ // (node server.js). No signal is delivered, so the shutdown handlers never
355
+ // run and the control-plane / MCP children survive — still holding ports
356
+ // 3400/3430, which makes the relaunched instance die on EADDRINUSE and
357
+ // "restart" quietly become "stop". taskkill /T takes the whole tree.
358
+ const like = SERVER_ENTRY.replace(/'/g, "''").replace(/([\[\]*?])/g, '`$1');
359
+ runQuiet('powershell', ['-NoProfile', '-NonInteractive', '-Command',
360
+ `Get-CimInstance Win32_Process -Filter "Name='node.exe'" | ` +
361
+ `Where-Object { $_.CommandLine -like '*${like}*' } | ` +
362
+ `ForEach-Object { taskkill.exe /PID $_.ProcessId /T /F } | Out-Null`]);
348
363
  runQuiet('schtasks', ['/Run', '/TN', WIN_TASK_NAME]);
349
364
  } else {
350
365
  runQuiet('systemctl', ['--user', 'restart', SYSTEMD_UNIT]);
@@ -573,8 +588,12 @@ async function serviceStatusWindows() {
573
588
  console.log(`Login service: ${installed ? 'installed' : 'not installed'}`);
574
589
  if (installed) {
575
590
  console.log(` Task: ${WIN_TASK_NAME}`);
576
- const state = /Status:\s*(\S+)/.exec(r.stdout || '');
577
- if (state) console.log(` State: ${state[1]}`);
591
+ // Locale-independent state (see serviceRunning): the schtasks LIST value
592
+ // is localized; the PowerShell enum name is not.
593
+ const st = runQuiet('powershell', ['-NoProfile', '-NonInteractive', '-Command',
594
+ `(Get-ScheduledTask -TaskName '${WIN_TASK_NAME}' -ErrorAction Stop).State`]);
595
+ const state = (st.stdout || '').trim();
596
+ if (st.status === 0 && state) console.log(` State: ${state}`);
578
597
  }
579
598
  }
580
599
 
@@ -5,9 +5,9 @@ import {
5
5
 
6
6
  // src/index.ts
7
7
  import { randomBytes as randomBytes2 } from "crypto";
8
- import { existsSync as existsSync5, readFileSync as readFileSync5, renameSync } from "fs";
9
- import { dirname as dirname4, join as join5 } from "path";
10
- import { homedir as homedir4 } from "os";
8
+ import { existsSync as existsSync6, readFileSync as readFileSync5, renameSync } from "fs";
9
+ import { dirname as dirname5, join as join6 } from "path";
10
+ import { homedir as homedir5 } from "os";
11
11
  import express from "express";
12
12
  import { createProxyMiddleware } from "http-proxy-middleware";
13
13
 
@@ -1540,15 +1540,15 @@ import { promisify } from "util";
1540
1540
  var run = promisify(execFile);
1541
1541
  var SUPPORTED = /* @__PURE__ */ new Set(["darwin", "win32", "linux"]);
1542
1542
  var MODULE_DIR = pathDirname(fileURLToPath(import.meta.url));
1543
- function findCli(dirname5 = MODULE_DIR) {
1543
+ function findCli(dirname6 = MODULE_DIR) {
1544
1544
  const candidates = [
1545
1545
  // Bundled (the shipped layout): dist/control-plane → dist → root → bin
1546
- resolve(dirname5, "..", "..", "bin", "suveren-gateway.js"),
1546
+ resolve(dirname6, "..", "..", "bin", "suveren-gateway.js"),
1547
1547
  // Bundled, were the routes/ directory ever preserved.
1548
- resolve(dirname5, "..", "..", "..", "bin", "suveren-gateway.js"),
1548
+ resolve(dirname6, "..", "..", "..", "bin", "suveren-gateway.js"),
1549
1549
  // Dev, running from source: the repo's own bundle directory.
1550
- resolve(dirname5, "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js"),
1551
- resolve(dirname5, "..", "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js")
1550
+ resolve(dirname6, "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js"),
1551
+ resolve(dirname6, "..", "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js")
1552
1552
  // Deliberately NO process.cwd() fallback: it makes the result depend on
1553
1553
  // where the process happened to be launched from, so the same install
1554
1554
  // resolves differently between a shell and a login service — and it would
@@ -1633,38 +1633,86 @@ function createAutostartRouter() {
1633
1633
 
1634
1634
  // src/lib/desktop-notify.ts
1635
1635
  import { spawn, spawnSync } from "child_process";
1636
+
1637
+ // src/lib/notifier-icon.ts
1638
+ import { writeFileSync as writeFileSync2, mkdirSync as mkdirSync2, existsSync as existsSync3 } from "fs";
1639
+ import { homedir as homedir2 } from "os";
1640
+ import { join as join2, dirname as dirname2 } from "path";
1641
+ var ICON_BASE64 = "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";
1642
+ function ensureNotifierIcon(dataDir) {
1643
+ try {
1644
+ const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join2(homedir2(), ".suveren");
1645
+ const path = join2(dir, "notifier-icon.png");
1646
+ if (!existsSync3(path)) {
1647
+ mkdirSync2(dirname2(path), { recursive: true });
1648
+ writeFileSync2(path, Buffer.from(ICON_BASE64, "base64"));
1649
+ }
1650
+ return path;
1651
+ } catch {
1652
+ return null;
1653
+ }
1654
+ }
1655
+
1656
+ // src/lib/desktop-notify.ts
1636
1657
  function osaQuote(value) {
1637
1658
  return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
1638
1659
  }
1639
1660
  function psQuote(value) {
1640
1661
  return `'${value.replace(/'/g, "''")}'`;
1641
1662
  }
1663
+ function xmlEscape(value) {
1664
+ return value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&apos;");
1665
+ }
1666
+ var WINDOWS_AUMID = "Suveren.Gateway";
1667
+ function windowsToastScript(title, message, url, iconPath) {
1668
+ const toastXml = `<toast${url ? ` activationType="protocol" launch="${xmlEscape(url)}"` : ""}><visual><binding template="ToastGeneric"><text>${xmlEscape(title)}</text><text>${xmlEscape(message)}</text>` + (iconPath ? `<image placement="appLogoOverride" src="${xmlEscape(iconPath)}"/>` : "") + `</binding></visual><audio src="ms-winsoundevent:Notification.Default"/></toast>`;
1669
+ return `$ErrorActionPreference='SilentlyContinue'; $aumid=${psQuote(WINDOWS_AUMID)}; $reg="HKCU:\\Software\\Classes\\AppUserModelId\\$aumid"; if (-not (Test-Path $reg)) { New-Item -Path $reg -Force | Out-Null }; New-ItemProperty -Path $reg -Name DisplayName -Value 'Suveren' -PropertyType String -Force | Out-Null; ` + (iconPath ? `New-ItemProperty -Path $reg -Name IconUri -Value ${psQuote(iconPath)} -PropertyType String -Force | Out-Null; ` : "") + `[Windows.UI.Notifications.ToastNotificationManager, Windows.UI.Notifications, ContentType=WindowsRuntime] | Out-Null; [Windows.Data.Xml.Dom.XmlDocument, Windows.Data.Xml.Dom, ContentType=WindowsRuntime] | Out-Null; $doc = New-Object Windows.Data.Xml.Dom.XmlDocument; $doc.LoadXml(${psQuote(toastXml)}); $toast = New-Object Windows.UI.Notifications.ToastNotification $doc; [Windows.UI.Notifications.ToastNotificationManager]::CreateToastNotifier($aumid).Show($toast)`;
1670
+ }
1671
+ var MAC_SOUND = "Glass";
1642
1672
  function buildNotifyCommand(platform, title, message, options = {}) {
1643
- const { url, hasTerminalNotifier: hasTerminalNotifier2 = false } = options;
1673
+ const { url, hasTerminalNotifier: hasTerminalNotifier2 = false, iconPath } = options;
1644
1674
  switch (platform) {
1645
1675
  case "darwin":
1646
1676
  if (url && hasTerminalNotifier2) {
1647
1677
  return {
1648
1678
  cmd: "terminal-notifier",
1649
- args: ["-title", title, "-message", message, "-open", url, "-group", "ai.suveren.gateway"]
1679
+ args: [
1680
+ "-title",
1681
+ title,
1682
+ "-message",
1683
+ message,
1684
+ "-open",
1685
+ url,
1686
+ "-sound",
1687
+ MAC_SOUND,
1688
+ ...iconPath ? ["-appIcon", iconPath] : [],
1689
+ "-group",
1690
+ "ai.suveren.gateway"
1691
+ ]
1650
1692
  };
1651
1693
  }
1652
1694
  return {
1653
1695
  cmd: "osascript",
1654
- args: ["-e", `display notification ${osaQuote(message)} with title ${osaQuote(title)}`]
1696
+ args: [
1697
+ "-e",
1698
+ `display notification ${osaQuote(message)} with title ${osaQuote(title)} sound name ${osaQuote(MAC_SOUND)}`
1699
+ ]
1655
1700
  };
1656
1701
  case "win32":
1657
1702
  return {
1658
1703
  cmd: "powershell",
1704
+ args: ["-NoProfile", "-NonInteractive", "-Command", windowsToastScript(title, message, url, iconPath)]
1705
+ };
1706
+ case "linux":
1707
+ return {
1708
+ cmd: "notify-send",
1659
1709
  args: [
1660
- "-NoProfile",
1661
- "-NonInteractive",
1662
- "-Command",
1663
- `Add-Type -AssemblyName System.Windows.Forms; $n = New-Object System.Windows.Forms.NotifyIcon; $n.Icon = [System.Drawing.SystemIcons]::Information; $n.BalloonTipTitle = ${psQuote(title)}; $n.BalloonTipText = ${psQuote(message)}; $n.Visible = $true; $n.ShowBalloonTip(15000); Start-Sleep -Seconds 16; $n.Dispose()`
1710
+ "--app-name=Suveren",
1711
+ ...iconPath ? ["-i", iconPath] : [],
1712
+ title,
1713
+ message
1664
1714
  ]
1665
1715
  };
1666
- case "linux":
1667
- return { cmd: "notify-send", args: ["--app-name=Suveren", title, message] };
1668
1716
  default:
1669
1717
  return null;
1670
1718
  }
@@ -1688,15 +1736,32 @@ function hasTerminalNotifier() {
1688
1736
  }
1689
1737
  return terminalNotifierCache;
1690
1738
  }
1739
+ function notifySpawnOptions(platform) {
1740
+ return {
1741
+ detached: platform !== "win32",
1742
+ stdio: ["ignore", "ignore", "pipe"]
1743
+ };
1744
+ }
1691
1745
  function notify(title, message, platform = process.platform, url) {
1692
1746
  const command = buildNotifyCommand(platform, title, message, {
1693
1747
  url,
1694
- // Only probe when a URL could actually be attached.
1695
- hasTerminalNotifier: url !== void 0 && platform === "darwin" ? hasTerminalNotifier() : false
1748
+ hasTerminalNotifier: platform === "darwin" ? hasTerminalNotifier() : false,
1749
+ // Windows and Linux show it on the toast itself; macOS only via
1750
+ // terminal-notifier. Failure to write it must never block the sound.
1751
+ iconPath: ensureNotifierIcon()
1696
1752
  });
1697
1753
  if (!command) return;
1698
1754
  try {
1699
- const child = spawn(command.cmd, command.args, { detached: true, stdio: "ignore" });
1755
+ const child = spawn(command.cmd, command.args, notifySpawnOptions(platform));
1756
+ let stderr = "";
1757
+ child.stderr?.on("data", (d) => {
1758
+ stderr += d.toString().slice(0, 500);
1759
+ });
1760
+ child.on("close", (code) => {
1761
+ if (code !== 0) {
1762
+ console.error(`[notify] ${command.cmd} exited ${code}${stderr ? `: ${stderr.trim()}` : ""}`);
1763
+ }
1764
+ });
1700
1765
  child.on("error", () => {
1701
1766
  });
1702
1767
  child.unref();
@@ -1812,13 +1877,13 @@ function createDecryptIntentRouter(vault2) {
1812
1877
 
1813
1878
  // src/routes/approved-intents.ts
1814
1879
  import { Router as Router9 } from "express";
1815
- import { readFileSync as readFileSync2, writeFileSync as writeFileSync2, existsSync as existsSync3, mkdirSync as mkdirSync2 } from "fs";
1816
- import { homedir as homedir2 } from "os";
1817
- import { join as join2 } from "path";
1818
- var SUVEREN_DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join2(homedir2(), ".suveren");
1819
- var FILE_PATH = join2(SUVEREN_DATA_DIR, "approved-intents.enc.json");
1880
+ import { readFileSync as readFileSync2, writeFileSync as writeFileSync3, existsSync as existsSync4, mkdirSync as mkdirSync3 } from "fs";
1881
+ import { homedir as homedir3 } from "os";
1882
+ import { join as join3 } from "path";
1883
+ var SUVEREN_DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join3(homedir3(), ".suveren");
1884
+ var FILE_PATH = join3(SUVEREN_DATA_DIR, "approved-intents.enc.json");
1820
1885
  function readFile() {
1821
- if (!existsSync3(FILE_PATH)) {
1886
+ if (!existsSync4(FILE_PATH)) {
1822
1887
  return { version: 1, entries: {} };
1823
1888
  }
1824
1889
  try {
@@ -1828,8 +1893,8 @@ function readFile() {
1828
1893
  }
1829
1894
  }
1830
1895
  function writeFile(data) {
1831
- mkdirSync2(SUVEREN_DATA_DIR, { recursive: true });
1832
- writeFileSync2(FILE_PATH, JSON.stringify(data, null, 2), "utf-8");
1896
+ mkdirSync3(SUVEREN_DATA_DIR, { recursive: true });
1897
+ writeFileSync3(FILE_PATH, JSON.stringify(data, null, 2), "utf-8");
1833
1898
  }
1834
1899
  function createApprovedIntentsRouter(vault2) {
1835
1900
  const router = Router9();
@@ -1875,7 +1940,7 @@ function createApprovedIntentsRouter(vault2) {
1875
1940
 
1876
1941
  // src/lib/update-checker.ts
1877
1942
  import { execSync } from "child_process";
1878
- import { dirname as dirname2 } from "path";
1943
+ import { dirname as dirname3 } from "path";
1879
1944
  import { fileURLToPath as fileURLToPath2 } from "url";
1880
1945
  var GHCR_IMAGE = "suverenai/suveren-gateway";
1881
1946
  var NPM_PACKAGE = "@suveren/gateway";
@@ -1941,7 +2006,7 @@ function compareSemver(a, b) {
1941
2006
  return 0;
1942
2007
  }
1943
2008
  function checkDev() {
1944
- const cwd = dirname2(fileURLToPath2(import.meta.url));
2009
+ const cwd = dirname3(fileURLToPath2(import.meta.url));
1945
2010
  try {
1946
2011
  execSync("git fetch origin --quiet", { cwd, stdio: "ignore", timeout: 15e3 });
1947
2012
  const out = execSync("git rev-list HEAD..origin/main --count", {
@@ -2012,15 +2077,15 @@ data: null
2012
2077
  import { Router as Router10 } from "express";
2013
2078
 
2014
2079
  // src/lib/gateway-settings.ts
2015
- import { readFileSync as readFileSync3, writeFileSync as writeFileSync3, mkdirSync as mkdirSync3 } from "fs";
2016
- import { homedir as homedir3 } from "os";
2017
- import { join as join3, dirname as dirname3 } from "path";
2080
+ import { readFileSync as readFileSync3, writeFileSync as writeFileSync4, mkdirSync as mkdirSync4 } from "fs";
2081
+ import { homedir as homedir4 } from "os";
2082
+ import { join as join4, dirname as dirname4 } from "path";
2018
2083
  var DEFAULT_SETTINGS = {
2019
2084
  desktopNotifications: true
2020
2085
  };
2021
2086
  function settingsPath(dataDir) {
2022
- const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join3(homedir3(), ".suveren");
2023
- return join3(dir, "settings.json");
2087
+ const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join4(homedir4(), ".suveren");
2088
+ return join4(dir, "settings.json");
2024
2089
  }
2025
2090
  function readSettings(dataDir) {
2026
2091
  try {
@@ -2038,8 +2103,8 @@ function writeSettings(patch, dataDir) {
2038
2103
  ...typeof patch.desktopNotifications === "boolean" ? { desktopNotifications: patch.desktopNotifications } : {}
2039
2104
  };
2040
2105
  const path = settingsPath(dataDir);
2041
- mkdirSync3(dirname3(path), { recursive: true });
2042
- writeFileSync3(path, JSON.stringify(next, null, 2) + "\n", "utf8");
2106
+ mkdirSync4(dirname4(path), { recursive: true });
2107
+ writeFileSync4(path, JSON.stringify(next, null, 2) + "\n", "utf8");
2043
2108
  return next;
2044
2109
  }
2045
2110
 
@@ -2184,16 +2249,16 @@ function startNotificationDispatcher(opts = {}) {
2184
2249
  }
2185
2250
 
2186
2251
  // src/lib/denials-reader.ts
2187
- import { existsSync as existsSync4, readFileSync as readFileSync4 } from "fs";
2188
- import { join as join4 } from "path";
2252
+ import { existsSync as existsSync5, readFileSync as readFileSync4 } from "fs";
2253
+ import { join as join5 } from "path";
2189
2254
  function loadDenials(dataDir, decrypt) {
2190
- const encPath = join4(dataDir, "denials.enc.json");
2191
- const plainPath = join4(dataDir, "denials.json");
2192
- if (existsSync4(encPath)) {
2255
+ const encPath = join5(dataDir, "denials.enc.json");
2256
+ const plainPath = join5(dataDir, "denials.json");
2257
+ if (existsSync5(encPath)) {
2193
2258
  const { blob } = JSON.parse(readFileSync4(encPath, "utf-8"));
2194
2259
  return JSON.parse(decrypt(blob)).records ?? [];
2195
2260
  }
2196
- if (existsSync4(plainPath)) {
2261
+ if (existsSync5(plainPath)) {
2197
2262
  return JSON.parse(readFileSync4(plainPath, "utf-8")).records ?? [];
2198
2263
  }
2199
2264
  return [];
@@ -2209,9 +2274,9 @@ function selectDenials(records, opts = {}) {
2209
2274
  // src/index.ts
2210
2275
  (function migrateDataDir() {
2211
2276
  if (process.env.SUVEREN_DATA_DIR) return;
2212
- const oldDir = join5(homedir4(), ".hap");
2213
- const newDir = join5(homedir4(), ".suveren");
2214
- if (!existsSync5(newDir) && existsSync5(oldDir)) {
2277
+ const oldDir = join6(homedir5(), ".hap");
2278
+ const newDir = join6(homedir5(), ".suveren");
2279
+ if (!existsSync6(newDir) && existsSync6(oldDir)) {
2215
2280
  try {
2216
2281
  renameSync(oldDir, newDir);
2217
2282
  console.error(`[Control Plane] Migrated data directory: ${oldDir} \u2192 ${newDir}`);
@@ -2224,7 +2289,7 @@ function selectDenials(records, opts = {}) {
2224
2289
  var SP_URL2 = process.env.SUVEREN_AS_URL ?? "https://www.suveren.ai";
2225
2290
  var port = parseInt(process.env.SUVEREN_CP_PORT ?? "3402", 10);
2226
2291
  var HAP_MODE = process.env.HAP_MODE ?? "personal";
2227
- var UI_DIST = process.env.HAP_UI_DIST ?? join5(import.meta.dirname ?? __dirname, "../../ui/dist");
2292
+ var UI_DIST = process.env.HAP_UI_DIST ?? join6(import.meta.dirname ?? __dirname, "../../ui/dist");
2228
2293
  var vault = new Vault();
2229
2294
  var internalSecret2 = process.env.SUVEREN_INTERNAL_SECRET ?? randomBytes2(32).toString("hex");
2230
2295
  setInternalSecret(internalSecret2);
@@ -2592,7 +2657,7 @@ app.get("/active-authorizations", authGuard, async (_req, res) => {
2592
2657
  });
2593
2658
  app.get("/denials", authGuard, (req, res) => {
2594
2659
  try {
2595
- const dataDir = process.env.SUVEREN_DATA_DIR ?? join5(homedir4(), ".suveren");
2660
+ const dataDir = process.env.SUVEREN_DATA_DIR ?? join6(homedir5(), ".suveren");
2596
2661
  const all = loadDenials(dataDir, (blob) => vault.decrypt(blob));
2597
2662
  const since = Number(req.query.since);
2598
2663
  const limit = Number(req.query.limit);
@@ -2625,11 +2690,11 @@ app.post("/resync-gates", authGuard, async (_req, res) => {
2625
2690
  }
2626
2691
  });
2627
2692
  var AGENT_CONTEXT_MAX_BYTES = 16 * 1024;
2628
- var SUVEREN_DATA_DIR2 = process.env.SUVEREN_DATA_DIR ?? join5(homedir4(), ".suveren");
2693
+ var SUVEREN_DATA_DIR2 = process.env.SUVEREN_DATA_DIR ?? join6(homedir5(), ".suveren");
2629
2694
  app.get("/agent-brief/context", authGuard, async (_req, res) => {
2630
2695
  try {
2631
2696
  const { readFileSync: readFileSync6, existsSync: fileExists } = await import("fs");
2632
- const filePath = join5(SUVEREN_DATA_DIR2, "context.md");
2697
+ const filePath = join6(SUVEREN_DATA_DIR2, "context.md");
2633
2698
  if (!fileExists(filePath)) {
2634
2699
  res.json({ content: "" });
2635
2700
  return;
@@ -2652,11 +2717,11 @@ app.put("/agent-brief/context", jsonParser, authGuard, async (req, res) => {
2652
2717
  res.status(413).json({ error: `Context exceeds ${AGENT_CONTEXT_MAX_BYTES}-byte cap` });
2653
2718
  return;
2654
2719
  }
2655
- const { mkdirSync: mkdirSync4, writeFileSync: writeFileSync4, renameSync: renameSync2 } = await import("fs");
2656
- mkdirSync4(SUVEREN_DATA_DIR2, { recursive: true });
2657
- const filePath = join5(SUVEREN_DATA_DIR2, "context.md");
2720
+ const { mkdirSync: mkdirSync5, writeFileSync: writeFileSync5, renameSync: renameSync2 } = await import("fs");
2721
+ mkdirSync5(SUVEREN_DATA_DIR2, { recursive: true });
2722
+ const filePath = join6(SUVEREN_DATA_DIR2, "context.md");
2658
2723
  const tmpPath = `${filePath}.tmp`;
2659
- writeFileSync4(tmpPath, content, "utf-8");
2724
+ writeFileSync5(tmpPath, content, "utf-8");
2660
2725
  renameSync2(tmpPath, filePath);
2661
2726
  res.json({ ok: true });
2662
2727
  } catch (err) {
@@ -2706,13 +2771,13 @@ app.use(
2706
2771
  })
2707
2772
  );
2708
2773
  function detectInstallMethod() {
2709
- if (existsSync5("/.dockerenv")) return "docker";
2774
+ if (existsSync6("/.dockerenv")) return "docker";
2710
2775
  const dir = import.meta.dirname ?? __dirname;
2711
2776
  if (dir.includes("/node_modules/@suveren/gateway/")) return "npm";
2712
2777
  let cursor = dir;
2713
2778
  for (let i = 0; i < 8; i++) {
2714
- if (existsSync5(join5(cursor, ".git"))) return "dev";
2715
- const parent = dirname4(cursor);
2779
+ if (existsSync6(join6(cursor, ".git"))) return "dev";
2780
+ const parent = dirname5(cursor);
2716
2781
  if (parent === cursor) break;
2717
2782
  cursor = parent;
2718
2783
  }
@@ -2724,8 +2789,8 @@ function detectRunningVersion() {
2724
2789
  return process.env.HAP_BUILD_SHA ?? "dev";
2725
2790
  }
2726
2791
  const dir = import.meta.dirname ?? __dirname;
2727
- const bundlePkg = join5(dir, "..", "..", "package.json");
2728
- if (existsSync5(bundlePkg)) {
2792
+ const bundlePkg = join6(dir, "..", "..", "package.json");
2793
+ if (existsSync6(bundlePkg)) {
2729
2794
  try {
2730
2795
  const pkg = JSON.parse(readFileSync5(bundlePkg, "utf8"));
2731
2796
  if (pkg.name === "@suveren/gateway" && typeof pkg.version === "string") {
@@ -2755,7 +2820,7 @@ app.get("/health", async (req, res) => {
2755
2820
  }
2756
2821
  });
2757
2822
  });
2758
- if (existsSync5(UI_DIST)) {
2823
+ if (existsSync6(UI_DIST)) {
2759
2824
  app.use(express.static(UI_DIST, {
2760
2825
  setHeaders: (res, filePath) => {
2761
2826
  if (filePath.endsWith("index.html")) {
@@ -2765,7 +2830,7 @@ if (existsSync5(UI_DIST)) {
2765
2830
  }));
2766
2831
  app.get("*", (_req, res) => {
2767
2832
  res.setHeader("Cache-Control", "no-store, must-revalidate");
2768
- res.sendFile(join5(UI_DIST, "index.html"));
2833
+ res.sendFile(join6(UI_DIST, "index.html"));
2769
2834
  });
2770
2835
  } else {
2771
2836
  app.get("/", (_req, res) => {
@@ -8,7 +8,7 @@ This package contains type definitions for node (https://nodejs.org/).
8
8
  Files were exported from https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node.
9
9
 
10
10
  ### Additional Details
11
- * Last updated: Mon, 27 Jul 2026 17:32:10 GMT
11
+ * Last updated: Fri, 07 Aug 2026 17:46:44 GMT
12
12
  * Dependencies: [undici-types](https://npmjs.com/package/undici-types)
13
13
 
14
14
  # Credits
@@ -227,7 +227,6 @@ declare module "node:child_process" {
227
227
  * new process in a shell or with the use of the `shell` option of `ChildProcess`:
228
228
  *
229
229
  * ```js
230
- * 'use strict';
231
230
  * import { spawn } from 'node:child_process';
232
231
  *
233
232
  * const subprocess = spawn(
@@ -2698,12 +2698,12 @@ declare module "node:crypto" {
2698
2698
  */
2699
2699
  function sign(
2700
2700
  algorithm: string | null | undefined,
2701
- data: ArrayBufferLike | NodeJS.ArrayBufferView,
2701
+ data: BinaryLike,
2702
2702
  key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,
2703
2703
  ): NonSharedBuffer;
2704
2704
  function sign(
2705
2705
  algorithm: string | null | undefined,
2706
- data: ArrayBufferLike | NodeJS.ArrayBufferView,
2706
+ data: BinaryLike,
2707
2707
  key: KeyLike | SignKeyObjectInput | SignPrivateKeyInput | SignJsonWebKeyInput,
2708
2708
  callback: (error: Error | null, data: NonSharedBuffer) => void,
2709
2709
  ): void;
@@ -2729,15 +2729,15 @@ declare module "node:crypto" {
2729
2729
  */
2730
2730
  function verify(
2731
2731
  algorithm: string | null | undefined,
2732
- data: ArrayBufferLike | NodeJS.ArrayBufferView,
2732
+ data: BinaryLike,
2733
2733
  key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
2734
- signature: ArrayBufferLike | NodeJS.ArrayBufferView,
2734
+ signature: BinaryLike,
2735
2735
  ): boolean;
2736
2736
  function verify(
2737
2737
  algorithm: string | null | undefined,
2738
- data: ArrayBufferLike | NodeJS.ArrayBufferView,
2738
+ data: BinaryLike,
2739
2739
  key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
2740
- signature: ArrayBufferLike | NodeJS.ArrayBufferView,
2740
+ signature: BinaryLike,
2741
2741
  callback: (error: Error | null, result: boolean) => void,
2742
2742
  ): void;
2743
2743
  /**
@@ -183,7 +183,7 @@ declare module "node:dns/promises" {
183
183
  * refresh: 900,
184
184
  * retry: 900,
185
185
  * expire: 1800,
186
- * minttl: 60 } ]
186
+ * minttl: 60 } ];
187
187
  * ```
188
188
  * @since v10.6.0
189
189
  */
@@ -226,7 +226,7 @@ declare module "node:dns/promises" {
226
226
  * regexp: '',
227
227
  * replacement: '_sip._udp.example.com',
228
228
  * order: 30,
229
- * preference: 100
229
+ * preference: 100,
230
230
  * }
231
231
  * ```
232
232
  * @since v10.6.0
@@ -265,7 +265,7 @@ declare module "node:dns/promises" {
265
265
  * refresh: 10000,
266
266
  * retry: 2400,
267
267
  * expire: 604800,
268
- * minttl: 3600
268
+ * minttl: 3600,
269
269
  * }
270
270
  * ```
271
271
  * @since v10.6.0
@@ -285,7 +285,7 @@ declare module "node:dns/promises" {
285
285
  * priority: 10,
286
286
  * weight: 5,
287
287
  * port: 21223,
288
- * name: 'service.example.com'
288
+ * name: 'service.example.com',
289
289
  * }
290
290
  * ```
291
291
  * @since v10.6.0
@@ -306,7 +306,7 @@ declare module "node:dns/promises" {
306
306
  * certUsage: 3,
307
307
  * selector: 1,
308
308
  * match: 1,
309
- * data: [ArrayBuffer]
309
+ * data: [ArrayBuffer],
310
310
  * }
311
311
  * ```
312
312
  * @since v23.9.0, v22.15.0
@@ -490,7 +490,7 @@ declare module "node:dns" {
490
490
  * regexp: '',
491
491
  * replacement: '_sip._udp.example.com',
492
492
  * order: 30,
493
- * preference: 100
493
+ * preference: 100,
494
494
  * }
495
495
  * ```
496
496
  * @since v0.9.12
@@ -547,7 +547,7 @@ declare module "node:dns" {
547
547
  * refresh: 10000,
548
548
  * retry: 2400,
549
549
  * expire: 604800,
550
- * minttl: 3600
550
+ * minttl: 3600,
551
551
  * }
552
552
  * ```
553
553
  * @since v0.11.10
@@ -573,7 +573,7 @@ declare module "node:dns" {
573
573
  * priority: 10,
574
574
  * weight: 5,
575
575
  * port: 21223,
576
- * name: 'service.example.com'
576
+ * name: 'service.example.com',
577
577
  * }
578
578
  * ```
579
579
  * @since v0.1.27
@@ -600,7 +600,7 @@ declare module "node:dns" {
600
600
  * certUsage: 3,
601
601
  * selector: 1,
602
602
  * match: 1,
603
- * data: [ArrayBuffer]
603
+ * data: [ArrayBuffer],
604
604
  * }
605
605
  * ```
606
606
  * @since v23.9.0, v22.15.0
@@ -650,7 +650,7 @@ declare module "node:dns" {
650
650
  * refresh: 900,
651
651
  * retry: 900,
652
652
  * expire: 1800,
653
- * minttl: 60 } ]
653
+ * minttl: 60 } ];
654
654
  * ```
655
655
  *
656
656
  * DNS server operators may choose not to respond to `ANY` queries. It may be better to call individual methods like {@link resolve4}, {@link resolveMx}, and so on. For more details, see
@@ -48,6 +48,13 @@ declare module "node:fs" {
48
48
  mtime: Date;
49
49
  ctime: Date;
50
50
  birthtime: Date;
51
+ // Deliberately not defining a type alias here... it'd be exported, and something in the ecosystem would inevitably start using it.
52
+ // TODO: replace with Temporal builtins once @types/node no longer supports TS <6.0.
53
+ atimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T : unknown;
54
+ mtimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T : unknown;
55
+ ctimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T : unknown;
56
+ birthtimeInstant: typeof globalThis extends { Temporal: { Instant: new(...args: any[]) => infer T } } ? T
57
+ : unknown;
51
58
  }
52
59
  interface Stats extends StatsBase<number> {}
53
60
  /**
@@ -922,6 +922,36 @@ declare module "node:http" {
922
922
  headers?: OutgoingHttpHeaders | OutgoingHttpHeader[],
923
923
  ): this;
924
924
  writeHead(statusCode: number, headers?: OutgoingHttpHeaders | OutgoingHttpHeader[]): this;
925
+ /**
926
+ * Sends an arbitrary HTTP/1.1 1xx informational response to the client. This
927
+ * is a generic equivalent of `response.writeContinue()`,
928
+ * `response.writeProcessing()` and `response.writeEarlyHints()`, and
929
+ * can be called multiple times before the final response. After the final
930
+ * response headers have been sent (via `response.writeHead()` or an
931
+ * implicit header), calling this method throws `ERR_HTTP_HEADERS_SENT`.
932
+ *
933
+ * Clients receive these responses via the [`'information'`](https://nodejs.org/docs/latest-v26.x/api/http.html#event-information)
934
+ * event on `http.ClientRequest`.
935
+ *
936
+ * ```js
937
+ * response.writeInformation(110, { 'X-Progress': '50%' });
938
+ * ```
939
+ * @since v26.2.0
940
+ * @param statusCode An HTTP 1xx informational status code, between `100`
941
+ * and `199` inclusive, excluding `101` (Switching Protocols) which is only
942
+ * available through the [`'upgrade'`](https://nodejs.org/docs/latest-v26.x/api/http.html#event-upgrade) event.
943
+ * @param headers An optional set of headers to send with the
944
+ * informational response. Accepts the same shapes as
945
+ * `response.writeHead()`.
946
+ * @param callback Optional, called once the message has been written
947
+ * to the socket.
948
+ */
949
+ writeInformation(
950
+ statusCode: number,
951
+ headers?: OutgoingHttpHeaders | readonly string[],
952
+ callback?: () => void,
953
+ ): void;
954
+ writeInformation(statusCode: number, callback: () => void): void;
925
955
  /**
926
956
  * Sends a HTTP/1.1 102 Processing message to the client, indicating that
927
957
  * the request body should be sent.