@sanctuary-framework/mcp-server 1.1.4 → 1.1.6

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/index.d.cts CHANGED
@@ -4325,6 +4325,12 @@ interface HubPolicyAndBudgetSources {
4325
4325
  * may persist records to disk or recompute them per call.
4326
4326
  */
4327
4327
  interface HubAgentRegistrySource {
4328
+ /**
4329
+ * Insert or replace a record. Used by wrap-side registration and by
4330
+ * read-side persistence refresh to merge records written after dashboard
4331
+ * boot.
4332
+ */
4333
+ put(record: LocalAgentRecord): void;
4328
4334
  list(filter?: LocalAgentRegistryFilter): LocalAgentRecord[];
4329
4335
  get(agentId: string): LocalAgentRecord | null;
4330
4336
  /**
@@ -4350,6 +4356,12 @@ interface HubServiceDeps {
4350
4356
  fortressId: string;
4351
4357
  /** Local agent registry source. */
4352
4358
  agentRegistry: HubAgentRegistrySource;
4359
+ /**
4360
+ * Optional best-effort persisted agent reader. When supplied, list
4361
+ * operations merge records written after hub construction before
4362
+ * returning the in-memory projection.
4363
+ */
4364
+ readPersistedLocalAgents?: () => LocalAgentRecord[];
4353
4365
  /** Inbox aggregation sources. */
4354
4366
  inboxSources: HubInboxSources;
4355
4367
  /** Activity feed sources. */
@@ -4403,6 +4415,7 @@ declare class HubService {
4403
4415
  constructor(deps: HubServiceDeps);
4404
4416
  private now;
4405
4417
  private nowIso;
4418
+ private refreshPersistedLocalAgents;
4406
4419
  listInbox(): HubInboxItem[];
4407
4420
  resolveInboxItem(itemId: string, action: HubInboxAction): Promise<HubInboxItem>;
4408
4421
  listAgents(filter?: LocalAgentRegistryFilter): LocalAgentRecord[];
@@ -4474,7 +4487,7 @@ declare class HubService {
4474
4487
  }
4475
4488
 
4476
4489
  /**
4477
- * v1.1 Server Wiring (v1.1.1 hotfix)
4490
+ * v1.1 Server Wiring (v1.1.1 hotfix; agent-registry persistence in v1.1.5)
4478
4491
  *
4479
4492
  * v1.1.0 shipped the v1.1 module suite (dashboard / hub API / exit bundle
4480
4493
  * endpoints / coordination) but no entry-point server imported any of it.
@@ -4484,10 +4497,13 @@ declare class HubService {
4484
4497
  *
4485
4498
  * The wiring is deliberately minimal at v1.1.1:
4486
4499
  *
4487
- * - Local agent registry starts empty. v1.2 will populate it from
4488
- * `discoverTenants()` and the wrapped harness manifest. v1.1.1 ships
4489
- * the API surface so existing operator scripts can hit it; the data
4490
- * plane is the next conversation.
4500
+ * - Local agent registry starts empty by default. v1.1.5 (Finding Z)
4501
+ * adds an optional `storagePath` input that rehydrates the registry
4502
+ * from `<storagePath>/state/_hub/local-agents.json`, written by
4503
+ * `sanctuary wrap` for each successfully wrapped harness. Callers
4504
+ * that pass `storagePath` get the wrap-populated set; callers that
4505
+ * omit it (legacy) keep the empty-by-default behavior. Real
4506
+ * harness-discovery via `discoverTenants()` remains v1.2 work.
4491
4507
  * - Inbox sources return empty arrays. The privacy chokepoint already
4492
4508
  * emits audit events through PR #69 / PR #71; the inbox aggregator is
4493
4509
  * the v1.2 work to project those into operator cards.
package/dist/index.d.ts CHANGED
@@ -4325,6 +4325,12 @@ interface HubPolicyAndBudgetSources {
4325
4325
  * may persist records to disk or recompute them per call.
4326
4326
  */
4327
4327
  interface HubAgentRegistrySource {
4328
+ /**
4329
+ * Insert or replace a record. Used by wrap-side registration and by
4330
+ * read-side persistence refresh to merge records written after dashboard
4331
+ * boot.
4332
+ */
4333
+ put(record: LocalAgentRecord): void;
4328
4334
  list(filter?: LocalAgentRegistryFilter): LocalAgentRecord[];
4329
4335
  get(agentId: string): LocalAgentRecord | null;
4330
4336
  /**
@@ -4350,6 +4356,12 @@ interface HubServiceDeps {
4350
4356
  fortressId: string;
4351
4357
  /** Local agent registry source. */
4352
4358
  agentRegistry: HubAgentRegistrySource;
4359
+ /**
4360
+ * Optional best-effort persisted agent reader. When supplied, list
4361
+ * operations merge records written after hub construction before
4362
+ * returning the in-memory projection.
4363
+ */
4364
+ readPersistedLocalAgents?: () => LocalAgentRecord[];
4353
4365
  /** Inbox aggregation sources. */
4354
4366
  inboxSources: HubInboxSources;
4355
4367
  /** Activity feed sources. */
@@ -4403,6 +4415,7 @@ declare class HubService {
4403
4415
  constructor(deps: HubServiceDeps);
4404
4416
  private now;
4405
4417
  private nowIso;
4418
+ private refreshPersistedLocalAgents;
4406
4419
  listInbox(): HubInboxItem[];
4407
4420
  resolveInboxItem(itemId: string, action: HubInboxAction): Promise<HubInboxItem>;
4408
4421
  listAgents(filter?: LocalAgentRegistryFilter): LocalAgentRecord[];
@@ -4474,7 +4487,7 @@ declare class HubService {
4474
4487
  }
4475
4488
 
4476
4489
  /**
4477
- * v1.1 Server Wiring (v1.1.1 hotfix)
4490
+ * v1.1 Server Wiring (v1.1.1 hotfix; agent-registry persistence in v1.1.5)
4478
4491
  *
4479
4492
  * v1.1.0 shipped the v1.1 module suite (dashboard / hub API / exit bundle
4480
4493
  * endpoints / coordination) but no entry-point server imported any of it.
@@ -4484,10 +4497,13 @@ declare class HubService {
4484
4497
  *
4485
4498
  * The wiring is deliberately minimal at v1.1.1:
4486
4499
  *
4487
- * - Local agent registry starts empty. v1.2 will populate it from
4488
- * `discoverTenants()` and the wrapped harness manifest. v1.1.1 ships
4489
- * the API surface so existing operator scripts can hit it; the data
4490
- * plane is the next conversation.
4500
+ * - Local agent registry starts empty by default. v1.1.5 (Finding Z)
4501
+ * adds an optional `storagePath` input that rehydrates the registry
4502
+ * from `<storagePath>/state/_hub/local-agents.json`, written by
4503
+ * `sanctuary wrap` for each successfully wrapped harness. Callers
4504
+ * that pass `storagePath` get the wrap-populated set; callers that
4505
+ * omit it (legacy) keep the empty-by-default behavior. Real
4506
+ * harness-discovery via `discoverTenants()` remains v1.2 work.
4491
4507
  * - Inbox sources return empty arrays. The privacy chokepoint already
4492
4508
  * emits audit events through PR #69 / PR #71; the inbox aggregator is
4493
4509
  * the v1.2 work to project those into operator cards.
package/dist/index.js CHANGED
@@ -14,7 +14,7 @@ import { ListToolsRequestSchema, CallToolRequestSchema } from '@modelcontextprot
14
14
  import { createServer as createServer$2 } from 'http';
15
15
  import { createServer as createServer$1 } from 'https';
16
16
  import { exec, execSync, spawn } from 'child_process';
17
- import { statSync, existsSync, readFileSync } from 'fs';
17
+ import { existsSync, readFileSync, statSync } from 'fs';
18
18
  import { fileURLToPath } from 'url';
19
19
  import { Client } from '@modelcontextprotocol/sdk/client/index.js';
20
20
  import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
@@ -26871,6 +26871,13 @@ var HubService = class {
26871
26871
  nowIso() {
26872
26872
  return this.now().toISOString();
26873
26873
  }
26874
+ refreshPersistedLocalAgents() {
26875
+ const readPersistedLocalAgents2 = this.deps.readPersistedLocalAgents;
26876
+ if (!readPersistedLocalAgents2) return;
26877
+ for (const record of readPersistedLocalAgents2()) {
26878
+ this.deps.agentRegistry.put(record);
26879
+ }
26880
+ }
26874
26881
  // ── Inbox ───────────────────────────────────────────────────────────
26875
26882
  listInbox() {
26876
26883
  const items = aggregateInbox(this.deps.inboxSources, this.inboxStore);
@@ -26882,6 +26889,7 @@ var HubService = class {
26882
26889
  }
26883
26890
  // ── Agents ──────────────────────────────────────────────────────────
26884
26891
  listAgents(filter) {
26892
+ this.refreshPersistedLocalAgents();
26885
26893
  const safeFilter = {
26886
26894
  ...filter ?? {},
26887
26895
  identity_id: this.deps.identityId
@@ -27298,6 +27306,21 @@ var HubService = class {
27298
27306
  return this.inboxStore.size();
27299
27307
  }
27300
27308
  };
27309
+ function localAgentsFilePath(storagePath) {
27310
+ return join(storagePath, "state", "_hub", "local-agents.json");
27311
+ }
27312
+ function readPersistedLocalAgents(storagePath) {
27313
+ const filePath = localAgentsFilePath(storagePath);
27314
+ if (!existsSync(filePath)) return [];
27315
+ try {
27316
+ const raw = readFileSync(filePath, "utf8");
27317
+ const parsed = JSON.parse(raw);
27318
+ if (!parsed || !Array.isArray(parsed.agents)) return [];
27319
+ return parsed.agents;
27320
+ } catch {
27321
+ return [];
27322
+ }
27323
+ }
27301
27324
 
27302
27325
  // src/dashboard/v1_1/wiring.ts
27303
27326
  var CapabilityErrorAgentController = class {
@@ -27329,11 +27352,15 @@ var CapabilityErrorAgentController = class {
27329
27352
  }
27330
27353
  };
27331
27354
  function buildV11Bindings(inputs) {
27332
- const registry = new InMemoryLocalAgentRegistry([]);
27355
+ const seed = inputs.storagePath !== void 0 ? readPersistedLocalAgents(inputs.storagePath) : [];
27356
+ const registry = new InMemoryLocalAgentRegistry(seed);
27357
+ const storagePath = inputs.storagePath;
27358
+ const readPersisted = storagePath !== void 0 ? () => readPersistedLocalAgents(storagePath) : void 0;
27333
27359
  const hubService = new HubService({
27334
27360
  identityId: inputs.identityId,
27335
27361
  fortressId: inputs.fortressId,
27336
27362
  agentRegistry: registry,
27363
+ ...readPersisted ? { readPersistedLocalAgents: readPersisted } : {},
27337
27364
  inboxSources: {
27338
27365
  listPendingApprovals: () => [],
27339
27366
  listRecentBlockedEgress: () => [],
@@ -29429,7 +29456,12 @@ Refusing to start the cocoon while the reset-history marker is unreadable.`
29429
29456
  buildV11Bindings({
29430
29457
  identityId: embeddedHubIdentityId,
29431
29458
  fortressId: fortressIdFromStoragePath(config.storage_path),
29432
- auditLog
29459
+ auditLog,
29460
+ // v1.1.5 (Finding Z): rehydrate the hub agent registry from
29461
+ // `<storagePath>/state/_hub/local-agents.json` so the embedded
29462
+ // dashboard surfaces wraps performed by prior `sanctuary wrap`
29463
+ // invocations against this same fortress.
29464
+ storagePath: config.storage_path
29433
29465
  })
29434
29466
  );
29435
29467
  await dashboard.start();