@suveren/gateway 0.13.0 → 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.
- package/README.md +19 -3
- package/bin/suveren-gateway.js +5 -0
- package/dist/control-plane/index.mjs +146 -114
- package/dist/mcp-server/http.mjs +162 -118
- package/dist/ui/assets/{index-CmLqzgqA.js → index-Cg6VaGKb.js} +12 -12
- package/dist/ui/index.html +1 -1
- package/lib/autostart-templates.mjs +15 -7
- package/node_modules/@hap/core/dist/index.d.mts +49 -1
- package/node_modules/@hap/core/dist/index.d.ts +49 -1
- package/node_modules/@hap/core/dist/index.js +50 -0
- package/node_modules/@hap/core/dist/index.mjs +49 -0
- package/node_modules/@hap/core/package.json +1 -1
- package/node_modules/@hap/core/src/frame.ts +63 -1
- package/node_modules/@hap/core/src/gatekeeper.ts +37 -0
- package/node_modules/@hap/core/src/types.ts +29 -1
- package/node_modules/hono/dist/cjs/hono-base.js +2 -0
- package/node_modules/hono/dist/cjs/middleware/language/language.js +1 -1
- package/node_modules/hono/dist/cjs/middleware/mount/index.js +71 -0
- package/node_modules/hono/dist/cjs/request.js +4 -4
- package/node_modules/hono/dist/hono-base.js +2 -0
- package/node_modules/hono/dist/middleware/mount/index.js +70 -0
- package/node_modules/hono/dist/request.js +4 -4
- package/node_modules/hono/dist/types/hono-base.d.ts +2 -0
- package/node_modules/hono/dist/types/jsx/base.d.ts +1 -1
- package/node_modules/hono/dist/types/middleware/mount/index.d.ts +46 -0
- package/node_modules/hono/dist/types/request.d.ts +4 -4
- package/node_modules/hono/package.json +9 -1
- package/package.json +2 -2
- package/profiles/index.json +3 -1
- package/profiles/purchase/0.6.profile.json +234 -0
- package/profiles/sales/0.3.profile.json +290 -0
- package/server.js +6 -3
|
@@ -5,8 +5,8 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
8
|
-
import { existsSync as
|
|
9
|
-
import { dirname as
|
|
8
|
+
import { existsSync as existsSync11, readFileSync as readFileSync13, renameSync as renameSync2 } from "fs";
|
|
9
|
+
import { dirname as dirname9, join as join13 } from "path";
|
|
10
10
|
import { homedir as homedir7 } from "os";
|
|
11
11
|
import express from "express";
|
|
12
12
|
import { createProxyMiddleware } from "http-proxy-middleware";
|
|
@@ -292,6 +292,35 @@ var Vault = class {
|
|
|
292
292
|
}
|
|
293
293
|
};
|
|
294
294
|
|
|
295
|
+
// src/lib/install-method.ts
|
|
296
|
+
import { existsSync as existsSync2, readFileSync as readFileSync2 } from "fs";
|
|
297
|
+
import { dirname as dirname2, join as join2 } from "path";
|
|
298
|
+
var INSTALL_MARKER = "install-method.json";
|
|
299
|
+
function readInstallMarker(bundleRoot) {
|
|
300
|
+
const file = join2(bundleRoot, INSTALL_MARKER);
|
|
301
|
+
if (!existsSync2(file)) return null;
|
|
302
|
+
try {
|
|
303
|
+
const parsed = JSON.parse(readFileSync2(file, "utf8"));
|
|
304
|
+
return typeof parsed.method === "string" ? parsed.method : null;
|
|
305
|
+
} catch {
|
|
306
|
+
return null;
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
function detectInstallMethod({ dir, dockerEnv, managed }) {
|
|
310
|
+
if (managed) return "managed";
|
|
311
|
+
if (readInstallMarker(dirname2(dirname2(dir))) === "msi") return "msi";
|
|
312
|
+
if (dockerEnv) return "docker";
|
|
313
|
+
if (dir.includes("/node_modules/@suveren/gateway/")) return "npm";
|
|
314
|
+
let cursor = dir;
|
|
315
|
+
for (let i = 0; i < 8; i++) {
|
|
316
|
+
if (existsSync2(join2(cursor, ".git"))) return "dev";
|
|
317
|
+
const parent = dirname2(cursor);
|
|
318
|
+
if (parent === cursor) break;
|
|
319
|
+
cursor = parent;
|
|
320
|
+
}
|
|
321
|
+
return "npm";
|
|
322
|
+
}
|
|
323
|
+
|
|
295
324
|
// src/routes/auth.ts
|
|
296
325
|
import { Router } from "express";
|
|
297
326
|
|
|
@@ -632,12 +661,12 @@ async function loadOrGenerateKeyPair(vault2) {
|
|
|
632
661
|
}
|
|
633
662
|
|
|
634
663
|
// src/lib/client-version.ts
|
|
635
|
-
import { readFileSync as
|
|
636
|
-
import { join as
|
|
664
|
+
import { readFileSync as readFileSync3 } from "fs";
|
|
665
|
+
import { join as join3 } from "path";
|
|
637
666
|
var UNKNOWN = "unknown";
|
|
638
667
|
function readJson(path) {
|
|
639
668
|
try {
|
|
640
|
-
return JSON.parse(
|
|
669
|
+
return JSON.parse(readFileSync3(path, "utf8"));
|
|
641
670
|
} catch {
|
|
642
671
|
return null;
|
|
643
672
|
}
|
|
@@ -648,13 +677,13 @@ function detectGatewayVersion() {
|
|
|
648
677
|
const start = import.meta.dirname ?? process.cwd();
|
|
649
678
|
let dir = start;
|
|
650
679
|
for (let up = 0; up < 6; up++) {
|
|
651
|
-
const pkg = readJson(
|
|
680
|
+
const pkg = readJson(join3(dir, "package.json"));
|
|
652
681
|
const name = pkg?.name;
|
|
653
682
|
const version = pkg?.version;
|
|
654
683
|
if (typeof version === "string" && (name === "@suveren/gateway" || name === "suveren-gateway")) {
|
|
655
684
|
return version;
|
|
656
685
|
}
|
|
657
|
-
const parent =
|
|
686
|
+
const parent = join3(dir, "..");
|
|
658
687
|
if (parent === dir) break;
|
|
659
688
|
dir = parent;
|
|
660
689
|
}
|
|
@@ -669,16 +698,16 @@ function clientVersionHeaders() {
|
|
|
669
698
|
|
|
670
699
|
// src/lib/as-pairing.ts
|
|
671
700
|
import { createHash as createHash2 } from "crypto";
|
|
672
|
-
import { existsSync as
|
|
673
|
-
import { dirname as
|
|
701
|
+
import { existsSync as existsSync3, mkdirSync as mkdirSync2, readFileSync as readFileSync4, unlinkSync, writeFileSync as writeFileSync2 } from "fs";
|
|
702
|
+
import { dirname as dirname3, join as join4 } from "path";
|
|
674
703
|
function pairingPath(dataDir) {
|
|
675
|
-
return
|
|
704
|
+
return join4(dataDir, "as-pairing.json");
|
|
676
705
|
}
|
|
677
706
|
function readPairing(dataDir) {
|
|
678
707
|
const path = pairingPath(dataDir);
|
|
679
|
-
if (!
|
|
708
|
+
if (!existsSync3(path)) return null;
|
|
680
709
|
try {
|
|
681
|
-
const data = JSON.parse(
|
|
710
|
+
const data = JSON.parse(readFileSync4(path, "utf-8"));
|
|
682
711
|
if (typeof data.asUrl !== "string" || typeof data.publicKeyHex !== "string") return null;
|
|
683
712
|
return {
|
|
684
713
|
asUrl: data.asUrl,
|
|
@@ -698,7 +727,7 @@ function writePairing(dataDir, asUrl, publicKeyHex, opts = {}) {
|
|
|
698
727
|
...opts.tlsSpkiPinHex ? { tlsSpkiPinHex: opts.tlsSpkiPinHex } : {}
|
|
699
728
|
};
|
|
700
729
|
const path = pairingPath(dataDir);
|
|
701
|
-
mkdirSync2(
|
|
730
|
+
mkdirSync2(dirname3(path), { recursive: true, mode: 448 });
|
|
702
731
|
writeFileSync2(path, JSON.stringify(pairing, null, 2), { encoding: "utf-8", mode: 384 });
|
|
703
732
|
return pairing;
|
|
704
733
|
}
|
|
@@ -715,7 +744,7 @@ function recordTlsPin(dataDir, asUrl, tlsSpkiPinHex) {
|
|
|
715
744
|
function clearPairing(dataDir) {
|
|
716
745
|
const path = pairingPath(dataDir);
|
|
717
746
|
try {
|
|
718
|
-
if (
|
|
747
|
+
if (existsSync3(path)) unlinkSync(path);
|
|
719
748
|
} catch {
|
|
720
749
|
}
|
|
721
750
|
}
|
|
@@ -733,7 +762,7 @@ import { canonicalize } from "@hap/core";
|
|
|
733
762
|
import { createHash as createHash3 } from "crypto";
|
|
734
763
|
import { checkServerIdentity as defaultCheckServerIdentity, rootCertificates } from "tls";
|
|
735
764
|
import { Agent as HttpsAgent2 } from "https";
|
|
736
|
-
import { readFileSync as
|
|
765
|
+
import { readFileSync as readFileSync5 } from "fs";
|
|
737
766
|
import { Agent, ProxyAgent, fetch as undiciFetch } from "undici";
|
|
738
767
|
|
|
739
768
|
// src/lib/proxy-env.ts
|
|
@@ -868,7 +897,7 @@ function effectiveCa() {
|
|
|
868
897
|
const path = process.env.NODE_EXTRA_CA_CERTS;
|
|
869
898
|
if (!path) return void 0;
|
|
870
899
|
try {
|
|
871
|
-
return [...rootCertificates,
|
|
900
|
+
return [...rootCertificates, readFileSync5(path, "utf-8")];
|
|
872
901
|
} catch {
|
|
873
902
|
return void 0;
|
|
874
903
|
}
|
|
@@ -1172,12 +1201,12 @@ async function verifyAsHoldsKey(asUrl, publicKeyHex, pinning = { enforce: false,
|
|
|
1172
1201
|
}
|
|
1173
1202
|
|
|
1174
1203
|
// src/lib/as-config.ts
|
|
1175
|
-
import { existsSync as
|
|
1176
|
-
import { dirname as
|
|
1204
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readFileSync as readFileSync7, writeFileSync as writeFileSync3 } from "fs";
|
|
1205
|
+
import { dirname as dirname4, join as join6 } from "path";
|
|
1177
1206
|
|
|
1178
1207
|
// src/lib/policy.ts
|
|
1179
|
-
import { existsSync as
|
|
1180
|
-
import { join as
|
|
1208
|
+
import { existsSync as existsSync4, readFileSync as readFileSync6 } from "fs";
|
|
1209
|
+
import { join as join5 } from "path";
|
|
1181
1210
|
import { spawnSync } from "child_process";
|
|
1182
1211
|
var POLICY_KEYS = ["AsUrl", "CaFile", "PinTls", "Proxy", "NoProxy", "Simulation", "InstallMethod"];
|
|
1183
1212
|
var DEFAULT_REGISTRY_BASE_KEY = "SOFTWARE\\Policies\\Suveren\\Gateway";
|
|
@@ -1212,7 +1241,7 @@ function validateAsUrl(candidate) {
|
|
|
1212
1241
|
function validateCaFile(candidate) {
|
|
1213
1242
|
const trimmed = candidate.trim();
|
|
1214
1243
|
if (!trimmed) return { ok: false, error: "The CA file path is empty." };
|
|
1215
|
-
if (!
|
|
1244
|
+
if (!existsSync4(trimmed)) return { ok: false, error: `No file at "${trimmed}".` };
|
|
1216
1245
|
return { ok: true, path: trimmed };
|
|
1217
1246
|
}
|
|
1218
1247
|
function validateProxyUrl(candidate) {
|
|
@@ -1278,7 +1307,7 @@ function policyFilePath() {
|
|
|
1278
1307
|
if (process.env.SUVEREN_POLICY_FILE) return process.env.SUVEREN_POLICY_FILE;
|
|
1279
1308
|
if (process.platform === "win32") {
|
|
1280
1309
|
const programData = process.env.ProgramData || process.env.PROGRAMDATA || "C:\\ProgramData";
|
|
1281
|
-
return
|
|
1310
|
+
return join5(programData, "Suveren", "gateway-policy.json");
|
|
1282
1311
|
}
|
|
1283
1312
|
if (process.platform === "darwin") {
|
|
1284
1313
|
return "/Library/Application Support/Suveren/gateway-policy.json";
|
|
@@ -1288,10 +1317,10 @@ function policyFilePath() {
|
|
|
1288
1317
|
function readPolicyFile() {
|
|
1289
1318
|
const path = policyFilePath();
|
|
1290
1319
|
const source = `the policy file (${path})`;
|
|
1291
|
-
if (!
|
|
1320
|
+
if (!existsSync4(path)) return { values: {}, source };
|
|
1292
1321
|
let data;
|
|
1293
1322
|
try {
|
|
1294
|
-
data = JSON.parse(
|
|
1323
|
+
data = JSON.parse(readFileSync6(path, "utf8"));
|
|
1295
1324
|
} catch (err) {
|
|
1296
1325
|
throw new Error(`Could not parse policy file ${path}: ${err instanceof Error ? err.message : String(err)}`);
|
|
1297
1326
|
}
|
|
@@ -1395,14 +1424,14 @@ function readPolicy() {
|
|
|
1395
1424
|
// src/lib/as-config.ts
|
|
1396
1425
|
var DEFAULT_AS_URL = "https://www.suveren.ai";
|
|
1397
1426
|
function configPath(dataDir) {
|
|
1398
|
-
return
|
|
1427
|
+
return join6(dataDir, "config.json");
|
|
1399
1428
|
}
|
|
1400
1429
|
function readAsConfigStrict(dataDir) {
|
|
1401
1430
|
const path = configPath(dataDir);
|
|
1402
|
-
if (!
|
|
1431
|
+
if (!existsSync5(path)) return {};
|
|
1403
1432
|
let data;
|
|
1404
1433
|
try {
|
|
1405
|
-
data = JSON.parse(
|
|
1434
|
+
data = JSON.parse(readFileSync7(path, "utf-8"));
|
|
1406
1435
|
} catch (err) {
|
|
1407
1436
|
throw new Error(
|
|
1408
1437
|
`Could not parse ${path}: ${err instanceof Error ? err.message : String(err)}`
|
|
@@ -1417,9 +1446,9 @@ function readAsConfigStrict(dataDir) {
|
|
|
1417
1446
|
}
|
|
1418
1447
|
function readAsConfig(dataDir) {
|
|
1419
1448
|
const path = configPath(dataDir);
|
|
1420
|
-
if (!
|
|
1449
|
+
if (!existsSync5(path)) return {};
|
|
1421
1450
|
try {
|
|
1422
|
-
const data = JSON.parse(
|
|
1451
|
+
const data = JSON.parse(readFileSync7(path, "utf-8"));
|
|
1423
1452
|
const out = {};
|
|
1424
1453
|
if (typeof data.asUrl === "string") out.asUrl = data.asUrl;
|
|
1425
1454
|
if (typeof data.caFile === "string") out.caFile = data.caFile;
|
|
@@ -1433,7 +1462,7 @@ function readAsConfig(dataDir) {
|
|
|
1433
1462
|
function writeAsConfig(dataDir, patch) {
|
|
1434
1463
|
const merged = { ...readAsConfig(dataDir), ...patch };
|
|
1435
1464
|
const path = configPath(dataDir);
|
|
1436
|
-
mkdirSync3(
|
|
1465
|
+
mkdirSync3(dirname4(path), { recursive: true, mode: 448 });
|
|
1437
1466
|
writeFileSync3(path, JSON.stringify(merged, null, 2), { encoding: "utf-8", mode: 384 });
|
|
1438
1467
|
return merged;
|
|
1439
1468
|
}
|
|
@@ -2437,18 +2466,18 @@ async function testAIConnectivity(config) {
|
|
|
2437
2466
|
}
|
|
2438
2467
|
|
|
2439
2468
|
// src/lib/agent-brief-store.ts
|
|
2440
|
-
import { existsSync as
|
|
2469
|
+
import { existsSync as existsSync6, readFileSync as readFileSync8 } from "fs";
|
|
2441
2470
|
import { homedir as homedir2 } from "os";
|
|
2442
|
-
import { join as
|
|
2471
|
+
import { join as join7 } from "path";
|
|
2443
2472
|
var AGENT_CONTEXT_MAX_BYTES = 16 * 1024;
|
|
2444
2473
|
function agentBriefPath() {
|
|
2445
|
-
const dataDir = process.env.SUVEREN_DATA_DIR ??
|
|
2446
|
-
return
|
|
2474
|
+
const dataDir = process.env.SUVEREN_DATA_DIR ?? join7(homedir2(), ".suveren");
|
|
2475
|
+
return join7(dataDir, "context.md");
|
|
2447
2476
|
}
|
|
2448
2477
|
function readAgentBrief() {
|
|
2449
2478
|
const filePath = agentBriefPath();
|
|
2450
|
-
if (!
|
|
2451
|
-
return
|
|
2479
|
+
if (!existsSync6(filePath)) return "";
|
|
2480
|
+
return readFileSync8(filePath, "utf-8");
|
|
2452
2481
|
}
|
|
2453
2482
|
|
|
2454
2483
|
// src/routes/ai.ts
|
|
@@ -2812,28 +2841,28 @@ function createMCPRouter() {
|
|
|
2812
2841
|
// src/routes/autostart.ts
|
|
2813
2842
|
import { Router as Router6 } from "express";
|
|
2814
2843
|
import { execFile } from "child_process";
|
|
2815
|
-
import { existsSync as
|
|
2844
|
+
import { existsSync as existsSync7 } from "fs";
|
|
2816
2845
|
import { dirname as pathDirname, resolve } from "path";
|
|
2817
2846
|
import { fileURLToPath } from "url";
|
|
2818
2847
|
import { promisify } from "util";
|
|
2819
2848
|
var run = promisify(execFile);
|
|
2820
2849
|
var SUPPORTED = /* @__PURE__ */ new Set(["darwin", "win32", "linux"]);
|
|
2821
2850
|
var MODULE_DIR = pathDirname(fileURLToPath(import.meta.url));
|
|
2822
|
-
function findCli(
|
|
2851
|
+
function findCli(dirname10 = MODULE_DIR) {
|
|
2823
2852
|
const candidates = [
|
|
2824
2853
|
// Bundled (the shipped layout): dist/control-plane → dist → root → bin
|
|
2825
|
-
resolve(
|
|
2854
|
+
resolve(dirname10, "..", "..", "bin", "suveren-gateway.js"),
|
|
2826
2855
|
// Bundled, were the routes/ directory ever preserved.
|
|
2827
|
-
resolve(
|
|
2856
|
+
resolve(dirname10, "..", "..", "..", "bin", "suveren-gateway.js"),
|
|
2828
2857
|
// Dev, running from source: the repo's own bundle directory.
|
|
2829
|
-
resolve(
|
|
2830
|
-
resolve(
|
|
2858
|
+
resolve(dirname10, "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js"),
|
|
2859
|
+
resolve(dirname10, "..", "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js")
|
|
2831
2860
|
// Deliberately NO process.cwd() fallback: it makes the result depend on
|
|
2832
2861
|
// where the process happened to be launched from, so the same install
|
|
2833
2862
|
// resolves differently between a shell and a login service — and it would
|
|
2834
2863
|
// mask a genuinely missing CLI whenever the cwd happened to be the repo.
|
|
2835
2864
|
];
|
|
2836
|
-
return candidates.find(
|
|
2865
|
+
return candidates.find(existsSync7) ?? null;
|
|
2837
2866
|
}
|
|
2838
2867
|
async function cli(args) {
|
|
2839
2868
|
const bin = findCli();
|
|
@@ -2914,16 +2943,16 @@ function createAutostartRouter() {
|
|
|
2914
2943
|
import { spawn, spawnSync as spawnSync2 } from "child_process";
|
|
2915
2944
|
|
|
2916
2945
|
// src/lib/notifier-icon.ts
|
|
2917
|
-
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as
|
|
2946
|
+
import { writeFileSync as writeFileSync4, mkdirSync as mkdirSync4, existsSync as existsSync8 } from "fs";
|
|
2918
2947
|
import { homedir as homedir3 } from "os";
|
|
2919
|
-
import { join as
|
|
2948
|
+
import { join as join8, dirname as dirname5 } from "path";
|
|
2920
2949
|
var ICON_BASE64 = "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";
|
|
2921
2950
|
function ensureNotifierIcon(dataDir) {
|
|
2922
2951
|
try {
|
|
2923
|
-
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ??
|
|
2924
|
-
const path =
|
|
2925
|
-
if (!
|
|
2926
|
-
mkdirSync4(
|
|
2952
|
+
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join8(homedir3(), ".suveren");
|
|
2953
|
+
const path = join8(dir, "notifier-icon.png");
|
|
2954
|
+
if (!existsSync8(path)) {
|
|
2955
|
+
mkdirSync4(dirname5(path), { recursive: true });
|
|
2927
2956
|
writeFileSync4(path, Buffer.from(ICON_BASE64, "base64"));
|
|
2928
2957
|
}
|
|
2929
2958
|
return path;
|
|
@@ -3126,17 +3155,17 @@ import { Router as Router9 } from "express";
|
|
|
3126
3155
|
|
|
3127
3156
|
// src/routes/approved-intents.ts
|
|
3128
3157
|
import { Router as Router8 } from "express";
|
|
3129
|
-
import { readFileSync as
|
|
3158
|
+
import { readFileSync as readFileSync9, writeFileSync as writeFileSync5, existsSync as existsSync9, mkdirSync as mkdirSync5 } from "fs";
|
|
3130
3159
|
import { homedir as homedir4 } from "os";
|
|
3131
|
-
import { join as
|
|
3132
|
-
var SUVEREN_DATA_DIR = process.env.SUVEREN_DATA_DIR ??
|
|
3133
|
-
var FILE_PATH =
|
|
3160
|
+
import { join as join9 } from "path";
|
|
3161
|
+
var SUVEREN_DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join9(homedir4(), ".suveren");
|
|
3162
|
+
var FILE_PATH = join9(SUVEREN_DATA_DIR, "approved-intents.enc.json");
|
|
3134
3163
|
function readFile() {
|
|
3135
|
-
if (!
|
|
3164
|
+
if (!existsSync9(FILE_PATH)) {
|
|
3136
3165
|
return { version: 1, entries: {} };
|
|
3137
3166
|
}
|
|
3138
3167
|
try {
|
|
3139
|
-
return JSON.parse(
|
|
3168
|
+
return JSON.parse(readFileSync9(FILE_PATH, "utf-8"));
|
|
3140
3169
|
} catch {
|
|
3141
3170
|
return { version: 1, entries: {} };
|
|
3142
3171
|
}
|
|
@@ -3420,7 +3449,7 @@ function createDecryptIntentRouter(vault2) {
|
|
|
3420
3449
|
|
|
3421
3450
|
// src/lib/update-checker.ts
|
|
3422
3451
|
import { execSync } from "child_process";
|
|
3423
|
-
import { dirname as
|
|
3452
|
+
import { dirname as dirname6 } from "path";
|
|
3424
3453
|
import { fileURLToPath as fileURLToPath2 } from "url";
|
|
3425
3454
|
var GHCR_IMAGE = "suverenai/suveren-gateway";
|
|
3426
3455
|
var NPM_PACKAGE = "@suveren/gateway";
|
|
@@ -3486,7 +3515,7 @@ function compareSemver(a, b) {
|
|
|
3486
3515
|
return 0;
|
|
3487
3516
|
}
|
|
3488
3517
|
function checkDev() {
|
|
3489
|
-
const cwd =
|
|
3518
|
+
const cwd = dirname6(fileURLToPath2(import.meta.url));
|
|
3490
3519
|
try {
|
|
3491
3520
|
execSync("git fetch origin --quiet", { cwd, stdio: "ignore", timeout: 15e3 });
|
|
3492
3521
|
const out = execSync("git rev-list HEAD..origin/main --count", {
|
|
@@ -3509,7 +3538,7 @@ async function check() {
|
|
|
3509
3538
|
checkDev();
|
|
3510
3539
|
return;
|
|
3511
3540
|
}
|
|
3512
|
-
if (installMethod === "npm" || installMethod === "managed") {
|
|
3541
|
+
if (installMethod === "npm" || installMethod === "managed" || installMethod === "msi") {
|
|
3513
3542
|
await checkNpm();
|
|
3514
3543
|
return;
|
|
3515
3544
|
}
|
|
@@ -3559,19 +3588,19 @@ data: ${data}
|
|
|
3559
3588
|
import { Router as Router12 } from "express";
|
|
3560
3589
|
|
|
3561
3590
|
// src/lib/gateway-settings.ts
|
|
3562
|
-
import { readFileSync as
|
|
3591
|
+
import { readFileSync as readFileSync10, writeFileSync as writeFileSync6, mkdirSync as mkdirSync6 } from "fs";
|
|
3563
3592
|
import { homedir as homedir5 } from "os";
|
|
3564
|
-
import { join as
|
|
3593
|
+
import { join as join10, dirname as dirname7 } from "path";
|
|
3565
3594
|
var DEFAULT_SETTINGS = {
|
|
3566
3595
|
desktopNotifications: true
|
|
3567
3596
|
};
|
|
3568
3597
|
function settingsPath(dataDir) {
|
|
3569
|
-
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ??
|
|
3570
|
-
return
|
|
3598
|
+
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join10(homedir5(), ".suveren");
|
|
3599
|
+
return join10(dir, "settings.json");
|
|
3571
3600
|
}
|
|
3572
3601
|
function readSettings(dataDir) {
|
|
3573
3602
|
try {
|
|
3574
|
-
const raw = JSON.parse(
|
|
3603
|
+
const raw = JSON.parse(readFileSync10(settingsPath(dataDir), "utf8"));
|
|
3575
3604
|
return {
|
|
3576
3605
|
desktopNotifications: typeof raw.desktopNotifications === "boolean" ? raw.desktopNotifications : DEFAULT_SETTINGS.desktopNotifications
|
|
3577
3606
|
};
|
|
@@ -3585,7 +3614,7 @@ function writeSettings(patch, dataDir) {
|
|
|
3585
3614
|
...typeof patch.desktopNotifications === "boolean" ? { desktopNotifications: patch.desktopNotifications } : {}
|
|
3586
3615
|
};
|
|
3587
3616
|
const path = settingsPath(dataDir);
|
|
3588
|
-
mkdirSync6(
|
|
3617
|
+
mkdirSync6(dirname7(path), { recursive: true });
|
|
3589
3618
|
writeFileSync6(path, JSON.stringify(next, null, 2) + "\n", "utf8");
|
|
3590
3619
|
return next;
|
|
3591
3620
|
}
|
|
@@ -3618,20 +3647,20 @@ function createGatewaySettingsRouter() {
|
|
|
3618
3647
|
import { Router as Router13 } from "express";
|
|
3619
3648
|
|
|
3620
3649
|
// src/lib/archived-mandates-store.ts
|
|
3621
|
-
import { readFileSync as
|
|
3650
|
+
import { readFileSync as readFileSync11, writeFileSync as writeFileSync7, mkdirSync as mkdirSync7, renameSync } from "fs";
|
|
3622
3651
|
import { homedir as homedir6 } from "os";
|
|
3623
|
-
import { join as
|
|
3652
|
+
import { join as join11, dirname as dirname8 } from "path";
|
|
3624
3653
|
var ID_PATTERN = /^[A-Za-z0-9_.:-]{1,200}$/;
|
|
3625
3654
|
function isValidMandateId(id) {
|
|
3626
3655
|
return typeof id === "string" && ID_PATTERN.test(id);
|
|
3627
3656
|
}
|
|
3628
3657
|
function storePath(dataDir) {
|
|
3629
|
-
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ??
|
|
3630
|
-
return
|
|
3658
|
+
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join11(homedir6(), ".suveren");
|
|
3659
|
+
return join11(dir, "archived-mandates.json");
|
|
3631
3660
|
}
|
|
3632
3661
|
function readArchived(dataDir) {
|
|
3633
3662
|
try {
|
|
3634
|
-
const raw = JSON.parse(
|
|
3663
|
+
const raw = JSON.parse(readFileSync11(storePath(dataDir), "utf8"));
|
|
3635
3664
|
if (!Array.isArray(raw.archived)) return [];
|
|
3636
3665
|
return [...new Set(raw.archived.filter(isValidMandateId))];
|
|
3637
3666
|
} catch {
|
|
@@ -3641,7 +3670,7 @@ function readArchived(dataDir) {
|
|
|
3641
3670
|
function writeArchived(ids, dataDir) {
|
|
3642
3671
|
const next = [...new Set(ids.filter(isValidMandateId))].sort();
|
|
3643
3672
|
const path = storePath(dataDir);
|
|
3644
|
-
mkdirSync7(
|
|
3673
|
+
mkdirSync7(dirname8(path), { recursive: true });
|
|
3645
3674
|
const tmp = `${path}.tmp`;
|
|
3646
3675
|
writeFileSync7(tmp, JSON.stringify({ archived: next }, null, 2) + "\n", "utf8");
|
|
3647
3676
|
renameSync(tmp, path);
|
|
@@ -3937,17 +3966,17 @@ function buildSessionHealth(vault2) {
|
|
|
3937
3966
|
}
|
|
3938
3967
|
|
|
3939
3968
|
// src/lib/denials-reader.ts
|
|
3940
|
-
import { existsSync as
|
|
3941
|
-
import { join as
|
|
3969
|
+
import { existsSync as existsSync10, readFileSync as readFileSync12 } from "fs";
|
|
3970
|
+
import { join as join12 } from "path";
|
|
3942
3971
|
function loadDenials(dataDir, decrypt) {
|
|
3943
|
-
const encPath =
|
|
3944
|
-
const plainPath =
|
|
3945
|
-
if (
|
|
3946
|
-
const { blob } = JSON.parse(
|
|
3972
|
+
const encPath = join12(dataDir, "denials.enc.json");
|
|
3973
|
+
const plainPath = join12(dataDir, "denials.json");
|
|
3974
|
+
if (existsSync10(encPath)) {
|
|
3975
|
+
const { blob } = JSON.parse(readFileSync12(encPath, "utf-8"));
|
|
3947
3976
|
return JSON.parse(decrypt(blob)).records ?? [];
|
|
3948
3977
|
}
|
|
3949
|
-
if (
|
|
3950
|
-
return JSON.parse(
|
|
3978
|
+
if (existsSync10(plainPath)) {
|
|
3979
|
+
return JSON.parse(readFileSync12(plainPath, "utf-8")).records ?? [];
|
|
3951
3980
|
}
|
|
3952
3981
|
return [];
|
|
3953
3982
|
}
|
|
@@ -3971,9 +4000,9 @@ function isSimulationMode() {
|
|
|
3971
4000
|
// src/index.ts
|
|
3972
4001
|
(function migrateDataDir() {
|
|
3973
4002
|
if (process.env.SUVEREN_DATA_DIR) return;
|
|
3974
|
-
const oldDir =
|
|
3975
|
-
const newDir =
|
|
3976
|
-
if (!
|
|
4003
|
+
const oldDir = join13(homedir7(), ".hap");
|
|
4004
|
+
const newDir = join13(homedir7(), ".suveren");
|
|
4005
|
+
if (!existsSync11(newDir) && existsSync11(oldDir)) {
|
|
3977
4006
|
try {
|
|
3978
4007
|
renameSync2(oldDir, newDir);
|
|
3979
4008
|
console.error(`[Control Plane] Migrated data directory: ${oldDir} \u2192 ${newDir}`);
|
|
@@ -3983,14 +4012,14 @@ function isSimulationMode() {
|
|
|
3983
4012
|
}
|
|
3984
4013
|
}
|
|
3985
4014
|
})();
|
|
3986
|
-
var DATA_DIR = process.env.SUVEREN_DATA_DIR ??
|
|
4015
|
+
var DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join13(homedir7(), ".suveren");
|
|
3987
4016
|
var SP_URL = resolveAsUrl(DATA_DIR);
|
|
3988
4017
|
validatePinTlsForUrl(resolvePinTls(DATA_DIR), SP_URL);
|
|
3989
4018
|
var POLICY_LOCKED = [...readPolicy().locked];
|
|
3990
4019
|
var POLICY_LOCKED_INSTALL_METHOD = readPolicy().policy.installMethod;
|
|
3991
4020
|
var port = parseInt(process.env.SUVEREN_CP_PORT ?? "3402", 10);
|
|
3992
4021
|
var HAP_MODE = process.env.HAP_MODE ?? "personal";
|
|
3993
|
-
var UI_DIST = process.env.HAP_UI_DIST ??
|
|
4022
|
+
var UI_DIST = process.env.HAP_UI_DIST ?? join13(import.meta.dirname ?? __dirname, "../../ui/dist");
|
|
3994
4023
|
var vault = new Vault(DATA_DIR);
|
|
3995
4024
|
(function repairIfAsUrlChanged() {
|
|
3996
4025
|
const pairing = readPairing(DATA_DIR);
|
|
@@ -4414,7 +4443,7 @@ app.get("/as-pairing", authGuard, (_req, res) => {
|
|
|
4414
4443
|
});
|
|
4415
4444
|
app.get("/denials", authGuard, (req, res) => {
|
|
4416
4445
|
try {
|
|
4417
|
-
const dataDir = process.env.SUVEREN_DATA_DIR ??
|
|
4446
|
+
const dataDir = process.env.SUVEREN_DATA_DIR ?? join13(homedir7(), ".suveren");
|
|
4418
4447
|
const all = loadDenials(dataDir, (blob) => vault.decrypt(blob));
|
|
4419
4448
|
const since = Number(req.query.since);
|
|
4420
4449
|
const limit = Number(req.query.limit);
|
|
@@ -4467,7 +4496,7 @@ app.put("/agent-brief/context", jsonParser, authGuard, async (req, res) => {
|
|
|
4467
4496
|
}
|
|
4468
4497
|
const { mkdirSync: mkdirSync8, writeFileSync: writeFileSync8, renameSync: renameSync3 } = await import("fs");
|
|
4469
4498
|
const filePath = agentBriefPath();
|
|
4470
|
-
mkdirSync8(
|
|
4499
|
+
mkdirSync8(dirname9(filePath), { recursive: true });
|
|
4471
4500
|
const tmpPath = `${filePath}.tmp`;
|
|
4472
4501
|
writeFileSync8(tmpPath, content, "utf-8");
|
|
4473
4502
|
renameSync3(tmpPath, filePath);
|
|
@@ -4544,30 +4573,23 @@ app.use(
|
|
|
4544
4573
|
}
|
|
4545
4574
|
})
|
|
4546
4575
|
);
|
|
4547
|
-
function
|
|
4548
|
-
|
|
4549
|
-
|
|
4550
|
-
|
|
4551
|
-
|
|
4552
|
-
|
|
4553
|
-
for (let i = 0; i < 8; i++) {
|
|
4554
|
-
if (existsSync10(join12(cursor, ".git"))) return "dev";
|
|
4555
|
-
const parent = dirname8(cursor);
|
|
4556
|
-
if (parent === cursor) break;
|
|
4557
|
-
cursor = parent;
|
|
4558
|
-
}
|
|
4559
|
-
return "npm";
|
|
4576
|
+
function detectInstallMethod2() {
|
|
4577
|
+
return detectInstallMethod({
|
|
4578
|
+
dir: import.meta.dirname ?? __dirname,
|
|
4579
|
+
dockerEnv: existsSync11("/.dockerenv"),
|
|
4580
|
+
managed: process.env.SUVEREN_INSTALL_METHOD === "managed" || POLICY_LOCKED_INSTALL_METHOD === "managed"
|
|
4581
|
+
});
|
|
4560
4582
|
}
|
|
4561
|
-
var INSTALL_METHOD =
|
|
4583
|
+
var INSTALL_METHOD = detectInstallMethod2();
|
|
4562
4584
|
function detectRunningVersion() {
|
|
4563
4585
|
if (INSTALL_METHOD === "docker") {
|
|
4564
4586
|
return process.env.HAP_BUILD_SHA ?? "dev";
|
|
4565
4587
|
}
|
|
4566
4588
|
const dir = import.meta.dirname ?? __dirname;
|
|
4567
|
-
const bundlePkg =
|
|
4568
|
-
if (
|
|
4589
|
+
const bundlePkg = join13(dir, "..", "..", "package.json");
|
|
4590
|
+
if (existsSync11(bundlePkg)) {
|
|
4569
4591
|
try {
|
|
4570
|
-
const pkg = JSON.parse(
|
|
4592
|
+
const pkg = JSON.parse(readFileSync13(bundlePkg, "utf8"));
|
|
4571
4593
|
if (pkg.name === "@suveren/gateway" && typeof pkg.version === "string") {
|
|
4572
4594
|
return pkg.version;
|
|
4573
4595
|
}
|
|
@@ -4606,7 +4628,7 @@ app.get("/health", async (req, res) => {
|
|
|
4606
4628
|
}
|
|
4607
4629
|
});
|
|
4608
4630
|
});
|
|
4609
|
-
if (
|
|
4631
|
+
if (existsSync11(UI_DIST)) {
|
|
4610
4632
|
app.use(express.static(UI_DIST, {
|
|
4611
4633
|
setHeaders: (res, filePath) => {
|
|
4612
4634
|
if (filePath.endsWith("index.html")) {
|
|
@@ -4616,7 +4638,7 @@ if (existsSync10(UI_DIST)) {
|
|
|
4616
4638
|
}));
|
|
4617
4639
|
app.get("*", (_req, res) => {
|
|
4618
4640
|
res.setHeader("Cache-Control", "no-store, must-revalidate");
|
|
4619
|
-
res.sendFile(
|
|
4641
|
+
res.sendFile(join13(UI_DIST, "index.html"));
|
|
4620
4642
|
});
|
|
4621
4643
|
} else {
|
|
4622
4644
|
app.get("/", (_req, res) => {
|
|
@@ -4638,16 +4660,26 @@ app.listen(port, "0.0.0.0", () => {
|
|
|
4638
4660
|
console.error(`[Control Plane] UI dist: ${UI_DIST}`);
|
|
4639
4661
|
console.error(`[Control Plane] Internal secret: configured`);
|
|
4640
4662
|
console.error(`[Control Plane] MCP server: ${MCP_BASE}`);
|
|
4641
|
-
|
|
4642
|
-
const
|
|
4643
|
-
|
|
4644
|
-
|
|
4645
|
-
|
|
4646
|
-
|
|
4647
|
-
|
|
4663
|
+
void (async () => {
|
|
4664
|
+
const deadline = Date.now() + 6e4;
|
|
4665
|
+
let lastErr;
|
|
4666
|
+
for (let delay = 500; Date.now() < deadline; delay = Math.min(delay * 2, 5e3)) {
|
|
4667
|
+
try {
|
|
4668
|
+
const d = await getManifests();
|
|
4669
|
+
const n = d?.manifests?.length ?? 0;
|
|
4670
|
+
if (n === 0) {
|
|
4671
|
+
console.error(`[Control Plane] \u26A0 MCP server at ${MCP_BASE} returned 0 integration manifests \u2014 wrong SUVEREN_MCP_INTERNAL_URL? (dev MCP is :3431, npm is :3430)`);
|
|
4672
|
+
} else {
|
|
4673
|
+
console.error(`[Control Plane] Integrations: ${n} manifests loaded from ${MCP_BASE}`);
|
|
4674
|
+
void backfillReadPolicyDefaults(d);
|
|
4675
|
+
}
|
|
4676
|
+
return;
|
|
4677
|
+
} catch (err) {
|
|
4678
|
+
lastErr = err;
|
|
4679
|
+
await new Promise((r) => setTimeout(r, delay));
|
|
4680
|
+
}
|
|
4648
4681
|
}
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
});
|
|
4682
|
+
console.error(`[Control Plane] \u26A0 Could not reach MCP server at ${MCP_BASE} for manifests within 60 s \u2014 wrong SUVEREN_MCP_INTERNAL_URL? (dev=:3431, npm=:3430). ${lastErr instanceof Error ? lastErr.message : lastErr}`);
|
|
4683
|
+
})();
|
|
4652
4684
|
startUpdateChecker(INSTALL_METHOD, RUNNING_VERSION);
|
|
4653
4685
|
});
|