char-slop/berry

multipurpose self-modifiable agentic harness

git clone https://git.t4t.associates/char-slop/berry

Charlotte Somadd skills extension for loading skillsa4e772a

main
3.0 KiB75 linesraw
1import { assertEquals, assertStringIncludes } from "@std/assert";
2import { BACKGROUND_CONTEXT as context } from "@earendil-works/chord/context";
3import { getOrThrow } from "@earendil-works/pi-durable/env";
4import { testExtension } from "@berry/api/testing.ts";
5import { tempDir } from "@berry/util";
6import code from "../../extensions/code/mod.ts";
7import { skillsExtension } from "../../extensions/skills/mod.ts";
8import { activeDirectory, hostEnvironment, writeSkill } from "../../extensions/skills/testing.ts";
9import { BOOTSTRAP, Connection, RemoteEnvironment } from "./connection.ts";
10
11Deno.test({
12  name:
13    "host skills expose ordinary readable paths and executable scripts on a remote worker without running them at load time",
14  ignore: Deno.build.os === "windows",
15}, async () => {
16  await using home = await tempDir();
17  await using target = await tempDir();
18  const host = hostEnvironment(home.path);
19  const main = await writeSkill(
20    host,
21    `${home.path}/.config/berry/skills`,
22    "release",
23    "Read references/checklist.txt and run scripts/check.sh when asked.",
24  );
25  const source = main.slice(0, -"/SKILL.md".length);
26  getOrThrow(
27    await host.writeFile(`${source}/references/checklist.txt`, "Host-authored checklist.", context),
28  );
29  getOrThrow(
30    await host.writeFile(
31      `${source}/scripts/check.sh`,
32      '#!/bin/sh\nprintf "%s" "$BERRY_MACHINE" > executed\ncat executed\n',
33      context,
34    ),
35  );
36  await Deno.chmod(`${source}/scripts/check.sh`, 0o755);
37  const connection = await Connection.open("skills-test", [
38    "env",
39    "BERRY_MACHINE=skills-test",
40    `HOME=${target.path}`,
41    `XDG_CONFIG_HOME=${target.path}/config`,
42    `XDG_CACHE_HOME=${target.path}/cache`,
43    Deno.execPath(),
44    "eval",
45    "--quiet",
46    BOOTSTRAP,
47  ]);
48  const env = new RemoteEnvironment("skills-test", connection, target.path);
49  const ext = testExtension(skillsExtension(host), { env });
50  const files = testExtension(code, { env });
51  try {
52    assertStringIncludes(await ext.prompt(), '"name":"release"');
53    await ext.call("load_skill", { name: "release" });
54    const directory = await activeDirectory(env, await ext.prompt());
55    assertEquals(directory.startsWith(`${target.path}/`), true);
56    assertStringIncludes(
57      await files.call("read", { path: `${directory}/references/checklist.txt` }) as string,
58      "Host-authored checklist.",
59    );
60    assertEquals(await Deno.stat(`${home.path}/executed`).catch(() => null), null);
61    assertEquals(getOrThrow(await env.exists("executed", context)), false);
62    const result = await files.call("bash", {
63      command: `${JSON.stringify(directory + "/scripts/check.sh")}`,
64      timeout: 10,
65    }) as { output: string; exitCode: number };
66    assertEquals(result.exitCode, 0);
67    assertEquals(result.output, "skills-test");
68    assertEquals(getOrThrow(await env.readTextFile("executed", context)), "skills-test");
69    assertEquals(await Deno.stat(`${home.path}/executed`).catch(() => null), null);
70  } finally {
71    await ext.dispose();
72    await files.dispose();
73    await connection.close();
74  }
75});