@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.js
CHANGED
|
@@ -2037,6 +2037,7 @@ var init_audit_log = __esm({
|
|
|
2037
2037
|
maxTotalSizeBytes;
|
|
2038
2038
|
maxEntries;
|
|
2039
2039
|
rotationInFlight = false;
|
|
2040
|
+
pendingWrites = /* @__PURE__ */ new Set();
|
|
2040
2041
|
constructor(storage, masterKey, config) {
|
|
2041
2042
|
this.storage = storage;
|
|
2042
2043
|
this.encryptionKey = derivePurposeKey(masterKey, "audit-log");
|
|
@@ -2045,6 +2046,15 @@ var init_audit_log = __esm({
|
|
|
2045
2046
|
}
|
|
2046
2047
|
/**
|
|
2047
2048
|
* Append an audit entry.
|
|
2049
|
+
*
|
|
2050
|
+
* The on-disk persist is async and tracked via `pendingWrites`. Long-lived
|
|
2051
|
+
* callers (the main MCP server) can ignore that tracking and let writes
|
|
2052
|
+
* drain naturally. Short-lived callers — the `sanctuary secrets` CLI which
|
|
2053
|
+
* `process.exit()`s immediately after returning from a broker mutation —
|
|
2054
|
+
* MUST await `flush()` before exiting, or in-flight writes get killed
|
|
2055
|
+
* with the event loop and the entry is silently lost. That was the
|
|
2056
|
+
* v0.10.0-rc.2 soak failure mode where `secrets audit` returned empty
|
|
2057
|
+
* after a clean 7-verb lifecycle.
|
|
2048
2058
|
*/
|
|
2049
2059
|
append(layer, operation, identityId, details, result = "success") {
|
|
2050
2060
|
const entry = {
|
|
@@ -2056,8 +2066,22 @@ var init_audit_log = __esm({
|
|
|
2056
2066
|
details
|
|
2057
2067
|
};
|
|
2058
2068
|
this.entries.push(entry);
|
|
2059
|
-
this.persistEntry(entry).catch(() => {
|
|
2069
|
+
const writePromise = this.persistEntry(entry).catch(() => {
|
|
2060
2070
|
});
|
|
2071
|
+
this.pendingWrites.add(writePromise);
|
|
2072
|
+
void writePromise.finally(() => this.pendingWrites.delete(writePromise));
|
|
2073
|
+
}
|
|
2074
|
+
/**
|
|
2075
|
+
* Wait for every in-flight `append()` persist (and its rotation pass) to
|
|
2076
|
+
* settle. Safe to call multiple times — newly-appended entries during a
|
|
2077
|
+
* flush are also awaited. Re-entrant only at the granularity of "drain
|
|
2078
|
+
* everything queued so far". Short-lived CLIs MUST call this before
|
|
2079
|
+
* `process.exit()` to keep audit writes durable.
|
|
2080
|
+
*/
|
|
2081
|
+
async flush() {
|
|
2082
|
+
while (this.pendingWrites.size > 0) {
|
|
2083
|
+
await Promise.allSettled([...this.pendingWrites]);
|
|
2084
|
+
}
|
|
2061
2085
|
}
|
|
2062
2086
|
async persistEntry(entry) {
|
|
2063
2087
|
const key = `${Date.now()}-${this.counter++}`;
|
|
@@ -2068,7 +2092,7 @@ var init_audit_log = __esm({
|
|
|
2068
2092
|
key,
|
|
2069
2093
|
stringToBytes(JSON.stringify(encrypted))
|
|
2070
2094
|
);
|
|
2071
|
-
this.maybeRotate().catch(() => {
|
|
2095
|
+
await this.maybeRotate().catch(() => {
|
|
2072
2096
|
});
|
|
2073
2097
|
}
|
|
2074
2098
|
/**
|
|
@@ -24128,11 +24152,13 @@ var init_runtime = __esm({
|
|
|
24128
24152
|
var cli_exports = {};
|
|
24129
24153
|
__export(cli_exports, {
|
|
24130
24154
|
COCOON_GOVERNOR_DEFAULTS: () => COCOON_GOVERNOR_DEFAULTS,
|
|
24155
|
+
PORT_FALLBACK_ATTEMPTS: () => PORT_FALLBACK_ATTEMPTS,
|
|
24131
24156
|
formatWrapSuccess: () => formatWrapSuccess,
|
|
24132
24157
|
parseCocoonArgs: () => parseCocoonArgs,
|
|
24133
24158
|
parseWrapArgs: () => parseWrapArgs,
|
|
24134
24159
|
runCocoon: () => runCocoon,
|
|
24135
|
-
runWrap: () => runWrap
|
|
24160
|
+
runWrap: () => runWrap,
|
|
24161
|
+
startDashboardWithFallback: () => startDashboardWithFallback
|
|
24136
24162
|
});
|
|
24137
24163
|
async function runWrap(options, deps = {}) {
|
|
24138
24164
|
if (options.unwrap) {
|
|
@@ -24376,7 +24402,8 @@ async function runCocoon(options) {
|
|
|
24376
24402
|
}
|
|
24377
24403
|
async function startDashboardWithFallback(startFn, preferredPort, authToken, serverVersion) {
|
|
24378
24404
|
let lastErr;
|
|
24379
|
-
for (let
|
|
24405
|
+
for (let i = 0; i < PORT_FALLBACK_ATTEMPTS; i++) {
|
|
24406
|
+
const port = preferredPort + i;
|
|
24380
24407
|
try {
|
|
24381
24408
|
const handle = await startFn({
|
|
24382
24409
|
port,
|
|
@@ -24395,8 +24422,9 @@ async function startDashboardWithFallback(startFn, preferredPort, authToken, ser
|
|
|
24395
24422
|
if (!isAddressInUse(err)) throw err;
|
|
24396
24423
|
}
|
|
24397
24424
|
}
|
|
24425
|
+
const lastPort = preferredPort + PORT_FALLBACK_ATTEMPTS - 1;
|
|
24398
24426
|
throw new Error(
|
|
24399
|
-
`No free dashboard port in
|
|
24427
|
+
`No free dashboard port in the ${PORT_FALLBACK_ATTEMPTS} ports starting at ${preferredPort} (tried ${preferredPort}-${lastPort}): ${lastErr?.message ?? "unknown"}`
|
|
24400
24428
|
);
|
|
24401
24429
|
}
|
|
24402
24430
|
function isAddressInUse(err) {
|
|
@@ -24644,7 +24672,7 @@ function printWrapHelp() {
|
|
|
24644
24672
|
5. Every tool call is logged, scanned, and tier-gated
|
|
24645
24673
|
`);
|
|
24646
24674
|
}
|
|
24647
|
-
var COCOON_GOVERNOR_DEFAULTS,
|
|
24675
|
+
var COCOON_GOVERNOR_DEFAULTS, PORT_FALLBACK_ATTEMPTS, parseCocoonArgs;
|
|
24648
24676
|
var init_cli = __esm({
|
|
24649
24677
|
"src/cocoon/cli.ts"() {
|
|
24650
24678
|
init_config_reader();
|
|
@@ -24658,7 +24686,7 @@ var init_cli = __esm({
|
|
|
24658
24686
|
rate_limit_per_tool: 20,
|
|
24659
24687
|
lifetime_limit: 1e3
|
|
24660
24688
|
};
|
|
24661
|
-
|
|
24689
|
+
PORT_FALLBACK_ATTEMPTS = 20;
|
|
24662
24690
|
parseCocoonArgs = parseWrapArgs;
|
|
24663
24691
|
}
|
|
24664
24692
|
});
|
|
@@ -26162,6 +26190,7 @@ async function openBroker(opts = {}) {
|
|
|
26162
26190
|
return {
|
|
26163
26191
|
broker,
|
|
26164
26192
|
close: async () => {
|
|
26193
|
+
await auditLog.flush();
|
|
26165
26194
|
}
|
|
26166
26195
|
};
|
|
26167
26196
|
}
|
|
@@ -27186,12 +27215,12 @@ function optionalNumber(args, key) {
|
|
|
27186
27215
|
const v = args[key];
|
|
27187
27216
|
return typeof v === "number" && Number.isFinite(v) ? v : void 0;
|
|
27188
27217
|
}
|
|
27189
|
-
var
|
|
27218
|
+
var PKG_VERSION3;
|
|
27190
27219
|
var init_broker_server = __esm({
|
|
27191
27220
|
"src/mcp/broker-server.ts"() {
|
|
27221
|
+
init_config();
|
|
27192
27222
|
init_token_issuer();
|
|
27193
|
-
|
|
27194
|
-
({ version: PKG_VERSION3 } = require4("../../package.json"));
|
|
27223
|
+
PKG_VERSION3 = SANCTUARY_VERSION;
|
|
27195
27224
|
}
|
|
27196
27225
|
});
|
|
27197
27226
|
|
|
@@ -27610,8 +27639,8 @@ async function checkForUpdate(currentVersion) {
|
|
|
27610
27639
|
} catch {
|
|
27611
27640
|
}
|
|
27612
27641
|
}
|
|
27613
|
-
var
|
|
27614
|
-
var { version: PKG_VERSION4 } =
|
|
27642
|
+
var require4 = createRequire(import.meta.url);
|
|
27643
|
+
var { version: PKG_VERSION4 } = require4("../package.json");
|
|
27615
27644
|
async function main() {
|
|
27616
27645
|
const args = process.argv.slice(2);
|
|
27617
27646
|
let passphrase = process.env.SANCTUARY_PASSPHRASE;
|