@suveren/gateway 0.30.0 → 0.31.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/content/integrations/calendar.json +3 -0
- package/content/integrations/crm.json +10 -0
- package/content/integrations/deploy-github.json +1 -0
- package/content/integrations/erp.json +4 -0
- package/content/integrations/gmail.json +4 -0
- package/content/integrations/linkedin.json +4 -0
- package/content/integrations/mail.json +1 -0
- package/content/integrations/mollie.json +5 -0
- package/content/integrations/records.json +4 -0
- package/dist/control-plane/index.mjs +81 -32
- package/dist/mcp-server/http.mjs +36 -1
- package/dist/ui/assets/index-B7qy0B9J.js +123 -0
- package/dist/ui/assets/index-DyZY5sLI.css +1 -0
- package/dist/ui/index.html +2 -2
- package/node_modules/undici/docs/docs/api/Client.md +2 -0
- package/node_modules/undici/lib/core/connect.js +10 -4
- package/node_modules/undici/lib/core/symbols.js +1 -0
- package/node_modules/undici/lib/dispatcher/agent.js +6 -2
- package/node_modules/undici/lib/dispatcher/client-h1.js +0 -2
- package/node_modules/undici/lib/dispatcher/client-h2.js +0 -4
- package/node_modules/undici/lib/dispatcher/client.js +3 -2
- package/node_modules/undici/lib/dispatcher/dispatcher-base.js +12 -0
- package/node_modules/undici/lib/handler/cache-handler.js +48 -0
- package/node_modules/undici/lib/handler/deduplication-handler.js +57 -13
- package/node_modules/undici/lib/handler/redirect-handler.js +8 -1
- package/node_modules/undici/lib/interceptor/decompress.js +15 -5
- package/node_modules/undici/lib/web/cookies/index.js +3 -1
- package/node_modules/undici/lib/web/cookies/parse.js +138 -137
- package/node_modules/undici/lib/web/cookies/util.js +21 -2
- package/node_modules/undici/lib/web/eventsource/eventsource-stream.js +90 -9
- package/node_modules/undici/lib/web/eventsource/eventsource.js +4 -1
- package/node_modules/undici/lib/web/fetch/index.js +3 -3
- package/node_modules/undici/lib/web/infra/index.js +14 -0
- package/node_modules/undici/lib/web/subresource-integrity/subresource-integrity.js +5 -5
- package/node_modules/undici/lib/web/websocket/receiver.js +13 -0
- package/node_modules/undici/package.json +1 -1
- package/node_modules/undici/types/client.d.ts +14 -0
- package/package.json +1 -1
- package/dist/ui/assets/index-C2BnlNib.js +0 -123
- package/dist/ui/assets/index-DPgewsLG.css +0 -1
|
@@ -122,6 +122,7 @@
|
|
|
122
122
|
}
|
|
123
123
|
},
|
|
124
124
|
"create_event": {
|
|
125
|
+
"summary": "Event: {summary|short}[ on {start.dateTime,start.date|date}]",
|
|
125
126
|
"executionMapping": {
|
|
126
127
|
"duration_minutes": "duration",
|
|
127
128
|
"lookahead_days": "lookahead",
|
|
@@ -143,6 +144,7 @@
|
|
|
143
144
|
"actionLabel": "Event created"
|
|
144
145
|
},
|
|
145
146
|
"update_event": {
|
|
147
|
+
"summary": "Update event[: {summary|short}]",
|
|
146
148
|
"executionMapping": {
|
|
147
149
|
"attendees": [
|
|
148
150
|
{
|
|
@@ -164,6 +166,7 @@
|
|
|
164
166
|
"actionLabel": "Event updated"
|
|
165
167
|
},
|
|
166
168
|
"delete_event": {
|
|
169
|
+
"summary": "Delete an event",
|
|
167
170
|
"executionMapping": {
|
|
168
171
|
"calendarId": "allowed_calendars"
|
|
169
172
|
},
|
|
@@ -74,6 +74,7 @@
|
|
|
74
74
|
},
|
|
75
75
|
"overrides": {
|
|
76
76
|
"create_contact": {
|
|
77
|
+
"summary": "Create contact {name}[ ({company})]",
|
|
77
78
|
"executionMapping": {
|
|
78
79
|
"type": "contact_type"
|
|
79
80
|
},
|
|
@@ -94,6 +95,7 @@
|
|
|
94
95
|
}
|
|
95
96
|
},
|
|
96
97
|
"update_contact": {
|
|
98
|
+
"summary": "Update contact {name,id}",
|
|
97
99
|
"executionMapping": {
|
|
98
100
|
"contact_type": "contact_type"
|
|
99
101
|
},
|
|
@@ -123,6 +125,7 @@
|
|
|
123
125
|
}
|
|
124
126
|
},
|
|
125
127
|
"delete_contact": {
|
|
128
|
+
"summary": "Archive a {contact_type} contact",
|
|
126
129
|
"executionMapping": {
|
|
127
130
|
"contact_type": "contact_type"
|
|
128
131
|
},
|
|
@@ -152,6 +155,7 @@
|
|
|
152
155
|
}
|
|
153
156
|
},
|
|
154
157
|
"restore_contact": {
|
|
158
|
+
"summary": "Restore a {contact_type} contact",
|
|
155
159
|
"executionMapping": {
|
|
156
160
|
"contact_type": "contact_type"
|
|
157
161
|
},
|
|
@@ -181,6 +185,7 @@
|
|
|
181
185
|
}
|
|
182
186
|
},
|
|
183
187
|
"convert_contact": {
|
|
188
|
+
"summary": "Convert a contact to {to_type}",
|
|
184
189
|
"executionMapping": {
|
|
185
190
|
"contact_type": "contact_type"
|
|
186
191
|
},
|
|
@@ -210,6 +215,7 @@
|
|
|
210
215
|
}
|
|
211
216
|
},
|
|
212
217
|
"log_activity": {
|
|
218
|
+
"summary": "Log {type}: {summary|short}",
|
|
213
219
|
"executionMapping": {
|
|
214
220
|
"contact_type": "contact_type"
|
|
215
221
|
},
|
|
@@ -229,6 +235,7 @@
|
|
|
229
235
|
}
|
|
230
236
|
},
|
|
231
237
|
"create_deal": {
|
|
238
|
+
"summary": "Create deal: {title|short}[ — {value|money}]",
|
|
232
239
|
"executionMapping": {
|
|
233
240
|
"contact_type": "contact_type"
|
|
234
241
|
},
|
|
@@ -248,6 +255,7 @@
|
|
|
248
255
|
}
|
|
249
256
|
},
|
|
250
257
|
"update_deal": {
|
|
258
|
+
"summary": "Update deal[: {title|short}][ — {value|money}]",
|
|
251
259
|
"executionMapping": {
|
|
252
260
|
"contact_type": "contact_type"
|
|
253
261
|
},
|
|
@@ -276,6 +284,7 @@
|
|
|
276
284
|
}
|
|
277
285
|
},
|
|
278
286
|
"create_task": {
|
|
287
|
+
"summary": "Create task: {title|short}[ (due {due_date|date})]",
|
|
279
288
|
"executionMapping": {
|
|
280
289
|
"contact_type": "contact_type"
|
|
281
290
|
},
|
|
@@ -295,6 +304,7 @@
|
|
|
295
304
|
}
|
|
296
305
|
},
|
|
297
306
|
"complete_task": {
|
|
307
|
+
"summary": "Complete a task",
|
|
298
308
|
"executionMapping": {
|
|
299
309
|
"contact_type": "contact_type"
|
|
300
310
|
},
|
|
@@ -99,6 +99,7 @@
|
|
|
99
99
|
"requiredValue": "unlimited"
|
|
100
100
|
},
|
|
101
101
|
"create_quote": {
|
|
102
|
+
"summary": "Quote of {value|money} net[ — {discount_pct|percent} discount]",
|
|
102
103
|
"executionMapping": {
|
|
103
104
|
"value": "value",
|
|
104
105
|
"discount_pct": "discount_pct",
|
|
@@ -133,6 +134,7 @@
|
|
|
133
134
|
}
|
|
134
135
|
},
|
|
135
136
|
"update_quote": {
|
|
137
|
+
"summary": "Update quote to {value|money} net[ — {discount_pct|percent} discount]",
|
|
136
138
|
"executionMapping": {
|
|
137
139
|
"value": "value",
|
|
138
140
|
"discount_pct": "discount_pct",
|
|
@@ -161,6 +163,7 @@
|
|
|
161
163
|
}
|
|
162
164
|
},
|
|
163
165
|
"send_quote": {
|
|
166
|
+
"summary": "Send quote of {value|money} net[ — {discount_pct|percent} discount]",
|
|
164
167
|
"executionMapping": {
|
|
165
168
|
"value": "value",
|
|
166
169
|
"discount_pct": "discount_pct",
|
|
@@ -179,6 +182,7 @@
|
|
|
179
182
|
}
|
|
180
183
|
},
|
|
181
184
|
"convert_quote_to_order": {
|
|
185
|
+
"summary": "Order of {value|money} net from a quote",
|
|
182
186
|
"executionMapping": {
|
|
183
187
|
"value": "value",
|
|
184
188
|
"discount_pct": "discount_pct",
|
|
@@ -80,6 +80,7 @@
|
|
|
80
80
|
},
|
|
81
81
|
"overrides": {
|
|
82
82
|
"send_message": {
|
|
83
|
+
"summary": "Email to {to|list}: {subject|short}",
|
|
83
84
|
"executionMapping": {
|
|
84
85
|
"to": [
|
|
85
86
|
{
|
|
@@ -108,6 +109,7 @@
|
|
|
108
109
|
"actionLabel": "Email sent"
|
|
109
110
|
},
|
|
110
111
|
"create_draft": {
|
|
112
|
+
"summary": "Draft email to {to|list}[: {subject|short}]",
|
|
111
113
|
"executionMapping": {
|
|
112
114
|
"to": [
|
|
113
115
|
{
|
|
@@ -136,6 +138,7 @@
|
|
|
136
138
|
"actionLabel": "Email drafted"
|
|
137
139
|
},
|
|
138
140
|
"send_draft": {
|
|
141
|
+
"summary": "Send a draft email",
|
|
139
142
|
"executionMapping": {},
|
|
140
143
|
"staticExecution": {
|
|
141
144
|
"recipient_count": 1,
|
|
@@ -206,6 +209,7 @@
|
|
|
206
209
|
}
|
|
207
210
|
},
|
|
208
211
|
"delete_draft": {
|
|
212
|
+
"summary": "Delete a draft email",
|
|
209
213
|
"executionMapping": {},
|
|
210
214
|
"staticExecution": {
|
|
211
215
|
"recipient_count": 0,
|
|
@@ -62,6 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"overrides": {
|
|
64
64
|
"create_post": {
|
|
65
|
+
"summary": "LinkedIn post: {text|short}",
|
|
65
66
|
"executionMapping": {
|
|
66
67
|
"visibility": "audience"
|
|
67
68
|
},
|
|
@@ -73,6 +74,7 @@
|
|
|
73
74
|
"actionLabel": "Post published"
|
|
74
75
|
},
|
|
75
76
|
"create_image_post": {
|
|
77
|
+
"summary": "LinkedIn image post: {text|short}",
|
|
76
78
|
"executionMapping": {
|
|
77
79
|
"visibility": "audience"
|
|
78
80
|
},
|
|
@@ -84,6 +86,7 @@
|
|
|
84
86
|
"actionLabel": "Image post published"
|
|
85
87
|
},
|
|
86
88
|
"create_article_post": {
|
|
89
|
+
"summary": "LinkedIn article: {title,articleUrl|short}",
|
|
87
90
|
"executionMapping": {
|
|
88
91
|
"visibility": "audience"
|
|
89
92
|
},
|
|
@@ -95,6 +98,7 @@
|
|
|
95
98
|
"actionLabel": "Article published"
|
|
96
99
|
},
|
|
97
100
|
"delete_post": {
|
|
101
|
+
"summary": "Delete a LinkedIn post",
|
|
98
102
|
"executionMapping": {},
|
|
99
103
|
"staticExecution": {
|
|
100
104
|
"allowed_platforms": "linkedin",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
},
|
|
39
39
|
"overrides": {
|
|
40
40
|
"CreatePayment": {
|
|
41
|
+
"summary": "Payment of {amount|money}: {description|short}",
|
|
41
42
|
"executionMapping": {
|
|
42
43
|
"amount": "amount",
|
|
43
44
|
"currency": "currency"
|
|
@@ -56,6 +57,7 @@
|
|
|
56
57
|
}
|
|
57
58
|
},
|
|
58
59
|
"CreatePaymentLink": {
|
|
60
|
+
"summary": "Payment link[ of {amount|money}]: {description|short}",
|
|
59
61
|
"executionMapping": {
|
|
60
62
|
"amount": "amount",
|
|
61
63
|
"currency": "currency"
|
|
@@ -89,12 +91,14 @@
|
|
|
89
91
|
}
|
|
90
92
|
},
|
|
91
93
|
"CancelSubscription": {
|
|
94
|
+
"summary": "Cancel a subscription",
|
|
92
95
|
"executionMapping": {},
|
|
93
96
|
"staticExecution": {
|
|
94
97
|
"action_type": "subscribe"
|
|
95
98
|
}
|
|
96
99
|
},
|
|
97
100
|
"CreateCustomer": {
|
|
101
|
+
"summary": "Create payment customer[ {name}]",
|
|
98
102
|
"executionMapping": {},
|
|
99
103
|
"staticExecution": {
|
|
100
104
|
"action_type": "charge"
|
|
@@ -113,6 +117,7 @@
|
|
|
113
117
|
}
|
|
114
118
|
},
|
|
115
119
|
"RevokeMandate": {
|
|
120
|
+
"summary": "Revoke a payment mandate",
|
|
116
121
|
"executionMapping": {},
|
|
117
122
|
"staticExecution": {
|
|
118
123
|
"action_type": "charge"
|
|
@@ -52,6 +52,7 @@
|
|
|
52
52
|
"category": "disabled"
|
|
53
53
|
},
|
|
54
54
|
"create_record": {
|
|
55
|
+
"summary": "Create {type}: {title|short}",
|
|
55
56
|
"executionMapping": {},
|
|
56
57
|
"staticExecution": {
|
|
57
58
|
"action_type": "write"
|
|
@@ -59,6 +60,7 @@
|
|
|
59
60
|
"actionLabel": "Record created"
|
|
60
61
|
},
|
|
61
62
|
"archive_record": {
|
|
63
|
+
"summary": "Archive a record",
|
|
62
64
|
"boundField": "archive_access",
|
|
63
65
|
"requiredValue": "allowed",
|
|
64
66
|
"executionMapping": {},
|
|
@@ -68,10 +70,12 @@
|
|
|
68
70
|
"actionLabel": "Record archived"
|
|
69
71
|
},
|
|
70
72
|
"update_record": {
|
|
73
|
+
"summary": "Update record[: {title|short}]",
|
|
71
74
|
"category": "disabled",
|
|
72
75
|
"actionLabel": "Record updated"
|
|
73
76
|
},
|
|
74
77
|
"delete_record": {
|
|
78
|
+
"summary": "Delete a record",
|
|
75
79
|
"boundField": "delete_access",
|
|
76
80
|
"requiredValue": "allowed",
|
|
77
81
|
"executionMapping": {},
|
|
@@ -5,9 +5,9 @@ import {
|
|
|
5
5
|
|
|
6
6
|
// src/index.ts
|
|
7
7
|
import { randomBytes as randomBytes3 } from "crypto";
|
|
8
|
-
import { existsSync as existsSync13, readFileSync as
|
|
9
|
-
import { dirname as
|
|
10
|
-
import { homedir as
|
|
8
|
+
import { existsSync as existsSync13, readFileSync as readFileSync17, renameSync as renameSync5 } from "fs";
|
|
9
|
+
import { dirname as dirname12, join as join17 } from "path";
|
|
10
|
+
import { homedir as homedir10 } from "os";
|
|
11
11
|
import express from "express";
|
|
12
12
|
import { createProxyMiddleware } from "http-proxy-middleware";
|
|
13
13
|
|
|
@@ -3384,15 +3384,15 @@ import { promisify } from "util";
|
|
|
3384
3384
|
var run = promisify(execFile);
|
|
3385
3385
|
var SUPPORTED = /* @__PURE__ */ new Set(["darwin", "win32", "linux"]);
|
|
3386
3386
|
var MODULE_DIR = pathDirname(fileURLToPath(import.meta.url));
|
|
3387
|
-
function findCli(
|
|
3387
|
+
function findCli(dirname13 = MODULE_DIR) {
|
|
3388
3388
|
const candidates = [
|
|
3389
3389
|
// Bundled (the shipped layout): dist/control-plane → dist → root → bin
|
|
3390
|
-
resolve(
|
|
3390
|
+
resolve(dirname13, "..", "..", "bin", "suveren-gateway.js"),
|
|
3391
3391
|
// Bundled, were the routes/ directory ever preserved.
|
|
3392
|
-
resolve(
|
|
3392
|
+
resolve(dirname13, "..", "..", "..", "bin", "suveren-gateway.js"),
|
|
3393
3393
|
// Dev, running from source: the repo's own bundle directory.
|
|
3394
|
-
resolve(
|
|
3395
|
-
resolve(
|
|
3394
|
+
resolve(dirname13, "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js"),
|
|
3395
|
+
resolve(dirname13, "..", "..", "..", "..", "..", "bundle", "bin", "suveren-gateway.js")
|
|
3396
3396
|
// Deliberately NO process.cwd() fallback: it makes the result depend on
|
|
3397
3397
|
// where the process happened to be launched from, so the same install
|
|
3398
3398
|
// resolves differently between a shell and a login service — and it would
|
|
@@ -4677,14 +4677,62 @@ function createBlockedSeenRouter(dataDir) {
|
|
|
4677
4677
|
return router;
|
|
4678
4678
|
}
|
|
4679
4679
|
|
|
4680
|
-
// src/routes/
|
|
4680
|
+
// src/routes/tickets-seen.ts
|
|
4681
4681
|
import { Router as Router20 } from "express";
|
|
4682
|
+
|
|
4683
|
+
// src/lib/tickets-seen-store.ts
|
|
4684
|
+
import { readFileSync as readFileSync15, writeFileSync as writeFileSync10, mkdirSync as mkdirSync10, renameSync as renameSync4 } from "fs";
|
|
4685
|
+
import { homedir as homedir9 } from "os";
|
|
4686
|
+
import { join as join15, dirname as dirname11 } from "path";
|
|
4687
|
+
function storePath3(dataDir) {
|
|
4688
|
+
const dir = dataDir ?? process.env.SUVEREN_DATA_DIR ?? join15(homedir9(), ".suveren");
|
|
4689
|
+
return join15(dir, "tickets-seen.json");
|
|
4690
|
+
}
|
|
4691
|
+
function readLastSeenTicketsAt(dataDir) {
|
|
4692
|
+
try {
|
|
4693
|
+
const raw = JSON.parse(readFileSync15(storePath3(dataDir), "utf8"));
|
|
4694
|
+
return typeof raw.lastSeenTicketsAt === "number" && Number.isFinite(raw.lastSeenTicketsAt) ? raw.lastSeenTicketsAt : 0;
|
|
4695
|
+
} catch {
|
|
4696
|
+
return 0;
|
|
4697
|
+
}
|
|
4698
|
+
}
|
|
4699
|
+
function markTicketsSeen(ts, dataDir) {
|
|
4700
|
+
const safeTs = typeof ts === "number" && Number.isFinite(ts) ? ts : Date.now();
|
|
4701
|
+
const path = storePath3(dataDir);
|
|
4702
|
+
mkdirSync10(dirname11(path), { recursive: true });
|
|
4703
|
+
const tmp = `${path}.tmp`;
|
|
4704
|
+
writeFileSync10(tmp, JSON.stringify({ lastSeenTicketsAt: safeTs }, null, 2) + "\n", "utf8");
|
|
4705
|
+
renameSync4(tmp, path);
|
|
4706
|
+
return safeTs;
|
|
4707
|
+
}
|
|
4708
|
+
|
|
4709
|
+
// src/routes/tickets-seen.ts
|
|
4710
|
+
function createTicketsSeenRouter(dataDir) {
|
|
4711
|
+
const router = Router20();
|
|
4712
|
+
router.get("/", (_req, res) => {
|
|
4713
|
+
res.json({ lastSeenTicketsAt: readLastSeenTicketsAt(dataDir) });
|
|
4714
|
+
});
|
|
4715
|
+
router.post("/", (req, res) => {
|
|
4716
|
+
const body = req.body;
|
|
4717
|
+
const ts = typeof body?.ts === "number" && Number.isFinite(body.ts) ? body.ts : Date.now();
|
|
4718
|
+
try {
|
|
4719
|
+
res.json({ lastSeenTicketsAt: markTicketsSeen(ts, dataDir) });
|
|
4720
|
+
} catch (err) {
|
|
4721
|
+
res.status(500).json({ error: `Could not save: ${err.message}` });
|
|
4722
|
+
}
|
|
4723
|
+
});
|
|
4724
|
+
return router;
|
|
4725
|
+
}
|
|
4726
|
+
|
|
4727
|
+
// src/routes/internal-events.ts
|
|
4728
|
+
import { Router as Router21 } from "express";
|
|
4682
4729
|
import { timingSafeEqual as timingSafeEqual3 } from "crypto";
|
|
4683
4730
|
var ALLOWED = [
|
|
4684
4731
|
"proposal-added",
|
|
4685
4732
|
"action-approval-needed",
|
|
4686
4733
|
"execution-failed",
|
|
4687
|
-
"denial-recorded"
|
|
4734
|
+
"denial-recorded",
|
|
4735
|
+
"ticket-recorded"
|
|
4688
4736
|
];
|
|
4689
4737
|
var SESSION_EXPIRED = "session-expired";
|
|
4690
4738
|
var AS_KEY_MISMATCH = "as-key-mismatch";
|
|
@@ -4698,7 +4746,7 @@ function secretMatches2(provided, expected) {
|
|
|
4698
4746
|
return timingSafeEqual3(a, b);
|
|
4699
4747
|
}
|
|
4700
4748
|
function createInternalEventsRouter(getSecret, onSessionExpired, onAsKeyMismatch, onAsTlsMismatch) {
|
|
4701
|
-
const router =
|
|
4749
|
+
const router = Router21();
|
|
4702
4750
|
router.post("/event", (req, res) => {
|
|
4703
4751
|
if (!secretMatches2(req.headers["x-internal-secret"], getSecret())) {
|
|
4704
4752
|
res.status(401).json({ error: "Unauthorized" });
|
|
@@ -4732,7 +4780,7 @@ function createInternalEventsRouter(getSecret, onSessionExpired, onAsKeyMismatch
|
|
|
4732
4780
|
}
|
|
4733
4781
|
|
|
4734
4782
|
// src/routes/internal-mandate.ts
|
|
4735
|
-
import { Router as
|
|
4783
|
+
import { Router as Router22 } from "express";
|
|
4736
4784
|
import { timingSafeEqual as timingSafeEqual4, randomUUID } from "crypto";
|
|
4737
4785
|
|
|
4738
4786
|
// src/lib/mandate-ceremony.ts
|
|
@@ -4914,7 +4962,7 @@ function secretMatches3(provided, expected) {
|
|
|
4914
4962
|
return a.length === b.length && timingSafeEqual4(a, b);
|
|
4915
4963
|
}
|
|
4916
4964
|
function createInternalMandateRouter(getSecret, deps) {
|
|
4917
|
-
const router =
|
|
4965
|
+
const router = Router22();
|
|
4918
4966
|
router.post("/mandate", async (req, res) => {
|
|
4919
4967
|
if (!secretMatches3(req.header("X-Internal-Secret") ?? void 0, getSecret())) {
|
|
4920
4968
|
res.status(401).json({ error: "unauthorized" });
|
|
@@ -5117,17 +5165,17 @@ function buildSessionHealth(vault2) {
|
|
|
5117
5165
|
}
|
|
5118
5166
|
|
|
5119
5167
|
// src/lib/denials-reader.ts
|
|
5120
|
-
import { existsSync as existsSync12, readFileSync as
|
|
5121
|
-
import { join as
|
|
5168
|
+
import { existsSync as existsSync12, readFileSync as readFileSync16 } from "fs";
|
|
5169
|
+
import { join as join16 } from "path";
|
|
5122
5170
|
function loadDenials(dataDir, decrypt) {
|
|
5123
|
-
const encPath =
|
|
5124
|
-
const plainPath =
|
|
5171
|
+
const encPath = join16(dataDir, "denials.enc.json");
|
|
5172
|
+
const plainPath = join16(dataDir, "denials.json");
|
|
5125
5173
|
if (existsSync12(encPath)) {
|
|
5126
|
-
const { blob } = JSON.parse(
|
|
5174
|
+
const { blob } = JSON.parse(readFileSync16(encPath, "utf-8"));
|
|
5127
5175
|
return JSON.parse(decrypt(blob)).records ?? [];
|
|
5128
5176
|
}
|
|
5129
5177
|
if (existsSync12(plainPath)) {
|
|
5130
|
-
return JSON.parse(
|
|
5178
|
+
return JSON.parse(readFileSync16(plainPath, "utf-8")).records ?? [];
|
|
5131
5179
|
}
|
|
5132
5180
|
return [];
|
|
5133
5181
|
}
|
|
@@ -5151,11 +5199,11 @@ function isSimulationMode() {
|
|
|
5151
5199
|
// src/index.ts
|
|
5152
5200
|
(function migrateDataDir() {
|
|
5153
5201
|
if (process.env.SUVEREN_DATA_DIR) return;
|
|
5154
|
-
const oldDir =
|
|
5155
|
-
const newDir =
|
|
5202
|
+
const oldDir = join17(homedir10(), ".hap");
|
|
5203
|
+
const newDir = join17(homedir10(), ".suveren");
|
|
5156
5204
|
if (!existsSync13(newDir) && existsSync13(oldDir)) {
|
|
5157
5205
|
try {
|
|
5158
|
-
|
|
5206
|
+
renameSync5(oldDir, newDir);
|
|
5159
5207
|
console.error(`[Control Plane] Migrated data directory: ${oldDir} \u2192 ${newDir}`);
|
|
5160
5208
|
} catch (err) {
|
|
5161
5209
|
console.error(`[Control Plane] FATAL: could not migrate data directory ${oldDir} \u2192 ${newDir}:`, err);
|
|
@@ -5163,7 +5211,7 @@ function isSimulationMode() {
|
|
|
5163
5211
|
}
|
|
5164
5212
|
}
|
|
5165
5213
|
})();
|
|
5166
|
-
var DATA_DIR = process.env.SUVEREN_DATA_DIR ??
|
|
5214
|
+
var DATA_DIR = process.env.SUVEREN_DATA_DIR ?? join17(homedir10(), ".suveren");
|
|
5167
5215
|
var SP_URL = resolveAsUrl(DATA_DIR);
|
|
5168
5216
|
validatePinTlsForUrl(resolvePinTls(DATA_DIR), SP_URL);
|
|
5169
5217
|
var POLICY_LOCKED = [...readPolicy().locked];
|
|
@@ -5171,7 +5219,7 @@ var POLICY_LOCKED_INSTALL_METHOD = readPolicy().policy.installMethod;
|
|
|
5171
5219
|
var POLICY_LOCKED_TEAM = readPolicy().policy.team;
|
|
5172
5220
|
var port = parseInt(process.env.SUVEREN_CP_PORT ?? "3402", 10);
|
|
5173
5221
|
var HAP_MODE = process.env.HAP_MODE ?? "personal";
|
|
5174
|
-
var UI_DIST = process.env.HAP_UI_DIST ??
|
|
5222
|
+
var UI_DIST = process.env.HAP_UI_DIST ?? join17(import.meta.dirname ?? __dirname, "../../ui/dist");
|
|
5175
5223
|
var vault = new Vault(DATA_DIR);
|
|
5176
5224
|
var shownSnapshotStore = new ShownSnapshotStore(DATA_DIR);
|
|
5177
5225
|
(function repairIfAsUrlChanged() {
|
|
@@ -5481,6 +5529,7 @@ app.use("/autostart", jsonParser, authGuard, createAutostartRouter());
|
|
|
5481
5529
|
app.use("/api/gateway-settings", jsonParser, authGuard, createGatewaySettingsRouter());
|
|
5482
5530
|
app.use("/api/archived-mandates", jsonParser, authGuard, createArchivedMandatesRouter());
|
|
5483
5531
|
app.use("/api/blocked-seen", jsonParser, authGuard, createBlockedSeenRouter());
|
|
5532
|
+
app.use("/api/tickets-seen", jsonParser, authGuard, createTicketsSeenRouter());
|
|
5484
5533
|
app.use("/api/encrypt-intent", jsonParser, authGuard, createEncryptIntentRouter());
|
|
5485
5534
|
app.use("/api/evidence-export", authGuard, createEvidenceExportRouter(SP_URL, vault, DATA_DIR, lockAsTlsMismatch));
|
|
5486
5535
|
app.use("/proposal-status", jsonParser, authGuard, createProposalStatusRouter(SP_URL, vault, DATA_DIR, lockAsTlsMismatch, shownSnapshotStore));
|
|
@@ -5657,7 +5706,7 @@ app.get("/as-pairing", authGuard, (_req, res) => {
|
|
|
5657
5706
|
});
|
|
5658
5707
|
app.get("/denials", authGuard, (req, res) => {
|
|
5659
5708
|
try {
|
|
5660
|
-
const dataDir = process.env.SUVEREN_DATA_DIR ??
|
|
5709
|
+
const dataDir = process.env.SUVEREN_DATA_DIR ?? join17(homedir10(), ".suveren");
|
|
5661
5710
|
const all = loadDenials(dataDir, (blob) => vault.decrypt(blob));
|
|
5662
5711
|
const since = Number(req.query.since);
|
|
5663
5712
|
const limit = Number(req.query.limit);
|
|
@@ -5716,12 +5765,12 @@ app.put("/agent-brief/context", jsonParser, authGuard, async (req, res) => {
|
|
|
5716
5765
|
res.status(413).json({ error: `Context exceeds ${AGENT_CONTEXT_MAX_BYTES}-byte cap` });
|
|
5717
5766
|
return;
|
|
5718
5767
|
}
|
|
5719
|
-
const { mkdirSync:
|
|
5768
|
+
const { mkdirSync: mkdirSync11, writeFileSync: writeFileSync11, renameSync: renameSync6 } = await import("fs");
|
|
5720
5769
|
const filePath = agentBriefPath();
|
|
5721
|
-
|
|
5770
|
+
mkdirSync11(dirname12(filePath), { recursive: true });
|
|
5722
5771
|
const tmpPath = `${filePath}.tmp`;
|
|
5723
|
-
|
|
5724
|
-
|
|
5772
|
+
writeFileSync11(tmpPath, content, "utf-8");
|
|
5773
|
+
renameSync6(tmpPath, filePath);
|
|
5725
5774
|
res.json({ ok: true });
|
|
5726
5775
|
} catch (err) {
|
|
5727
5776
|
console.error("[Control Plane] agent-brief/context PUT failed:", err);
|
|
@@ -5813,10 +5862,10 @@ function detectRunningVersion() {
|
|
|
5813
5862
|
return process.env.HAP_BUILD_SHA ?? "dev";
|
|
5814
5863
|
}
|
|
5815
5864
|
const dir = import.meta.dirname ?? __dirname;
|
|
5816
|
-
const bundlePkg =
|
|
5865
|
+
const bundlePkg = join17(dir, "..", "..", "package.json");
|
|
5817
5866
|
if (existsSync13(bundlePkg)) {
|
|
5818
5867
|
try {
|
|
5819
|
-
const pkg = JSON.parse(
|
|
5868
|
+
const pkg = JSON.parse(readFileSync17(bundlePkg, "utf8"));
|
|
5820
5869
|
if (pkg.name === "@suveren/gateway" && typeof pkg.version === "string") {
|
|
5821
5870
|
return pkg.version;
|
|
5822
5871
|
}
|
|
@@ -5868,7 +5917,7 @@ if (existsSync13(UI_DIST)) {
|
|
|
5868
5917
|
}));
|
|
5869
5918
|
app.get("*", (_req, res) => {
|
|
5870
5919
|
res.setHeader("Cache-Control", "no-store, must-revalidate");
|
|
5871
|
-
res.sendFile(
|
|
5920
|
+
res.sendFile(join17(UI_DIST, "index.html"));
|
|
5872
5921
|
});
|
|
5873
5922
|
} else {
|
|
5874
5923
|
app.get("/", (_req, res) => {
|
package/dist/mcp-server/http.mjs
CHANGED
|
@@ -3348,6 +3348,7 @@ var SharedState = class {
|
|
|
3348
3348
|
} catch (err) {
|
|
3349
3349
|
throw new ArchiveWriteError(`Receipt archive write failed: ${err instanceof Error ? err.message : String(err)}`);
|
|
3350
3350
|
}
|
|
3351
|
+
void notifyControlPlane("ticket-recorded");
|
|
3351
3352
|
}
|
|
3352
3353
|
setGateContent(path, authorizationId, profileId, content, opts) {
|
|
3353
3354
|
this.gateStore.set(authorizationId, {
|
|
@@ -4020,10 +4021,44 @@ function invalidDisplayHintsReason(toolName, entry) {
|
|
|
4020
4021
|
}
|
|
4021
4022
|
return null;
|
|
4022
4023
|
}
|
|
4024
|
+
var SUMMARY_FORMATS = ["money", "percent", "list", "short", "date"];
|
|
4025
|
+
function invalidSummaryReason(toolName, entry) {
|
|
4026
|
+
if (entry === null || typeof entry !== "object") return null;
|
|
4027
|
+
const summary = entry.summary;
|
|
4028
|
+
if (summary === void 0) return null;
|
|
4029
|
+
const at = `override "${toolName}".summary`;
|
|
4030
|
+
if (typeof summary !== "string" || summary.trim().length === 0) return `${at} must be a non-empty string`;
|
|
4031
|
+
if (summary.length > 200) return `${at} must be at most 200 characters`;
|
|
4032
|
+
const balanced = (open, close) => {
|
|
4033
|
+
let d = 0;
|
|
4034
|
+
for (const ch of summary) {
|
|
4035
|
+
if (ch === open) {
|
|
4036
|
+
d += 1;
|
|
4037
|
+
if (d > 1) return false;
|
|
4038
|
+
}
|
|
4039
|
+
if (ch === close) {
|
|
4040
|
+
d -= 1;
|
|
4041
|
+
if (d < 0) return false;
|
|
4042
|
+
}
|
|
4043
|
+
}
|
|
4044
|
+
return d === 0;
|
|
4045
|
+
};
|
|
4046
|
+
if (!balanced("{", "}")) return `${at} has unbalanced or nested { }`;
|
|
4047
|
+
if (!balanced("[", "]")) return `${at} has unbalanced or nested [ ]`;
|
|
4048
|
+
for (const m of summary.matchAll(/\{([^{}]+)\}/g)) {
|
|
4049
|
+
const [paths, fmt, extra] = m[1].split("|").map((x) => x.trim());
|
|
4050
|
+
if (extra !== void 0) return `${at} {${m[1]}} has more than one format`;
|
|
4051
|
+
if (!paths.split(",").every((p) => /^[A-Za-z_][\w-]*(\.[A-Za-z_][\w-]*)*$/.test(p.trim()))) {
|
|
4052
|
+
return `${at} {${m[1]}} has an invalid field path`;
|
|
4053
|
+
}
|
|
4054
|
+
if (fmt !== void 0 && !SUMMARY_FORMATS.includes(fmt)) return `${at} {${m[1]}} has unknown format "${fmt}"`;
|
|
4055
|
+
}
|
|
4056
|
+
return null;
|
|
4057
|
+
}
|
|
4023
4058
|
function invalidManifestPreviewReason(manifest) {
|
|
4024
4059
|
const overrides = manifest.toolGating?.overrides ?? {};
|
|
4025
4060
|
for (const [toolName, entry] of Object.entries(overrides)) {
|
|
4026
|
-
const reason = invalidPreviewReason(toolName, entry) ?? invalidDisplayHintsReason(toolName, entry);
|
|
4061
|
+
const reason = invalidPreviewReason(toolName, entry) ?? invalidDisplayHintsReason(toolName, entry) ?? invalidSummaryReason(toolName, entry);
|
|
4027
4062
|
if (reason) return reason;
|
|
4028
4063
|
}
|
|
4029
4064
|
return null;
|