
This project implements some of Beagle SCM's functionality for regular git repos. The work is ongoing; so far it can do:
bee install to add a hook to a git repo),bee ./myfile to open),bee http --port 8888 to run,
then open http://localhost:8888/myproject in a browser),bee log or
http://localhost:8888/myproject/log then click around),index/perma.js:6:ur, see them in the pager/browser,
bee see for CLI use, commit hook or be mint to create)Reproducing Beagle's smooth worktree workflows has proven difficult, as git submodule and git worktree implementations are rather abrasive.
Bundle with the quickjab runtime for a standalone binary. That carries dog/ (libdog), dog/abc/ (libabc) and test/ (the jab-shared API suite) as submodules:
cmake -S <quickjab> -B build -GNinja -DCMAKE_BUILD_TYPE=Release \
-DJAB_JSRC=<js bundle tree> -DQUICKJAB_JSRC_PACK=ON -DJAB_BIN=bee
ninja -C build quickjab
ctest --test-dir build -R '^JSRC'
That leaves the binary at build/bin/bee and runs this tree's own
test/*/run.sh suites against it, exactly as CI does
(.github/build-bee.sh). Tagging X.Y.Z releases the same build:
a source tarball plus bee for linux x86_64/arm64, macOS arm64 and a
fully static linux x86_64.
The standalone (bundled) bee binary call patterns:
bee -- in a git repo: index it, open the list browser;bee <path>... -- page files/dirs off the filesystembee //<name> <verb> [args] -- the CONTEXT slot (BEE-023): the verb runs in
the repo <name>, and //<name>/<rel> is a path inside it wherever an arg is
a path (bee cat //bee-journal/todo/BEE/BEE-023.mkd)
<name> is a basename off ~/.config/bee/repos, else the directory $SRC_ROOT/<name> ($HOME/src by default) when a git repo or a linked worktree sits there$SRC_ROOT hit is read-only for that run -- it is never registered; use bee install for that//<name> is an argument like any otherbee //<name> is the zero-arg story in that repo: index it, open the list browserbee index [<repo>] -- build/refresh <repo>/.git/be/; lazy, fully derived;
ALL THREE passes, the commit walk, the tip-blob link scan and the kv meta
sweep, each off its own mark, all on the one summary line
kv: N files, M pairs is the keyed lane (BEE-024): the .md/.mkd
files this worktree carries and the live meta pairs they holdbee lindex [<target>] -- backlink suspects; lazy, tip blobs only
<target>: the paths that may link to a file or a ticket code, looked
up in every repo of ~/.config/bee/repos (read-only) and printed
repo-qualified, the local repo firstbee sym [--paths] <ident> [.ext|<dir>]... -- where a symbol is mentioned
(BEE-063, BEE-066); one prefix scan of the SYM rows the tip-blob pass mints
uri the address <path>:<line>, text
the raw mention line with a line of context either side, the file's own
tags with the mention marked; two windows merge where they overlap~/.config/bee/repos answers (read-only), the local firstu8bFeed and U8BFeed are two queries.c an extension, dog/abc/ a SEGMENT-ALIGNED
path run at any depth (never catalog/abc); alike words OR, the two
kinds AND, and a path run prunes the rows before the cap is weighed--paths: one repo-qualified path per line and no file opened, for scriptsbee log [<n>] [<hex>|<path>][?<rev>] -- commit log, newest first; off-mainline rows grey
<n> caps the rows, 0 = all<hex>: that commit's ancestry<path>: the file's revisions?<rev>: a branch, tag or hexlet names the tip -- log ?main, log f.c?v2<sub>/<path>: the submodule's own history, its rows opening in the subbee commit [<hex>] -- one commit, header + message; tree/parent hashes are linksbee diff [<hex> [<hex>]|<path>] -- the token-level diff: one weave per path,
seeded at the two revisions' merge base, every token naming its own commit
<hex>: that commit vs its first parent<hex> <hex>: any two revisions, rooted at their merge base<path>: that file/dir onlybee status — the quad: one row per path that is not quiet, four chars
wide, upstream HEAD index worktree, . same, x removed, o
created, v advanced, ! conflicted; position is authoritativebee list [<path>][?<rev>] -- dir browser: marker, name, last commit, agebee cat <path>[?<rev>] -- the file's own bytes, syntax-paintedbee tree [<hex>|<path>][?<rev>] -- raw git-tree rows, .. row when descendedbee blob <hexlet> -- a blob by object namebee see [-C<n>] <ref>... -- the chunk each reference names, two lines of context each way; the only CLI door onto a permalink
door.js resolves: permalink, path, partial, ticket code, pocket page, another registered repobee cite <path>[?<rev>] -- the file with every anchored reference on it already quoted, one line above the landing and two below
f.c:12 and the permalink f.c:12:aB alike, resolved through the same door see asks; a bare filename or a ticket code is left alonebee cited <path> -- the mirror of cite: every reference ELSEWHERE that points at this file, quoted under the line it lands on
bee todo [TOPIC] [Key:Value]... -- the ticket board: <●> KEY ┄ title per open ticket, the row a click onto bee see KEY
todo/ -- topic headers with counts, Sub: families on dotted rails; when that repo (or, with no context, the local one) has no todo/, every registered repo's, newest first, each row prefixed by its repoTOPIC is one topic's list, Key:Value a filter -- keys AND, one key repeated ORs, Key:* is presence and Key: absence; Sev: paints the bullet CRIT red, HIGH orange, LOW dimNow: OPEN, or no Now: and no closed header mark; todo/done/ never lists and the answer comes off the BEE-024 lane, one query per repo per run$SRC_ROOT worktree carries the two BEE-027 frames; a worktree whose tail is no ticket code lists in a trailing worktrees blockbee http [--port <n>] -- the same views over HTTP on localhost:8034, read-only, every registered repo, links to known files resolved and clickable
/<repo>/<verb>/<arg> -- /<repo>/cat/<path> the file (a .md rendered), /<repo>/list/<dir>/ the browser; a verb-less /<repo>/<path> 301s to that form, and a segment that spells a verb (todo/) IS the verb (BEE-028)/<repo>/raw/<path> is the highlighted source,/<repo>/bytes/<path>[?<rev>] ships the file's raw bytes,/quickjab/cat/dog/abc/TCP.c), never under a name of its ownbee fork //repo-TKT-123 -- a ticket worktree of a registered repo at $SRC_ROOT/repo-TKT-123, on a branch named by the tail
- (//bee-journal-BEE-023 is the journal's); the tail is free text, usually a ticket codegit worktree remove is how it goes awaybee wts -- the ticket worktrees under $SRC_ROOT, one line each: <name>-<tail> then the two board frames
<registry name>-<tail> holding a repo; git worktree list is never consulted and nothing is registered[v3 v1 v2 v5 !1] is the BEE-022 quad's column counts -- upstream, head, stage, worktree, conflicted, position authoritative[o2 o1 a1b2c] is commits ahead, commits behind and the current tipbee todo board (BEE-025) is what spends these rowsbee install [<repo>] -- wire bee as the repo's git merge driver and its pre- and post-commit hooks, list it in ~/.config/bee/repos, index it
bee index redirects to the original instead)bee hook --post on the commit just made, quietly; git ignores its status, so it can never block or undo a commitbee hook [<repo>] -- the pre-commit pass: fresh file:line(:col) refs
in the staged text become file:line:hash permalinks, re-staged
bee hook --post [<repo>] is the post-commit pass: index's three passes over the commit just made, quiet, and it never writes ~/.config/bee/repos -- install is the one verb that registers a repobee mint [--dry-run] <file>... -- the same upgrade for refs that ALREADY landed transient, in the working copy only; the hook cannot reach those
bee merge <base> <ours> <theirs> [-o <out>] [-p <path>] -- CRDT 3-way file merge
<ours> (or <out>), exit 0git merge-filebee mark <file.mkd> -- that page rendered to ONE HTML document on stdout (.mkd, .md, .rst), the writing left to the shell
.mkd/.md/.rst link takes the .html name rendered beside it, so a dumped tree links up; every other destination rides verbatim/assets/css/style.css, and the body carries no bee chromebee chat [dir] [outdir] -- Claude session logs to StrictMark pages, append-only reruns116 commits
Hacker News (1)
JavaScript
62.3%
Shell
37.5%

This project implements some of Beagle SCM's functionality for regular git repos. The work is ongoing; so far it can do:
bee install to add a hook to a git repo),bee ./myfile to open),bee http --port 8888 to run,
then open http://localhost:8888/myproject in a browser),bee log or
http://localhost:8888/myproject/log then click around),index/perma.js:6:ur, see them in the pager/browser,
bee see for CLI use, commit hook or be mint to create)Reproducing Beagle's smooth worktree workflows has proven difficult, as git submodule and git worktree implementations are rather abrasive.
Bundle with the quickjab runtime for a standalone binary. That carries dog/ (libdog), dog/abc/ (libabc) and test/ (the jab-shared API suite) as submodules:
cmake -S <quickjab> -B build -GNinja -DCMAKE_BUILD_TYPE=Release \
-DJAB_JSRC=<js bundle tree> -DQUICKJAB_JSRC_PACK=ON -DJAB_BIN=bee
ninja -C build quickjab
ctest --test-dir build -R '^JSRC'
That leaves the binary at build/bin/bee and runs this tree's own
test/*/run.sh suites against it, exactly as CI does
(.github/build-bee.sh). Tagging X.Y.Z releases the same build:
a source tarball plus bee for linux x86_64/arm64, macOS arm64 and a
fully static linux x86_64.
The standalone (bundled) bee binary call patterns:
bee -- in a git repo: index it, open the list browser;bee <path>... -- page files/dirs off the filesystembee //<name> <verb> [args] -- the CONTEXT slot (BEE-023): the verb runs in
the repo <name>, and //<name>/<rel> is a path inside it wherever an arg is
a path (bee cat //bee-journal/todo/BEE/BEE-023.mkd)
<name> is a basename off ~/.config/bee/repos, else the directory $SRC_ROOT/<name> ($HOME/src by default) when a git repo or a linked worktree sits there$SRC_ROOT hit is read-only for that run -- it is never registered; use bee install for that//<name> is an argument like any otherbee //<name> is the zero-arg story in that repo: index it, open the list browserbee index [<repo>] -- build/refresh <repo>/.git/be/; lazy, fully derived;
ALL THREE passes, the commit walk, the tip-blob link scan and the kv meta
sweep, each off its own mark, all on the one summary line
kv: N files, M pairs is the keyed lane (BEE-024): the .md/.mkd
files this worktree carries and the live meta pairs they holdbee lindex [<target>] -- backlink suspects; lazy, tip blobs only
<target>: the paths that may link to a file or a ticket code, looked
up in every repo of ~/.config/bee/repos (read-only) and printed
repo-qualified, the local repo firstbee sym [--paths] <ident> [.ext|<dir>]... -- where a symbol is mentioned
(BEE-063, BEE-066); one prefix scan of the SYM rows the tip-blob pass mints
uri the address <path>:<line>, text
the raw mention line with a line of context either side, the file's own
tags with the mention marked; two windows merge where they overlap~/.config/bee/repos answers (read-only), the local firstu8bFeed and U8BFeed are two queries.c an extension, dog/abc/ a SEGMENT-ALIGNED
path run at any depth (never catalog/abc); alike words OR, the two
kinds AND, and a path run prunes the rows before the cap is weighed--paths: one repo-qualified path per line and no file opened, for scriptsbee log [<n>] [<hex>|<path>][?<rev>] -- commit log, newest first; off-mainline rows grey
<n> caps the rows, 0 = all<hex>: that commit's ancestry<path>: the file's revisions?<rev>: a branch, tag or hexlet names the tip -- log ?main, log f.c?v2<sub>/<path>: the submodule's own history, its rows opening in the subbee commit [<hex>] -- one commit, header + message; tree/parent hashes are linksbee diff [<hex> [<hex>]|<path>] -- the token-level diff: one weave per path,
seeded at the two revisions' merge base, every token naming its own commit
<hex>: that commit vs its first parent<hex> <hex>: any two revisions, rooted at their merge base<path>: that file/dir onlybee status — the quad: one row per path that is not quiet, four chars
wide, upstream HEAD index worktree, . same, x removed, o
created, v advanced, ! conflicted; position is authoritativebee list [<path>][?<rev>] -- dir browser: marker, name, last commit, agebee cat <path>[?<rev>] -- the file's own bytes, syntax-paintedbee tree [<hex>|<path>][?<rev>] -- raw git-tree rows, .. row when descendedbee blob <hexlet> -- a blob by object namebee see [-C<n>] <ref>... -- the chunk each reference names, two lines of context each way; the only CLI door onto a permalink
door.js resolves: permalink, path, partial, ticket code, pocket page, another registered repobee cite <path>[?<rev>] -- the file with every anchored reference on it already quoted, one line above the landing and two below
f.c:12 and the permalink f.c:12:aB alike, resolved through the same door see asks; a bare filename or a ticket code is left alonebee cited <path> -- the mirror of cite: every reference ELSEWHERE that points at this file, quoted under the line it lands on
bee todo [TOPIC] [Key:Value]... -- the ticket board: <●> KEY ┄ title per open ticket, the row a click onto bee see KEY
todo/ -- topic headers with counts, Sub: families on dotted rails; when that repo (or, with no context, the local one) has no todo/, every registered repo's, newest first, each row prefixed by its repoTOPIC is one topic's list, Key:Value a filter -- keys AND, one key repeated ORs, Key:* is presence and Key: absence; Sev: paints the bullet CRIT red, HIGH orange, LOW dimNow: OPEN, or no Now: and no closed header mark; todo/done/ never lists and the answer comes off the BEE-024 lane, one query per repo per run$SRC_ROOT worktree carries the two BEE-027 frames; a worktree whose tail is no ticket code lists in a trailing worktrees blockbee http [--port <n>] -- the same views over HTTP on localhost:8034, read-only, every registered repo, links to known files resolved and clickable
/<repo>/<verb>/<arg> -- /<repo>/cat/<path> the file (a .md rendered), /<repo>/list/<dir>/ the browser; a verb-less /<repo>/<path> 301s to that form, and a segment that spells a verb (todo/) IS the verb (BEE-028)/<repo>/raw/<path> is the highlighted source,/<repo>/bytes/<path>[?<rev>] ships the file's raw bytes,/quickjab/cat/dog/abc/TCP.c), never under a name of its ownbee fork //repo-TKT-123 -- a ticket worktree of a registered repo at $SRC_ROOT/repo-TKT-123, on a branch named by the tail
- (//bee-journal-BEE-023 is the journal's); the tail is free text, usually a ticket codegit worktree remove is how it goes awaybee wts -- the ticket worktrees under $SRC_ROOT, one line each: <name>-<tail> then the two board frames
<registry name>-<tail> holding a repo; git worktree list is never consulted and nothing is registered[v3 v1 v2 v5 !1] is the BEE-022 quad's column counts -- upstream, head, stage, worktree, conflicted, position authoritative[o2 o1 a1b2c] is commits ahead, commits behind and the current tipbee todo board (BEE-025) is what spends these rowsbee install [<repo>] -- wire bee as the repo's git merge driver and its pre- and post-commit hooks, list it in ~/.config/bee/repos, index it
bee index redirects to the original instead)bee hook --post on the commit just made, quietly; git ignores its status, so it can never block or undo a commitbee hook [<repo>] -- the pre-commit pass: fresh file:line(:col) refs
in the staged text become file:line:hash permalinks, re-staged
bee hook --post [<repo>] is the post-commit pass: index's three passes over the commit just made, quiet, and it never writes ~/.config/bee/repos -- install is the one verb that registers a repobee mint [--dry-run] <file>... -- the same upgrade for refs that ALREADY landed transient, in the working copy only; the hook cannot reach those
bee merge <base> <ours> <theirs> [-o <out>] [-p <path>] -- CRDT 3-way file merge
<ours> (or <out>), exit 0git merge-filebee mark <file.mkd> -- that page rendered to ONE HTML document on stdout (.mkd, .md, .rst), the writing left to the shell
.mkd/.md/.rst link takes the .html name rendered beside it, so a dumped tree links up; every other destination rides verbatim/assets/css/style.css, and the body carries no bee chromebee chat [dir] [outdir] -- Claude session logs to StrictMark pages, append-only rerunsHacker News (1)
116 commits
JavaScript
62.3%
Shell
37.5%