labgate 0.1.0 → 0.3.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/README.md +17 -0
- package/dist/cli.js +206 -5
- package/dist/cli.js.map +1 -1
- package/dist/lib/config.d.ts +1 -0
- package/dist/lib/config.js +61 -11
- package/dist/lib/config.js.map +1 -1
- package/dist/lib/container.d.ts +1 -2
- package/dist/lib/container.js +152 -156
- package/dist/lib/container.js.map +1 -1
- package/dist/lib/feedback.d.ts +5 -0
- package/dist/lib/feedback.js +82 -0
- package/dist/lib/feedback.js.map +1 -0
- package/dist/lib/runtime.js +14 -8
- package/dist/lib/runtime.js.map +1 -1
- package/package.json +7 -3
package/README.md
CHANGED
|
@@ -8,6 +8,8 @@ Policy-controlled sandboxes for LLM coding agents on HPC systems.
|
|
|
8
8
|
npm i -g labgate
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
+
Note: LabGate uses `node-pty` only for the optional sticky footer. On minimal Linux installs, that dependency may fail to build without a compiler toolchain. If it fails, the install still works and LabGate falls back to non-sticky output.
|
|
12
|
+
|
|
11
13
|
LabGate auto-detects your container runtime (Apptainer, Singularity, Podman, or Docker) and offers to install one if none is found.
|
|
12
14
|
|
|
13
15
|
## Quick start
|
|
@@ -60,6 +62,7 @@ labgate init --force
|
|
|
60
62
|
```bash
|
|
61
63
|
labgate claude [workdir] # launch Claude Code
|
|
62
64
|
labgate codex [workdir] # launch Codex
|
|
65
|
+
labgate feedback # submit feedback (interactive or piped)
|
|
63
66
|
labgate status # list running sessions
|
|
64
67
|
labgate stop <id> # stop a session
|
|
65
68
|
labgate init [--force] # create/reset config
|
|
@@ -73,6 +76,20 @@ labgate claude --image my-image:tag # use a different container image
|
|
|
73
76
|
labgate claude --no-footer # disable the status footer line
|
|
74
77
|
```
|
|
75
78
|
|
|
79
|
+
## Feedback
|
|
80
|
+
|
|
81
|
+
Submit feedback from the CLI:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
labgate feedback
|
|
85
|
+
echo "This was great" | labgate feedback
|
|
86
|
+
labgate feedback "Short feedback message"
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
If `LABGATE_FEEDBACK_URL` is set, LabGate will `POST` feedback JSON to that URL.
|
|
90
|
+
If `LABGATE_FEEDBACK_TOKEN` is set, it will be sent as a Bearer token.
|
|
91
|
+
If no URL is configured or the request fails, feedback is saved locally at `~/.labgate/feedback.jsonl`.
|
|
92
|
+
|
|
76
93
|
## How it works
|
|
77
94
|
|
|
78
95
|
LabGate builds a sandboxed container from your config:
|
package/dist/cli.js
CHANGED
|
@@ -7,12 +7,16 @@ const config_js_1 = require("./lib/config.js");
|
|
|
7
7
|
const init_js_1 = require("./lib/init.js");
|
|
8
8
|
const container_js_1 = require("./lib/container.js");
|
|
9
9
|
const runtime_js_1 = require("./lib/runtime.js");
|
|
10
|
+
const feedback_js_1 = require("./lib/feedback.js");
|
|
10
11
|
const AGENTS = ['claude', 'codex'];
|
|
12
|
+
// Read version from package.json so it stays in sync
|
|
13
|
+
const pkgPath = (0, path_1.resolve)(__dirname, '..', 'package.json');
|
|
14
|
+
const PKG_VERSION = JSON.parse((0, fs_1.readFileSync)(pkgPath, 'utf-8')).version;
|
|
11
15
|
const program = new commander_1.Command();
|
|
12
16
|
program
|
|
13
17
|
.name('labgate')
|
|
14
18
|
.description('Policy-controlled sandboxes for LLM coding agents')
|
|
15
|
-
.version(
|
|
19
|
+
.version(PKG_VERSION);
|
|
16
20
|
// ── labgate init ──────────────────────────────────────────
|
|
17
21
|
program
|
|
18
22
|
.command('init')
|
|
@@ -38,11 +42,172 @@ for (const agent of AGENTS) {
|
|
|
38
42
|
.option('--dry-run', 'Print the container command without running it')
|
|
39
43
|
.option('--image <uri>', 'Override container image')
|
|
40
44
|
.option('--no-footer', 'Disable status footer line')
|
|
41
|
-
.option('--
|
|
45
|
+
.option('--verbose', 'Show detailed debug output')
|
|
42
46
|
.action(async (workdir, opts) => {
|
|
43
47
|
await runAgent(agent, workdir, opts);
|
|
44
48
|
});
|
|
45
49
|
}
|
|
50
|
+
// ── labgate feedback ──────────────────────────────────────
|
|
51
|
+
program
|
|
52
|
+
.command('feedback')
|
|
53
|
+
.description('Submit feedback to LabGate')
|
|
54
|
+
.argument('[message...]', 'Feedback message (omit to enter interactively)')
|
|
55
|
+
.action(async (messageParts) => {
|
|
56
|
+
try {
|
|
57
|
+
const message = await (0, feedback_js_1.collectFeedback)(messageParts ?? []);
|
|
58
|
+
if (!message) {
|
|
59
|
+
console.error('Error: feedback cannot be empty');
|
|
60
|
+
process.exit(1);
|
|
61
|
+
}
|
|
62
|
+
const result = await (0, feedback_js_1.submitFeedback)(message);
|
|
63
|
+
console.log(result.detail);
|
|
64
|
+
}
|
|
65
|
+
catch (err) {
|
|
66
|
+
console.error(`Error: ${err?.message ?? String(err)}`);
|
|
67
|
+
process.exit(1);
|
|
68
|
+
}
|
|
69
|
+
});
|
|
70
|
+
// ── labgate config [key] [value] ──────────────────────────
|
|
71
|
+
const configCmd = program
|
|
72
|
+
.command('config')
|
|
73
|
+
.description('View or modify config');
|
|
74
|
+
configCmd
|
|
75
|
+
.command('get')
|
|
76
|
+
.description('Get a config value (dot-notation key)')
|
|
77
|
+
.argument('<key>', 'Config key (e.g. network.mode, session_timeout_hours)')
|
|
78
|
+
.action((key) => {
|
|
79
|
+
const config = (0, config_js_1.loadConfig)();
|
|
80
|
+
const value = getNestedValue(config, key);
|
|
81
|
+
if (value === undefined) {
|
|
82
|
+
console.error(`Unknown config key: ${key}`);
|
|
83
|
+
process.exit(1);
|
|
84
|
+
}
|
|
85
|
+
console.log(typeof value === 'object' ? JSON.stringify(value, null, 2) : String(value));
|
|
86
|
+
});
|
|
87
|
+
configCmd
|
|
88
|
+
.command('set')
|
|
89
|
+
.description('Set a config value (dot-notation key)')
|
|
90
|
+
.argument('<key>', 'Config key (e.g. network.mode, session_timeout_hours)')
|
|
91
|
+
.argument('<value>', 'Value to set')
|
|
92
|
+
.action((key, value) => {
|
|
93
|
+
const configPath = (0, config_js_1.getConfigPath)();
|
|
94
|
+
if (!(0, fs_1.existsSync)(configPath)) {
|
|
95
|
+
console.error('No config file found. Run "labgate init" first.');
|
|
96
|
+
process.exit(1);
|
|
97
|
+
}
|
|
98
|
+
try {
|
|
99
|
+
const rawText = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
100
|
+
// Strip comments for JSON parsing
|
|
101
|
+
const stripped = rawText
|
|
102
|
+
.split('\n')
|
|
103
|
+
.filter(line => !line.trimStart().startsWith('//'))
|
|
104
|
+
.join('\n');
|
|
105
|
+
const obj = JSON.parse(stripped);
|
|
106
|
+
// Parse the value (numbers, booleans, JSON arrays/objects)
|
|
107
|
+
let parsed;
|
|
108
|
+
if (value === 'true')
|
|
109
|
+
parsed = true;
|
|
110
|
+
else if (value === 'false')
|
|
111
|
+
parsed = false;
|
|
112
|
+
else if (/^\d+(\.\d+)?$/.test(value))
|
|
113
|
+
parsed = Number(value);
|
|
114
|
+
else {
|
|
115
|
+
try {
|
|
116
|
+
parsed = JSON.parse(value);
|
|
117
|
+
}
|
|
118
|
+
catch {
|
|
119
|
+
parsed = value;
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
setNestedValue(obj, key, parsed);
|
|
123
|
+
// Re-validate before writing
|
|
124
|
+
const testConfig = { ...(0, config_js_1.loadConfig)(), ...obj };
|
|
125
|
+
const errors = (0, config_js_1.validateConfig)(testConfig);
|
|
126
|
+
if (errors.length > 0) {
|
|
127
|
+
console.error('Invalid config value:');
|
|
128
|
+
for (const e of errors)
|
|
129
|
+
console.error(` - ${e}`);
|
|
130
|
+
process.exit(1);
|
|
131
|
+
}
|
|
132
|
+
(0, fs_1.writeFileSync)(configPath, JSON.stringify(obj, null, 2) + '\n', 'utf-8');
|
|
133
|
+
console.log(`Set ${key} = ${JSON.stringify(parsed)}`);
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
console.error(`Error: ${err.message}`);
|
|
137
|
+
process.exit(1);
|
|
138
|
+
}
|
|
139
|
+
});
|
|
140
|
+
configCmd
|
|
141
|
+
.command('show')
|
|
142
|
+
.description('Show the full resolved config')
|
|
143
|
+
.action(() => {
|
|
144
|
+
const config = (0, config_js_1.loadConfig)();
|
|
145
|
+
console.log(JSON.stringify(config, null, 2));
|
|
146
|
+
});
|
|
147
|
+
configCmd
|
|
148
|
+
.command('path')
|
|
149
|
+
.description('Print the config file path')
|
|
150
|
+
.action(() => {
|
|
151
|
+
console.log((0, config_js_1.getConfigPath)());
|
|
152
|
+
});
|
|
153
|
+
// ── labgate logs ──────────────────────────────────────────
|
|
154
|
+
program
|
|
155
|
+
.command('logs')
|
|
156
|
+
.description('View audit logs')
|
|
157
|
+
.option('-n, --lines <count>', 'Number of recent lines to show', '20')
|
|
158
|
+
.option('--follow', 'Follow the log file for new entries')
|
|
159
|
+
.action(async (opts) => {
|
|
160
|
+
const config = (0, config_js_1.loadConfig)();
|
|
161
|
+
if (!config.audit.enabled) {
|
|
162
|
+
console.log('Audit logging is disabled. Enable it in config: audit.enabled = true');
|
|
163
|
+
return;
|
|
164
|
+
}
|
|
165
|
+
const logDir = (0, config_js_1.getLogDir)(config);
|
|
166
|
+
if (!(0, fs_1.existsSync)(logDir)) {
|
|
167
|
+
console.log('No audit logs found yet.');
|
|
168
|
+
return;
|
|
169
|
+
}
|
|
170
|
+
// Find the most recent log file
|
|
171
|
+
const files = (0, fs_1.readdirSync)(logDir)
|
|
172
|
+
.filter((f) => f.endsWith('.jsonl'))
|
|
173
|
+
.sort()
|
|
174
|
+
.reverse();
|
|
175
|
+
if (files.length === 0) {
|
|
176
|
+
console.log('No audit logs found yet.');
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
const logFile = (0, path_1.resolve)(logDir, files[0]);
|
|
180
|
+
console.log(`Log file: ${logFile}\n`);
|
|
181
|
+
const content = (0, fs_1.readFileSync)(logFile, 'utf-8').trim();
|
|
182
|
+
if (!content) {
|
|
183
|
+
console.log('Log file is empty.');
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const allLines = content.split('\n');
|
|
187
|
+
const count = parseInt(opts.lines, 10) || 20;
|
|
188
|
+
const lines = allLines.slice(-count);
|
|
189
|
+
for (const line of lines) {
|
|
190
|
+
try {
|
|
191
|
+
const event = JSON.parse(line);
|
|
192
|
+
const time = event.timestamp?.slice(11, 19) ?? '??:??:??';
|
|
193
|
+
const sess = event.session?.slice(0, 8) ?? '????????';
|
|
194
|
+
const ev = event.event ?? 'unknown';
|
|
195
|
+
const extra = [];
|
|
196
|
+
if (event.agent)
|
|
197
|
+
extra.push(`agent=${event.agent}`);
|
|
198
|
+
if (event.exit_code !== undefined)
|
|
199
|
+
extra.push(`exit=${event.exit_code}`);
|
|
200
|
+
if (event.timeout_hours)
|
|
201
|
+
extra.push(`timeout=${event.timeout_hours}h`);
|
|
202
|
+
if (event.network_mode)
|
|
203
|
+
extra.push(`net=${event.network_mode}`);
|
|
204
|
+
console.log(`${time} [${sess}] ${ev}${extra.length ? ' ' + extra.join(' ') : ''}`);
|
|
205
|
+
}
|
|
206
|
+
catch {
|
|
207
|
+
console.log(line);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
});
|
|
46
211
|
// ── labgate status ────────────────────────────────────────
|
|
47
212
|
program
|
|
48
213
|
.command('status')
|
|
@@ -60,6 +225,28 @@ program
|
|
|
60
225
|
const { stopSession } = await import('./lib/container.js');
|
|
61
226
|
await stopSession(id);
|
|
62
227
|
});
|
|
228
|
+
// ── Dot-notation helpers ──────────────────────────────────
|
|
229
|
+
function getNestedValue(obj, key) {
|
|
230
|
+
const parts = key.split('.');
|
|
231
|
+
let current = obj;
|
|
232
|
+
for (const part of parts) {
|
|
233
|
+
if (current == null || typeof current !== 'object')
|
|
234
|
+
return undefined;
|
|
235
|
+
current = current[part];
|
|
236
|
+
}
|
|
237
|
+
return current;
|
|
238
|
+
}
|
|
239
|
+
function setNestedValue(obj, key, value) {
|
|
240
|
+
const parts = key.split('.');
|
|
241
|
+
let current = obj;
|
|
242
|
+
for (let i = 0; i < parts.length - 1; i++) {
|
|
243
|
+
if (current[parts[i]] == null || typeof current[parts[i]] !== 'object') {
|
|
244
|
+
current[parts[i]] = {};
|
|
245
|
+
}
|
|
246
|
+
current = current[parts[i]];
|
|
247
|
+
}
|
|
248
|
+
current[parts[parts.length - 1]] = value;
|
|
249
|
+
}
|
|
63
250
|
async function runAgent(agent, workdir, opts) {
|
|
64
251
|
// Resolve workdir
|
|
65
252
|
const resolved = (0, path_1.resolve)(workdir);
|
|
@@ -67,13 +254,25 @@ async function runAgent(agent, workdir, opts) {
|
|
|
67
254
|
console.error(`Error: directory does not exist: ${resolved}`);
|
|
68
255
|
process.exit(1);
|
|
69
256
|
}
|
|
257
|
+
const verbose = opts.verbose ?? false;
|
|
70
258
|
// Load config (creates default if missing) — need config.runtime for runtime check
|
|
71
|
-
const
|
|
72
|
-
if (!(0, fs_1.existsSync)(
|
|
259
|
+
const cfgPath = (0, config_js_1.getConfigPath)();
|
|
260
|
+
if (!(0, fs_1.existsSync)(cfgPath)) {
|
|
73
261
|
console.log('[labgate] No config found. Running "labgate init" first...\n');
|
|
74
262
|
await (0, init_js_1.initConfig)({ force: false });
|
|
75
263
|
}
|
|
76
264
|
const config = (0, config_js_1.loadConfig)();
|
|
265
|
+
if (verbose) {
|
|
266
|
+
console.log(`[labgate] Config: ${cfgPath}`);
|
|
267
|
+
console.log(`[labgate] Runtime preference: ${config.runtime}`);
|
|
268
|
+
console.log(`[labgate] Image: ${opts.image ?? config.image}`);
|
|
269
|
+
console.log(`[labgate] Network mode: ${config.network.mode}`);
|
|
270
|
+
console.log(`[labgate] Blocked patterns: ${config.filesystem.blocked_patterns.length}`);
|
|
271
|
+
console.log(`[labgate] Command blacklist: ${config.commands.blacklist.join(', ')}`);
|
|
272
|
+
console.log(`[labgate] Extra mounts: ${config.filesystem.extra_paths.length}`);
|
|
273
|
+
console.log(`[labgate] Sandbox home: ${config_js_1.LABGATE_DIR}/ai-home`);
|
|
274
|
+
console.log('');
|
|
275
|
+
}
|
|
77
276
|
// Check container runtime is available — offer to install if missing
|
|
78
277
|
// (skip for dry-run so users can preview without runtime)
|
|
79
278
|
if (!opts.dryRun) {
|
|
@@ -81,6 +280,9 @@ async function runAgent(agent, workdir, opts) {
|
|
|
81
280
|
if (!runtime.ok) {
|
|
82
281
|
process.exit(1);
|
|
83
282
|
}
|
|
283
|
+
if (verbose) {
|
|
284
|
+
console.log(`[labgate] Detected runtime: ${runtime.runtime} (${runtime.version})`);
|
|
285
|
+
}
|
|
84
286
|
}
|
|
85
287
|
// Start the session
|
|
86
288
|
await (0, container_js_1.startSession)({
|
|
@@ -90,7 +292,6 @@ async function runAgent(agent, workdir, opts) {
|
|
|
90
292
|
dryRun: opts.dryRun ?? false,
|
|
91
293
|
imageOverride: opts.image,
|
|
92
294
|
footerMode: opts.footer === false ? 'off' : 'once',
|
|
93
|
-
statusline: opts.statusline ?? true,
|
|
94
295
|
});
|
|
95
296
|
}
|
|
96
297
|
program.parse();
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":";;AAAA,yCAAoC;AACpC,+BAA+B;AAC/B,2BAAgC;AAChC,+CAA4D;AAC5D,2CAA2C;AAC3C,qDAAkD;AAClD,iDAAiD;AAEjD,MAAM,MAAM,GAAG,CAAC,QAAQ,EAAE,OAAO,CAAU,CAAC;AAG5C,MAAM,OAAO,GAAG,IAAI,mBAAO,EAAE,CAAC;AAE9B,OAAO;KACJ,IAAI,CAAC,SAAS,CAAC;KACf,WAAW,CAAC,mDAAmD,CAAC;KAChE,OAAO,CAAC,OAAO,CAAC,CAAC;AAEpB,6DAA6D;AAC7D,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,iDAAiD,CAAC;KAC9D,MAAM,CAAC,SAAS,EAAE,2BAA2B,CAAC;KAC9C,MAAM,CAAC,KAAK,EAAE,IAAI,EAAE,EAAE;IACrB,IAAI,CAAC;QACH,MAAM,IAAA,oBAAU,EAAC,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,EAAE,CAAC,CAAC;IAC1C,CAAC;IAAC,OAAO,GAAQ,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,CAAC,OAAO,EAAE,CAAC,CAAC;QACvC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;AACH,CAAC,CAAC,CAAC;AAEL,6DAA6D;AAC7D,2DAA2D;AAC3D,6DAA6D;AAC7D,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;IAC3B,OAAO;SACJ,OAAO,CAAC,KAAK,CAAC;SACd,WAAW,CAAC,UAAU,KAAK,2BAA2B,CAAC;SACvD,QAAQ,CAAC,WAAW,EAAE,4BAA4B,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;SAClE,MAAM,CAAC,WAAW,EAAE,gDAAgD,CAAC;SACrE,MAAM,CAAC,eAAe,EAAE,0BAA0B,CAAC;SACnD,MAAM,CAAC,aAAa,EAAE,4BAA4B,CAAC;SACnD,MAAM,CAAC,iBAAiB,EAAE,iCAAiC,CAAC;SAC5D,MAAM,CAAC,KAAK,EAAE,OAAe,EAAE,IAAI,EAAE,EAAE;QACtC,MAAM,QAAQ,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,CAAC,CAAC;IACvC,CAAC,CAAC,CAAC;AACP,CAAC;AAED,6DAA6D;AAC7D,OAAO;KACJ,OAAO,CAAC,QAAQ,CAAC;KACjB,WAAW,CAAC,+BAA+B,CAAC;KAC5C,MAAM,CAAC,KAAK,IAAI,EAAE;IACjB,MAAM,EAAE,YAAY,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC5D,MAAM,YAAY,EAAE,CAAC;AACvB,CAAC,CAAC,CAAC;AAEL,6DAA6D;AAC7D,OAAO;KACJ,OAAO,CAAC,MAAM,CAAC;KACf,WAAW,CAAC,gCAAgC,CAAC;KAC7C,QAAQ,CAAC,MAAM,EAAE,8BAA8B,CAAC;KAChD,MAAM,CAAC,KAAK,EAAE,EAAU,EAAE,EAAE;IAC3B,MAAM,EAAE,WAAW,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;IAC3D,MAAM,WAAW,CAAC,EAAE,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAEL,KAAK,UAAU,QAAQ,CAAC,KAAY,EAAE,OAAe,EAAE,IAAS;IAC9D,kBAAkB;IAClB,MAAM,QAAQ,GAAG,IAAA,cAAO,EAAC,OAAO,CAAC,CAAC;IAClC,IAAI,CAAC,IAAA,eAAU,EAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,KAAK,CAAC,oCAAoC,QAAQ,EAAE,CAAC,CAAC;QAC9D,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,mFAAmF;IACnF,MAAM,UAAU,GAAG,IAAA,yBAAa,GAAE,CAAC;IACnC,IAAI,CAAC,IAAA,eAAU,EAAC,UAAU,CAAC,EAAE,CAAC;QAC5B,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;QAC5E,MAAM,IAAA,oBAAU,EAAC,EAAE,KAAK,EAAE,KAAK,EAAE,CAAC,CAAC;IACrC,CAAC;IACD,MAAM,MAAM,GAAG,IAAA,sBAAU,GAAE,CAAC;IAE5B,qEAAqE;IACrE,0DAA0D;IAC1D,IAAI,CAAC,IAAI,CAAC,MAAM,EAAE,CAAC;QACjB,MAAM,OAAO,GAAG,MAAM,IAAA,0BAAa,EAAC,MAAM,CAAC,OAAO,CAAC,CAAC;QACpD,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,IAAA,2BAAY,EAAC;QACjB,KAAK;QACL,OAAO,EAAE,QAAQ;QACjB,MAAM;QACN,MAAM,EAAE,IAAI,CAAC,MAAM,IAAI,KAAK;QAC5B,aAAa,EAAE,IAAI,CAAC,KAAK;QACzB,UAAU,EAAE,IAAI,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM;QAClD,UAAU,EAAE,IAAI,CAAC,UAAU,IAAI,IAAI;KACpC,CAAC,CAAC;AACL,CAAC;AAED,OAAO,CAAC,KAAK,EAAE,CAAC"}
|
|
1
|
+
{"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/config.d.ts
CHANGED
|
@@ -44,4 +44,5 @@ export declare function getSandboxHome(): string;
|
|
|
44
44
|
export declare function getImagesDir(): string;
|
|
45
45
|
export declare function getEmptyDir(): string;
|
|
46
46
|
export declare function getLogDir(config: LabgateConfig): string;
|
|
47
|
+
export declare function validateConfig(config: LabgateConfig): string[];
|
|
47
48
|
export declare function loadConfig(): LabgateConfig;
|
package/dist/lib/config.js
CHANGED
|
@@ -6,6 +6,7 @@ exports.getSandboxHome = getSandboxHome;
|
|
|
6
6
|
exports.getImagesDir = getImagesDir;
|
|
7
7
|
exports.getEmptyDir = getEmptyDir;
|
|
8
8
|
exports.getLogDir = getLogDir;
|
|
9
|
+
exports.validateConfig = validateConfig;
|
|
9
10
|
exports.loadConfig = loadConfig;
|
|
10
11
|
const fs_1 = require("fs");
|
|
11
12
|
const path_1 = require("path");
|
|
@@ -82,33 +83,73 @@ function getEmptyDir() {
|
|
|
82
83
|
function getLogDir(config) {
|
|
83
84
|
return config.audit.log_dir.replace(/^~/, (0, os_1.homedir)());
|
|
84
85
|
}
|
|
86
|
+
// ── Deep clone helper ──────────────────────────────────────
|
|
87
|
+
function cloneConfig(config) {
|
|
88
|
+
return JSON.parse(JSON.stringify(config));
|
|
89
|
+
}
|
|
90
|
+
// ── Validation ────────────────────────────────────────────
|
|
91
|
+
const VALID_RUNTIMES = ['auto', 'apptainer', 'singularity', 'podman', 'docker'];
|
|
92
|
+
const VALID_NETWORK_MODES = ['none', 'filtered', 'host'];
|
|
93
|
+
const VALID_MOUNT_MODES = ['rw', 'ro'];
|
|
94
|
+
function validateConfig(config) {
|
|
95
|
+
const errors = [];
|
|
96
|
+
if (!VALID_RUNTIMES.includes(config.runtime)) {
|
|
97
|
+
errors.push(`Invalid runtime: "${config.runtime}". Must be one of: ${VALID_RUNTIMES.join(', ')}`);
|
|
98
|
+
}
|
|
99
|
+
if (!config.image || typeof config.image !== 'string') {
|
|
100
|
+
errors.push('image must be a non-empty string');
|
|
101
|
+
}
|
|
102
|
+
if (typeof config.session_timeout_hours !== 'number' || config.session_timeout_hours < 0) {
|
|
103
|
+
errors.push('session_timeout_hours must be a non-negative number');
|
|
104
|
+
}
|
|
105
|
+
if (!VALID_NETWORK_MODES.includes(config.network.mode)) {
|
|
106
|
+
errors.push(`Invalid network.mode: "${config.network.mode}". Must be one of: ${VALID_NETWORK_MODES.join(', ')}`);
|
|
107
|
+
}
|
|
108
|
+
if (!Array.isArray(config.filesystem.blocked_patterns)) {
|
|
109
|
+
errors.push('filesystem.blocked_patterns must be an array');
|
|
110
|
+
}
|
|
111
|
+
if (!Array.isArray(config.commands.blacklist)) {
|
|
112
|
+
errors.push('commands.blacklist must be an array');
|
|
113
|
+
}
|
|
114
|
+
for (const mount of config.filesystem.extra_paths) {
|
|
115
|
+
if (!mount.path || typeof mount.path !== 'string') {
|
|
116
|
+
errors.push('Each extra_paths entry must have a non-empty "path" string');
|
|
117
|
+
}
|
|
118
|
+
if (!VALID_MOUNT_MODES.includes(mount.mode)) {
|
|
119
|
+
errors.push(`Invalid mount mode "${mount.mode}" for path "${mount.path}". Must be "rw" or "ro"`);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
return errors;
|
|
123
|
+
}
|
|
85
124
|
// ── Loader ────────────────────────────────────────────────
|
|
86
125
|
function loadConfig() {
|
|
87
126
|
const configPath = getConfigPath();
|
|
88
127
|
if (!(0, fs_1.existsSync)(configPath)) {
|
|
89
|
-
return
|
|
128
|
+
return cloneConfig(exports.DEFAULT_CONFIG);
|
|
90
129
|
}
|
|
91
130
|
try {
|
|
92
131
|
const rawText = (0, fs_1.readFileSync)(configPath, 'utf-8');
|
|
93
|
-
// Strip // comments (our config uses them for documentation)
|
|
94
|
-
const stripped = rawText
|
|
132
|
+
// Strip full-line // comments (our config uses them for documentation)
|
|
133
|
+
const stripped = rawText
|
|
134
|
+
.split('\n')
|
|
135
|
+
.filter(line => !line.trimStart().startsWith('//'))
|
|
136
|
+
.join('\n');
|
|
95
137
|
const raw = JSON.parse(stripped);
|
|
96
|
-
// Merge with defaults so missing fields get filled in
|
|
97
|
-
|
|
98
|
-
return {
|
|
138
|
+
// Merge with defaults so missing fields get filled in
|
|
139
|
+
const config = {
|
|
99
140
|
runtime: raw.runtime ?? exports.DEFAULT_CONFIG.runtime,
|
|
100
141
|
image: raw.image ?? exports.DEFAULT_CONFIG.image,
|
|
101
142
|
session_timeout_hours: raw.session_timeout_hours ?? exports.DEFAULT_CONFIG.session_timeout_hours,
|
|
102
143
|
filesystem: {
|
|
103
|
-
extra_paths: raw.filesystem?.extra_paths ?? exports.DEFAULT_CONFIG.filesystem.extra_paths,
|
|
104
|
-
blocked_patterns: raw.filesystem?.blocked_patterns ?? exports.DEFAULT_CONFIG.filesystem.blocked_patterns,
|
|
144
|
+
extra_paths: raw.filesystem?.extra_paths ?? [...exports.DEFAULT_CONFIG.filesystem.extra_paths],
|
|
145
|
+
blocked_patterns: raw.filesystem?.blocked_patterns ?? [...exports.DEFAULT_CONFIG.filesystem.blocked_patterns],
|
|
105
146
|
},
|
|
106
147
|
commands: {
|
|
107
|
-
blacklist: raw.commands?.blacklist ?? exports.DEFAULT_CONFIG.commands.blacklist,
|
|
148
|
+
blacklist: raw.commands?.blacklist ?? [...exports.DEFAULT_CONFIG.commands.blacklist],
|
|
108
149
|
},
|
|
109
150
|
network: {
|
|
110
151
|
mode: raw.network?.mode ?? exports.DEFAULT_CONFIG.network.mode,
|
|
111
|
-
allowed_domains: raw.network?.allowed_domains ?? exports.DEFAULT_CONFIG.network.allowed_domains,
|
|
152
|
+
allowed_domains: raw.network?.allowed_domains ?? [...exports.DEFAULT_CONFIG.network.allowed_domains],
|
|
112
153
|
},
|
|
113
154
|
slurm: {
|
|
114
155
|
enabled: raw.slurm?.enabled ?? exports.DEFAULT_CONFIG.slurm.enabled,
|
|
@@ -118,11 +159,20 @@ function loadConfig() {
|
|
|
118
159
|
log_dir: raw.audit?.log_dir ?? exports.DEFAULT_CONFIG.audit.log_dir,
|
|
119
160
|
},
|
|
120
161
|
};
|
|
162
|
+
const errors = validateConfig(config);
|
|
163
|
+
if (errors.length > 0) {
|
|
164
|
+
console.error(`Warning: invalid config in ${configPath}:`);
|
|
165
|
+
for (const e of errors)
|
|
166
|
+
console.error(` - ${e}`);
|
|
167
|
+
console.error('Using default config.');
|
|
168
|
+
return cloneConfig(exports.DEFAULT_CONFIG);
|
|
169
|
+
}
|
|
170
|
+
return config;
|
|
121
171
|
}
|
|
122
172
|
catch (err) {
|
|
123
173
|
console.error(`Warning: could not parse ${configPath}: ${err.message}`);
|
|
124
174
|
console.error('Using default config.');
|
|
125
|
-
return
|
|
175
|
+
return cloneConfig(exports.DEFAULT_CONFIG);
|
|
126
176
|
}
|
|
127
177
|
}
|
|
128
178
|
//# sourceMappingURL=config.js.map
|
package/dist/lib/config.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":";;;AA0HA,sCAEC;AAED,wCAEC;AAED,oCAEC;AAED,kCAEC;AAED,8BAEC;AAID,
|
|
1
|
+
{"version":3,"file":"config.js","sourceRoot":"","sources":["../../src/lib/config.ts"],"names":[],"mappings":"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"}
|
package/dist/lib/container.d.ts
CHANGED
|
@@ -6,14 +6,13 @@ export interface SessionOpts {
|
|
|
6
6
|
dryRun: boolean;
|
|
7
7
|
imageOverride?: string;
|
|
8
8
|
footerMode?: 'off' | 'once' | 'sticky';
|
|
9
|
-
statusline?: boolean;
|
|
10
9
|
}
|
|
11
10
|
/**
|
|
12
11
|
* Convert a container image URI to a local SIF filename.
|
|
13
12
|
* e.g. "docker.io/library/ubuntu:22.04" → "docker.io_library_ubuntu_22.04.sif"
|
|
14
13
|
*/
|
|
15
14
|
export declare function imageToSifName(image: string): string;
|
|
16
|
-
export declare function buildEntrypoint(agent: string
|
|
15
|
+
export declare function buildEntrypoint(agent: string): string;
|
|
17
16
|
export declare function startSession(session: SessionOpts): Promise<void>;
|
|
18
17
|
export declare function listSessions(): Promise<void>;
|
|
19
18
|
export declare function stopSession(id: string): Promise<void>;
|