char-slop/berry

multipurpose self-modifiable agentic harness

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

Charlotte Somdocs: defer configuration facts to their sources5a1e0f9

main
4.1 KiB69 linesraw

berry

a self-modifiable agent harness on pi-durable and pi-codemode, with an aftercare frontend.

layout

  • api/: @berry/api, what extensions are written against. mod.ts (server side), web.ts (renderers), testing.ts (one extension without a harness), host.ts (modules the app and extension bundles share).
  • server/: berry.ts is the harness (extension compiler, event folding, the builtin berry extension with codemode and its prompt sections); codemode.ts, loader.ts (reloads), web.ts (extension frontend builds), http.ts, tree.ts, auth.ts/logins.ts, supervisor.ts → main.ts. dev.ts is a faux model; fixture.ts is the test harness.
  • extensions/<name>/: mod.ts, optional web.tsx, tests.
  • util/: @berry/util, what tests share: until, tempDir, onPath, PNG; dom.ts has withDom (a happy-dom page as globals), fill/press, viewContext, and fakeBerry (a fake server for the app). palette.ts is plain data the app's bundles import too ( berry's terminal colors); extension modules may import any of it as a bare specifier. web/testing.ts signs the app's client in to one.
  • web/: the app.
  • data/: the live database. never touch it.

commands

  • deno check server/main.ts web/main.tsx extensions/*/mod.ts extensions/*/web.tsx
  • deno lint, deno fmt
  • deno task build builds web/ into web/dist

you may be running inside berry

  • saving extensions/ reloads that extension in place. server/ and api/ changes need a restart (the header's restart button, which interrupts calls in other conversations). an extension's reload copies only its own directory, so @berry/api changes need a restart too.
  • the server serves web/dist from disk: deno task build and a browser reload pick up app changes, with no restart.
  • don't run a second server on data/. a scratch instance takes BERRY_DB, BERRY_PORT, BERRY_TOKEN, and BERRY_DEV_MODEL=1 (the dev/echo model, which spends no tokens).

conventions

  • events are kept forever: a reducer must keep folding every event shape it has ever recorded. add new shapes rather than changing old ones.
  • an extension imports only its own directory's files and bare specifiers, so small helpers are repeated across extensions rather than shared. web.tsx never imports server-only modules.
  • harness behaviour is tested through server/fixture.ts (faux provider, memory storage), and extensions through @berry/api/testing.ts. tests are named for the behaviour they pin down.
  • tests share helpers through @berry/util (a bare specifier, so extension tests may use it too) rather than repeating them. a fixture that needs cleanup is AsyncDisposable, used with await using.
  • doc comments are one sentence on what a thing is or why it exists; line comments are lowercase and explain motivation only.
  • styles, the app's and extensions' alike, use the tokens in web/style.css's :root: its colors, its type sizes (even pixels), and space in pixels on a 4px grid. each element's line height is its own, snapped to the grid, so a block takes more room with padding rather than a taller line.
  • dependency versions and policy live in deno.json. for pi package source, read node_modules/@earendil-works/<pkg>/ (READMEs; the .js.map files carry sourcesContent).
  • version control is jj, colocated with git. don't commit unless asked.

tests

  • test behavior, not CSS implementation. don't load stylesheets into DOM tests to assert selectors, declarations, dimensions, opacity, or animation timings: that duplicates the CSS and adds test churn.
  • check cosmetic changes in the browser. keep automated coverage for state, interactions, content, accessibility, and real rendering logic (such as ANSI color parsing), not style-change detectors.
  • a test earns its place by catching a regression nothing else would. don't pin exact copy, markup, schemas, or storage layouts; don't loop over inputs that take the same path; don't retest what a dependency guarantees (such as pi-durable persisting a document), or what another layer's test already covers.
1# berry
2
3a self-modifiable agent harness on pi-durable and pi-codemode, with an aftercare frontend.
4
5## layout
6
7- `api/`: `@berry/api`, what extensions are written against. `mod.ts` (server side), `web.ts`
8  (renderers), `testing.ts` (one extension without a harness), `host.ts` (modules the app and
9  extension bundles share).
10- `server/`: `berry.ts` is the harness (extension compiler, event folding, the builtin `berry`
11  extension with codemode and its prompt sections); `codemode.ts`, `loader.ts` (reloads), `web.ts`
12  (extension frontend builds), `http.ts`, `tree.ts`, `auth.ts`/`logins.ts`, `supervisor.ts` →
13  `main.ts`. `dev.ts` is a faux model; `fixture.ts` is the test harness.
14- `extensions/<name>/`: `mod.ts`, optional `web.tsx`, tests.
15- `util/`: `@berry/util`, what tests share: `until`, `tempDir`, `onPath`, `PNG`; `dom.ts` has
16  `withDom` (a happy-dom page as globals), `fill`/`press`, `viewContext`, and `fakeBerry` (a fake
17  server for the app). `palette.ts` is plain data the app's bundles import too ( berry's terminal
18  colors); extension modules may import any of it as a bare specifier. `web/testing.ts` signs the
19  app's client in to one.
20- `web/`: the app.
21- `data/`: the live database. never touch it.
22
23## commands
24
25- `deno check server/main.ts web/main.tsx extensions/*/mod.ts extensions/*/web.tsx`
26- `deno lint`, `deno fmt`
27- `deno task build` builds `web/` into `web/dist`
28
29## you may be running inside berry
30
31- saving `extensions/` reloads that extension in place. `server/` and `api/` changes need a restart
32  (the header's restart button, which interrupts calls in other conversations). an extension's
33  reload copies only its own directory, so `@berry/api` changes need a restart too.
34- the server serves `web/dist` from disk: `deno task build` and a browser reload pick up app
35  changes, with no restart.
36- don't run a second server on `data/`. a scratch instance takes `BERRY_DB`, `BERRY_PORT`,
37  `BERRY_TOKEN`, and `BERRY_DEV_MODEL=1` (the `dev/echo` model, which spends no tokens).
38
39## conventions
40
41- events are kept forever: a reducer must keep folding every event shape it has ever recorded. add
42  new shapes rather than changing old ones.
43- an extension imports only its own directory's files and bare specifiers, so small helpers are
44  repeated across extensions rather than shared. `web.tsx` never imports server-only modules.
45- harness behaviour is tested through `server/fixture.ts` (faux provider, memory storage), and
46  extensions through `@berry/api/testing.ts`. tests are named for the behaviour they pin down.
47- tests share helpers through `@berry/util` (a bare specifier, so extension tests may use it too)
48  rather than repeating them. a fixture that needs cleanup is `AsyncDisposable`, used with
49  `await using`.
50- doc comments are one sentence on what a thing is or why it exists; line comments are lowercase and
51  explain motivation only.
52- styles, the app's and extensions' alike, use the tokens in `web/style.css`'s `:root`: its colors,
53  its type sizes (even pixels), and space in pixels on a 4px grid. each element's line height is its
54  own, snapped to the grid, so a block takes more room with padding rather than a taller line.
55- dependency versions and policy live in `deno.json`. for pi package source, read
56  `node_modules/@earendil-works/<pkg>/` (READMEs; the `.js.map` files carry `sourcesContent`).
57- version control is jj, colocated with git. don't commit unless asked.
58
59## tests
60
61- test behavior, not CSS implementation. don't load stylesheets into DOM tests to assert selectors,
62  declarations, dimensions, opacity, or animation timings: that duplicates the CSS and adds test
63  churn.
64- check cosmetic changes in the browser. keep automated coverage for state, interactions, content,
65  accessibility, and real rendering logic (such as ANSI color parsing), not style-change detectors.
66- a test earns its place by catching a regression nothing else would. don't pin exact copy, markup,
67  schemas, or storage layouts; don't loop over inputs that take the same path; don't retest what a
68  dependency guarantees (such as pi-durable persisting a document), or what another layer's test
69  already covers.