# hof's root Node manifest says version 1.0.0 and ISC while everything else says Apache

> hofstadter-io/hof is a Go command line tool built on CUE for data models, code generation and a task engine, whose Makefile generates its own continuous integration workflows from CUE files. Its Node manifest, its readme and its release history each tell a different version story.

**hofstadter-io/hof** — A developer experience centered on CUE. Unifies schemas, data models, deterministic and agentic code generation, workflow and task engine, dagger powered environments, coding assistant, and vscode extension; woven together on the CUE lattice. Squint harder if you can't see the cube :]

- Repository: https://github.com/hofstadter-io/hof
- Website: https://hofstadter.io
- Stars: 614 · Forks: 48
- Language: Go
- License: Apache-2.0
- Published: 2026-09-15 · Updated: 2026-09-15 · Language: en
- Canonical page: https://hysenlabs.com/projects/hofstadter-io-hof

## The root Node manifest declares a different version and a different licence

There is a package manifest at the repository root, and it describes something else entirely. It names the package, sets its version to 1.0.0, and declares the ISC licence. The repository metadata says Apache 2.0, the closing section of the readme says Apache 2.0 and points at the licence file, and the release tags are a 0.6 line followed by two 0.7 pre-release builds. So a package index reading the manifest sees a permissive licence that does not match the one the project states twice, and a version number that matches neither the tags nor the Go module. The rest of the file is scaffold: an empty description, an empty keywords array, an empty author, a main entry pointing at a JavaScript file that is not at the root, and a test script that echoes an error and exits. What it is actually for is driving the editor extension build through a workspace filter.

## Its own continuous integration is generated from CUE files using hof

The Makefile is where this project is most unusual, and the reason is that the tool builds part of itself. A target walks the CUE files under the continuous integration directory and runs the project's own export command on each one, writing the result into the workflow directory as a YAML file. A second target does the same for the dev container definition, generating the JSON from a CUE file. The practical consequence is a bootstrap dependency: changing a workflow means having a working binary to export with, so a contributor who cannot build the tool cannot regenerate its own pipeline. Two other details sit in the same file. The help target simply prints the Makefile, and the Makefile's first line includes another file that holds most of the real targets, so the printed help is mostly the wrapper. The comment above that target misspells the phrase it is trying to say.

## The downloads link points at a repository name that is not this one

The installation section calls a page on the releases area the preferred method and then offers no command for it, on the reasoning that the downloads are there. The one install command in the document is a Homebrew tap:
```bash
brew install hofstadter-io/tap/hof
hof --help
hof version
```
The link itself has a small problem: the path it points to uses a dotted form of the organisation name rather than the hyphenated one the repository actually uses, so the preferred method is a link that does not resolve to this project. For an existing installation, a specific version is requested through the tool's own update command with a version argument, written with the same tag prefix the releases use. So the three documented paths are a page that does not link correctly, a package manager line, and a self-update that can only fetch what the tool knows how to retrieve.

## The completion line installs bash completions into a profile nothing else reads

The shell snippet is presented as covering four shells: bash, zsh, fish and PowerShell. What it actually runs is the bash completion generator, appended to a profile file in the user's home directory, followed by sourcing that file. On a Linux system that works. On a Mac with a default shell of zsh, a profile file of that name is not read, so the completion never loads and the sourcing line does nothing either. The document does not offer the other three invocations even though the comment claims them, so a user on any of those shells has to guess the argument. It is a small thing, and it is the kind of thing that gets fixed by reading the completion command's own help output rather than the readme.

## The documented structure lists six directories out of roughly forty

The project structure section gives six entries: the continuous integration scripts, the main command entrypoint, the documentation site source, the source for the flow command and task engine, the core logic for the subcommands, and the test scripts and data. The actual top level is close to forty entries and includes all six. It also includes a second documentation tree kept alongside the current one, a design directory, a notes directory, a directory of reproduction cases, a schemas directory, a catalog directory, an extensions directory, a hack directory for tooling, a script directory and an images directory. Two directory names mirror the project's own tool names, and there are two workspace files and two sets of CUE files at the root. The six-item list is a useful summary and a poor map, since the parts a newcomer needs to orient themselves are the ones it leaves out.

## Two tool identities and a help listing that stops mid-word

The repository carries a second name alongside its own. There are two state directories named after the two tools, two editor workspace files, and a CUE file for each at the root, which suggests one codebase serving two tools with a shared core. The readme only ever describes one of them, so the second appears in the layout and nowhere in the prose. The command line listing has the same problem in a different form. It is a pasted copy of the help output, and the last entry visible is a format command whose description is cut off mid-word. What that tells a reader is that the listing was captured from a terminal at some point and pasted without finishing, which means the command list in the readme is both incomplete and behind whatever the binary now prints.

## Three dagger modules, two glob libraries and two SQL drivers

The Go module's requirement block is worth reading as an inventory. Dagger, the tool that provides the container environments, appears three times under three import paths and at three versions, one of them a pseudo-version built from a commit rather than a tag. Glob matching is doubled, with one modern doublestar library and one older minimal one. Database access is doubled too, with a Postgres driver and a pure-Go SQLite driver. A test framework sits in the main requirement block rather than in a test-only group, which is a convention rather than a fault. The module also depends on a sibling package published by the same organisation at version 1.0.0, so part of this tool is maintained outside this repository. The interpreter line is pinned to a patch release, which is stricter than most projects need and consistent with the three executable build targets the readme documents for contributors:
```bash
make build
make test
make docs-serve
```

## An unfinished note is still in the readme, and so is a misspelling

Three small editorial artefacts survive in the front page, which is unusual for a project with this much documentation. There is an HTML comment left in place containing a half-written note about a source of truth, a unified abstraction and interoperability, with two of the three words misspelled. The feature table misspells bootstrapping. And the table itself has two columns with an empty header over the second one, with the ASCII formula in the code-generation row reading as an unfinished sketch rather than a description. On releases, the two newest tags are pre-release builds of the same line from January, and the last non-alpha tag is from December 2024, so the history reads as one stable line ending and a pre-release line that started and then went quiet.

## Conclusion

Read it as an alpha with a real design behind it, not as a stable tool, since the newest releases are pre-release builds from January and the last non-alpha is from December 2024. Decide on CUE before anything else, because every feature the project offers is built on it and the schemas are its unit of work. If you plan to change its continuous integration, note that those workflows are generated by the tool itself, and check the licence question against the package manifest rather than the repository page before you redistribute anything.

## FAQ

### What is hof?

A Go command line tool described as unifying data models, schemas, code generation and a task engine, built on CUE. It has two interfaces: a command line aimed at scripting and automation, and a terminal interface aimed at exploring and designing.

### How do I install hof?

The document calls a downloads page the preferred method but gives no command for it, and the link uses a dotted form of the organisation name that does not match the repository. The one command shown is a Homebrew tap install, and an existing installation can request a specific version through an update command taking a version argument.

### What does running make with no arguments do in the hof repository?

It prints the Makefile, because the help target is the first target and its recipe is to print that file. Since the Makefile's first line includes another file that holds most of the real targets, the printed output shows the wrapper rather than the full list of what you can build.

### How does hof generate its own GitHub Actions workflows?

Through its Makefile: each CUE file under the continuous integration directory is passed to the project's own export command and written out as a workflow file. The dev container configuration is generated the same way, so changing either one requires a working hof binary.

### Which licence does hof use?

The repository metadata and the closing section of the readme both say Apache 2.0 and point at the licence file. The Node manifest at the repository root declares ISC instead, which is the value a package index would show.

## Sources

- [hofstadter-io/hof on GitHub](https://github.com/hofstadter-io/hof)
- [License: Apache-2.0](https://github.com/hofstadter-io/hof/blob/_next/LICENSE)
- [Project website](https://hofstadter.io)
- [README](https://github.com/hofstadter-io/hof/blob/_next/README.md)
- [Releases](https://github.com/hofstadter-io/hof/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/hofstadter-io-hof
