@blen/fedreg-mcp-server 2.0.11 → 2.1.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.
Files changed (68) hide show
  1. package/CHANGELOG.md +7 -1
  2. package/README.md +13 -2
  3. package/dist/accounts/app.d.ts +16 -0
  4. package/dist/accounts/app.d.ts.map +1 -0
  5. package/dist/accounts/app.js +352 -0
  6. package/dist/accounts/app.js.map +1 -0
  7. package/dist/accounts/config.d.ts +16 -0
  8. package/dist/accounts/config.d.ts.map +1 -0
  9. package/dist/accounts/config.js +50 -0
  10. package/dist/accounts/config.js.map +1 -0
  11. package/dist/accounts/crypto.d.ts +18 -0
  12. package/dist/accounts/crypto.d.ts.map +1 -0
  13. package/dist/accounts/crypto.js +43 -0
  14. package/dist/accounts/crypto.js.map +1 -0
  15. package/dist/accounts/portal.d.ts +8 -0
  16. package/dist/accounts/portal.d.ts.map +1 -0
  17. package/dist/accounts/portal.js +170 -0
  18. package/dist/accounts/portal.js.map +1 -0
  19. package/dist/accounts/provider.d.ts +2568 -0
  20. package/dist/accounts/provider.d.ts.map +1 -0
  21. package/dist/accounts/provider.js +107 -0
  22. package/dist/accounts/provider.js.map +1 -0
  23. package/dist/accounts/runtime.d.ts +16 -0
  24. package/dist/accounts/runtime.d.ts.map +1 -0
  25. package/dist/accounts/runtime.js +122 -0
  26. package/dist/accounts/runtime.js.map +1 -0
  27. package/dist/accounts/store.d.ts +25 -0
  28. package/dist/accounts/store.d.ts.map +1 -0
  29. package/dist/accounts/store.js +142 -0
  30. package/dist/accounts/store.js.map +1 -0
  31. package/dist/bin.js +13 -4
  32. package/dist/bin.js.map +1 -1
  33. package/dist/sdk/bindings.js +1 -1
  34. package/dist/sdk/bindings.js.map +1 -1
  35. package/dist/sdk/sources/corpus-loader.d.ts +3 -1
  36. package/dist/sdk/sources/corpus-loader.d.ts.map +1 -1
  37. package/dist/sdk/sources/corpus-loader.js +10 -2
  38. package/dist/sdk/sources/corpus-loader.js.map +1 -1
  39. package/dist/sdk/sources/source.d.ts +2 -5
  40. package/dist/sdk/sources/source.d.ts.map +1 -1
  41. package/dist/server/mcpServer.js +1 -1
  42. package/dist/server/mcpServer.js.map +1 -1
  43. package/dist/server/toolCatalog.d.ts +2 -1
  44. package/dist/server/toolCatalog.d.ts.map +1 -1
  45. package/dist/server/toolCatalog.js.map +1 -1
  46. package/dist/server/zodToJsonSchema.d.ts +1 -1
  47. package/dist/server/zodToJsonSchema.d.ts.map +1 -1
  48. package/dist/tools/describeSchema.d.ts +1 -1
  49. package/dist/tools/describeSchema.d.ts.map +1 -1
  50. package/dist/tools/describeSchema.js +1 -1
  51. package/dist/tools/describeSchema.js.map +1 -1
  52. package/dist/tools/execute.d.ts +4 -2
  53. package/dist/tools/execute.d.ts.map +1 -1
  54. package/dist/tools/execute.js +5 -4
  55. package/dist/tools/execute.js.map +1 -1
  56. package/dist/tools/searchApi.d.ts +1 -1
  57. package/dist/tools/searchApi.d.ts.map +1 -1
  58. package/dist/tools/searchApi.js +1 -1
  59. package/dist/tools/searchApi.js.map +1 -1
  60. package/dist/util/httpClient.d.ts +9 -4
  61. package/dist/util/httpClient.d.ts.map +1 -1
  62. package/dist/util/httpClient.js +1 -1
  63. package/dist/util/httpClient.js.map +1 -1
  64. package/dist/web/assets/blen-logo-BKJFojyj.png +0 -0
  65. package/dist/web/assets/index--Hn7cjpj.js +299 -0
  66. package/dist/web/assets/index-bNtg7OeV.css +2 -0
  67. package/dist/web/index.html +14 -0
  68. package/package.json +35 -7
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.d.ts","sourceRoot":"","sources":["../../src/accounts/provider.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AACjD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,YAAY,CAAC;AAGxC,eAAO,MAAM,MAAM,UAAoC,CAAC;AAExD,6EAA6E;AAC7E,wBAAgB,UAAU,CAAC,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yCA0FkojB,CAAC;yCAAoD,CAAC;;;;;;;;;yCAAoW,CAAC;yCAAoD,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;wBAAgmD,CAAC;;oCAAiF,CAAC;;;0CAAoJ,CAAC;;2CAA4F,CAAC;+CAA4D,CAAC;;;;;qCAAqL,CAAC;gCAA4C,CAAC;;;;qDAAkM,CAAC;gEAA+F,CAAC;qCAAyF,CAAC;oCAAgD,CAAC;6BAA2C,CAAC;0BAAsC,CAAC;mCAA+C,CAAC;0DAAsE,CAAC;qEAAoG,CAAC;sCAA0F,CAAC;6DAAyE,CAAC;wEAAuG,CAAC;;8DAAoK,CAAC;qDAAkE,CAAC;4CAAyD,CAAC;oDAAiE,CAAC;iDAA8D,CAAC;;;;;;;;;;;;;;;;;;;;sCAA2qB,CAAC;uCAAkC,CAAC;qCAAgC,CAAC;;;;;;;;;sCAAoO,CAAC;uCAAkC,CAAC;qCAAgC,CAAC;;;;;;;;;;uCAAoQ,CAAC;qCAAgC,CAAC;;;;;;;;;;sCAAqQ,CAAC;qCAAgC,CAAC;;;;;;;;;;;;sCAA4S,CAAC;uCAAkC,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAA+3D,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAA+hD,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;yDAAk3G,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kCAAqpT,CAAC;;;sCAAiF,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAAupnB,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAAw/M,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;qCAAgxB,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAAwyC,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAAkkF,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAAw5D,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;qCAAuyB,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAA80B,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;qCAAisB,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;qCAAwsB,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;qCAA63B,CAAC;qCAAkD,CAAC;;;;;;;;;iCAA8Q,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAvBnxhF;AACD,MAAM,MAAM,IAAI,GAAG,UAAU,CAAC,OAAO,UAAU,CAAC,CAAC;AAEjD,wBAAsB,cAAc,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,aAAa,EAAE,KAAK,EAAE,KAAK,iBAmBnF"}
@@ -0,0 +1,107 @@
1
+ import { betterAuth } from 'better-auth';
2
+ import { mcp } from '@better-auth/mcp';
3
+ import { cimd } from '@better-auth/cimd';
4
+ import { fetchClientMetadataResource } from '@better-auth/cimd/node';
5
+ import { getMigrations } from 'better-auth/db/migration';
6
+ import { APIError, createAuthMiddleware, getSessionFromCtx } from 'better-auth/api';
7
+ import { digest } from './crypto.js';
8
+ export const SCOPES = ['fedreg:read', 'offline_access'];
9
+ /** Same Google / OAuth provider as Data.gov, scoped to personal accounts. */
10
+ export function createAuth(config, store) {
11
+ return betterAuth({
12
+ baseURL: config.origin,
13
+ basePath: '/api/auth',
14
+ secret: config.authSecret,
15
+ database: store.pool,
16
+ trustedOrigins: [config.origin],
17
+ logger: { disabled: true },
18
+ advanced: { useSecureCookies: config.production },
19
+ // Better Auth enables its limiter only when NODE_ENV is exactly 'production', but an unset
20
+ // NODE_ENV is production here. The app exempts OAuth registration and token endpoints from
21
+ // its own IP limit on the strength of these limits, so tie them to the same flag.
22
+ rateLimit: { enabled: config.production },
23
+ session: { expiresIn: 7 * 86400, cookieCache: { enabled: false } },
24
+ account: { encryptOAuthTokens: true, accountLinking: { enabled: false } },
25
+ emailAndPassword: { enabled: false },
26
+ disabledPaths: ['/link-social', '/update-user', '/change-email'],
27
+ socialProviders: {
28
+ google: {
29
+ clientId: config.googleClientId,
30
+ clientSecret: config.googleClientSecret,
31
+ accessType: 'online',
32
+ prompt: 'select_account',
33
+ },
34
+ },
35
+ hooks: {
36
+ before: createAuthMiddleware(async (ctx) => {
37
+ if (!['/oauth2/authorize', '/oauth2/consent', '/oauth2/continue'].includes(ctx.path))
38
+ return;
39
+ const logged = await getSessionFromCtx(ctx);
40
+ if (logged && !logged.user.emailVerified)
41
+ throw new APIError('FORBIDDEN', { error: 'access_denied' });
42
+ }),
43
+ },
44
+ plugins: [
45
+ mcp({
46
+ resource: `${config.origin}/mcp`,
47
+ loginPage: '/sign-in',
48
+ consentPage: '/consent',
49
+ scopes: SCOPES,
50
+ grantTypes: ['authorization_code', 'refresh_token'],
51
+ disableJwtPlugin: true,
52
+ storeClientSecret: 'encrypted',
53
+ storeTokens: { hash: digest },
54
+ refreshTokenReuseInterval: 0,
55
+ rateLimit: { register: { window: 60, max: 120 }, token: { window: 60, max: 1200 } },
56
+ accessTokenExpiresIn: 900,
57
+ refreshTokenExpiresIn: 30 * 86400,
58
+ codeExpiresIn: 600,
59
+ allowDynamicClientRegistration: true,
60
+ allowUnauthenticatedClientRegistration: true,
61
+ clientRegistrationDefaultScopes: SCOPES,
62
+ clientPrivileges: () => false,
63
+ resourcePrivileges: () => false,
64
+ // Personal accounts have one key source. Every new authorization gets the
65
+ // same key-entry step as SAM.gov; /oauth2/continue completes this step.
66
+ postLogin: {
67
+ page: '/connect',
68
+ shouldRedirect: async ({ user, session }) => !await store.connectionReady(session.id, user.id),
69
+ consentReferenceId: async () => 'personal',
70
+ },
71
+ customAccessTokenClaims: async ({ user }) => {
72
+ if (!user?.emailVerified)
73
+ throw new APIError('FORBIDDEN', { error: 'access_denied' });
74
+ return {};
75
+ },
76
+ }),
77
+ cimd({ fetchClientMetadataResource, metadataProfile: 'mcp-2026-07-28' }),
78
+ ],
79
+ });
80
+ }
81
+ export async function initializeAuth(auth, config, store) {
82
+ const lock = await store.pool.connect();
83
+ try {
84
+ await lock.query("SELECT pg_advisory_lock(hashtext('fedreg-auth-migration'))");
85
+ const migration = await getMigrations(auth.options);
86
+ await migration.runMigrations();
87
+ const context = await auth.$context;
88
+ const resource = `${config.origin}/mcp`;
89
+ if (!await context.adapter.findOne({ model: 'oauthResource', where: [{ field: 'identifier', value: resource }] })) {
90
+ await context.adapter.create({ model: 'oauthResource', data: {
91
+ identifier: resource, name: 'Federal Register MCP', allowedScopes: SCOPES,
92
+ disabled: false, policyVersion: 1, createdAt: new Date(), updatedAt: new Date(),
93
+ } });
94
+ }
95
+ }
96
+ finally {
97
+ try {
98
+ await lock.query("SELECT pg_advisory_unlock(hashtext('fedreg-auth-migration'))");
99
+ }
100
+ catch {
101
+ lock.release(true);
102
+ throw new Error('Auth migration lock connection failed');
103
+ }
104
+ lock.release();
105
+ }
106
+ }
107
+ //# sourceMappingURL=provider.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"provider.js","sourceRoot":"","sources":["../../src/accounts/provider.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import type { CatalogDeps } from '../server/toolCatalog.js';
2
+ import type { SupervisorConfig } from '../supervisor/index.js';
3
+ import type { HttpHandle } from '../server/http.js';
4
+ import type { Dispatcher } from 'undici';
5
+ import { Store } from './store.js';
6
+ import type { AccountConfig } from './config.js';
7
+ /**
8
+ * Keep public-source caches shared. The regs table is always present in account mode;
9
+ * each method loads the caller's key on first use, so fr/ecfr-only code never touches
10
+ * the database. Clients are cached by a digest of owner + key: the key is read on every
11
+ * execute that uses regs, so a saved, rotated or deleted key takes effect on the next call
12
+ * on every replica, while identical queries still hit the client's response cache.
13
+ */
14
+ export declare function accountDependencies(deps: CatalogDeps, cfg: SupervisorConfig, store: Store, dispatcher?: Dispatcher): CatalogDeps;
15
+ export declare function startAccountHttp(deps: CatalogDeps, cfg: SupervisorConfig, config: AccountConfig, port: number, host: string): Promise<HttpHandle>;
16
+ //# sourceMappingURL=runtime.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.d.ts","sourceRoot":"","sources":["../../src/accounts/runtime.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAC;AAC5D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,wBAAwB,CAAC;AAC/D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AACpD,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AAMzC,OAAO,EAAE,KAAK,EAAiB,MAAM,YAAY,CAAC;AAClD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAUjD;;;;;;GAMG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,gBAAgB,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,CAAC,EAAE,UAAU,GAAG,WAAW,CAuEhI;AAED,wBAAsB,gBAAgB,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE,gBAAgB,EAAE,MAAM,EAAE,aAAa,EAAE,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC,CA0BvJ"}
@@ -0,0 +1,122 @@
1
+ import { createServer } from 'node:http';
2
+ import { Pool } from 'pg';
3
+ import { log } from '../util/logger.js';
4
+ import { createRegsSource } from '../sdk/sources/regs.js';
5
+ import { LRUCache } from 'lru-cache';
6
+ import { createAccountApp } from './app.js';
7
+ import { digest } from './crypto.js';
8
+ import { Store, personalOwner } from './store.js';
9
+ /** Account-scoped regs clients, reused across executes so their response caches survive. */
10
+ const ACCOUNT_CLIENT_MAX = 500;
11
+ const ACCOUNT_CLIENT_TTL_MS = 60 * 60 * 1000;
12
+ /** Per-account response cache cap: up to ACCOUNT_CLIENT_MAX of these caches live at once. */
13
+ const ACCOUNT_CACHE_MAX_ITEMS = 200;
14
+ const unavailable = (message) => Object.assign(new Error(message), { name: 'SourceUnavailable' });
15
+ /**
16
+ * Keep public-source caches shared. The regs table is always present in account mode;
17
+ * each method loads the caller's key on first use, so fr/ecfr-only code never touches
18
+ * the database. Clients are cached by a digest of owner + key: the key is read on every
19
+ * execute that uses regs, so a saved, rotated or deleted key takes effect on the next call
20
+ * on every replica, while identical queries still hit the client's response cache.
21
+ */
22
+ export function accountDependencies(deps, cfg, store, dispatcher) {
23
+ // Even if the process has a legacy key, never put it in the hosted account catalog.
24
+ const clients = Object.fromEntries(Object.entries(deps.sdk.clients).filter(([name]) => name !== 'regs'));
25
+ const methods = Object.fromEntries(Object.entries(deps.sdk.methods).filter(([name]) => name !== 'regs'));
26
+ // A keyless source still registers every method; only the names are needed here.
27
+ const regsNames = Object.keys(createRegsSource({
28
+ frBaseUrl: cfg.frBaseUrl, ecfrBaseUrl: cfg.ecfrBaseUrl, regsBaseUrl: 'https://api.regulations.gov',
29
+ userAgent: cfg.userAgent, timeoutMs: cfg.upstreamTimeoutMs, retries: 0,
30
+ cacheTtlMs: cfg.cacheTtlMs, cacheMaxItems: cfg.cacheMaxItems,
31
+ }).methods);
32
+ const sdk = { ...deps.sdk, clients, methods: Object.freeze(methods) };
33
+ const sources = new LRUCache({ max: ACCOUNT_CLIENT_MAX, ttl: ACCOUNT_CLIENT_TTL_MS });
34
+ const sourceFor = (owner, key) => {
35
+ const id = digest(`${owner}\0${key}`);
36
+ let regs = sources.get(id);
37
+ if (!regs) {
38
+ regs = createRegsSource({
39
+ frBaseUrl: cfg.frBaseUrl, ecfrBaseUrl: cfg.ecfrBaseUrl,
40
+ // Account credentials can never be redirected by an operator's legacy upstream override.
41
+ regsBaseUrl: 'https://api.regulations.gov', regsApiKey: key,
42
+ userAgent: cfg.userAgent, timeoutMs: cfg.upstreamTimeoutMs, retries: 0,
43
+ cacheTtlMs: cfg.cacheTtlMs, cacheMaxItems: Math.min(cfg.cacheMaxItems, ACCOUNT_CACHE_MAX_ITEMS),
44
+ // The hourly account limit runs after the client's cache and in-flight dedupe, like the
45
+ // process-wide bucket in key mode, so repeated identical calls do not spend the quota.
46
+ regsPreflightLimiter: { tryTake: () => store.allow(`regs:${owner}`, cfg.regsRatePerHour, 3600) },
47
+ ...(dispatcher ? { dispatcher } : {}),
48
+ });
49
+ sources.set(id, regs);
50
+ }
51
+ return regs;
52
+ };
53
+ return {
54
+ ...deps, sdk,
55
+ // Account mode limits regs per account in PostgreSQL; the in-memory per-subject quota would
56
+ // cap accounts below that, and inconsistently across replicas.
57
+ regsSubjectQuota: undefined,
58
+ sdkForSubject: async (subject) => {
59
+ if (!subject || subject === 'anonymous')
60
+ throw new Error('An authenticated account is required');
61
+ const owner = personalOwner(subject);
62
+ // Loaded at most once per execute, and only if the code calls regs.
63
+ let loaded;
64
+ const loadKey = () => loaded ??= store.getKey(owner).catch(err => {
65
+ // A transient database error or a retired encryption key must not break fr/ecfr calls.
66
+ log.warn('account.key_unavailable', { name: err.name });
67
+ throw unavailable('Your saved regulations.gov API key could not be loaded. Try again, or save it again at /account.');
68
+ });
69
+ const accountMethods = Object.fromEntries(regsNames.map(name => [name, async (...args) => {
70
+ const key = await loadKey();
71
+ if (!key)
72
+ throw unavailable('Save a regulations.gov API key in your account at /account.');
73
+ const method = sourceFor(owner, key).methods[name];
74
+ const redact = (text) => text.split(key).join('[REDACTED]');
75
+ let value;
76
+ try {
77
+ value = await method(...args);
78
+ }
79
+ catch (err) {
80
+ // Keep the error's name and status (404 for a bad id, RateLimited for 429) so callers can
81
+ // react; scrub the key from the message and never forward the upstream body.
82
+ const e = err;
83
+ const status = typeof e.status === 'number' ? e.status : undefined;
84
+ throw Object.assign(new Error(redact(typeof e.message === 'string' && e.message ? e.message : 'Regulations.gov request failed')), { name: typeof e.name === 'string' ? e.name : 'Error', ...(status === undefined ? {} : { status }) });
85
+ }
86
+ // Defensive redaction if an upstream ever echoes a credential, including object keys.
87
+ const json = JSON.stringify(value);
88
+ return json?.includes(key) ? JSON.parse(redact(json)) : value;
89
+ }]));
90
+ return { ...sdk, methods: Object.freeze({ ...sdk.methods, regs: Object.freeze(accountMethods) }) };
91
+ },
92
+ };
93
+ }
94
+ export async function startAccountHttp(deps, cfg, config, port, host) {
95
+ const pool = new Pool({ connectionString: config.databaseUrl, max: 10 });
96
+ pool.on('error', () => log.error('account.database_error'));
97
+ const store = new Store(pool, config.keyring);
98
+ let service;
99
+ try {
100
+ await store.initialize();
101
+ service = await createAccountApp(config, store, accountDependencies(deps, cfg, store));
102
+ const server = createServer(service.app);
103
+ await new Promise((resolve, reject) => { server.once('error', reject); server.listen(port, host, resolve); });
104
+ const cleanup = setInterval(() => { void store.cleanup().catch(() => log.error('account.cleanup_failed')); }, 60_000);
105
+ cleanup.unref();
106
+ return {
107
+ port: server.address().port,
108
+ close: async () => {
109
+ clearInterval(cleanup);
110
+ await service.close();
111
+ await new Promise((resolve, reject) => server.close(err => err ? reject(err) : resolve()));
112
+ await pool.end();
113
+ },
114
+ };
115
+ }
116
+ catch (error) {
117
+ await service?.close();
118
+ await pool.end();
119
+ throw error;
120
+ }
121
+ }
122
+ //# sourceMappingURL=runtime.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"runtime.js","sourceRoot":"","sources":["../../src/accounts/runtime.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,25 @@
1
+ import type { Pool } from 'pg';
2
+ import { Keyring } from './crypto.js';
3
+ /** Personal credential owner derived exclusively from the authenticated user. */
4
+ export declare const personalOwner: (userId: string) => string;
5
+ export declare class Store {
6
+ readonly pool: Pool;
7
+ private readonly keyring;
8
+ constructor(pool: Pool, keyring: Keyring);
9
+ initialize(): Promise<void>;
10
+ saveKey(owner: string, key: string, actor?: string): Promise<boolean>;
11
+ getKey(owner: string): Promise<string | undefined>;
12
+ keyStatus(owner: string): Promise<{
13
+ connected: boolean;
14
+ updatedAt: any;
15
+ }>;
16
+ deleteKey(owner: string, actor?: string): Promise<void>;
17
+ private changeKey;
18
+ markConnectionReady(sessionId: string, userId: string): Promise<void>;
19
+ connectionReady(sessionId: string, userId: string): Promise<boolean>;
20
+ clearConnectionStep(sessionId: string): Promise<void>;
21
+ allow(bucket: string, maximum: number, seconds: number): Promise<boolean>;
22
+ rotateKeys(batchSize?: number): Promise<number>;
23
+ cleanup(): Promise<void>;
24
+ }
25
+ //# sourceMappingURL=store.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.d.ts","sourceRoot":"","sources":["../../src/accounts/store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,IAAI,CAAC;AAC/B,OAAO,EAAE,OAAO,EAAuB,MAAM,aAAa,CAAC;AAE3D,iFAAiF;AACjF,eAAO,MAAM,aAAa,GAAI,QAAQ,MAAM,WAAqB,CAAC;AAElE,qBAAa,KAAK;IAEd,QAAQ,CAAC,IAAI,EAAE,IAAI;IACnB,OAAO,CAAC,QAAQ,CAAC,OAAO;gBADf,IAAI,EAAE,IAAI,EACF,OAAO,EAAE,OAAO;IAE7B,UAAU;IAgCV,OAAO,CAAC,KAAK,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;IAWlD,MAAM,CAAC,KAAK,EAAE,MAAM;IAQpB,SAAS,CAAC,KAAK,EAAE,MAAM;;;;IAMvB,SAAS,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,CAAC,EAAE,MAAM;YAS/B,SAAS;IA0BjB,mBAAmB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAOrD,eAAe,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM;IAOjD,mBAAmB,CAAC,SAAS,EAAE,MAAM;IAGrC,KAAK,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM;IAStD,UAAU,CAAC,SAAS,SAAM;IAgC1B,OAAO;CAId"}
@@ -0,0 +1,142 @@
1
+ import { digest } from './crypto.js';
2
+ /** Personal credential owner derived exclusively from the authenticated user. */
3
+ export const personalOwner = (userId) => `user:${userId}`;
4
+ export class Store {
5
+ pool;
6
+ keyring;
7
+ constructor(pool, keyring) {
8
+ this.pool = pool;
9
+ this.keyring = keyring;
10
+ }
11
+ async initialize() {
12
+ const client = await this.pool.connect();
13
+ try {
14
+ await client.query('BEGIN');
15
+ // IF NOT EXISTS alone does not serialize simultaneous first-time DDL.
16
+ await client.query("SELECT pg_advisory_xact_lock(hashtext('fedreg-store-migration'))");
17
+ await client.query(`
18
+ CREATE TABLE IF NOT EXISTS credentials (
19
+ owner TEXT PRIMARY KEY,
20
+ ciphertext JSONB NOT NULL,
21
+ updated_at TIMESTAMPTZ NOT NULL DEFAULT now()
22
+ );
23
+ CREATE TABLE IF NOT EXISTS connection_steps (
24
+ session_id TEXT PRIMARY KEY, user_id TEXT NOT NULL,
25
+ expires_at TIMESTAMPTZ NOT NULL
26
+ );
27
+ CREATE TABLE IF NOT EXISTS request_limits (
28
+ bucket TEXT PRIMARY KEY, count INTEGER NOT NULL, expires_at TIMESTAMPTZ NOT NULL
29
+ );
30
+ CREATE TABLE IF NOT EXISTS audit_events (
31
+ id BIGSERIAL PRIMARY KEY, tenant TEXT NOT NULL, actor TEXT NOT NULL,
32
+ action TEXT NOT NULL, created_at TIMESTAMPTZ NOT NULL DEFAULT now()
33
+ );
34
+ `);
35
+ await client.query('COMMIT');
36
+ }
37
+ catch (error) {
38
+ await client.query('ROLLBACK');
39
+ throw error;
40
+ }
41
+ finally {
42
+ client.release();
43
+ }
44
+ }
45
+ async saveKey(owner, key, actor) {
46
+ const ciphertext = this.keyring.seal(key, `regulations.gov:${owner}`);
47
+ return this.changeKey(owner, actor, 'credential.saved', `INSERT INTO credentials(owner,ciphertext) VALUES($1,$2)
48
+ ON CONFLICT(owner) DO UPDATE SET ciphertext=$2,updated_at=now()`, [owner, ciphertext]);
49
+ }
50
+ async getKey(owner) {
51
+ const result = await this.pool.query('SELECT ciphertext FROM credentials WHERE owner=$1', [
52
+ owner,
53
+ ]);
54
+ return result.rows[0]
55
+ ? this.keyring.open(result.rows[0].ciphertext, `regulations.gov:${owner}`)
56
+ : undefined;
57
+ }
58
+ async keyStatus(owner) {
59
+ const result = await this.pool.query('SELECT updated_at FROM credentials WHERE owner=$1', [
60
+ owner,
61
+ ]);
62
+ return { connected: result.rowCount === 1, updatedAt: result.rows[0]?.updated_at };
63
+ }
64
+ async deleteKey(owner, actor) {
65
+ await this.changeKey(owner, actor, 'credential.deleted', 'DELETE FROM credentials WHERE owner=$1', [owner]);
66
+ }
67
+ async changeKey(owner, actor, action, sql, values) {
68
+ const client = await this.pool.connect();
69
+ try {
70
+ await client.query('BEGIN');
71
+ await client.query(sql, values);
72
+ if (actor)
73
+ await client.query('INSERT INTO audit_events(tenant,actor,action) VALUES($1,$2,$3)', [
74
+ owner,
75
+ actor,
76
+ action,
77
+ ]);
78
+ await client.query('COMMIT');
79
+ return true;
80
+ }
81
+ catch (error) {
82
+ await client.query('ROLLBACK');
83
+ throw error;
84
+ }
85
+ finally {
86
+ client.release();
87
+ }
88
+ }
89
+ async markConnectionReady(sessionId, userId) {
90
+ await this.pool.query(`INSERT INTO connection_steps(session_id,user_id,expires_at) VALUES($1,$2,now()+interval '10 minutes')
91
+ ON CONFLICT(session_id) DO UPDATE SET user_id=$2,expires_at=now()+interval '10 minutes'`, [sessionId, userId]);
92
+ }
93
+ async connectionReady(sessionId, userId) {
94
+ const result = await this.pool.query('SELECT 1 FROM connection_steps WHERE session_id=$1 AND user_id=$2 AND expires_at>now()', [sessionId, userId]);
95
+ return result.rowCount === 1;
96
+ }
97
+ async clearConnectionStep(sessionId) {
98
+ await this.pool.query('DELETE FROM connection_steps WHERE session_id=$1', [sessionId]);
99
+ }
100
+ async allow(bucket, maximum, seconds) {
101
+ const result = await this.pool.query(`INSERT INTO request_limits(bucket,count,expires_at) VALUES($1,1,now()+$2*interval '1 second')
102
+ ON CONFLICT(bucket) DO UPDATE SET count=CASE WHEN request_limits.expires_at<=now() THEN 1 ELSE request_limits.count+1 END,
103
+ expires_at=CASE WHEN request_limits.expires_at<=now() THEN now()+$2*interval '1 second' ELSE request_limits.expires_at END RETURNING count`, [digest(bucket), seconds]);
104
+ return result.rows[0].count <= maximum;
105
+ }
106
+ async rotateKeys(batchSize = 100) {
107
+ if (!Number.isInteger(batchSize) || batchSize < 1 || batchSize > 1000)
108
+ throw new Error('Invalid rotation batch size');
109
+ const client = await this.pool.connect();
110
+ try {
111
+ await client.query('BEGIN');
112
+ const rows = await client.query("SELECT owner,ciphertext FROM credentials WHERE ciphertext->>'kid' <> $1 ORDER BY owner LIMIT $2 FOR UPDATE", [this.keyring.activeId, batchSize]);
113
+ for (const row of rows.rows) {
114
+ const context = `regulations.gov:${row.owner}`;
115
+ const sealed = this.keyring.seal(this.keyring.open(row.ciphertext, context), context);
116
+ await client.query('UPDATE credentials SET ciphertext=$2 WHERE owner=$1', [
117
+ row.owner,
118
+ sealed,
119
+ ]);
120
+ await client.query('INSERT INTO audit_events(tenant,actor,action) VALUES($1,$2,$3)', [
121
+ row.owner,
122
+ 'service-operator',
123
+ 'credential.reencrypted',
124
+ ]);
125
+ }
126
+ await client.query('COMMIT');
127
+ return rows.rowCount ?? 0;
128
+ }
129
+ catch (error) {
130
+ await client.query('ROLLBACK');
131
+ throw error;
132
+ }
133
+ finally {
134
+ client.release();
135
+ }
136
+ }
137
+ async cleanup() {
138
+ await this.pool.query('DELETE FROM request_limits WHERE expires_at<now()');
139
+ await this.pool.query('DELETE FROM connection_steps WHERE expires_at<now()');
140
+ }
141
+ }
142
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../src/accounts/store.ts"],"names":[],"mappings":"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"}
package/dist/bin.js CHANGED
@@ -54,11 +54,14 @@ function atLeastOne(value, fallback) {
54
54
  }
55
55
  async function main() {
56
56
  const args = parseArgs(process.argv.slice(2));
57
- const deps = await buildSupervisor({
57
+ const accounts = args.http && process.env.FEDREG_AUTH_PROVIDER === 'accounts';
58
+ if (accounts && args.insecure)
59
+ throw new Error('Account authentication cannot be combined with --insecure');
60
+ const cfg = {
58
61
  frBaseUrl: process.env.FEDREG_FR_BASE_URL ?? 'https://www.federalregister.gov/api/v1',
59
62
  ecfrBaseUrl: process.env.FEDREG_ECFR_BASE_URL ?? 'https://www.ecfr.gov/api',
60
63
  regsBaseUrl: process.env.FEDREG_REGS_BASE_URL ?? 'https://api.regulations.gov',
61
- regsApiKey: process.env.FEDREG_REGS_API_KEY,
64
+ regsApiKey: accounts ? undefined : process.env.FEDREG_REGS_API_KEY,
62
65
  userAgent: process.env.FEDREG_USER_AGENT ?? 'fedreg-mcp-server/2.0 (+https://github.com/blen-labs/fedreg-mcp-server)',
63
66
  upstreamTimeoutMs: Number(process.env.FEDREG_UPSTREAM_TIMEOUT_MS ?? 20_000),
64
67
  upstreamRetries: Number(process.env.FEDREG_UPSTREAM_RETRIES ?? 3),
@@ -79,9 +82,15 @@ async function main() {
79
82
  regsRatePerHour: atLeastOne(process.env.FEDREG_REGS_RATE_PER_HOUR, 1000),
80
83
  // Require >= 1; per-subject hourly cap, not "unlimited".
81
84
  regsSubjectRatePerHour: atLeastOne(process.env.FEDREG_REGS_SUBJECT_RATE_PER_HOUR, 500),
82
- });
85
+ };
86
+ const deps = await buildSupervisor(cfg);
83
87
  let handle;
84
- if (args.http) {
88
+ if (accounts) {
89
+ const { loadAccountConfig } = await import('./accounts/config.js');
90
+ const { startAccountHttp } = await import('./accounts/runtime.js');
91
+ handle = await startAccountHttp(deps, cfg, loadAccountConfig(process.env), args.port, args.host);
92
+ }
93
+ else if (args.http) {
85
94
  const allowedOrigins = process.env.FEDREG_ALLOWED_ORIGINS
86
95
  ? process.env.FEDREG_ALLOWED_ORIGINS.split(',').map(s => s.trim().toLowerCase()).filter(Boolean)
87
96
  : undefined;
package/dist/bin.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,SAAS,EAAmB,MAAM,kBAAkB,CAAC;AAC9D,OAAO,EAAE,eAAe,EAAE,iBAAiB,EAAyB,MAAM,uBAAuB,CAAC;AAClG,OAAO,EAAE,4BAA4B,EAAE,MAAM,oBAAoB,CAAC;AAElE,OAAO,EAAE,GAAG,EAAE,MAAM,kBAAkB,CAAC;AAUvC,SAAS,SAAS,CAAC,IAAc;IAC/B,MAAM,IAAI,GAAY;QACpB,IAAI,EAAE,KAAK;QACX,IAAI,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,IAAI,CAAC;QACtC,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,IAAI,IAAI,SAAS;QACnC,OAAO,EAAG,OAAO,CAAC,GAAG,CAAC,cAA0C,IAAI,MAAM;QAC1E,QAAQ,EAAE,KAAK;KAChB,CAAC;IACF,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,CAAC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,IAAI,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;aAChC,IAAI,CAAC,KAAK,YAAY;YAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC;aAC7C,IAAI,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;aAClD,IAAI,CAAC,KAAK,QAAQ;YAAE,IAAI,CAAC,IAAI,GAAG,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC;aAClD,IAAI,CAAC,KAAK,WAAW;YAAE,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,EAAE,CAAC,CAAgB,CAAC;aAC/D,IAAI,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,IAAI,EAAE,CAAC;YACtC,SAAS,EAAE,CAAC;YACZ,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IACD,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,SAAS;IAChB,OAAO,CAAC,MAAM,CAAC,KAAK,CAAC;;;;;;;;;CAStB,CAAC,CAAC;AACH,CAAC;AAED,wGAAwG;AACxG,SAAS,QAAQ,CAAC,KAAyB,EAAE,QAAgB,EAAE,GAAG,GAAG,CAAC;IACpE,MAAM,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,QAAQ,CAAC,CAAC;IACpC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC;AAChE,CAAC;AAED,+EAA+E;AAC/E,SAAS,UAAU,CAAC,KAAyB,EAAE,QAAgB;IAC7D,OAAO,QAAQ,CAAC,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAAC;AACtC,CAAC;AAED,KAAK,UAAU,IAAI;IACjB,MAAM,IAAI,GAAG,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;IAE9C,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,GAAG,CAAC,oBAAoB,KAAK,UAAU,CAAC;IAC9E,IAAI,QAAQ,IAAI,IAAI,CAAC,QAAQ;QAAE,MAAM,IAAI,KAAK,CAAC,2DAA2D,CAAC,CAAC;IAC5G,MAAM,GAAG,GAAqB;QAC5B,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,IAAI,wCAAwC;QACrF,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,0BAA0B;QAC3E,WAAW,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB,IAAI,6BAA6B;QAC9E,UAAU,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB;QAClE,SAAS,EAAE,OAAO,CAAC,GAAG,CAAC,iBAAiB,IAAI,yEAAyE;QACrH,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,MAAM,CAAC;QAC3E,eAAe,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,uBAAuB,IAAI,CAAC,CAAC;QACjE,UAAU,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,mBAAmB,IAAI,OAAO,CAAC;QAC9D,aAAa,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,IAAI,IAAI,CAAC;QACjE,OAAO,EAAE,IAAI,CAAC,OAAO;QACrB,8EAA8E;QAC9E,mBAAmB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,iBAAiB,CAAC,WAAW,CAAC;QACvG,kBAAkB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,4BAA4B,EAAE,iBAAiB,CAAC,UAAU,CAAC;QACtG,iBAAiB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,2BAA2B,EAAE,iBAAiB,CAAC,SAAS,CAAC;QACnG,wBAAwB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,mCAAmC,EAAE,4BAA4B,CAAC;QACnH,sBAAsB,EAAE,CAAC,GAAG,EAAE;YAC5B,MAAM,CAAC,GAAG,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,iCAAiC,IAAI,EAAE,CAAC,CAAC;YACtE,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QAC/C,CAAC,CAAC,EAAE;QACJ,2EAA2E;QAC3E,0EAA0E;QAC1E,eAAe,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,yBAAyB,EAAE,IAAI,CAAC;QACxE,yDAAyD;QACzD,sBAAsB,EAAE,UAAU,CAAC,OAAO,CAAC,GAAG,CAAC,iCAAiC,EAAE,GAAG,CAAC;KACvF,CAAC;IACF,MAAM,IAAI,GAAG,MAAM,eAAe,CAAC,GAAG,CAAC,CAAC;IAExC,IAAI,MAA8B,CAAC;IAEnC,IAAI,QAAQ,EAAE,CAAC;QACb,MAAM,EAAE,iBAAiB,EAAE,GAAG,MAAM,MAAM,CAAC,sBAAsB,CAAC,CAAC;QACnE,MAAM,EAAE,gBAAgB,EAAE,GAAG,MAAM,MAAM,CAAC,uBAAuB,CAAC,CAAC;QACnE,MAAM,GAAG,MAAM,gBAAgB,CAAC,IAAI,EAAE,GAAG,EAAE,iBAAiB,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;IACnG,CAAC;SAAM,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACrB,MAAM,cAAc,GAAG,OAAO,CAAC,GAAG,CAAC,sBAAsB;YACvD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YAChG,CAAC,CAAC,SAAS,CAAC;QACd,MAAM,YAAY,GAAG,OAAO,CAAC,GAAG,CAAC,oBAAoB;YACnD,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;YAC9F,CAAC,CAAC,SAAS,CAAC;QAEd,MAAM,GAAG,MAAM,SAAS,CAAC,IAAI,EAAE;YAC7B,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,IAAI,EAAE,IAAI,CAAC,IAAI;YACf,wFAAwF;YACxF,2FAA2F;YAC3F,GAAG,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,aAAa,EAAE,CAAC,CAAC;YAC3C,KAAK,EAAE,QAAQ,CAAC,OAAO,CAAC,GAAG,CAAC,eAAe,EAAE,EAAE,EAAE,CAAC,CAAC;YACnD,cAAc,EAAE,CAAC,GAAG,EAAE;gBACpB,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,uBAAuB,EAAE,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;gBACvE,IAAI,CAAC,IAAI;oBAAE,OAAO,SAAS,CAAC;gBAC5B,IAAI,cAAc,CAAC,IAAI,CAAC,IAAI,CAAC;oBAAE,OAAO,IAAI,CAAC;gBAC3C,GAAG,CAAC,IAAI,CAAC,iCAAiC,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC9D,OAAO,SAAS,CAAC;YACnB,CAAC,CAAC,EAAE;YACJ,iBAAiB,EAAE,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,MAAM,CAAC;YAC3E,QAAQ,EAAE,IAAI,CAAC,QAAQ;YACvB,YAAY;YACZ,cAAc;YACd,YAAY,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;YAC9C,IAAI,EAAE;gBACJ,QAAQ,EAAG,OAAO,CAAC,GAAG,CAAC,oBAA2C,IAAI,MAAM;gBAC5E,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB;gBACtC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;gBAC1C,OAAO,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;gBACzC,QAAQ,EAAE,OAAO,CAAC,GAAG,CAAC,oBAAoB;gBAC1C,MAAM,EAAE,OAAO,CAAC,GAAG,CAAC,kBAAkB,EAAE,KAAK,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC;aACtF;SACF,CAAC,CAAC;IACL,CAAC;SAAM,CAAC;QACN,MAAM,UAAU,CAAC,IAAI,CAAC,CAAC;IACzB,CAAC;IAED,oFAAoF;IACpF,MAAM,QAAQ,GAAG,KAAK,EAAE,MAAc,EAAE,EAAE;QACxC,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,MAAM,EAAE,CAAC,CAAC;QACvC,IAAI,CAAC;YACH,IAAI,MAAM;gBAAE,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC;QACnC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,GAAG,CAAC,IAAI,CAAC,gBAAgB,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,CAAC,CAAC;QAChE,CAAC;QACD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC;IACF,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC;IACtD,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,KAAK,QAAQ,CAAC,QAAQ,CAAC,CAAC,CAAC;AACtD,CAAC;AAID,IAAI,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE;IACjB,GAAG,CAAC,KAAK,CAAC,WAAW,EAAE,EAAE,KAAK,EAAG,GAAa,CAAC,OAAO,EAAE,KAAK,EAAG,GAAa,CAAC,KAAK,EAAE,CAAC,CAAC;IACvF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC,CAAC,CAAC"}
@@ -13,7 +13,7 @@ export function buildSdk(cfg) {
13
13
  methods: Object.freeze(methods),
14
14
  meta: sources.map(({ name, label, enabled, disabledReason }) => ({ name, label, enabled, disabledReason })),
15
15
  registeredNames: sources.map(s => s.name),
16
- version: () => '2.0.11', // x-release-version
16
+ version: () => '2.1.0', // x-release-version
17
17
  };
18
18
  }
19
19
  //# sourceMappingURL=bindings.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"bindings.js","sourceRoot":"","sources":["../../src/sdk/bindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,oBAAoB,CAAC;AAWnE,MAAM,UAAU,QAAQ,CAAC,GAAiB;IACxC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,OAAO,GAA+B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChE,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YAC3B,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;QAC9B,CAAC;IACD,OAAO;QACL,OAAO;QACP,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3G,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,OAAO,EAAE,GAAG,EAAE,CAAC,QAAQ,EAAE,oBAAoB;KAC9C,CAAC;AACJ,CAAC"}
1
+ {"version":3,"file":"bindings.js","sourceRoot":"","sources":["../../src/sdk/bindings.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAqB,MAAM,oBAAoB,CAAC;AAWnE,MAAM,UAAU,QAAQ,CAAC,GAAiB;IACxC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,CAAC;IAChC,MAAM,OAAO,GAA2B,EAAE,CAAC;IAC3C,MAAM,OAAO,GAA+B,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAChE,KAAK,MAAM,CAAC,IAAI,OAAO;QAAE,IAAI,CAAC,CAAC,OAAO,EAAE,CAAC;YACvC,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,MAAM,CAAC;YAC3B,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,OAAO,CAAC;QAC9B,CAAC;IACD,OAAO;QACL,OAAO;QACP,OAAO,EAAE,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC;QAC/B,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,EAAE,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,CAAC,CAAC;QAC3G,eAAe,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC;QACzC,OAAO,EAAE,GAAG,EAAE,CAAC,OAAO,EAAE,oBAAoB;KAC7C,CAAC;AACJ,CAAC"}
@@ -1,6 +1,8 @@
1
1
  import type { CorpusEntry } from '../../search/corpus.js';
2
- export declare function loadSourceCorpus(name: string): {
2
+ type SourceCorpus = {
3
3
  endpoints: CorpusEntry[];
4
4
  fields: CorpusEntry[];
5
5
  };
6
+ export declare function loadSourceCorpus(name: string): SourceCorpus;
7
+ export {};
6
8
  //# sourceMappingURL=corpus-loader.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"corpus-loader.d.ts","sourceRoot":"","sources":["../../../src/sdk/sources/corpus-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG;IAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAGlG"}
1
+ {"version":3,"file":"corpus-loader.d.ts","sourceRoot":"","sources":["../../../src/sdk/sources/corpus-loader.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAI1D,KAAK,YAAY,GAAG;IAAE,SAAS,EAAE,WAAW,EAAE,CAAC;IAAC,MAAM,EAAE,WAAW,EAAE,CAAA;CAAE,CAAC;AAMxE,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,GAAG,YAAY,CAQ3D"}
@@ -2,8 +2,16 @@ import { readFileSync } from 'node:fs';
2
2
  import { fileURLToPath } from 'node:url';
3
3
  import { dirname, resolve } from 'node:path';
4
4
  const __dirname = dirname(fileURLToPath(import.meta.url));
5
+ // The corpus files are static; parse each once. Source factories run more than once
6
+ // (buildSupervisor builds sources twice, and account mode builds a regs source per execute).
7
+ const cache = new Map();
5
8
  export function loadSourceCorpus(name) {
6
- const path = resolve(__dirname, `../../../schema/${name}.json`);
7
- return JSON.parse(readFileSync(path, 'utf8'));
9
+ let corpus = cache.get(name);
10
+ if (!corpus) {
11
+ const path = resolve(__dirname, `../../../schema/${name}.json`);
12
+ corpus = JSON.parse(readFileSync(path, 'utf8'));
13
+ cache.set(name, corpus);
14
+ }
15
+ return corpus;
8
16
  }
9
17
  //# sourceMappingURL=corpus-loader.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"corpus-loader.js","sourceRoot":"","sources":["../../../src/sdk/sources/corpus-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG7C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAE1D,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,mBAAmB,IAAI,OAAO,CAAC,CAAC;IAChE,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAwD,CAAC;AACvG,CAAC"}
1
+ {"version":3,"file":"corpus-loader.js","sourceRoot":"","sources":["../../../src/sdk/sources/corpus-loader.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AACvC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AACzC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAG7C,MAAM,SAAS,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;AAI1D,oFAAoF;AACpF,6FAA6F;AAC7F,MAAM,KAAK,GAAG,IAAI,GAAG,EAAwB,CAAC;AAE9C,MAAM,UAAU,gBAAgB,CAAC,IAAY;IAC3C,IAAI,MAAM,GAAG,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;IAC7B,IAAI,CAAC,MAAM,EAAE,CAAC;QACZ,MAAM,IAAI,GAAG,OAAO,CAAC,SAAS,EAAE,mBAAmB,IAAI,OAAO,CAAC,CAAC;QAChE,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAiB,CAAC;QAChE,KAAK,CAAC,GAAG,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;IAC1B,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -1,6 +1,6 @@
1
1
  import type { Dispatcher } from 'undici';
2
2
  import type { CorpusEntry } from '../../search/corpus.js';
3
- import type { UpstreamGateLike } from '../../util/httpClient.js';
3
+ import type { PreflightLimiter, UpstreamGateLike } from '../../util/httpClient.js';
4
4
  export interface SourceMeta {
5
5
  name: string;
6
6
  label: string;
@@ -27,10 +27,7 @@ export interface SourceConfig {
27
27
  cacheTtlMs: number;
28
28
  cacheMaxItems: number;
29
29
  dispatcher?: Dispatcher;
30
- regsPreflightLimiter?: {
31
- tryTake(): boolean;
32
- secondsUntilNext?(): number;
33
- };
30
+ regsPreflightLimiter?: PreflightLimiter;
34
31
  /** Process-wide admission control per public upstream; built once in buildSupervisor. */
35
32
  frGate?: UpstreamGateLike;
36
33
  ecfrGate?: UpstreamGateLike;
@@ -1 +1 @@
1
- {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/sdk/sources/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEjE,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,MAAO,SAAQ,UAAU;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE;QAAE,SAAS,EAAE,WAAW,EAAE,CAAC;QAAC,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;CAC7D;AAID,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,oBAAoB,CAAC,EAAE;QAAE,OAAO,IAAI,OAAO,CAAC;QAAC,gBAAgB,CAAC,IAAI,MAAM,CAAA;KAAE,CAAC;IAC3E,yFAAyF;IACzF,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B"}
1
+ {"version":3,"file":"source.d.ts","sourceRoot":"","sources":["../../../src/sdk/sources/source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAC;AACzC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wBAAwB,CAAC;AAC1D,OAAO,KAAK,EAAE,gBAAgB,EAAE,gBAAgB,EAAE,MAAM,0BAA0B,CAAC;AAEnF,MAAM,WAAW,UAAU;IACzB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,OAAO,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,MAAO,SAAQ,UAAU;IACxC,MAAM,EAAE,MAAM,CAAC;IACf,OAAO,EAAE,UAAU,CAAC;IACpB,MAAM,EAAE;QAAE,SAAS,EAAE,WAAW,EAAE,CAAC;QAAC,MAAM,EAAE,WAAW,EAAE,CAAA;KAAE,CAAC;CAC7D;AAID,MAAM,MAAM,UAAU,GAAG,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,OAAO,CAAC,CAAC,CAAC;AAE/E,MAAM,WAAW,YAAY;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,MAAM,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,aAAa,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,UAAU,CAAC;IACxB,oBAAoB,CAAC,EAAE,gBAAgB,CAAC;IACxC,yFAAyF;IACzF,MAAM,CAAC,EAAE,gBAAgB,CAAC;IAC1B,QAAQ,CAAC,EAAE,gBAAgB,CAAC;CAC7B"}