@sanctuary-framework/mcp-server 0.10.0 → 0.10.1
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/dist/cli.cjs +41 -12
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +41 -12
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +26 -2
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +18 -0
- package/dist/index.d.ts +18 -0
- package/dist/index.js +26 -2
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -2040,6 +2040,7 @@ var init_audit_log = __esm({
|
|
|
2040
2040
|
maxTotalSizeBytes;
|
|
2041
2041
|
maxEntries;
|
|
2042
2042
|
rotationInFlight = false;
|
|
2043
|
+
pendingWrites = /* @__PURE__ */ new Set();
|
|
2043
2044
|
constructor(storage, masterKey, config) {
|
|
2044
2045
|
this.storage = storage;
|
|
2045
2046
|
this.encryptionKey = derivePurposeKey(masterKey, "audit-log");
|
|
@@ -2048,6 +2049,15 @@ var init_audit_log = __esm({
|
|
|
2048
2049
|
}
|
|
2049
2050
|
/**
|
|
2050
2051
|
* Append an audit entry.
|
|
2052
|
+
*
|
|
2053
|
+
* The on-disk persist is async and tracked via `pendingWrites`. Long-lived
|
|
2054
|
+
* callers (the main MCP server) can ignore that tracking and let writes
|
|
2055
|
+
* drain naturally. Short-lived callers — the `sanctuary secrets` CLI which
|
|
2056
|
+
* `process.exit()`s immediately after returning from a broker mutation —
|
|
2057
|
+
* MUST await `flush()` before exiting, or in-flight writes get killed
|
|
2058
|
+
* with the event loop and the entry is silently lost. That was the
|
|
2059
|
+
* v0.10.0-rc.2 soak failure mode where `secrets audit` returned empty
|
|
2060
|
+
* after a clean 7-verb lifecycle.
|
|
2051
2061
|
*/
|
|
2052
2062
|
append(layer, operation, identityId, details, result = "success") {
|
|
2053
2063
|
const entry = {
|
|
@@ -2059,8 +2069,22 @@ var init_audit_log = __esm({
|
|
|
2059
2069
|
details
|
|
2060
2070
|
};
|
|
2061
2071
|
this.entries.push(entry);
|
|
2062
|
-
this.persistEntry(entry).catch(() => {
|
|
2072
|
+
const writePromise = this.persistEntry(entry).catch(() => {
|
|
2063
2073
|
});
|
|
2074
|
+
this.pendingWrites.add(writePromise);
|
|
2075
|
+
void writePromise.finally(() => this.pendingWrites.delete(writePromise));
|
|
2076
|
+
}
|
|
2077
|
+
/**
|
|
2078
|
+
* Wait for every in-flight `append()` persist (and its rotation pass) to
|
|
2079
|
+
* settle. Safe to call multiple times — newly-appended entries during a
|
|
2080
|
+
* flush are also awaited. Re-entrant only at the granularity of "drain
|
|
2081
|
+
* everything queued so far". Short-lived CLIs MUST call this before
|
|
2082
|
+
* `process.exit()` to keep audit writes durable.
|
|
2083
|
+
*/
|
|
2084
|
+
async flush() {
|
|
2085
|
+
while (this.pendingWrites.size > 0) {
|
|
2086
|
+
await Promise.allSettled([...this.pendingWrites]);
|
|
2087
|
+
}
|
|
2064
2088
|
}
|
|
2065
2089
|
async persistEntry(entry) {
|
|
2066
2090
|
const key = `${Date.now()}-${this.counter++}`;
|
|
@@ -2071,7 +2095,7 @@ var init_audit_log = __esm({
|
|
|
2071
2095
|
key,
|
|
2072
2096
|
stringToBytes(JSON.stringify(encrypted))
|
|
2073
2097
|
);
|
|
2074
|
-
this.maybeRotate().catch(() => {
|
|
2098
|
+
await this.maybeRotate().catch(() => {
|
|
2075
2099
|
});
|
|
2076
2100
|
}
|
|
2077
2101
|
/**
|
|
@@ -24131,11 +24155,13 @@ var init_runtime = __esm({
|
|
|
24131
24155
|
var cli_exports = {};
|
|
24132
24156
|
__export(cli_exports, {
|
|
24133
24157
|
COCOON_GOVERNOR_DEFAULTS: () => COCOON_GOVERNOR_DEFAULTS,
|
|
24158
|
+
PORT_FALLBACK_ATTEMPTS: () => PORT_FALLBACK_ATTEMPTS,
|
|
24134
24159
|
formatWrapSuccess: () => formatWrapSuccess,
|
|
24135
24160
|
parseCocoonArgs: () => parseCocoonArgs,
|
|
24136
24161
|
parseWrapArgs: () => parseWrapArgs,
|
|
24137
24162
|
runCocoon: () => runCocoon,
|
|
24138
|
-
runWrap: () => runWrap
|
|
24163
|
+
runWrap: () => runWrap,
|
|
24164
|
+
startDashboardWithFallback: () => startDashboardWithFallback
|
|
24139
24165
|
});
|
|
24140
24166
|
async function runWrap(options, deps = {}) {
|
|
24141
24167
|
if (options.unwrap) {
|
|
@@ -24379,7 +24405,8 @@ async function runCocoon(options) {
|
|
|
24379
24405
|
}
|
|
24380
24406
|
async function startDashboardWithFallback(startFn, preferredPort, authToken, serverVersion) {
|
|
24381
24407
|
let lastErr;
|
|
24382
|
-
for (let
|
|
24408
|
+
for (let i = 0; i < PORT_FALLBACK_ATTEMPTS; i++) {
|
|
24409
|
+
const port = preferredPort + i;
|
|
24383
24410
|
try {
|
|
24384
24411
|
const handle = await startFn({
|
|
24385
24412
|
port,
|
|
@@ -24398,8 +24425,9 @@ async function startDashboardWithFallback(startFn, preferredPort, authToken, ser
|
|
|
24398
24425
|
if (!isAddressInUse(err)) throw err;
|
|
24399
24426
|
}
|
|
24400
24427
|
}
|
|
24428
|
+
const lastPort = preferredPort + PORT_FALLBACK_ATTEMPTS - 1;
|
|
24401
24429
|
throw new Error(
|
|
24402
|
-
`No free dashboard port in
|
|
24430
|
+
`No free dashboard port in the ${PORT_FALLBACK_ATTEMPTS} ports starting at ${preferredPort} (tried ${preferredPort}-${lastPort}): ${lastErr?.message ?? "unknown"}`
|
|
24403
24431
|
);
|
|
24404
24432
|
}
|
|
24405
24433
|
function isAddressInUse(err) {
|
|
@@ -24647,7 +24675,7 @@ function printWrapHelp() {
|
|
|
24647
24675
|
5. Every tool call is logged, scanned, and tier-gated
|
|
24648
24676
|
`);
|
|
24649
24677
|
}
|
|
24650
|
-
var COCOON_GOVERNOR_DEFAULTS,
|
|
24678
|
+
var COCOON_GOVERNOR_DEFAULTS, PORT_FALLBACK_ATTEMPTS, parseCocoonArgs;
|
|
24651
24679
|
var init_cli = __esm({
|
|
24652
24680
|
"src/cocoon/cli.ts"() {
|
|
24653
24681
|
init_config_reader();
|
|
@@ -24661,7 +24689,7 @@ var init_cli = __esm({
|
|
|
24661
24689
|
rate_limit_per_tool: 20,
|
|
24662
24690
|
lifetime_limit: 1e3
|
|
24663
24691
|
};
|
|
24664
|
-
|
|
24692
|
+
PORT_FALLBACK_ATTEMPTS = 20;
|
|
24665
24693
|
parseCocoonArgs = parseWrapArgs;
|
|
24666
24694
|
}
|
|
24667
24695
|
});
|
|
@@ -26165,6 +26193,7 @@ async function openBroker(opts = {}) {
|
|
|
26165
26193
|
return {
|
|
26166
26194
|
broker,
|
|
26167
26195
|
close: async () => {
|
|
26196
|
+
await auditLog.flush();
|
|
26168
26197
|
}
|
|
26169
26198
|
};
|
|
26170
26199
|
}
|
|
@@ -27189,12 +27218,12 @@ function optionalNumber(args, key) {
|
|
|
27189
27218
|
const v = args[key];
|
|
27190
27219
|
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
27191
27220
|
}
|
|
27192
|
-
var
|
|
27221
|
+
var PKG_VERSION3;
|
|
27193
27222
|
var init_broker_server = __esm({
|
|
27194
27223
|
"src/mcp/broker-server.ts"() {
|
|
27224
|
+
init_config();
|
|
27195
27225
|
init_token_issuer();
|
|
27196
|
-
|
|
27197
|
-
({ version: PKG_VERSION3 } = require4("../../package.json"));
|
|
27226
|
+
PKG_VERSION3 = SANCTUARY_VERSION;
|
|
27198
27227
|
}
|
|
27199
27228
|
});
|
|
27200
27229
|
|
|
@@ -27613,8 +27642,8 @@ async function checkForUpdate(currentVersion) {
|
|
|
27613
27642
|
} catch {
|
|
27614
27643
|
}
|
|
27615
27644
|
}
|
|
27616
|
-
var
|
|
27617
|
-
var { version: PKG_VERSION4 } =
|
|
27645
|
+
var require4 = module$1.createRequire((typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('cli.cjs', document.baseURI).href)));
|
|
27646
|
+
var { version: PKG_VERSION4 } = require4("../package.json");
|
|
27618
27647
|
async function main() {
|
|
27619
27648
|
const args = process.argv.slice(2);
|
|
27620
27649
|
let passphrase = process.env.SANCTUARY_PASSPHRASE;
|