network-ai 5.3.2 → 5.4.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.
@@ -0,0 +1,500 @@
1
+ "use strict";
2
+ /**
3
+ * EnvironmentManager — Multi-environment isolation for Network-AI
4
+ *
5
+ * Provides strict data directory separation between environments
6
+ * (dev, st, sit, qa, sandbox, preprod, prod) with promotion chain
7
+ * enforcement, approval gates, and automatic backup/restore.
8
+ *
9
+ * Promotion chain: dev → st → sit → qa → preprod → prod
10
+ * Sandbox is a dead-end (non-promotable testing space).
11
+ *
12
+ * Gate types:
13
+ * - auto: promotion proceeds without human interaction
14
+ * - confirm: promotion requires `confirmedBy` string to be set
15
+ * - approval: promotion requires `approvedBy` string to be set
16
+ *
17
+ * @module EnvironmentManager
18
+ * @version 1.0.0
19
+ */
20
+ Object.defineProperty(exports, "__esModule", { value: true });
21
+ exports.EnvironmentManager = void 0;
22
+ const fs_1 = require("fs");
23
+ const path_1 = require("path");
24
+ const crypto_1 = require("crypto");
25
+ // ============================================================================
26
+ // DEFAULTS
27
+ // ============================================================================
28
+ /** Default promotion chain. */
29
+ const DEFAULT_CHAIN = ['dev', 'st', 'sit', 'qa', 'preprod', 'prod'];
30
+ /** Default gate configuration. */
31
+ const DEFAULT_GATES = {
32
+ dev: 'auto',
33
+ st: 'auto',
34
+ sit: 'auto',
35
+ qa: 'auto',
36
+ sandbox: 'auto',
37
+ preprod: 'confirm',
38
+ prod: 'approval',
39
+ };
40
+ /**
41
+ * Files that ARE copied during promotion (config artefacts only).
42
+ * Live operational state is never promoted.
43
+ */
44
+ const PROMOTE_INCLUDE = [
45
+ 'trust_levels.json',
46
+ 'budget_ceilings.json',
47
+ 'validation_rules.json',
48
+ ];
49
+ /**
50
+ * Files/directories that are NEVER copied during promotion.
51
+ * Matches by name prefix or exact name.
52
+ */
53
+ const PROMOTE_EXCLUDE = [
54
+ 'audit_log.jsonl',
55
+ 'active_grants.json',
56
+ 'pending_changes',
57
+ '.backups',
58
+ ];
59
+ // ============================================================================
60
+ // MAIN CLASS
61
+ // ============================================================================
62
+ /**
63
+ * Manages isolated data directories for multiple deployment environments.
64
+ *
65
+ * @example
66
+ * ```typescript
67
+ * const mgr = new EnvironmentManager('/path/to/project/data');
68
+ * mgr.initAll();
69
+ * const devDir = mgr.getDataDir('dev'); // → /path/to/project/data/dev
70
+ * mgr.promote('dev', 'st'); // auto-gate
71
+ * mgr.promote('qa', 'preprod', { confirmedBy: 'ops-lead' });
72
+ * mgr.promote('preprod', 'prod', { approvedBy: 'cto@example.com' });
73
+ * ```
74
+ */
75
+ class EnvironmentManager {
76
+ baseDir;
77
+ config;
78
+ /**
79
+ * @param baseDir - Root data directory (e.g. `path.join(process.cwd(), 'data')`).
80
+ * @param config - Optional overrides for chain, gates, and backup retention.
81
+ */
82
+ constructor(baseDir, config) {
83
+ this.baseDir = (0, path_1.resolve)(baseDir);
84
+ this.config = {
85
+ chain: config?.chain ?? DEFAULT_CHAIN,
86
+ gates: { ...DEFAULT_GATES, ...(config?.gates ?? {}) },
87
+ backupRetain: config?.backupRetain ?? 10,
88
+ };
89
+ // Load env-config.json if present (overrides constructor config)
90
+ this._loadEnvConfig();
91
+ }
92
+ // --------------------------------------------------------------------------
93
+ // Path helpers
94
+ // --------------------------------------------------------------------------
95
+ /**
96
+ * Returns the isolated data directory for the given environment.
97
+ * Creates it if it does not exist.
98
+ */
99
+ getDataDir(env) {
100
+ const envPath = (0, path_1.join)(this.baseDir, env);
101
+ // Normalise and guard against traversal
102
+ const safe = (0, path_1.resolve)(envPath);
103
+ if (!safe.startsWith(this.baseDir + require('path').sep) && safe !== this.baseDir) {
104
+ throw new Error(`Environment name '${env}' would escape the base directory`);
105
+ }
106
+ return safe;
107
+ }
108
+ // --------------------------------------------------------------------------
109
+ // Init
110
+ // --------------------------------------------------------------------------
111
+ /**
112
+ * Scaffold the standard subdirectory layout for a single environment.
113
+ * Idempotent — safe to call multiple times.
114
+ */
115
+ init(env) {
116
+ const base = this.getDataDir(env);
117
+ const dirs = [
118
+ base,
119
+ (0, path_1.join)(base, 'blackboard'),
120
+ (0, path_1.join)(base, 'pending_changes'),
121
+ (0, path_1.join)(base, '.backups'),
122
+ ];
123
+ for (const d of dirs) {
124
+ (0, fs_1.mkdirSync)(d, { recursive: true, mode: 0o700 });
125
+ }
126
+ // Touch empty state files so downstream code never hits ENOENT
127
+ this._touchJson((0, path_1.join)(base, 'trust_levels.json'), {});
128
+ this._touchJson((0, path_1.join)(base, 'active_grants.json'), []);
129
+ this._touchJson((0, path_1.join)(base, 'project-context.json'), { env });
130
+ this._touchFile((0, path_1.join)(base, 'audit_log.jsonl'));
131
+ }
132
+ /** Scaffold all environments in the promotion chain plus sandbox. */
133
+ initAll() {
134
+ const envs = new Set([...this.config.chain, 'sandbox']);
135
+ for (const env of envs) {
136
+ this.init(env);
137
+ }
138
+ }
139
+ // --------------------------------------------------------------------------
140
+ // Promotion
141
+ // --------------------------------------------------------------------------
142
+ /**
143
+ * Promotes configuration artefacts from one environment to the next.
144
+ * Live state (audit log, active grants, pending changes, blackboard entries)
145
+ * is never promoted.
146
+ *
147
+ * @throws {Error} If gate requirements are not met, or sandbox is the source.
148
+ */
149
+ promote(from, to, options = {}) {
150
+ if (!this.isPromotable(from)) {
151
+ throw new Error(`Environment '${from}' is not promotable (sandbox is a dead-end)`);
152
+ }
153
+ const chain = this.config.chain;
154
+ const fromIdx = chain.indexOf(from);
155
+ const toIdx = chain.indexOf(to);
156
+ if (fromIdx === -1)
157
+ throw new Error(`Environment '${from}' is not in the promotion chain`);
158
+ if (toIdx === -1)
159
+ throw new Error(`Environment '${to}' is not in the promotion chain`);
160
+ if (toIdx !== fromIdx + 1) {
161
+ throw new Error(`Can only promote one step at a time (${from} → ${chain[fromIdx + 1]}, not ${to})`);
162
+ }
163
+ // Gate enforcement
164
+ const gate = this.getGateType(to);
165
+ if (gate === 'confirm' && !options.confirmedBy) {
166
+ throw new Error(`Promotion to '${to}' requires confirmedBy (gate: confirm)`);
167
+ }
168
+ if (gate === 'approval' && !options.approvedBy) {
169
+ throw new Error(`Promotion to '${to}' requires approvedBy (gate: approval)`);
170
+ }
171
+ // Auto-backup destination before overwriting
172
+ if ((0, fs_1.existsSync)(this.getDataDir(to))) {
173
+ this.backup(to);
174
+ }
175
+ const fromDir = this.getDataDir(from);
176
+ const toDir = this.getDataDir(to);
177
+ this.init(to);
178
+ const copied = [];
179
+ const skipped = [];
180
+ // Copy only promotion-safe config files
181
+ for (const file of PROMOTE_INCLUDE) {
182
+ const src = (0, path_1.join)(fromDir, file);
183
+ const dst = (0, path_1.join)(toDir, file);
184
+ if ((0, fs_1.existsSync)(src)) {
185
+ (0, fs_1.copyFileSync)(src, dst);
186
+ copied.push(file);
187
+ }
188
+ else {
189
+ skipped.push(file);
190
+ }
191
+ }
192
+ const result = {
193
+ from,
194
+ to,
195
+ configsCopied: copied,
196
+ skipped,
197
+ timestamp: new Date().toISOString(),
198
+ };
199
+ if (options.approvedBy)
200
+ result.approvedBy = options.approvedBy;
201
+ if (options.confirmedBy)
202
+ result.confirmedBy = options.confirmedBy;
203
+ return result;
204
+ }
205
+ // --------------------------------------------------------------------------
206
+ // Diff
207
+ // --------------------------------------------------------------------------
208
+ /**
209
+ * Compares configuration artefacts between two environments.
210
+ * Only compares promotion-safe files.
211
+ */
212
+ diff(env1, env2) {
213
+ const dir1 = this.getDataDir(env1);
214
+ const dir2 = this.getDataDir(env2);
215
+ const differences = [];
216
+ const files1 = this._listConfigFiles(dir1);
217
+ const files2 = this._listConfigFiles(dir2);
218
+ const allFiles = new Set([...files1, ...files2]);
219
+ for (const file of allFiles) {
220
+ const p1 = (0, path_1.join)(dir1, file);
221
+ const p2 = (0, path_1.join)(dir2, file);
222
+ const has1 = (0, fs_1.existsSync)(p1);
223
+ const has2 = (0, fs_1.existsSync)(p2);
224
+ if (has1 && !has2) {
225
+ differences.push({ file, status: 'removed' });
226
+ }
227
+ else if (!has1 && has2) {
228
+ differences.push({ file, status: 'added' });
229
+ }
230
+ else if (has1 && has2) {
231
+ const c1 = (0, fs_1.readFileSync)(p1, 'utf-8');
232
+ const c2 = (0, fs_1.readFileSync)(p2, 'utf-8');
233
+ if (c1 !== c2) {
234
+ differences.push({ file, status: 'changed' });
235
+ }
236
+ }
237
+ }
238
+ return { env1, env2, differences };
239
+ }
240
+ // --------------------------------------------------------------------------
241
+ // Listing
242
+ // --------------------------------------------------------------------------
243
+ /** List all environments, whether they exist, and how many blackboard keys each has. */
244
+ list() {
245
+ const envs = new Set([...this.config.chain, 'sandbox']);
246
+ return Array.from(envs).map(name => {
247
+ const dir = (0, path_1.join)(this.baseDir, name);
248
+ const exists = (0, fs_1.existsSync)(dir);
249
+ let keyCount = 0;
250
+ if (exists) {
251
+ const bbDir = (0, path_1.join)(dir, 'blackboard');
252
+ if ((0, fs_1.existsSync)(bbDir)) {
253
+ try {
254
+ keyCount = (0, fs_1.readdirSync)(bbDir).filter(f => f.endsWith('.json')).length;
255
+ }
256
+ catch { /* ignore */ }
257
+ }
258
+ }
259
+ return { name, exists, keyCount };
260
+ });
261
+ }
262
+ /** Returns the configured promotion chain. */
263
+ getChain() {
264
+ return [...this.config.chain];
265
+ }
266
+ /**
267
+ * Returns true if the environment can be used as a promotion source.
268
+ * 'sandbox' is always false.
269
+ */
270
+ isPromotable(env) {
271
+ if (env === 'sandbox')
272
+ return false;
273
+ return this.config.chain.includes(env);
274
+ }
275
+ /**
276
+ * Returns the next environment in the chain after `env`, or null if `env`
277
+ * is the last in the chain or not in the chain.
278
+ */
279
+ getNextEnv(env) {
280
+ const idx = this.config.chain.indexOf(env);
281
+ if (idx === -1 || idx === this.config.chain.length - 1)
282
+ return null;
283
+ return this.config.chain[idx + 1];
284
+ }
285
+ /** Returns the gate type controlling promotion INTO the given environment. */
286
+ getGateType(env) {
287
+ return this.config.gates[env] ?? 'auto';
288
+ }
289
+ // --------------------------------------------------------------------------
290
+ // Backup / Restore
291
+ // --------------------------------------------------------------------------
292
+ /**
293
+ * Creates a timestamped backup of an environment's data directory.
294
+ * Stored at `data/<env>/.backups/<backupId>/`.
295
+ * Automatically prunes old backups to retain at most `backupRetain` copies.
296
+ */
297
+ backup(env) {
298
+ const envDir = this.getDataDir(env);
299
+ const backupsDir = (0, path_1.join)(envDir, '.backups');
300
+ (0, fs_1.mkdirSync)(backupsDir, { recursive: true, mode: 0o700 });
301
+ const backupId = new Date().toISOString().replace(/[:.]/g, '-') + '_' + (0, crypto_1.randomUUID)().slice(0, 8);
302
+ const backupPath = (0, path_1.join)(backupsDir, backupId);
303
+ (0, fs_1.mkdirSync)(backupPath, { recursive: true, mode: 0o700 });
304
+ const files = this._collectBackupFiles(envDir);
305
+ for (const rel of files) {
306
+ const src = (0, path_1.join)(envDir, rel);
307
+ const dst = (0, path_1.join)(backupPath, rel);
308
+ (0, fs_1.mkdirSync)((0, path_1.join)(backupPath, rel.includes('/') ? rel.substring(0, rel.lastIndexOf('/')) : '.'), { recursive: true });
309
+ try {
310
+ (0, fs_1.copyFileSync)(src, dst);
311
+ }
312
+ catch { /* skip unreadable */ }
313
+ }
314
+ // Write manifest
315
+ const manifest = {
316
+ backupId,
317
+ env,
318
+ timestamp: new Date().toISOString(),
319
+ sizeBytes: this._dirSize(backupPath),
320
+ path: backupPath,
321
+ };
322
+ (0, fs_1.writeFileSync)((0, path_1.join)(backupPath, '_manifest.json'), JSON.stringify(manifest, null, 2), 'utf-8');
323
+ // Prune old backups
324
+ this.pruneBackups(env, this.config.backupRetain);
325
+ return { backupId, env, path: backupPath, filesCount: files.length };
326
+ }
327
+ /**
328
+ * Restores an environment from a previously created backup.
329
+ *
330
+ * @param env - The environment to restore into.
331
+ * @param backupId - The backup ID (from `listBackups()`).
332
+ */
333
+ restore(env, backupId) {
334
+ const envDir = this.getDataDir(env);
335
+ const backupsDir = (0, path_1.join)(envDir, '.backups');
336
+ const backupPath = (0, path_1.join)(backupsDir, backupId);
337
+ if (!(0, fs_1.existsSync)(backupPath)) {
338
+ throw new Error(`Backup '${backupId}' not found for environment '${env}'`);
339
+ }
340
+ // Create a safety backup of the current state before restoring
341
+ this.backup(env);
342
+ const files = this._collectBackupFiles(backupPath);
343
+ let restored = 0;
344
+ for (const rel of files) {
345
+ if (rel === '_manifest.json')
346
+ continue;
347
+ const src = (0, path_1.join)(backupPath, rel);
348
+ const dst = (0, path_1.join)(envDir, rel);
349
+ try {
350
+ (0, fs_1.mkdirSync)((0, path_1.join)(envDir, rel.includes('/') ? rel.substring(0, rel.lastIndexOf('/')) : '.'), { recursive: true });
351
+ (0, fs_1.copyFileSync)(src, dst);
352
+ restored++;
353
+ }
354
+ catch { /* skip */ }
355
+ }
356
+ return { backupId, env, filesRestored: restored };
357
+ }
358
+ /**
359
+ * Lists all backups for an environment, newest first.
360
+ */
361
+ listBackups(env) {
362
+ const envDir = this.getDataDir(env);
363
+ const backupsDir = (0, path_1.join)(envDir, '.backups');
364
+ if (!(0, fs_1.existsSync)(backupsDir))
365
+ return [];
366
+ const entries = [];
367
+ for (const name of (0, fs_1.readdirSync)(backupsDir)) {
368
+ const manifest = (0, path_1.join)(backupsDir, name, '_manifest.json');
369
+ if ((0, fs_1.existsSync)(manifest)) {
370
+ try {
371
+ const entry = JSON.parse((0, fs_1.readFileSync)(manifest, 'utf-8'));
372
+ entries.push(entry);
373
+ }
374
+ catch { /* corrupt manifest, skip */ }
375
+ }
376
+ }
377
+ // Sort newest first
378
+ return entries.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
379
+ }
380
+ /**
381
+ * Removes old backups for an environment, keeping only the `keep` most recent.
382
+ * @returns Number of backups deleted.
383
+ */
384
+ pruneBackups(env, keep) {
385
+ const all = this.listBackups(env);
386
+ if (all.length <= keep)
387
+ return 0;
388
+ const toDelete = all.slice(keep);
389
+ let deleted = 0;
390
+ for (const entry of toDelete) {
391
+ try {
392
+ (0, fs_1.rmSync)(entry.path, { recursive: true, force: true });
393
+ deleted++;
394
+ }
395
+ catch { /* ignore */ }
396
+ }
397
+ return deleted;
398
+ }
399
+ // --------------------------------------------------------------------------
400
+ // Private helpers
401
+ // --------------------------------------------------------------------------
402
+ _loadEnvConfig() {
403
+ const configPath = (0, path_1.join)(this.baseDir, 'env-config.json');
404
+ if (!(0, fs_1.existsSync)(configPath))
405
+ return;
406
+ try {
407
+ const raw = JSON.parse((0, fs_1.readFileSync)(configPath, 'utf-8'));
408
+ if (Array.isArray(raw.chain))
409
+ this.config.chain = raw.chain;
410
+ if (raw.gates && typeof raw.gates === 'object') {
411
+ Object.assign(this.config.gates, raw.gates);
412
+ }
413
+ if (typeof raw.backupRetain === 'number')
414
+ this.config.backupRetain = raw.backupRetain;
415
+ }
416
+ catch { /* malformed config — silently ignore */ }
417
+ }
418
+ _touchJson(filePath, defaultValue) {
419
+ try {
420
+ const fd = (0, fs_1.openSync)(filePath, (fs_1.constants.O_CREAT | fs_1.constants.O_EXCL | fs_1.constants.O_WRONLY), 0o600);
421
+ try {
422
+ (0, fs_1.writeFileSync)(fd, JSON.stringify(defaultValue, null, 2));
423
+ }
424
+ finally {
425
+ (0, fs_1.closeSync)(fd);
426
+ }
427
+ }
428
+ catch { /* file already exists — that's fine */ }
429
+ }
430
+ _touchFile(filePath) {
431
+ try {
432
+ const fd = (0, fs_1.openSync)(filePath, (fs_1.constants.O_CREAT | fs_1.constants.O_EXCL | fs_1.constants.O_WRONLY), 0o600);
433
+ (0, fs_1.closeSync)(fd);
434
+ }
435
+ catch { /* file already exists — that's fine */ }
436
+ }
437
+ _listConfigFiles(dir) {
438
+ if (!(0, fs_1.existsSync)(dir))
439
+ return [];
440
+ try {
441
+ return (0, fs_1.readdirSync)(dir).filter(f => {
442
+ if (PROMOTE_EXCLUDE.some(ex => f === ex || f.startsWith(ex)))
443
+ return false;
444
+ // Only include regular files, not directories
445
+ try {
446
+ return (0, fs_1.statSync)((0, path_1.join)(dir, f)).isFile();
447
+ }
448
+ catch {
449
+ return false;
450
+ }
451
+ });
452
+ }
453
+ catch {
454
+ return [];
455
+ }
456
+ }
457
+ _collectBackupFiles(dir) {
458
+ const results = [];
459
+ const walk = (current, prefix) => {
460
+ let entries;
461
+ try {
462
+ entries = (0, fs_1.readdirSync)(current);
463
+ }
464
+ catch {
465
+ return;
466
+ }
467
+ for (const entry of entries) {
468
+ if (entry === '.backups')
469
+ continue; // don't back up backups
470
+ const full = (0, path_1.join)(current, entry);
471
+ const rel = prefix ? `${prefix}/${entry}` : entry;
472
+ try {
473
+ const info = (0, fs_1.statSync)(full);
474
+ if (info.isDirectory()) {
475
+ walk(full, rel);
476
+ }
477
+ else {
478
+ results.push(rel);
479
+ }
480
+ }
481
+ catch { /* skip */ }
482
+ }
483
+ };
484
+ walk(dir, '');
485
+ return results;
486
+ }
487
+ _dirSize(dir) {
488
+ let size = 0;
489
+ const files = this._collectBackupFiles(dir);
490
+ for (const rel of files) {
491
+ try {
492
+ size += (0, fs_1.statSync)((0, path_1.join)(dir, rel)).size;
493
+ }
494
+ catch { /* skip */ }
495
+ }
496
+ return size;
497
+ }
498
+ }
499
+ exports.EnvironmentManager = EnvironmentManager;
500
+ //# sourceMappingURL=env-manager.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"env-manager.js","sourceRoot":"","sources":["../../lib/env-manager.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;AAEH,2BAYY;AACZ,+BAAqC;AACrC,mCAAoC;AAiFpC,+EAA+E;AAC/E,WAAW;AACX,+EAA+E;AAE/E,+BAA+B;AAC/B,MAAM,aAAa,GAAc,CAAC,KAAK,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,CAAC;AAE/E,kCAAkC;AAClC,MAAM,aAAa,GAA6B;IAC9C,GAAG,EAAE,MAAM;IACX,EAAE,EAAE,MAAM;IACV,GAAG,EAAE,MAAM;IACX,EAAE,EAAE,MAAM;IACV,OAAO,EAAE,MAAM;IACf,OAAO,EAAE,SAAS;IAClB,IAAI,EAAE,UAAU;CACjB,CAAC;AAEF;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,mBAAmB;IACnB,sBAAsB;IACtB,uBAAuB;CACxB,CAAC;AAEF;;;GAGG;AACH,MAAM,eAAe,GAAG;IACtB,iBAAiB;IACjB,oBAAoB;IACpB,iBAAiB;IACjB,UAAU;CACX,CAAC;AAEF,+EAA+E;AAC/E,aAAa;AACb,+EAA+E;AAE/E;;;;;;;;;;;;GAYG;AACH,MAAa,kBAAkB;IACZ,OAAO,CAAS;IAChB,MAAM,CAAY;IAEnC;;;OAGG;IACH,YAAY,OAAe,EAAE,MAA2B;QACtD,IAAI,CAAC,OAAO,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC;QAChC,IAAI,CAAC,MAAM,GAAG;YACZ,KAAK,EAAE,MAAM,EAAE,KAAK,IAAI,aAAa;YACrC,KAAK,EAAE,EAAE,GAAG,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,IAAI,EAAE,CAAC,EAAE;YACrD,YAAY,EAAE,MAAM,EAAE,YAAY,IAAI,EAAE;SACzC,CAAC;QACF,iEAAiE;QACjE,IAAI,CAAC,cAAc,EAAE,CAAC;IACxB,CAAC;IAED,6EAA6E;IAC7E,eAAe;IACf,6EAA6E;IAE7E;;;OAGG;IACH,UAAU,CAAC,GAAY;QACrB,MAAM,OAAO,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACxC,wCAAwC;QACxC,MAAM,IAAI,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC;QAC9B,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,CAAC,IAAI,IAAI,KAAK,IAAI,CAAC,OAAO,EAAE,CAAC;YAClF,MAAM,IAAI,KAAK,CAAC,qBAAqB,GAAG,mCAAmC,CAAC,CAAC;QAC/E,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,6EAA6E;IAC7E,OAAO;IACP,6EAA6E;IAE7E;;;OAGG;IACH,IAAI,CAAC,GAAY;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QAClC,MAAM,IAAI,GAAG;YACX,IAAI;YACJ,IAAA,WAAI,EAAC,IAAI,EAAE,YAAY,CAAC;YACxB,IAAA,WAAI,EAAC,IAAI,EAAE,iBAAiB,CAAC;YAC7B,IAAA,WAAI,EAAC,IAAI,EAAE,UAAU,CAAC;SACvB,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC;YACrB,IAAA,cAAS,EAAC,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QACjD,CAAC;QACD,+DAA+D;QAC/D,IAAI,CAAC,UAAU,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,mBAAmB,CAAC,EAAE,EAAE,CAAC,CAAC;QACrD,IAAI,CAAC,UAAU,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,oBAAoB,CAAC,EAAE,EAAE,CAAC,CAAC;QACtD,IAAI,CAAC,UAAU,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,sBAAsB,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,CAAC;QAC7D,IAAI,CAAC,UAAU,CAAC,IAAA,WAAI,EAAC,IAAI,EAAE,iBAAiB,CAAC,CAAC,CAAC;IACjD,CAAC;IAED,qEAAqE;IACrE,OAAO;QACL,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;QACxD,KAAK,MAAM,GAAG,IAAI,IAAI,EAAE,CAAC;YACvB,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IAED,6EAA6E;IAC7E,YAAY;IACZ,6EAA6E;IAE7E;;;;;;OAMG;IACH,OAAO,CAAC,IAAa,EAAE,EAAW,EAAE,UAA0B,EAAE;QAC9D,IAAI,CAAC,IAAI,CAAC,YAAY,CAAC,IAAI,CAAC,EAAE,CAAC;YAC7B,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,6CAA6C,CAAC,CAAC;QACrF,CAAC;QAED,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC;QAChC,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;QACpC,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;QAChC,IAAI,OAAO,KAAK,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,IAAI,iCAAiC,CAAC,CAAC;QAC3F,IAAI,KAAK,KAAK,CAAC,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,gBAAgB,EAAE,iCAAiC,CAAC,CAAC;QACvF,IAAI,KAAK,KAAK,OAAO,GAAG,CAAC,EAAE,CAAC;YAC1B,MAAM,IAAI,KAAK,CAAC,wCAAwC,IAAI,MAAM,KAAK,CAAC,OAAO,GAAG,CAAC,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;QACtG,CAAC;QAED,mBAAmB;QACnB,MAAM,IAAI,GAAG,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,IAAI,KAAK,SAAS,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,iBAAiB,EAAE,wCAAwC,CAAC,CAAC;QAC/E,CAAC;QACD,IAAI,IAAI,KAAK,UAAU,IAAI,CAAC,OAAO,CAAC,UAAU,EAAE,CAAC;YAC/C,MAAM,IAAI,KAAK,CAAC,iBAAiB,EAAE,wCAAwC,CAAC,CAAC;QAC/E,CAAC;QAED,6CAA6C;QAC7C,IAAI,IAAA,eAAU,EAAC,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;YACpC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QAED,MAAM,OAAO,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACtC,MAAM,KAAK,GAAG,IAAI,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;QAClC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;QAEd,MAAM,MAAM,GAAa,EAAE,CAAC;QAC5B,MAAM,OAAO,GAAa,EAAE,CAAC;QAE7B,wCAAwC;QACxC,KAAK,MAAM,IAAI,IAAI,eAAe,EAAE,CAAC;YACnC,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YAChC,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,KAAK,EAAE,IAAI,CAAC,CAAC;YAC9B,IAAI,IAAA,eAAU,EAAC,GAAG,CAAC,EAAE,CAAC;gBACpB,IAAA,iBAAY,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvB,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACpB,CAAC;iBAAM,CAAC;gBACN,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACrB,CAAC;QACH,CAAC;QAED,MAAM,MAAM,GAAoB;YAC9B,IAAI;YACJ,EAAE;YACF,aAAa,EAAE,MAAM;YACrB,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QACF,IAAI,OAAO,CAAC,UAAU;YAAE,MAAM,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QAC/D,IAAI,OAAO,CAAC,WAAW;YAAE,MAAM,CAAC,WAAW,GAAG,OAAO,CAAC,WAAW,CAAC;QAElE,OAAO,MAAM,CAAC;IAChB,CAAC;IAED,6EAA6E;IAC7E,OAAO;IACP,6EAA6E;IAE7E;;;OAGG;IACH,IAAI,CAAC,IAAa,EAAE,IAAa;QAC/B,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QACnC,MAAM,WAAW,GAAkB,EAAE,CAAC;QAEtC,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,MAAM,GAAG,IAAI,CAAC,gBAAgB,CAAC,IAAI,CAAC,CAAC;QAC3C,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,MAAM,EAAE,GAAG,MAAM,CAAC,CAAC,CAAC;QAEjD,KAAK,MAAM,IAAI,IAAI,QAAQ,EAAE,CAAC;YAC5B,MAAM,EAAE,GAAG,IAAA,WAAI,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5B,MAAM,EAAE,GAAG,IAAA,WAAI,EAAC,IAAI,EAAE,IAAI,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAA,eAAU,EAAC,EAAE,CAAC,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAA,eAAU,EAAC,EAAE,CAAC,CAAC;YAE5B,IAAI,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;YAChD,CAAC;iBAAM,IAAI,CAAC,IAAI,IAAI,IAAI,EAAE,CAAC;gBACzB,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YAC9C,CAAC;iBAAM,IAAI,IAAI,IAAI,IAAI,EAAE,CAAC;gBACxB,MAAM,EAAE,GAAG,IAAA,iBAAY,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBACrC,MAAM,EAAE,GAAG,IAAA,iBAAY,EAAC,EAAE,EAAE,OAAO,CAAC,CAAC;gBACrC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC;oBACd,WAAW,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;QACH,CAAC;QAED,OAAO,EAAE,IAAI,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC;IACrC,CAAC;IAED,6EAA6E;IAC7E,UAAU;IACV,6EAA6E;IAE7E,wFAAwF;IACxF,IAAI;QACF,MAAM,IAAI,GAAG,IAAI,GAAG,CAAC,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,SAAS,CAAC,CAAC,CAAC;QACxD,OAAO,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE;YACjC,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,OAAO,EAAE,IAAI,CAAC,CAAC;YACrC,MAAM,MAAM,GAAG,IAAA,eAAU,EAAC,GAAG,CAAC,CAAC;YAC/B,IAAI,QAAQ,GAAG,CAAC,CAAC;YACjB,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,KAAK,GAAG,IAAA,WAAI,EAAC,GAAG,EAAE,YAAY,CAAC,CAAC;gBACtC,IAAI,IAAA,eAAU,EAAC,KAAK,CAAC,EAAE,CAAC;oBACtB,IAAI,CAAC;wBACH,QAAQ,GAAG,IAAA,gBAAW,EAAC,KAAK,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC;oBACxE,CAAC;oBAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;gBAC1B,CAAC;YACH,CAAC;YACD,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAC;QACpC,CAAC,CAAC,CAAC;IACL,CAAC;IAED,8CAA8C;IAC9C,QAAQ;QACN,OAAO,CAAC,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IAChC,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,GAAY;QACvB,IAAI,GAAG,KAAK,SAAS;YAAE,OAAO,KAAK,CAAC;QACpC,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC;IACzC,CAAC;IAED;;;OAGG;IACH,UAAU,CAAC,GAAY;QACrB,MAAM,GAAG,GAAG,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC3C,IAAI,GAAG,KAAK,CAAC,CAAC,IAAI,GAAG,KAAK,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC;QACpE,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,GAAG,CAAC,CAAC,CAAC;IACpC,CAAC;IAED,8EAA8E;IAC9E,WAAW,CAAC,GAAY;QACtB,OAAO,IAAI,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,MAAM,CAAC;IAC1C,CAAC;IAED,6EAA6E;IAC7E,mBAAmB;IACnB,6EAA6E;IAE7E;;;;OAIG;IACH,MAAM,CAAC,GAAY;QACjB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5C,IAAA,cAAS,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAExD,MAAM,QAAQ,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,GAAG,GAAG,IAAA,mBAAU,GAAE,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjG,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAC9C,IAAA,cAAS,EAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;QAExD,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,MAAM,CAAC,CAAC;QAC/C,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC9B,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAClC,IAAA,cAAS,EAAC,IAAA,WAAI,EAAC,UAAU,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;YACnH,IAAI,CAAC;gBAAC,IAAA,iBAAY,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,qBAAqB,CAAC,CAAC;QACjE,CAAC;QAED,iBAAiB;QACjB,MAAM,QAAQ,GAAgB;YAC5B,QAAQ;YACR,GAAG;YACH,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,IAAI,CAAC,QAAQ,CAAC,UAAU,CAAC;YACpC,IAAI,EAAE,UAAU;SACjB,CAAC;QACF,IAAA,kBAAa,EAAC,IAAA,WAAI,EAAC,UAAU,EAAE,gBAAgB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,QAAQ,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QAE9F,oBAAoB;QACpB,IAAI,CAAC,YAAY,CAAC,GAAG,EAAE,IAAI,CAAC,MAAM,CAAC,YAAY,CAAC,CAAC;QAEjD,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,IAAI,EAAE,UAAU,EAAE,UAAU,EAAE,KAAK,CAAC,MAAM,EAAE,CAAC;IACvE,CAAC;IAED;;;;;OAKG;IACH,OAAO,CAAC,GAAY,EAAE,QAAgB;QACpC,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5C,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;QAE9C,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,KAAK,CAAC,WAAW,QAAQ,gCAAgC,GAAG,GAAG,CAAC,CAAC;QAC7E,CAAC;QAED,+DAA+D;QAC/D,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAEjB,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,UAAU,CAAC,CAAC;QACnD,IAAI,QAAQ,GAAG,CAAC,CAAC;QACjB,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,GAAG,KAAK,gBAAgB;gBAAE,SAAS;YACvC,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,GAAG,CAAC,CAAC;YAClC,MAAM,GAAG,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,GAAG,CAAC,CAAC;YAC9B,IAAI,CAAC;gBACH,IAAA,cAAS,EAAC,IAAA,WAAI,EAAC,MAAM,EAAE,GAAG,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,EAAE,GAAG,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;gBAC/G,IAAA,iBAAY,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC;gBACvB,QAAQ,EAAE,CAAC;YACb,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QACxB,CAAC;QAED,OAAO,EAAE,QAAQ,EAAE,GAAG,EAAE,aAAa,EAAE,QAAQ,EAAE,CAAC;IACpD,CAAC;IAED;;OAEG;IACH,WAAW,CAAC,GAAY;QACtB,MAAM,MAAM,GAAG,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;QACpC,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,MAAM,EAAE,UAAU,CAAC,CAAC;QAC5C,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC;YAAE,OAAO,EAAE,CAAC;QAEvC,MAAM,OAAO,GAAkB,EAAE,CAAC;QAClC,KAAK,MAAM,IAAI,IAAI,IAAA,gBAAW,EAAC,UAAU,CAAC,EAAE,CAAC;YAC3C,MAAM,QAAQ,GAAG,IAAA,WAAI,EAAC,UAAU,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;YAC1D,IAAI,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;gBACzB,IAAI,CAAC;oBACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,QAAQ,EAAE,OAAO,CAAC,CAAgB,CAAC;oBACzE,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACtB,CAAC;gBAAC,MAAM,CAAC,CAAC,4BAA4B,CAAC,CAAC;YAC1C,CAAC;QACH,CAAC;QAED,oBAAoB;QACpB,OAAO,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,GAAG,IAAI,IAAI,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,OAAO,EAAE,CAAC,CAAC;IACnG,CAAC;IAED;;;OAGG;IACH,YAAY,CAAC,GAAY,EAAE,IAAY;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,CAAC;QAClC,IAAI,GAAG,CAAC,MAAM,IAAI,IAAI;YAAE,OAAO,CAAC,CAAC;QAEjC,MAAM,QAAQ,GAAG,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;QACjC,IAAI,OAAO,GAAG,CAAC,CAAC;QAChB,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,IAAI,CAAC;gBACH,IAAA,WAAM,EAAC,KAAK,CAAC,IAAI,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;gBACrD,OAAO,EAAE,CAAC;YACZ,CAAC;YAAC,MAAM,CAAC,CAAC,YAAY,CAAC,CAAC;QAC1B,CAAC;QACD,OAAO,OAAO,CAAC;IACjB,CAAC;IAED,6EAA6E;IAC7E,kBAAkB;IAClB,6EAA6E;IAErE,cAAc;QACpB,MAAM,UAAU,GAAG,IAAA,WAAI,EAAC,IAAI,CAAC,OAAO,EAAE,iBAAiB,CAAC,CAAC;QACzD,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC;YAAE,OAAO;QACpC,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,IAAA,iBAAY,EAAC,UAAU,EAAE,OAAO,CAAC,CAAuB,CAAC;YAChF,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC;gBAAE,IAAI,CAAC,MAAM,CAAC,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC;YAC5D,IAAI,GAAG,CAAC,KAAK,IAAI,OAAO,GAAG,CAAC,KAAK,KAAK,QAAQ,EAAE,CAAC;gBAC/C,MAAM,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC;YAC9C,CAAC;YACD,IAAI,OAAO,GAAG,CAAC,YAAY,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,YAAY,GAAG,GAAG,CAAC,YAAY,CAAC;QACxF,CAAC;QAAC,MAAM,CAAC,CAAC,wCAAwC,CAAC,CAAC;IACtD,CAAC;IAEO,UAAU,CAAC,QAAgB,EAAE,YAAqB;QACxD,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAA,aAAQ,EAAC,QAAQ,EAAE,CAAC,cAAS,CAAC,OAAO,GAAG,cAAS,CAAC,MAAM,GAAG,cAAS,CAAC,QAAQ,CAAW,EAAE,KAAK,CAAC,CAAC;YAC5G,IAAI,CAAC;gBACH,IAAA,kBAAa,EAAC,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;YAC3D,CAAC;oBAAS,CAAC;gBACT,IAAA,cAAS,EAAC,EAAE,CAAC,CAAC;YAChB,CAAC;QACH,CAAC;QAAC,MAAM,CAAC,CAAC,uCAAuC,CAAC,CAAC;IACrD,CAAC;IAEO,UAAU,CAAC,QAAgB;QACjC,IAAI,CAAC;YACH,MAAM,EAAE,GAAG,IAAA,aAAQ,EAAC,QAAQ,EAAE,CAAC,cAAS,CAAC,OAAO,GAAG,cAAS,CAAC,MAAM,GAAG,cAAS,CAAC,QAAQ,CAAW,EAAE,KAAK,CAAC,CAAC;YAC5G,IAAA,cAAS,EAAC,EAAE,CAAC,CAAC;QAChB,CAAC;QAAC,MAAM,CAAC,CAAC,uCAAuC,CAAC,CAAC;IACrD,CAAC;IAEO,gBAAgB,CAAC,GAAW;QAClC,IAAI,CAAC,IAAA,eAAU,EAAC,GAAG,CAAC;YAAE,OAAO,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,OAAO,IAAA,gBAAW,EAAC,GAAG,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE;gBACjC,IAAI,eAAe,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,UAAU,CAAC,EAAE,CAAC,CAAC;oBAAE,OAAO,KAAK,CAAC;gBAC3E,8CAA8C;gBAC9C,IAAI,CAAC;oBACH,OAAO,IAAA,aAAQ,EAAC,IAAA,WAAI,EAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,MAAM,EAAE,CAAC;gBACzC,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,KAAK,CAAC;gBACf,CAAC;YACH,CAAC,CAAC,CAAC;QACL,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,CAAC;QACZ,CAAC;IACH,CAAC;IAEO,mBAAmB,CAAC,GAAW;QACrC,MAAM,OAAO,GAAa,EAAE,CAAC;QAC7B,MAAM,IAAI,GAAG,CAAC,OAAe,EAAE,MAAc,EAAQ,EAAE;YACrD,IAAI,OAAiB,CAAC;YACtB,IAAI,CAAC;gBAAC,OAAO,GAAG,IAAA,gBAAW,EAAC,OAAO,CAAC,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC;gBAAC,OAAO;YAAC,CAAC;YACzD,KAAK,MAAM,KAAK,IAAI,OAAO,EAAE,CAAC;gBAC5B,IAAI,KAAK,KAAK,UAAU;oBAAE,SAAS,CAAC,wBAAwB;gBAC5D,MAAM,IAAI,GAAG,IAAA,WAAI,EAAC,OAAO,EAAE,KAAK,CAAC,CAAC;gBAClC,MAAM,GAAG,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC;gBAClD,IAAI,CAAC;oBACH,MAAM,IAAI,GAAG,IAAA,aAAQ,EAAC,IAAI,CAAC,CAAC;oBAC5B,IAAI,IAAI,CAAC,WAAW,EAAE,EAAE,CAAC;wBACvB,IAAI,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC;oBAClB,CAAC;yBAAM,CAAC;wBACN,OAAO,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;oBACpB,CAAC;gBACH,CAAC;gBAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;YACxB,CAAC;QACH,CAAC,CAAC;QACF,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC;QACd,OAAO,OAAO,CAAC;IACjB,CAAC;IAEO,QAAQ,CAAC,GAAW;QAC1B,IAAI,IAAI,GAAG,CAAC,CAAC;QACb,MAAM,KAAK,GAAG,IAAI,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAC;QAC5C,KAAK,MAAM,GAAG,IAAI,KAAK,EAAE,CAAC;YACxB,IAAI,CAAC;gBAAC,IAAI,IAAI,IAAA,aAAQ,EAAC,IAAA,WAAI,EAAC,GAAG,EAAE,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;YAAC,CAAC;YAAC,MAAM,CAAC,CAAC,UAAU,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;CACF;AAlbD,gDAkbC"}
@@ -29,6 +29,12 @@ export interface LockedBlackboardOptions {
29
29
  conflictResolution?: ConflictResolutionStrategy;
30
30
  /** Minimum milliseconds between consecutive write/commit operations (0 = no throttle) */
31
31
  throttleMs?: number;
32
+ /**
33
+ * Environment name (e.g. `'dev'`, `'prod'`). When set, all data is scoped
34
+ * to `<basePath>/<env>/` keeping environments completely isolated.
35
+ * Falls back to the `NETWORK_AI_ENV` environment variable when not provided.
36
+ */
37
+ env?: string;
32
38
  }
33
39
  export interface BlackboardEntry {
34
40
  key: string;
@@ -1 +1 @@
1
- {"version":3,"file":"locked-blackboard.d.ts","sourceRoot":"","sources":["../../lib/locked-blackboard.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"locked-blackboard.d.ts","sourceRoot":"","sources":["../../lib/locked-blackboard.ts"],"names":[],"mappings":"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"}
@@ -227,23 +227,42 @@ class LockedBlackboard {
227
227
  // Resolve to an absolute path to prevent insecure relative/temp-dir path propagation
228
228
  const resolvedBase = (0, path_1.resolve)(basePath);
229
229
  this.basePath = resolvedBase;
230
- this.blackboardPath = (0, path_1.join)(resolvedBase, 'swarm-blackboard.md');
231
- this.lockPath = (0, path_1.join)(resolvedBase, 'data', '.blackboard.lock');
232
- this.pendingDir = (0, path_1.join)(resolvedBase, 'data', 'pending_changes');
233
- this.lock = new FileLock(this.lockPath);
234
230
  // Support both signatures:
235
231
  // new LockedBlackboard(path, auditLogger, options)
236
232
  // new LockedBlackboard(path, options)
237
- if (auditLoggerOrOptions && typeof auditLoggerOrOptions === 'object' && ('conflictResolution' in auditLoggerOrOptions || 'throttleMs' in auditLoggerOrOptions)) {
233
+ let env;
234
+ if (auditLoggerOrOptions && typeof auditLoggerOrOptions === 'object' && ('conflictResolution' in auditLoggerOrOptions || 'throttleMs' in auditLoggerOrOptions || 'env' in auditLoggerOrOptions)) {
238
235
  const opts = auditLoggerOrOptions;
239
236
  this.conflictResolution = opts.conflictResolution ?? 'first-commit-wins';
240
237
  this.throttleMs = opts.throttleMs ?? 0;
238
+ env = opts.env;
241
239
  }
242
240
  else {
243
241
  this.auditLogger = auditLoggerOrOptions;
244
242
  this.conflictResolution = options?.conflictResolution ?? 'first-commit-wins';
245
243
  this.throttleMs = options?.throttleMs ?? 0;
244
+ env = options?.env;
245
+ }
246
+ // Fall back to NETWORK_AI_ENV environment variable when env not supplied
247
+ const activeEnv = env ?? process.env['NETWORK_AI_ENV'] ?? '';
248
+ // Validate env name to prevent path traversal (CWE-22)
249
+ if (activeEnv && !/^[a-zA-Z0-9_-]+$/.test(activeEnv)) {
250
+ throw new Error(`Invalid environment name '${activeEnv}': only alphanumeric, dash, and underscore are allowed`);
251
+ }
252
+ if (activeEnv) {
253
+ // Scope all data to <basePath>/<env>/ for full environment isolation
254
+ const envBase = (0, path_1.join)(resolvedBase, activeEnv);
255
+ this.blackboardPath = (0, path_1.join)(envBase, 'swarm-blackboard.md');
256
+ this.lockPath = (0, path_1.join)(envBase, '.blackboard.lock');
257
+ this.pendingDir = (0, path_1.join)(envBase, 'pending_changes');
246
258
  }
259
+ else {
260
+ // Legacy paths — backward compatible with existing deployments
261
+ this.blackboardPath = (0, path_1.join)(resolvedBase, 'swarm-blackboard.md');
262
+ this.lockPath = (0, path_1.join)(resolvedBase, 'data', '.blackboard.lock');
263
+ this.pendingDir = (0, path_1.join)(resolvedBase, 'data', 'pending_changes');
264
+ }
265
+ this.lock = new FileLock(this.lockPath);
247
266
  this.initialize();
248
267
  }
249
268
  initialize() {