FuguBench

fugubench(1)

NAME

fugubench — outfit a FuguBSD checkout for a coding agent

SYNOPSIS

fugubench [-h] [-C dir] [--verbose] verb [argument ...]

fugubench deps [--dry-run] [--os name] [--arch name] tool | runtime | test | develop

fugubench deps --update-sums [--force] [--os name] [--arch name]

fugubench doctor [--fix]

fugubench fetch file url

fugubench hook install

fugubench hook SessionStart | SessionEnd

fugubench hook WorktreeCreate | WorktreeRemove

fugubench install

fugubench shim

fugubench traces [--root dir] [--name name]

fugubench update [--version tag] [--allow-downgrade]

fugubench version

fugubench wiki init

fugubench wiki open project session

fugubench wiki note | admit page file

fugubench wiki close session

fugubench wiki status | candidates

fugubench worktree create name

fugubench worktree remove [--force] name

fugubench worktree list

fugubench worktree clone path ...

DESCRIPTION

fugubench outfits a FuguBSD checkout for a coding agent. It installs the dependencies of a repository, makes and removes worktrees, operates the learning library, answers the Claude Code hooks, and measures the sessions. One verb serves each concern.

The released program is one packed perl file that runs on core perl 5.34. It loads no CPAN module, and the pack carries the Fugu modules that it uses.

A verb operates one checkout: the repository that holds the manifests, the worktrees, or the library clone. The program walks up from the start directory to the nearest .toolingrc, and that directory is the checkout root. The start is the -C value, the payload ‘cwd’ of a hook, or the current directory. A worktree holds a .toolingrc of its own, and is a checkout.

Standard output carries the result of a verb. Every diagnostic, and every line of a child command, goes to standard error. A usage error prints the usage to standard error and exits 2.

The options are as follows:

dir
Read dir as the checkout root, in front of the walk above.
, --help
Print the usage to standard output and exit 0. A verb in front of the option gives the usage of that verb.
Trace each child command on standard error. A verb can add its own progress lines to that stream.

The verbs are as follows:

[--dry-run] environment
Install one dependency environment from deps/<OS>.txt, where the file name holds the system name of uname(1). The environments are tool, runtime, test and develop.

--dry-run prints each command to standard output, and runs none of them. --os and --arch replace the two words of uname(1), which a manifest writes as ‘{os}’ and ‘{arch}’.

--update-sums [--force]
Record the digest of each versioned download of the manifest in deps/SHA256.txt. --force rewrites a recorded digest.
[--fix]
Report the state of the checkout, as one ‘ok <check>: <detail>’ or ‘problem <check>: <detail>’ line for each check. The checks are the version of the program, the presence of git(1), make(1) and a downloader on PATH, the hook entries and the worktree base reference of .claude/settings.json, and the state of the library clone. The verb exits 1 when it wrote one problem line.

--fix skips the pending commit of a library clone that sits in a stopped rebase, when that commit adds a session page with no observation.

file url
Download one URL to one file, through the downloader of the program.
event
Answer one Claude Code hook event. The events are SessionStart, SessionEnd, WorktreeCreate and WorktreeRemove, and another word is a usage error.
Write the four hook entries in .claude/settings.json of the checkout, and keep every other key of the file.
Copy the running program to ~/.local/bin/fugubench with mode 755, atomically, and print the path.
Print the wrapper shim of a consumer to standard output. The shim is POSIX shell, and a consumer keeps it at scripts/fugubench. The shim is the pin of the release. A checkout with no tag carries the version 0.0.0, and the verb refuses such a version.
[--root dir] [--name name]
Measure the Claude Code sessions of the checkout. The verb prints one line for each session that holds a request, sorted by start time, under a header. The verb reads the trace directory of the checkout, of each worktree of it, and of each project clone in either. --root names a trace root in place of ~/.claude/projects/, and --name replaces the derived name.
[--version tag] [--allow-downgrade]
Replace the running program with a verified release. The result line is ‘fugubench <version>’, and a failed update prints no line.

The verb refuses a version below the running one, without --allow-downgrade.

Print ‘fugubench <version>’ and the Fugu version of the snapshot on one line.
Clone wiki.origin into the library directory when that directory is absent.
project session
Start the session page of session, commit, and push. The page name is Session-<project>-<date>-<n>.md, and the verb writes it to standard output as the only line.
page file
 
page file
Append the text of file to page after one blank line, commit, and push. The two subcommands differ in the commit subject only.
session
Append the ‘Closed:’ line to the page of session, commit, and push.
Report each open session with its page, its ‘Claim:’ count, and its ‘Admitted:’ count, and then the count of unpushed commits.
Report each undelivered candidate of the page Rule-candidates.md, with its age in days and its date.
name
Make the worktree at <root>/<worktree.base>/<name>, on a new branch name that starts at the local HEAD of the main checkout. The verb then runs ‘make -C <worktree> bootstrap MAIN=<root>’ when the worktree holds a makefile. It writes the worktree path to standard output as the only line.
[--force] name
Remove the worktree of name and delete its branch. Without --force, the verb refuses a worktree that holds work at risk, and the message names each cause. The causes are an uncommitted change in the worktree or in a repository inside it, and a commit that no remote holds.
Report each worktree with its name, its age in days, and its state. The state is clean, or each cause of remove.
path ...
Copy each gitignored path of the main checkout that -C names into the current directory, with no network.

CONFIGURATION

fugubench reads its keys from .toolingrc, the identity file of the synced FuguBSD tools. A line holds a key, whitespace, and a value. A ‘#’ starts a comment. The program ignores every other key of the file.

wiki.origin   https://github.com/FuguBSD/Wiki.git
wiki.projects Projects

The keys are as follows:

The library clone, under the home of wiki.origin. The default is Wiki.
The URL of the library repository. It has no default, and wiki init stops without it.
The project name of a session at the root. The default is the name of the root directory.
The directory whose children are project clones. The default is Projects.
The directory of the worktrees, under the root. The default is .claude/worktrees.

ENVIRONMENT

The program that the wrapper shim runs in place of the release. A developer points it at bin/fugubench of a checkout. A value that names no executable makes the shim report the value and exit non-zero. An empty value names no executable either.
With a value, deps adds --local-lib with that value to each cpanm(1) command.

FILES

.toolingrc
The configuration of the checkout.
deps/<OS>.txt
The dependency manifest of one operating system.
scripts/fugubench
The wrapper shim of a consumer.
.claude/settings.json
The settings file of Claude Code, which hook install writes.
~/.local/bin/fugubench
The program that install copies.
~/.cache/fugubench/<version>/
The shim cache of one release.
~/.claude/projects/
The default trace root of traces.

EXIT STATUS

fugubench exits with one of the following values:

0
Success.
1
A failure. doctor also gives this status for a report that names a problem.
2
A usage error.
3
A configuration error: no .toolingrc above the start directory, or a key that no file holds.

No verb defines another code.

EXAMPLES

Outfit a checkout, install the hooks, and read the report:

$ fugubench deps tool
$ fugubench deps test
$ fugubench hook install
$ fugubench doctor

Make a worktree, list the worktrees, and remove it again:

$ fugubench worktree create bugfix/parser
/home/dick/FuguBench/.claude/worktrees/bugfix/parser
$ fugubench worktree list
bugfix/parser                               2 d  clean
$ fugubench worktree remove bugfix/parser

Open a session page, add one observation, and close the session:

$ page="$(fugubench wiki open FuguBench 4f21c0)"
$ fugubench wiki note "$page" observation.txt
$ fugubench wiki close 4f21c0

Run the checkout in place of the release that the shim pins:

$ FUGUBENCH=$PWD/bin/fugubench scripts/fugubench version
fugubench 0.0.0 (Fugu 0.5.0)

SEE ALSO

cpanm(1), git(1), make(1), perl(1), uname(1)

The module documentation is in the .pod sidecars beside lib/App/FuguBench/.

AUTHORS

Dick Olsson <hi@senzilla.io>