network-ai 5.3.1 → 5.4.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.
- package/INTEGRATION_GUIDE.md +80 -3
- package/QUICKSTART.md +40 -0
- package/README.md +8 -7
- package/SKILL.md +41 -64
- package/bin/cli.ts +155 -0
- package/dist/bin/cli.js +156 -0
- package/dist/bin/cli.js.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +11 -2
- package/dist/index.js.map +1 -1
- package/dist/lib/agent-runtime.d.ts +28 -0
- package/dist/lib/agent-runtime.d.ts.map +1 -1
- package/dist/lib/agent-runtime.js +68 -1
- package/dist/lib/agent-runtime.js.map +1 -1
- package/dist/lib/env-manager.d.ts +179 -0
- package/dist/lib/env-manager.d.ts.map +1 -0
- package/dist/lib/env-manager.js +491 -0
- package/dist/lib/env-manager.js.map +1 -0
- package/dist/lib/locked-blackboard.d.ts +6 -0
- package/dist/lib/locked-blackboard.d.ts.map +1 -1
- package/dist/lib/locked-blackboard.js +24 -5
- package/dist/lib/locked-blackboard.js.map +1 -1
- package/dist/lib/mcp-tool-consumer.js +1 -1
- package/package.json +1 -1
- package/scripts/blackboard.py +25 -4
- package/scripts/check_permission.py +28 -2
- package/scripts/context_manager.py +28 -2
- package/scripts/swarm_guard.py +25 -2
- package/scripts/validate_token.py +23 -1
|
@@ -0,0 +1,491 @@
|
|
|
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
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
420
|
+
(0, fs_1.writeFileSync)(filePath, JSON.stringify(defaultValue, null, 2), { mode: 0o600 });
|
|
421
|
+
}
|
|
422
|
+
}
|
|
423
|
+
_touchFile(filePath) {
|
|
424
|
+
if (!(0, fs_1.existsSync)(filePath)) {
|
|
425
|
+
(0, fs_1.writeFileSync)(filePath, '', { mode: 0o600 });
|
|
426
|
+
}
|
|
427
|
+
}
|
|
428
|
+
_listConfigFiles(dir) {
|
|
429
|
+
if (!(0, fs_1.existsSync)(dir))
|
|
430
|
+
return [];
|
|
431
|
+
try {
|
|
432
|
+
return (0, fs_1.readdirSync)(dir).filter(f => {
|
|
433
|
+
if (PROMOTE_EXCLUDE.some(ex => f === ex || f.startsWith(ex)))
|
|
434
|
+
return false;
|
|
435
|
+
// Only include regular files, not directories
|
|
436
|
+
try {
|
|
437
|
+
return (0, fs_1.statSync)((0, path_1.join)(dir, f)).isFile();
|
|
438
|
+
}
|
|
439
|
+
catch {
|
|
440
|
+
return false;
|
|
441
|
+
}
|
|
442
|
+
});
|
|
443
|
+
}
|
|
444
|
+
catch {
|
|
445
|
+
return [];
|
|
446
|
+
}
|
|
447
|
+
}
|
|
448
|
+
_collectBackupFiles(dir) {
|
|
449
|
+
const results = [];
|
|
450
|
+
const walk = (current, prefix) => {
|
|
451
|
+
let entries;
|
|
452
|
+
try {
|
|
453
|
+
entries = (0, fs_1.readdirSync)(current);
|
|
454
|
+
}
|
|
455
|
+
catch {
|
|
456
|
+
return;
|
|
457
|
+
}
|
|
458
|
+
for (const entry of entries) {
|
|
459
|
+
if (entry === '.backups')
|
|
460
|
+
continue; // don't back up backups
|
|
461
|
+
const full = (0, path_1.join)(current, entry);
|
|
462
|
+
const rel = prefix ? `${prefix}/${entry}` : entry;
|
|
463
|
+
try {
|
|
464
|
+
const info = (0, fs_1.statSync)(full);
|
|
465
|
+
if (info.isDirectory()) {
|
|
466
|
+
walk(full, rel);
|
|
467
|
+
}
|
|
468
|
+
else {
|
|
469
|
+
results.push(rel);
|
|
470
|
+
}
|
|
471
|
+
}
|
|
472
|
+
catch { /* skip */ }
|
|
473
|
+
}
|
|
474
|
+
};
|
|
475
|
+
walk(dir, '');
|
|
476
|
+
return results;
|
|
477
|
+
}
|
|
478
|
+
_dirSize(dir) {
|
|
479
|
+
let size = 0;
|
|
480
|
+
const files = this._collectBackupFiles(dir);
|
|
481
|
+
for (const rel of files) {
|
|
482
|
+
try {
|
|
483
|
+
size += (0, fs_1.statSync)((0, path_1.join)(dir, rel)).size;
|
|
484
|
+
}
|
|
485
|
+
catch { /* skip */ }
|
|
486
|
+
}
|
|
487
|
+
return size;
|
|
488
|
+
}
|
|
489
|
+
}
|
|
490
|
+
exports.EnvironmentManager = EnvironmentManager;
|
|
491
|
+
//# sourceMappingURL=env-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env-manager.js","sourceRoot":"","sources":["../../lib/env-manager.ts"],"names":[],"mappings":"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"}
|
|
@@ -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":"AAAA;;;;;;;;;;;;;;;;GAgBG;AAiBH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAQrD,0EAA0E;AAC1E,MAAM,MAAM,0BAA0B,GAAG,mBAAmB,GAAG,eAAe,CAAC;AAE/E,kEAAkE;AAClE,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE1C,kDAAkD;AAClD,MAAM,WAAW,uBAAuB;IACtC;;;OAGG;IACH,kBAAkB,CAAC,EAAE,0BAA0B,CAAC;IAChD,yFAAyF;IACzF,UAAU,CAAC,EAAE,MAAM,CAAC;
|
|
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
|
-
|
|
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() {
|