@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.
- package/bin/suveren-gateway.js +24 -5
- package/dist/control-plane/index.mjs +126 -61
- package/node_modules/@types/node/README.md +1 -1
- package/node_modules/@types/node/child_process.d.ts +0 -1
- package/node_modules/@types/node/crypto.d.ts +6 -6
- package/node_modules/@types/node/dns/promises.d.ts +5 -5
- package/node_modules/@types/node/dns.d.ts +5 -5
- package/node_modules/@types/node/fs.d.ts +7 -0
- package/node_modules/@types/node/http.d.ts +30 -0
- package/node_modules/@types/node/http2.d.ts +4 -4
- package/node_modules/@types/node/os.d.ts +30 -30
- package/node_modules/@types/node/package.json +2 -2
- package/node_modules/@types/node/perf_hooks.d.ts +2 -1
- package/node_modules/@types/node/process.d.ts +42 -43
- package/node_modules/@types/node/quic.d.ts +1049 -84
- package/node_modules/@types/node/sqlite.d.ts +14 -1
- package/node_modules/@types/node/stream/iter.d.ts +3 -2
- package/node_modules/@types/node/test.d.ts +61 -0
- package/node_modules/@types/node/v8.d.ts +20 -23
- package/package.json +1 -1
package/bin/suveren-gateway.js
CHANGED
|
@@ -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
|
-
|
|
327
|
-
|
|
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
|
-
|
|
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
|
-
|
|
577
|
-
|
|
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
|
|
9
|
-
import { dirname as
|
|
10
|
-
import { homedir as
|
|
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(
|
|
1543
|
+
function findCli(dirname6 = MODULE_DIR) {
|
|
1544
1544
|
const candidates = [
|
|
1545
1545
|
// Bundled (the shipped layout): dist/control-plane → dist → root → bin
|
|
1546
|
-
resolve(
|
|
1546
|
+
resolve(dirname6, "..", "..", "bin", "suveren-gateway.js"),
|
|
1547
1547
|
// Bundled, were the routes/ directory ever preserved.
|
|
1548
|
-
resolve(
|
|
1548
|
+
resolve(dirname6, "..", "..", "..", "bin", "suveren-gateway.js"),
|
|
1549
1549
|
// Dev, running from source: the repo's own bundle directory.
|
|
1550
|
-
resolve(
|
|
1551
|
-
resolve(
|
|
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, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
|
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: [
|
|
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: [
|
|
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
|
-
"-
|
|
1661
|
-
"-
|
|
1662
|
-
|
|
1663
|
-
|
|
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
|
-
|
|
1695
|
-
|
|
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,
|
|
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
|
|
1816
|
-
import { homedir as
|
|
1817
|
-
import { join as
|
|
1818
|
-
var SUVEREN_DATA_DIR = process.env.SUVEREN_DATA_DIR ??
|
|
1819
|
-
var FILE_PATH =
|
|
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 (!
|
|
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
|
-
|
|
1832
|
-
|
|
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
|
|
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 =
|
|
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
|
|
2016
|
-
import { homedir as
|
|
2017
|
-
import { join as
|
|
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 ??
|
|
2023
|
-
return
|
|
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
|
-
|
|
2042
|
-
|
|
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
|
|
2188
|
-
import { join as
|
|
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 =
|
|
2191
|
-
const plainPath =
|
|
2192
|
-
if (
|
|
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 (
|
|
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 =
|
|
2213
|
-
const newDir =
|
|
2214
|
-
if (!
|
|
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 ??
|
|
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 ??
|
|
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 ??
|
|
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 =
|
|
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:
|
|
2656
|
-
|
|
2657
|
-
const filePath =
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
2715
|
-
const parent =
|
|
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 =
|
|
2728
|
-
if (
|
|
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 (
|
|
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(
|
|
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:
|
|
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
|
|
@@ -2698,12 +2698,12 @@ declare module "node:crypto" {
|
|
|
2698
2698
|
*/
|
|
2699
2699
|
function sign(
|
|
2700
2700
|
algorithm: string | null | undefined,
|
|
2701
|
-
data:
|
|
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:
|
|
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:
|
|
2732
|
+
data: BinaryLike,
|
|
2733
2733
|
key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
|
|
2734
|
-
signature:
|
|
2734
|
+
signature: BinaryLike,
|
|
2735
2735
|
): boolean;
|
|
2736
2736
|
function verify(
|
|
2737
2737
|
algorithm: string | null | undefined,
|
|
2738
|
-
data:
|
|
2738
|
+
data: BinaryLike,
|
|
2739
2739
|
key: KeyLike | VerifyKeyObjectInput | VerifyPublicKeyInput | VerifyJsonWebKeyInput,
|
|
2740
|
-
signature:
|
|
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.
|