lastlight 0.5.1 → 0.6.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.
Files changed (43) hide show
  1. package/.claude-plugin/marketplace.json +14 -0
  2. package/README.md +39 -0
  3. package/agent-context/rules.md +0 -38
  4. package/agent-context/soul.md +0 -11
  5. package/dist/cli.js +24 -0
  6. package/dist/cli.js.map +1 -1
  7. package/dist/config.d.ts +1 -1
  8. package/dist/config.js +3 -3
  9. package/dist/config.js.map +1 -1
  10. package/dist/engine/agent-executor.d.ts +2 -139
  11. package/dist/engine/agent-executor.js +76 -996
  12. package/dist/engine/agent-executor.js.map +1 -1
  13. package/dist/engine/executors/backends.d.ts +41 -0
  14. package/dist/engine/executors/backends.js +541 -0
  15. package/dist/engine/executors/backends.js.map +1 -0
  16. package/dist/engine/executors/shared.d.ts +189 -0
  17. package/dist/engine/executors/shared.js +612 -0
  18. package/dist/engine/executors/shared.js.map +1 -0
  19. package/dist/sandbox/index.d.ts +1 -1
  20. package/dist/sandbox/index.js +1 -1
  21. package/dist/sandbox/index.js.map +1 -1
  22. package/dist/sandbox/smol.d.ts +162 -0
  23. package/dist/sandbox/smol.integration.test.d.ts +1 -0
  24. package/dist/sandbox/smol.integration.test.js +130 -0
  25. package/dist/sandbox/smol.integration.test.js.map +1 -0
  26. package/dist/sandbox/smol.js +485 -0
  27. package/dist/sandbox/smol.js.map +1 -0
  28. package/dist/skills-install.d.ts +12 -0
  29. package/dist/skills-install.js +179 -0
  30. package/dist/skills-install.js.map +1 -0
  31. package/package.json +4 -2
  32. package/plugins/lastlight/.claude-plugin/plugin.json +12 -0
  33. package/plugins/lastlight/README.md +44 -0
  34. package/plugins/lastlight/skills/lastlight-client/SKILL.md +82 -0
  35. package/plugins/lastlight/skills/lastlight-evals/SKILL.md +97 -0
  36. package/plugins/lastlight/skills/lastlight-evals/references/instance-schema.md +84 -0
  37. package/plugins/lastlight/skills/lastlight-evals/references/models-json.md +42 -0
  38. package/plugins/lastlight/skills/lastlight-overlay/SKILL.md +72 -0
  39. package/plugins/lastlight/skills/lastlight-overlay/references/forking.md +55 -0
  40. package/plugins/lastlight/skills/lastlight-overlay/references/overlay-layout.md +52 -0
  41. package/plugins/lastlight/skills/lastlight-server/SKILL.md +124 -0
  42. package/plugins/lastlight/skills/lastlight-server/references/env-schema.md +103 -0
  43. package/plugins/lastlight/skills/lastlight-server/references/operations.md +60 -0
@@ -0,0 +1,485 @@
1
+ import { execFileSync, execFile as execFileCb, spawn } from "child_process";
2
+ import { promisify } from "util";
3
+ import { lookup } from "node:dns/promises";
4
+ import { existsSync, readdirSync } from "fs";
5
+ import { join, resolve } from "path";
6
+ import { randomUUID } from "crypto";
7
+ const execFileAsync = promisify(execFileCb);
8
+ /**
9
+ * smolvm sandbox manager — runs agent tasks inside local micro-VMs.
10
+ *
11
+ * Structural peer of {@link DockerSandbox}: Last Light owns the isolation
12
+ * boundary, bind-mounts the per-task workspace, runs `agentic-pi run --sandbox
13
+ * none` *inside* the machine, and parses the JSONL event stream exactly as the
14
+ * docker path does. Differences from docker:
15
+ *
16
+ * - **Isolation** is a real micro-VM (own kernel) via smolvm's host
17
+ * hypervisor (Apple Silicon Hypervisor.framework / Linux KVM), not a
18
+ * sibling container. No daemon, no Docker (smolvm drives the hypervisor
19
+ * directly).
20
+ * - **Egress** is enforced natively per-machine via `--allow-host` (sourced
21
+ * from `egress-allowlist.ts`), so this backend needs none of the coredns +
22
+ * nginx-egress sidecar stack. `--allow-host` implies `--net`; we always
23
+ * enable networking (the agent must reach the LLM provider).
24
+ * - **Secrets** (provider keys, GITHUB_TOKEN) are injected via smolvm's
25
+ * `--secret-env GUEST=HOST` so values never appear on the argv — the host
26
+ * env of the spawned `smolvm` process carries them; smolvm resolves them
27
+ * into the guest at start.
28
+ * - **Image** is whatever `SMOLVM_IMAGE` names. smolvm's `-I` accepts a
29
+ * registry ref OR a local `docker save` archive (`./img.tar`) / unpacked
30
+ * rootfs dir — the latter needs NO registry, so it works under the strict
31
+ * egress allowlist. The lastlight sandbox image (built locally by docker)
32
+ * is consumed offline via `docker save lastlight-sandbox:latest -o img.tar`
33
+ * then `SMOLVM_IMAGE=img.tar`. Archives are cached by hash; `start` resolves
34
+ * from cache, not the network.
35
+ *
36
+ * Driven via the **smolvm CLI** (`execFile`), verified against smolvm 1.2.5.
37
+ *
38
+ * Feasibility-spike scope (documented gaps vs docker):
39
+ * - We exec `agentic-pi` directly rather than running the sandbox image's
40
+ * entrypoint, so the entrypoint's git-credential-helper setup is skipped.
41
+ * Read-only profiles (agentic-pi's built-in github tools + minted
42
+ * GITHUB_TOKEN) work; repo-write `git push` from the workspace is out of
43
+ * scope here.
44
+ * - The workload runs VM-grade (root) by default; workspace writes land as
45
+ * root on the host bind mount. No shared package-manager cache, no SSRF
46
+ * metadata floor in unrestricted mode, no in-network OTEL collector.
47
+ * - The image (`SMOLVM_IMAGE`) must be resolvable by smolvm (a registry ref,
48
+ * or a local image it can load) — see the spike plan's verification steps.
49
+ */
50
+ /**
51
+ * Where the per-task workspace is bind-mounted inside the guest. smolvm treats
52
+ * `/workspace` specially — a `-v <host>:/workspace` mount "takes priority" and
53
+ * the host share is used directly (instead of the VM's storage-disk workspace),
54
+ * which avoids the `virtiofs` carve-out other mount targets get. The probe in
55
+ * {@link SmolSandbox.resolveHostWorkspace} still confirms the actual host path.
56
+ */
57
+ export const SMOL_WORKSPACE_DIR = "/workspace";
58
+ /** Binary used to drive smolvm. Overridable for dev/CI (e.g. a vendored build). */
59
+ function smolBin() {
60
+ return process.env.SMOLVM_BIN || "smolvm";
61
+ }
62
+ /**
63
+ * OCI image the micro-VM boots. Reuses the lean lastlight sandbox image by
64
+ * default (agentic-pi + node + git + gh baked in); the image must be
65
+ * resolvable by smolvm (see the spike plan's verification steps).
66
+ */
67
+ function smolImage() {
68
+ return process.env.SMOLVM_IMAGE || "lastlight-sandbox:latest";
69
+ }
70
+ /** Cached probe — only check the smolvm binary once per process. */
71
+ let _smolAvailable = null;
72
+ /** True when the smolvm CLI is invocable on this host. */
73
+ export function smolAvailable() {
74
+ if (_smolAvailable === null) {
75
+ try {
76
+ execFileSync(smolBin(), ["--version"], { stdio: "ignore", timeout: 5000 });
77
+ _smolAvailable = true;
78
+ console.log(`[smol] smolvm available (image: ${smolImage()})`);
79
+ }
80
+ catch {
81
+ _smolAvailable = false;
82
+ console.log("[smol] smolvm CLI not available — smol backend unavailable");
83
+ }
84
+ }
85
+ return _smolAvailable;
86
+ }
87
+ const THINKING = new Set(["off", "minimal", "low", "medium", "high", "xhigh"]);
88
+ const PROFILES = new Set(["read", "issues-write", "review-write", "repo-write"]);
89
+ const WEB_SEARCH_PROVIDERS = new Set(["tavily", "brave", "exa"]);
90
+ const HOST_RE = /^[A-Za-z0-9.-]+$/;
91
+ const ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
92
+ const PATH_RE = /^[A-Za-z0-9/_.-]+$/;
93
+ export class SmolSandbox {
94
+ config;
95
+ machines = new Map();
96
+ constructor(config) {
97
+ this.config = config;
98
+ }
99
+ /** Create + start a micro-VM with the workspace bind-mounted and egress locked. */
100
+ async create(opts) {
101
+ const machineName = `lastlight-smol-${sanitizeName(opts.taskId)}-${randomUUID().slice(0, 8)}`;
102
+ const worktreePath = resolve(opts.worktreePath);
103
+ // smolvm machine create -n <name> -I <image> -v <host>:<guest> \
104
+ // --net [--allow-host <h>]...
105
+ // smolvm machine start --name <name>
106
+ const allowFlags = (await this.resolvableAllowHosts()).flatMap((h) => ["--allow-host", h]);
107
+ const args = [
108
+ "machine", "create",
109
+ "-n", machineName,
110
+ "-I", this.config.imageName || smolImage(),
111
+ "-v", `${worktreePath}:${SMOL_WORKSPACE_DIR}`,
112
+ "--net",
113
+ ...allowFlags,
114
+ ];
115
+ try {
116
+ execCmd(smolBin(), args, { timeout: 60_000 });
117
+ execCmd(smolBin(), ["machine", "start", "--name", machineName], { timeout: 120_000 });
118
+ }
119
+ catch (err) {
120
+ execSafe(smolBin(), ["machine", "delete", "-f", "--name", machineName]);
121
+ throw new Error(`Failed to create smol sandbox: ${err.message}`);
122
+ }
123
+ console.log(`[smol] Created: ${machineName}`);
124
+ await this.waitForReady(machineName);
125
+ const hostWorkspace = await this.resolveHostWorkspace(machineName, worktreePath);
126
+ const info = { machineName, worktreePath, hostWorkspace };
127
+ this.machines.set(opts.taskId, info);
128
+ return info;
129
+ }
130
+ /**
131
+ * Discover the host directory that backs the guest workspace mount. Writes a
132
+ * sentinel file from inside the guest at {@link SMOL_WORKSPACE_DIR}, then
133
+ * locates it under the mount source on the host — its parent dir is the
134
+ * host-side workspace root. Falls back to the source root if not found
135
+ * (e.g. a future smolvm that shares the source directly and the scan misses).
136
+ */
137
+ async resolveHostWorkspace(machineName, worktreePath) {
138
+ const sentinel = `.smol-probe-${randomUUID().slice(0, 8)}`;
139
+ try {
140
+ await execFileAsync(smolBin(), ["machine", "exec", "--name", machineName, "--", "sh", "-c", `: > ${SMOL_WORKSPACE_DIR}/${sentinel}`], { timeout: 10_000 });
141
+ const hit = findFileUnder(worktreePath, sentinel, 4);
142
+ await execFileAsync(smolBin(), ["machine", "exec", "--name", machineName, "--", "rm", "-f", `${SMOL_WORKSPACE_DIR}/${sentinel}`], { timeout: 10_000 }).catch(() => { });
143
+ if (hit) {
144
+ const dir = hit.slice(0, hit.length - sentinel.length - 1);
145
+ if (dir !== worktreePath)
146
+ console.log(`[smol] Workspace share lands at ${dir} (not the source root)`);
147
+ return dir;
148
+ }
149
+ }
150
+ catch (err) {
151
+ console.warn(`[smol] Could not probe workspace mount (${err.message}) — assuming source root`);
152
+ }
153
+ return worktreePath;
154
+ }
155
+ /** Wait until the machine can run a trivial command (boot completion). */
156
+ async waitForReady(machineName, timeoutMs = 20000) {
157
+ const start = Date.now();
158
+ while (Date.now() - start < timeoutMs) {
159
+ try {
160
+ await execFileAsync(smolBin(), ["machine", "exec", "--name", machineName, "--", "true"], { timeout: 5000 });
161
+ return;
162
+ }
163
+ catch {
164
+ await new Promise((r) => setTimeout(r, 500));
165
+ }
166
+ }
167
+ console.warn(`[smol] Timed out waiting for ${machineName} to be ready — proceeding anyway`);
168
+ }
169
+ /**
170
+ * Run `agentic-pi run --sandbox none …` inside the machine. Mirrors
171
+ * {@link DockerSandbox.runAgent}: streams stdout line-by-line for the live
172
+ * shim and writes the prompt to the child's stdin (`-i`). The agentic-pi
173
+ * argv is passed directly after `--` (no `sh -c`), so no shell quoting.
174
+ */
175
+ async runAgent(taskId, prompt, opts) {
176
+ const info = this.machines.get(taskId);
177
+ if (!info)
178
+ throw new Error(`No smol machine for task ${taskId}`);
179
+ const model = opts?.model || "anthropic/claude-sonnet-4-6";
180
+ const timeout = this.config.timeoutSeconds || 1800;
181
+ const piArgs = ["agentic-pi", "run", "--model", model, "--sandbox", "none"];
182
+ if (opts?.thinking) {
183
+ if (!THINKING.has(opts.thinking)) {
184
+ throw new Error(`Refusing to pass thinking "${opts.thinking}" — must be one of ${[...THINKING].join("|")}`);
185
+ }
186
+ piArgs.push("--thinking", opts.thinking);
187
+ }
188
+ if (opts?.profile) {
189
+ if (!PROFILES.has(opts.profile)) {
190
+ throw new Error(`Refusing to pass profile "${opts.profile}" — must be one of ${[...PROFILES].join("|")}`);
191
+ }
192
+ piArgs.push("--profile", opts.profile);
193
+ }
194
+ if (opts?.webSearch === true) {
195
+ if (opts.webSearchProvider) {
196
+ if (!WEB_SEARCH_PROVIDERS.has(opts.webSearchProvider)) {
197
+ throw new Error(`Refusing to pass web-search-provider "${opts.webSearchProvider}" — must be one of ${[...WEB_SEARCH_PROVIDERS].join("|")}`);
198
+ }
199
+ piArgs.push("--web-search-provider", opts.webSearchProvider);
200
+ }
201
+ }
202
+ else {
203
+ piArgs.push("--no-web-search");
204
+ }
205
+ for (const dir of opts?.skillDirs ?? []) {
206
+ if (!dir.startsWith(SMOL_WORKSPACE_DIR) || !PATH_RE.test(dir)) {
207
+ throw new Error(`Refusing to pass skill dir "${dir}" — must live under ${SMOL_WORKSPACE_DIR}`);
208
+ }
209
+ piArgs.push("--skill", dir);
210
+ }
211
+ if (!PATH_RE.test(model)) {
212
+ throw new Error(`Refusing to pass model "${model}" — bad charset`);
213
+ }
214
+ // Passed as a single argv token each (no shell), so `KEY=VALUE` is literal.
215
+ for (const [k, v] of Object.entries(opts?.sandboxEnv ?? {})) {
216
+ if (!ENV_KEY_RE.test(k))
217
+ throw new Error(`Refusing sandbox-env key "${k}" — bad charset`);
218
+ if (/[\n\r]/.test(v))
219
+ throw new Error(`Refusing sandbox-env value for "${k}" — contains newline`);
220
+ piArgs.push("--sandbox-env", `${k}=${v}`);
221
+ }
222
+ const workdir = opts?.agentCwd ?? SMOL_WORKSPACE_DIR;
223
+ if (!workdir.startsWith(SMOL_WORKSPACE_DIR) || !PATH_RE.test(workdir)) {
224
+ throw new Error(`Refusing to pass agent cwd "${workdir}" — must live under ${SMOL_WORKSPACE_DIR}`);
225
+ }
226
+ const { flags: secretFlags, childEnv } = this.secretEnv();
227
+ const argv = [
228
+ "machine", "exec", "--name", info.machineName,
229
+ "-w", workdir, "-i",
230
+ ...secretFlags,
231
+ "--", ...piArgs,
232
+ ];
233
+ const STDERR_TAIL_BYTES = 8 * 1024;
234
+ return await new Promise((resolvePromise, reject) => {
235
+ const child = spawn(smolBin(), argv, { stdio: ["pipe", "pipe", "pipe"], env: childEnv });
236
+ child.stdin.write(prompt);
237
+ child.stdin.end();
238
+ let stderrTail = "";
239
+ let buf = "";
240
+ const timer = setTimeout(() => {
241
+ child.kill("SIGKILL");
242
+ reject(new Error(`Smol agent timed out after ${timeout}s`));
243
+ }, timeout * 1000);
244
+ child.stdout.setEncoding("utf-8");
245
+ child.stdout.on("data", (chunk) => {
246
+ if (!opts?.onLine)
247
+ return;
248
+ buf += chunk;
249
+ let nl;
250
+ while ((nl = buf.indexOf("\n")) >= 0) {
251
+ const line = buf.slice(0, nl);
252
+ buf = buf.slice(nl + 1);
253
+ if (line.length > 0) {
254
+ try {
255
+ opts.onLine(line);
256
+ }
257
+ catch { /* swallow listener errors */ }
258
+ }
259
+ }
260
+ });
261
+ child.stderr.setEncoding("utf-8");
262
+ child.stderr.on("data", (chunk) => {
263
+ stderrTail += chunk;
264
+ if (stderrTail.length > STDERR_TAIL_BYTES)
265
+ stderrTail = stderrTail.slice(-STDERR_TAIL_BYTES);
266
+ });
267
+ child.on("error", (err) => {
268
+ clearTimeout(timer);
269
+ reject(new Error(`Smol agent spawn failed: ${err.message}`));
270
+ });
271
+ child.on("close", (code) => {
272
+ clearTimeout(timer);
273
+ if (buf.length > 0 && opts?.onLine) {
274
+ try {
275
+ opts.onLine(buf);
276
+ }
277
+ catch { /* ignore */ }
278
+ }
279
+ if (code === 0)
280
+ resolvePromise();
281
+ else
282
+ reject(new Error(`Smol agent failed (exit ${code}): ${stderrTail || "no output"}`));
283
+ });
284
+ });
285
+ }
286
+ /**
287
+ * Run a deterministic shell command in the machine and resolve with its exit
288
+ * code + bounded output. Non-agent sibling of {@link runAgent}; powers
289
+ * `type: bash` / `type: script` phases. The command is a shell string, so it
290
+ * runs under `sh -c`.
291
+ */
292
+ async runCommand(taskId, command, opts) {
293
+ const info = this.machines.get(taskId);
294
+ if (!info)
295
+ throw new Error(`No smol machine for task ${taskId}`);
296
+ const timeout = opts?.timeoutSeconds || this.config.timeoutSeconds || 1800;
297
+ const workdir = opts?.cwd ?? SMOL_WORKSPACE_DIR;
298
+ if (!workdir.startsWith(SMOL_WORKSPACE_DIR) || !PATH_RE.test(workdir)) {
299
+ throw new Error(`Refusing to run command in cwd "${workdir}" — must live under ${SMOL_WORKSPACE_DIR}`);
300
+ }
301
+ const envFlags = [];
302
+ for (const [k, v] of Object.entries(opts?.sandboxEnv ?? {})) {
303
+ if (!ENV_KEY_RE.test(k))
304
+ throw new Error(`Refusing sandbox-env key "${k}" — bad charset`);
305
+ if (/[\n\r]/.test(v))
306
+ throw new Error(`Refusing sandbox-env value for "${k}" — contains newline`);
307
+ envFlags.push("-e", `${k}=${v}`);
308
+ }
309
+ const { flags: secretFlags, childEnv } = this.secretEnv();
310
+ const argv = [
311
+ "machine", "exec", "--name", info.machineName,
312
+ "-w", workdir,
313
+ ...envFlags, ...secretFlags,
314
+ "--", "sh", "-c", command,
315
+ ];
316
+ const STDOUT_TAIL_BYTES = 256 * 1024;
317
+ const STDERR_TAIL_BYTES = 32 * 1024;
318
+ return await new Promise((resolvePromise, reject) => {
319
+ const child = spawn(smolBin(), argv, { stdio: ["ignore", "pipe", "pipe"], env: childEnv });
320
+ let stdoutTail = "";
321
+ let stderrTail = "";
322
+ let buf = "";
323
+ let timedOut = false;
324
+ const timer = setTimeout(() => {
325
+ timedOut = true;
326
+ child.kill("SIGKILL");
327
+ }, timeout * 1000);
328
+ child.stdout.setEncoding("utf-8");
329
+ child.stdout.on("data", (chunk) => {
330
+ stdoutTail += chunk;
331
+ if (stdoutTail.length > STDOUT_TAIL_BYTES)
332
+ stdoutTail = stdoutTail.slice(-STDOUT_TAIL_BYTES);
333
+ if (!opts?.onLine)
334
+ return;
335
+ buf += chunk;
336
+ let nl;
337
+ while ((nl = buf.indexOf("\n")) >= 0) {
338
+ const line = buf.slice(0, nl);
339
+ buf = buf.slice(nl + 1);
340
+ if (line.length > 0) {
341
+ try {
342
+ opts.onLine(line);
343
+ }
344
+ catch { /* swallow listener errors */ }
345
+ }
346
+ }
347
+ });
348
+ child.stderr.setEncoding("utf-8");
349
+ child.stderr.on("data", (chunk) => {
350
+ stderrTail += chunk;
351
+ if (stderrTail.length > STDERR_TAIL_BYTES)
352
+ stderrTail = stderrTail.slice(-STDERR_TAIL_BYTES);
353
+ });
354
+ child.on("error", (err) => {
355
+ clearTimeout(timer);
356
+ reject(new Error(`Smol command spawn failed: ${err.message}`));
357
+ });
358
+ child.on("close", (code) => {
359
+ clearTimeout(timer);
360
+ if (buf.length > 0 && opts?.onLine) {
361
+ try {
362
+ opts.onLine(buf);
363
+ }
364
+ catch { /* ignore */ }
365
+ }
366
+ resolvePromise({
367
+ exitCode: timedOut ? 124 : (code ?? 1),
368
+ stdout: stdoutTail,
369
+ stderr: stderrTail,
370
+ timedOut,
371
+ });
372
+ });
373
+ });
374
+ }
375
+ /** Stop + delete the machine. */
376
+ async destroy(taskId) {
377
+ const info = this.machines.get(taskId);
378
+ if (!info)
379
+ return;
380
+ execSafe(smolBin(), ["machine", "stop", "--name", info.machineName]);
381
+ execSafe(smolBin(), ["machine", "delete", "-f", "--name", info.machineName]);
382
+ this.machines.delete(taskId);
383
+ console.log(`[smol] Destroyed: ${info.machineName}`);
384
+ }
385
+ /**
386
+ * The allowlist hosts that smolvm can actually use, in original order.
387
+ *
388
+ * smolvm resolves every `--allow-host` to its IP(s) AT VM START and aborts
389
+ * `create` if ANY entry fails to resolve. Our `egress-allowlist.ts` follows an
390
+ * apex+subdomain convention (e.g. `githubusercontent.com`), and some of those
391
+ * bare apexes have no A record — they'd abort the whole VM. So we pre-resolve
392
+ * here and drop the unresolvable ones.
393
+ *
394
+ * CAVEAT: unlike docker (SNI) / gondolin (hostname), smolvm's filter is
395
+ * IP-pinned at start — `--allow-host github.com` allows github.com's IPs only,
396
+ * NOT api.github.com or rotating CDN IPs. A faithful apex+subdomain policy
397
+ * would need each concrete subdomain enumerated; that's a spike gap.
398
+ */
399
+ async resolvableAllowHosts() {
400
+ if (!this.config.allowHosts)
401
+ return [];
402
+ const ok = new Set();
403
+ const dropped = [];
404
+ await Promise.all(this.config.allowHosts.map(async (h) => {
405
+ if (!HOST_RE.test(h))
406
+ throw new Error(`Refusing to pass allow-host "${h}" — bad charset`);
407
+ try {
408
+ await lookup(h);
409
+ ok.add(h);
410
+ }
411
+ catch {
412
+ dropped.push(h);
413
+ }
414
+ }));
415
+ if (dropped.length) {
416
+ console.warn(`[smol] Dropping unresolvable allow-host entries (smolvm resolves each at VM start): ${dropped.join(", ")}`);
417
+ }
418
+ return this.config.allowHosts.filter((h) => ok.has(h));
419
+ }
420
+ /**
421
+ * Build `--secret-env GUEST=GUEST` flags for every machine-env var plus the
422
+ * child-process env that carries their values, so secrets (tokens, provider
423
+ * keys) reach the guest via smolvm's secret channel rather than the argv.
424
+ */
425
+ secretEnv() {
426
+ const flags = [];
427
+ const childEnv = { ...process.env };
428
+ for (const [k, v] of Object.entries(this.config.env)) {
429
+ if (!ENV_KEY_RE.test(k) || /[\n\r]/.test(v))
430
+ continue;
431
+ flags.push("--secret-env", `${k}=${k}`);
432
+ childEnv[k] = v;
433
+ }
434
+ return { flags, childEnv };
435
+ }
436
+ }
437
+ /** Strip a taskId down to the charset smolvm accepts in a machine name. */
438
+ function sanitizeName(taskId) {
439
+ return taskId.replace(/[^A-Za-z0-9_-]/g, "-").slice(0, 48);
440
+ }
441
+ /**
442
+ * Depth-limited search for a file named `name` under `root`, returning its
443
+ * absolute path (or null). Used to locate the mount-probe sentinel; the share
444
+ * lands at most a couple of levels deep, so a shallow walk suffices and avoids
445
+ * descending into a large checkout.
446
+ */
447
+ function findFileUnder(root, name, maxDepth) {
448
+ if (!existsSync(root))
449
+ return null;
450
+ let entries;
451
+ try {
452
+ entries = readdirSync(root, { withFileTypes: true });
453
+ }
454
+ catch {
455
+ return null;
456
+ }
457
+ for (const e of entries) {
458
+ if (e.isFile() && e.name === name)
459
+ return join(root, name);
460
+ }
461
+ if (maxDepth <= 0)
462
+ return null;
463
+ for (const e of entries) {
464
+ if (e.isDirectory()) {
465
+ const hit = findFileUnder(join(root, e.name), name, maxDepth - 1);
466
+ if (hit)
467
+ return hit;
468
+ }
469
+ }
470
+ return null;
471
+ }
472
+ function execCmd(cmd, args, opts) {
473
+ return execFileSync(cmd, args, {
474
+ encoding: "utf-8",
475
+ stdio: ["pipe", "pipe", "pipe"],
476
+ timeout: opts?.timeout,
477
+ });
478
+ }
479
+ function execSafe(cmd, args) {
480
+ try {
481
+ execFileSync(cmd, args, { stdio: "ignore" });
482
+ }
483
+ catch { /* ignore */ }
484
+ }
485
+ //# sourceMappingURL=smol.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"smol.js","sourceRoot":"","sources":["../../src/sandbox/smol.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,12 @@
1
+ export type SkillScope = "user" | "project";
2
+ export interface SkillsOpts {
3
+ /** Install scope — `user` (~/.claude) or `project` (<cwd>/.claude). Default `user`. */
4
+ scope?: SkillScope;
5
+ /** Skip the `claude` marketplace path and always copy skill dirs directly. */
6
+ noMarketplace?: boolean;
7
+ }
8
+ export declare function skillsInstall(opts: SkillsOpts): Promise<void>;
9
+ export declare function skillsList(opts: SkillsOpts): Promise<void>;
10
+ export declare function skillsUninstall(opts: SkillsOpts): Promise<void>;
11
+ /** Entry point dispatched from `src/cli.ts` for `lastlight skills …`. */
12
+ export declare function skills(args: string[], opts: SkillsOpts): Promise<void>;