okforge
v1.0.12
Published
Open Knowledge Format (OKF) skill for Claude Code — deterministic okf bundle mechanics and a Stop-hook nudge.
Maintainers
Readme
okforge — Open Knowledge Format bundle skill
A Claude Code skill for maintaining a repository's Open Knowledge Format
(OKF) knowledge bundle under .okf/, usable in any repository.
OKF is an open, human- and agent-friendly format for knowledge — the
metadata, context, and curated insight that surrounds a system. A bundle is a
directory of plain markdown files: each concept document carries YAML frontmatter
with a required type, and reserved index.md / log.md files provide listings
and history. If you can cat a file you can read OKF; if you can git clone a
repo you can ship it.
The skill prose lives in dotclaude_folder/skills/ (each
SKILL.md is an instruction file Claude loads, shipped as data and copied into a
target's .claude/ by okforge install); its deterministic mechanics live in
src/ as a small TypeScript CLI. The model writes the prose; the CLI
answers "what is each folder derived from?" and "is the bundle still well-formed?".
Blog series
Two short series on okforge — what it does, and the thinking behind it.
Workflow — a five-step walkthrough, from install to payoff:
- Your Repo Can Document Itself in One Command
- Documentation Is a Derived Artifact. Configure It Like One.
- The Best Doc Reminder Fires Once and Shuts Up
- Make "Are the Docs Current" a CI Check, Not a Vibe
- Markdown in Git Beats a Vector Database for Your Own System's Knowledge
Principles — the why and how behind the design:
- The Most Dangerous Documentation Is the Kind You Don't Trust
- Don't Ask a Model What Code Can Compute
- AI Can Recover What Your Code Does. It Can't Recover Why.
- Your Agent's Knowledge Base Is Probably Overengineered
- I Shipped a Dev Tool in Two Days. The Code Was the Easy Part.
How to install
Run install from the root of the repository you want to add OKF to (Node >=
20.12, no install step — npx fetches it):
npx okforge install .claudeWhen the destination folder is named .claude, this drops the skill prose into
.claude/skills/ and registers the npx okforge nudge Stop hook in
.claude/settings.json (idempotent and non-destructive — existing settings and
hooks are preserved). For any other destination it copies the skills only and
leaves settings.json untouched.
Then write an .okforge.config.json at the project root describing that repo's
folder-to-source mapping (see .okforge.config.json
below), and ask Claude to "set up okf" — or run /okforge-maintain — to scaffold the bundle.
Why a skill
The .okf/ bundle is derived from source — each folder is generated from
specific files, so when those files change the docs drift. The hard parts to keep
consistent are the OKF format, the folder-to-source mapping, and link integrity.
The skill keeps those uniform so you can focus on accurate prose.
What it does
Three modes, chosen from how you ask:
| You say | Mode | What happens |
|---|---|---|
| "set up okf", "create an OKF bundle", bundle missing | scaffold | Creates .okforge.config.json, .okf/index.md (root, with okf_version), .okf/log.md, the folders from the mapping, and refreshes each. |
| "the API changed, update okf", "refresh okf for X", "update the OKF docs" | refresh | Reads the current source for the affected folder(s) and regenerates only the docs whose source actually changed, grounded in what it read. |
| "check okf", "is the bundle conformant", "any dead links" | check | Runs the conformance and dead-link lint. |
Invoke it by asking Claude in plain language, or with /okforge-maintain. Regeneration is
model-driven, so refresh is a draft-then-review loop: the skill rewrites the
affected docs, you review them, then commit. It will not silently rewrite docs
whose source did not change.
Automatic capture going forward
A companion Stop hook, npx okforge nudge (registered in
.claude/settings.json), reminds you when a session changed source that an OKF
folder documents but left .okf/ untouched. It is deliberately gentle:
non-blocking, at most once per session, and silent if you already touched .okf/
that session. It reads the same mapping the skill uses (via npx okforge stale),
so the skill and the nudge never diverge.
Where the bundle lives
The bundle is the .okf/ directory at the repository root — a valid OKF bundle is
just a subdirectory of a larger repo, so there is no build step or manifest beyond
okf_version in the root .okf/index.md. The folder-to-source mapping lives next
to it in .okforge.config.json at the project root.
Usable in any repository: .okforge.config.json
okforge ships with no repository-specific paths. Each repo declares its own
folder-to-source mapping in .okforge.config.json at the project root:
{
"folders": {
"runtime_concepts": ["packages/foo/src/model/", "packages/foo/src/event/"],
"config_formats": ["packages/foo/data/schemas/thing.schema.json"]
}
}Each key is an OKF concept folder; each value is the list of source path prefixes
that folder is derived from. With no config present, map/folders are empty and
stale is a no-op; check still works, since it lints the bundle's markdown
alone. This is the only project-specific part — both the skill and the nudge read
it from here.
The okforge CLI
The bundled okforge CLI owns the
deterministic mechanics, run with npx (Node >= 20.12). <dir> defaults to the
current directory (the repository root).
| Command | Purpose |
|---|---|
| okforge map [<dir>] | Print the full folder-to-source mapping. |
| okforge folders [<dir>] | List the OKF concept folders. |
| okforge sources <folder> [<dir>] | Print the source paths a folder is derived from. |
| okforge stale [<dir>] | List folders whose source changed since HEAD while the folder was not edited. |
| okforge check [<dir>] | Conformance + dead-link lint; exits non-zero on problems. |
| okforge graph <op> [args] [--bundle <dir>] | Read-only concept-graph queries over a bundle (overview, concept, neighbors, orphans, broken, path), as JSON; powers the okforge-query skill. |
| okforge webview generate [<bundle>] [-o <dir>] | Bake a bundle into a dependency-free static site. <bundle> may be a local dir or an http(s)/GitHub URL (default .okf). |
| okforge webview show [<bundle>] | Generate the site into a temp dir and serve it over HTTP until interrupted. |
| okforge nudge | Stop-hook entry: read the hook payload on stdin and maybe remind. |
| okforge install [<agent_folder>] | Copy the bundled okf skill into an agent folder (default .); when that folder is named .claude, also register the nudge Stop hook in its settings.json. |
check verifies: snake_case names only, every non-index .md has a non-empty
frontmatter type, sub-folder index.md files carry no frontmatter, and every
bundle-relative .md link resolves.
Development
npm install
npm run okforge -- <command> # run the CLI from source via tsx
npm run typecheck # tsc --noEmit
npm run build # compile to dist/ and copy the webview template
npm run symlink:dotclaude # mirror dotclaude_folder/ into .claude/ as symlinks
npm run webview:open # build the .okf webview and open it (also :build / :deploy)You can also run the source directly with npx tsx src/cli.ts <command>.
symlink:dotclaude makes okforge dogfood its own skills: it links each file under
dotclaude_folder/ into .claude/ with a relative symlink, so the okforge-maintain
and okforge-query skills are live in this repo while their tracked source stays in
dotclaude_folder/. It is idempotent and never overwrites a real file (e.g.
.claude/settings.json).
Layout
src/ the okforge CLI (mechanics)
├── cli.ts Commander entry; wires the subcommands below
├── misc/
│ ├── okf_store.ts mapping load, stale detection, conformance lint
│ ├── okf_graph.ts read-only concept-graph model (links, neighbors, orphans, paths)
│ └── okf_fetch.ts download a remote bundle by crawling its markdown links
├── webview/
│ └── template/ static browser app baked into every generated site
└── commands/
├── map_command.ts print the folder-to-source mapping
├── folders_command.ts list the concept folders
├── sources_command.ts print a folder's source paths
├── stale_command.ts folders whose source changed since HEAD
├── check_command.ts conformance + dead-link lint
├── graph_command.ts concept-graph queries for the okforge-query skill
├── webview_command.ts generate/serve the static webview
├── nudge_command.ts the Stop-hook nudge
└── install_command.ts copy the skills into a target agent folder
dotclaude_folder/ data shipped to a target's .claude/ by `okforge install`
└── skills/
├── okforge-maintain/
│ └── SKILL.md maintain the bundle (scaffold / refresh / check)
└── okforge-query/
├── SKILL.md read-only browser for any OKF bundle
└── references/okf-rules.md OKF v0.1 rules the browser encodes
contribs/ optional extensions, not part of the npm package
└── webview/ GitHub Pages deploy tooling + generated dist/Conventions
- File and folder names are snake_case. No kebab-case, no spaces.
- Every non-index
.mdis a concept document: YAML frontmatter with a non-emptytype, then structural markdown (headings, lists, tables, code) using the conventional# Schema/# Examples/# Citationssections where they apply. index.mdis reserved and carries no frontmatter — except the root.okf/index.md, which declaresokf_version: "0.1"andtype: Bundle Index.- Cross-link concepts with relative markdown paths from the doc
(
../runtime_concepts/job_store.md,./sibling.md) — not bundle-root absolute paths; cite real source files with repo-relative paths (../../packages/...). - Ground every claim in real source. Do not invent fields, routes, flags, or states; if uncertain, omit.
License
MIT © Jerome Etienne
