@sanctuary-framework/mcp-server 1.1.1 → 1.1.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/dist/cli.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  import { mkdir, writeFile, readFile, stat, unlink, readdir, rm, chmod, access, constants, appendFile, lstat, copyFile, realpath } from 'fs/promises';
3
- import { join, dirname, isAbsolute, resolve, basename, sep } from 'path';
3
+ import { join, dirname, resolve, isAbsolute, basename, sep } from 'path';
4
4
  import { platform, homedir, userInfo, hostname } from 'os';
5
5
  import { createRequire } from 'module';
6
6
  import { createHash, randomBytes as randomBytes$1, randomUUID, createHmac } from 'crypto';
@@ -11884,6 +11884,20 @@ async function handleRequest(deps, req, res) {
11884
11884
  const url = new URL(req.url ?? "/", `http://${host}`);
11885
11885
  const method = (req.method ?? "GET").toUpperCase();
11886
11886
  const path = url.pathname;
11887
+ if (deps.v11Bindings) {
11888
+ const handled = await dispatchV11Request(
11889
+ {
11890
+ bindings: deps.v11Bindings,
11891
+ ...deps.authToken !== void 0 ? { authToken: deps.authToken } : {},
11892
+ loopbackAutoAuth: deps.loopbackAutoAuth ?? false
11893
+ },
11894
+ req,
11895
+ res,
11896
+ url,
11897
+ method
11898
+ );
11899
+ if (handled) return true;
11900
+ }
11887
11901
  if (!isAuthorized(deps, req, url)) {
11888
11902
  writeJSON(res, 401, { error: "unauthorized" });
11889
11903
  return true;
@@ -12064,6 +12078,7 @@ var init_api = __esm({
12064
12078
  init_registry();
12065
12079
  init_init();
12066
12080
  init_discovery();
12081
+ init_dispatch();
12067
12082
  }
12068
12083
  });
12069
12084
 
@@ -13599,6 +13614,53 @@ var init_v1_1 = __esm({
13599
13614
  init_client();
13600
13615
  }
13601
13616
  });
13617
+
13618
+ // src/dashboard/v1_1/dispatch.ts
13619
+ async function dispatchV11Request(inputs, req, res, url, method) {
13620
+ const { bindings, authToken, loopbackAutoAuth } = inputs;
13621
+ if (method === "GET" && (url.pathname === "/v1.1" || url.pathname === "/v1.1/")) {
13622
+ return handleDashboardV11Route(
13623
+ {
13624
+ identityId: bindings.identityId,
13625
+ fortressId: bindings.fortressId,
13626
+ ...authToken !== void 0 ? { authToken } : {}
13627
+ },
13628
+ req,
13629
+ res
13630
+ );
13631
+ }
13632
+ if (url.pathname.startsWith("/api/hub/")) {
13633
+ const authConfig = {
13634
+ loopbackAutoAuth,
13635
+ ...authToken !== void 0 ? { authToken } : {}
13636
+ };
13637
+ return handleHubRoute(
13638
+ { authConfig, service: bindings.hubService },
13639
+ req,
13640
+ res
13641
+ );
13642
+ }
13643
+ if (method === "GET" && url.pathname === "/api/identities") {
13644
+ const authConfig = {
13645
+ loopbackAutoAuth,
13646
+ ...authToken !== void 0 ? { authToken } : {}
13647
+ };
13648
+ const aliasReq = Object.create(req);
13649
+ aliasReq.url = "/api/hub/agents" + url.search;
13650
+ return handleHubRoute(
13651
+ { authConfig, service: bindings.hubService },
13652
+ aliasReq,
13653
+ res
13654
+ );
13655
+ }
13656
+ return false;
13657
+ }
13658
+ var init_dispatch = __esm({
13659
+ "src/dashboard/v1_1/dispatch.ts"() {
13660
+ init_api_router();
13661
+ init_v1_1();
13662
+ }
13663
+ });
13602
13664
  function isDashboardViewRoute(method, path) {
13603
13665
  if (method !== "GET") return false;
13604
13666
  return path === "/" || path === "/dashboard" || path === "/fortress" || path === "/events";
@@ -13611,8 +13673,7 @@ var init_dashboard = __esm({
13611
13673
  init_dashboard_html();
13612
13674
  init_fortress_view();
13613
13675
  init_system_prompt_generator();
13614
- init_api_router();
13615
- init_v1_1();
13676
+ init_dispatch();
13616
13677
  SESSION_TTL_REMOTE_MS = 5 * 60 * 1e3;
13617
13678
  SESSION_TTL_LOCAL_MS = 24 * 60 * 60 * 1e3;
13618
13679
  MAX_SESSIONS = 1e3;
@@ -13734,45 +13795,17 @@ var init_dashboard = __esm({
13734
13795
  */
13735
13796
  async dispatchV11(req, res, url, method) {
13736
13797
  if (!this.v11Bindings) return false;
13737
- if (method === "GET" && (url.pathname === "/v1.1" || url.pathname === "/v1.1/")) {
13738
- const handled = handleDashboardV11Route(
13739
- {
13740
- identityId: this.v11Bindings.identityId,
13741
- fortressId: this.v11Bindings.fortressId,
13742
- ...this.authToken !== void 0 ? { authToken: this.authToken } : {}
13743
- },
13744
- req,
13745
- res
13746
- );
13747
- return handled;
13748
- }
13749
- if (url.pathname.startsWith("/api/hub/")) {
13750
- const authConfig = {
13751
- loopbackAutoAuth: this._autoAuthLocalhost,
13752
- ...this.authToken !== void 0 ? { authToken: this.authToken } : {}
13753
- };
13754
- const handled = await handleHubRoute(
13755
- { authConfig, service: this.v11Bindings.hubService },
13756
- req,
13757
- res
13758
- );
13759
- return handled;
13760
- }
13761
- if (method === "GET" && url.pathname === "/api/identities") {
13762
- const authConfig = {
13763
- loopbackAutoAuth: this._autoAuthLocalhost,
13764
- ...this.authToken !== void 0 ? { authToken: this.authToken } : {}
13765
- };
13766
- const aliasReq = Object.create(req);
13767
- aliasReq.url = "/api/hub/agents" + url.search;
13768
- const handled = await handleHubRoute(
13769
- { authConfig, service: this.v11Bindings.hubService },
13770
- aliasReq,
13771
- res
13772
- );
13773
- return handled;
13774
- }
13775
- return false;
13798
+ return dispatchV11Request(
13799
+ {
13800
+ bindings: this.v11Bindings,
13801
+ ...this.authToken !== void 0 ? { authToken: this.authToken } : {},
13802
+ loopbackAutoAuth: this._autoAuthLocalhost
13803
+ },
13804
+ req,
13805
+ res,
13806
+ url,
13807
+ method
13808
+ );
13776
13809
  }
13777
13810
  /**
13778
13811
  * v0.10.2: enable (or disable) the loopback auto-auth fast path. See
@@ -30020,14 +30053,18 @@ async function startDashboardServer(options) {
30020
30053
  }
30021
30054
  }
30022
30055
  };
30023
- const deps = {
30024
- sources: options.sources,
30025
- authToken: options.authToken,
30026
- approvals: options.approvals,
30027
- onEvent
30028
- };
30056
+ let v11Bindings = null;
30057
+ let v11LoopbackAutoAuth = false;
30029
30058
  const server = createServer$2(async (req, res) => {
30030
30059
  try {
30060
+ const deps = {
30061
+ sources: options.sources,
30062
+ authToken: options.authToken,
30063
+ approvals: options.approvals,
30064
+ onEvent,
30065
+ v11Bindings,
30066
+ loopbackAutoAuth: v11LoopbackAutoAuth
30067
+ };
30031
30068
  const served = await handleRequest(deps, req, res);
30032
30069
  if (!served) {
30033
30070
  res.writeHead(404, { "Content-Type": "application/json" });
@@ -30065,7 +30102,13 @@ async function startDashboardServer(options) {
30065
30102
  publishActivity: (entry) => publish({ type: "activity", data: entry }),
30066
30103
  publishApproval: (approval) => publish({ type: "approval", data: approval }),
30067
30104
  publishInbox: (item) => publish({ type: "inbox", data: item }),
30068
- publishAgentStatus: (snapshot) => publish({ type: "agent_status", data: snapshot })
30105
+ publishAgentStatus: (snapshot) => publish({ type: "agent_status", data: snapshot }),
30106
+ setV11Bindings: (bindings) => {
30107
+ v11Bindings = bindings;
30108
+ },
30109
+ setV11LoopbackAutoAuth: (enabled) => {
30110
+ v11LoopbackAutoAuth = enabled;
30111
+ }
30069
30112
  };
30070
30113
  }
30071
30114
  var DEFAULT_PORT, DEFAULT_HOST;
@@ -31329,12 +31372,14 @@ async function runWrap(options, deps = {}) {
31329
31372
  const storagePath = resolveStoragePath();
31330
31373
  let passphraseLocation;
31331
31374
  let passphraseSource;
31375
+ let passphraseValue;
31332
31376
  if (options.passphrase) {
31333
31377
  try {
31334
31378
  const persist = deps.persistPassphrase ?? ((value) => persistUserProvidedPassphrase(value, { storagePath }));
31335
31379
  const persisted = await persist(options.passphrase);
31336
31380
  passphraseLocation = persisted.location;
31337
31381
  passphraseSource = persisted.source;
31382
+ passphraseValue = options.passphrase;
31338
31383
  console.error(
31339
31384
  `
31340
31385
  \u{1F510} Persisted user-supplied passphrase (${persisted.location}).`
@@ -31352,12 +31397,14 @@ async function runWrap(options, deps = {}) {
31352
31397
  } else if (process.env.SANCTUARY_PASSPHRASE) {
31353
31398
  passphraseLocation = "SANCTUARY_PASSPHRASE";
31354
31399
  passphraseSource = "env";
31400
+ passphraseValue = process.env.SANCTUARY_PASSPHRASE;
31355
31401
  } else {
31356
31402
  try {
31357
31403
  const resolve5 = deps.resolvePassphrase ?? (() => getOrCreatePassphrase({ storagePath }));
31358
31404
  const resolved = await resolve5();
31359
31405
  passphraseLocation = resolved.location;
31360
31406
  passphraseSource = resolved.source;
31407
+ passphraseValue = resolved.value;
31361
31408
  if (resolved.source === "generated") {
31362
31409
  console.error(
31363
31410
  `
@@ -31415,6 +31462,13 @@ async function runWrap(options, deps = {}) {
31415
31462
  if (process.env.SANCTUARY_DASHBOARD_ENABLED) {
31416
31463
  sanctuaryEnv.SANCTUARY_DASHBOARD_ENABLED = process.env.SANCTUARY_DASHBOARD_ENABLED;
31417
31464
  }
31465
+ if (options.fortress) {
31466
+ sanctuaryEnv.SANCTUARY_FORTRESS_PATH = resolve(options.fortress);
31467
+ } else if (process.env.SANCTUARY_FORTRESS_PATH) {
31468
+ sanctuaryEnv.SANCTUARY_FORTRESS_PATH = resolve(
31469
+ process.env.SANCTUARY_FORTRESS_PATH
31470
+ );
31471
+ }
31418
31472
  const rewrite = deps.rewriteConfig ?? rewriteConfigForCocoon;
31419
31473
  await rewrite(
31420
31474
  agentConfig,
@@ -31442,6 +31496,40 @@ async function runWrap(options, deps = {}) {
31442
31496
  authToken,
31443
31497
  readPackageVersion()
31444
31498
  );
31499
+ if (passphraseValue !== void 0) {
31500
+ try {
31501
+ const v11Storage = new FilesystemStorage(`${storagePath}/state`);
31502
+ let existingParams;
31503
+ try {
31504
+ const raw = await v11Storage.read("_meta", "key-params");
31505
+ if (raw) {
31506
+ existingParams = JSON.parse(bytesToString(raw));
31507
+ }
31508
+ } catch {
31509
+ }
31510
+ const derived = await deriveMasterKey(passphraseValue, existingParams);
31511
+ if (!existingParams) {
31512
+ await v11Storage.write(
31513
+ "_meta",
31514
+ "key-params",
31515
+ stringToBytes(JSON.stringify(derived.params))
31516
+ );
31517
+ }
31518
+ const wrapAuditLog = new AuditLog(v11Storage, derived.key);
31519
+ dashboard.setV11Bindings(
31520
+ buildV11Bindings({
31521
+ identityId: `fortress:${storagePath}`,
31522
+ fortressId: fortressIdFromStoragePath(storagePath),
31523
+ auditLog: wrapAuditLog
31524
+ })
31525
+ );
31526
+ dashboard.setV11LoopbackAutoAuth(true);
31527
+ } catch (err) {
31528
+ console.error(
31529
+ ` Note: v1.1 dashboard surfaces unavailable on wrap URL (${err.message}). Run \`sanctuary dashboard\` to reach them.`
31530
+ );
31531
+ }
31532
+ }
31445
31533
  const dashboardUrl = `${dashboard.url}?token=${authToken}`;
31446
31534
  const webhookCallbackPortRaw = process.env.SANCTUARY_WEBHOOK_CALLBACK_PORT;
31447
31535
  const webhookCallbackPort = webhookCallbackPortRaw ? parseInt(webhookCallbackPortRaw, 10) : void 0;
@@ -31804,6 +31892,11 @@ var init_cli2 = __esm({
31804
31892
  init_config_reader();
31805
31893
  init_passphrase();
31806
31894
  init_dashboard2();
31895
+ init_wiring();
31896
+ init_filesystem();
31897
+ init_key_derivation();
31898
+ init_encoding();
31899
+ init_audit_log();
31807
31900
  init_config();
31808
31901
  init_paths();
31809
31902
  init_runtime();
@@ -35198,10 +35291,10 @@ __export(dashboard_standalone_exports, {
35198
35291
  renderTenantDiscoveryHint: () => renderTenantDiscoveryHint,
35199
35292
  startStandaloneDashboard: () => startStandaloneDashboard
35200
35293
  });
35201
- async function discoverableSubTenants(currentStoragePath) {
35294
+ async function discoverableSubTenants(currentStoragePath, discoveryOptions) {
35202
35295
  let all;
35203
35296
  try {
35204
- all = await discoverTenants();
35297
+ all = await discoverTenants(discoveryOptions);
35205
35298
  } catch {
35206
35299
  return [];
35207
35300
  }
@@ -35604,6 +35697,9 @@ var { version: PKG_VERSION4 } = require4("../package.json");
35604
35697
  async function main() {
35605
35698
  const args = process.argv.slice(2);
35606
35699
  let passphrase = process.env.SANCTUARY_PASSPHRASE;
35700
+ if (process.env.SANCTUARY_FORTRESS_PATH && !process.env.SANCTUARY_STORAGE_PATH) {
35701
+ process.env.SANCTUARY_STORAGE_PATH = process.env.SANCTUARY_FORTRESS_PATH;
35702
+ }
35607
35703
  if (args[0] === "dashboard") {
35608
35704
  await runStandaloneDashboard(args.slice(1));
35609
35705
  return;