# Jibb Jibb is a UI language for Urbit: a Hoon dialect with an indentation layout. Its design doc, [Jibb — an Elm-architecture UI language for Urbit](https://claude.ai/artifact/DMBr48qzi5z8hcwn2ccPBv), is the spec, and where this code and the doc disagree, the doc wins. Milestone 1 of the doc's eight, the parser and the `%jibb` mark, is done; milestone 2, types and prelude, is in progress. The type checker and Hoon importer are partial. [docs/](docs/) holds a copy of the doc's tabs, the status of each milestone, the open questions, a development guide, a map of the compiler, and the brief for milestone 2. ## Layout - `jibb-dev/`: what app desks vendor: the `%jibb` mark, the compiler, the partial Hoon type reader and the beginning of the prelude; later the browser library. - `jibb/`: the `%jibb` desk, for the shared host (milestone 4). - `my-app/`: an example app desk built from the doc's worked examples. - `vendor/`: pinned copies of the base-dev and landscape files the desks need. - `tests/`: golden cases in `golden//`, and on-ship tests for the `-test` thread in `lib/jibb.hoon`. - `tools/`: dev tooling: `golden`, `hoon` and `doc-blocks`, with their self-test in `testdata/`, and `ship`. - `docs/`: the doc's tabs as Markdown in `spec/`, the status, the open questions, the development guide, the compiler's map, and briefs for milestones in `prompts/`. ## Golden tests Each case, `tests/golden//`, holds `source.jibb`, `about.txt` (where it comes from, what it tests, the expected outcome), and the expected outputs: `tokens.txt` from the layout pass and `tree.txt` from the parser. A file holds the output plus one trailing newline. A case may also have a `path.txt` specifying its logical `/ui/.../*.jibb` path. An `expect-types:` line in `about.txt` opts it into the provisional `golden-types` checker output in `types.txt`; `--update` creates it. A case can select Hoon molds in `imports.txt` and provide each module in `sur/.txt`, or select marks in `marks.txt` and provide their source in `mar/.txt`. `modules.txt` selects Jibb source fixtures; their trees go in `module-trees.txt`, and the partial checker can resolve a subset of library imports. See [docs/development.md](docs/development.md). Run them without a ship. This needs `urbit` on PATH and Python 3. ``` tools/golden # every case: PASS or FAIL, a diff per failure, a summary tools/golden --case 'doc-grammar-*' # only the cases matching a glob tools/golden --show --case foo # print the outputs, don't compare ``` When outputs change on purpose, regenerate them, then review the diff before committing: ``` tools/golden --update git diff tests/golden ``` `tools/golden` compiles `jibb-dev/lib/jibb.hoon` once under `urbit eval` and calls its `golden` arm on each case under `mule`, so a crash fails only its own case. `--update` never writes a crash. Errors and crash traces point at lines of the library. The exit status is 0 when every case passes, 1 when a case fails, and 2 when the tests can't run, for example because the library doesn't compile. To try the library by hand: ``` tools/hoon '(golden /a/b/jibb (crip "++ main view"))' tools/hoon --raw --cord src=tests/golden/foo/source.jibb 'tree:(golden /a/b/jibb src)' ``` `tools/testdata/selftest` tests both tools against a stub library, and `tools/doc-blocks` against Markdown it writes. `tools/importer-test` compares the partial Hoon importer's fixture projections against their golden file. `tools/type-import-test`, `tools/type-tlon-test`, `tools/type-mark-test`, `tools/type-poke-test` and `tools/type-api-paths-test` check importer/checker, prelude and partial API path analysis boundaries under eval; the ship suite runs the same fixtures. ### The doc's examples Every code block the design doc labels `jibb` is a golden case, `doc---`, where `` counts the tab's code blocks, labelled or not. To check that none is missing or stale, export the doc's tabs as Markdown and pass the files, or a folder of them: ``` tools/doc-blocks docs/spec # the snapshot in docs/spec tools/doc-blocks Grammar.md Overview.md Core-language.md # fresh exports ``` It matches each labelled block to the case whose `source.jibb` is the block's text plus a newline, and lists the blocks no case holds, each with a diff against the closest unmatched case, and the `doc-*` cases no block holds. Pass every tab with Jibb blocks, or the other tabs' cases count as stale. The exit status is 0 when every block has a case and every case a block, 1 when one doesn't, and 2 when the check can't run, for example because no block is labelled `jibb`. ## Fake ship `tools/ship` runs the desks on a fake `~zod` at `/root/urbit/zod` (`--pier` or `$JIBB_PIER`). It needs Python 3 and click (`/root/src/tools/pkg/click/click`, or `--click`). The ship runs in the background, logging to `/root/urbit/zod.log`. ``` tools/ship start # start it and wait until it's live tools/ship status # running or not; desks, revisions, mounts tools/ship log # the end of its log tools/ship stop ``` `tools/ship sync ` assembles a desk from the repo's folders, creates it if it's missing (as `|new-desk` does), mounts it, deletes from the desk through Clay the files the repo doesn't have, makes the mount hold exactly the repo's files, runs `|commit` and waits until the desk matches the repo, checking every file. If Clay rejects the commit, it prints Clay's error, which the log doesn't show. | Desk | Assembled from | | --- | --- | | `my-app` | `vendor/*`, then `jibb-dev` without `tests/`, then `my-app` | | `jibb` | `vendor/*`, then `jibb` | | `jibb-dev` | `vendor/*`, then `jibb-dev`, then `tests/`, with `tests/lib/jibb.hoon` generated, and `jibb/sys.kelvin` | The `jibb-dev` desk runs the golden cases on the ship, as `-test` arms. `tools/ship gen-tests` writes `tests/lib/jibb.hoon` from `tests/golden`: for each case it imports `source.jibb`, `tokens.txt` and `tree.txt` with `/*`, and its `test-` arm compares `golden:jibb` with them. Cases opted into `types.txt` also compare the partial inference output. Don't edit that file; `--check` says whether it's up to date. `tools/ship test` regenerates it, syncs the desk and runs `-test /=jibb-dev=/tests`, printing each case's OK, FAILED or CRASHED and the reason. It exits 0 only when every case passes. ``` tools/ship test # the library and tests/golden tools/ship test --stub --golden tools/testdata/ship-golden tools/ship test --lib some/other/jibb.hoon ``` A sync with nothing to commit takes about 2 s. A commit adds 3 to 10 s, and 300 cases (900 files) sync in about 10 s. `-test` takes 1 to 3 s with the stub library. `--stub` swaps in `tools/testdata/ship-stub.hoon`, and `tools/testdata/ship-selftest` checks the generator and the runner against it with the cases in `tools/testdata/ship-golden`. Runs with `--stub`, `--lib`, or a custom `--golden` include only the generated golden test program: the repository's other test programs run with the default library and corpus. A subsequent default `tools/ship test` restores them. `tools/ship check-commit` proves that `|commit` stores `.jibb` files. It syncs `my-app`, reads every `/ui` file back with `%cx`, byte for byte, and converts `%jibb` to `%mime` and `%txt` and back. It commits half-written files, then deletes them. It merges a file that two desks changed on different lines, and checks that changes to the same line conflict. It can be rerun, and it leaves the two scratch desks it merges with (`%jibb-check-ours` and `%jibb-check-theirs`) holding only what `|new-desk` gives, unmounted. `tools/clay-fixtures` syncs `my-app`, builds its example `/sur` files and marks through Clay, and checks selected types read from the compiled graphs and passed to the partial checker. It compares the results with golden files under `tests/clay-fixtures/`. For anything else: ``` tools/ship scry /cx/=my-app=/ui/about/jibb --raw # a file's bytes tools/ship scry /ct/=jibb=/ --type '(list path)' tools/ship hoon '(add 2 2)' # as dojo, with our, now, eny tools/ship run thread.hoon # a strand tools/ship poke hood kiln-commit '[%my-app |]' tools/ship commit|mount|unmount ``` What the ship does that you might not expect: - `|merge` with kiln's default strategy, `%auto`, stops at "auto merge failed on strategy %fine" whenever a fast-forward isn't possible: kiln moves on to `%meet` only on a `%bad-fine-merge` error, and this Clay reports `%merge-failed`. Pass `=gem %mate`. - `%txt` keeps no final newline: vere's `+to-wain` jet ends the last line there, where the Hoon in zuse gives an empty line after it. So a `.jibb` file that a three-way merge changes, which goes through `%txt` (`grad %txt`, as `%hoon` does), loses its final newline. Likewise the ship can't tell a golden `tokens.txt` or `tree.txt` that lacks its final newline; `tools/golden` and `tools/ship test` catch it. - `|commit` deletes from the desk only the files vere has seen in the mount since the ship started: the ones it wrote there and the ones an earlier `|commit` found. So after a restart, a file deleted from the mount before the next `|commit` stays on the desk. That is why `tools/ship sync` deletes such files through Clay, with a `%info` task. - conn.sock closes the connection as soon as it has written a reply, so a reply bigger than the socket buffer, about 200 KB, is cut off. `tools/ship` keeps its replies small and reads big files in parts.