Repository navigation
Development
github-actions[bot] edited this page Oct 7, 2026
·
7 revisions
mise install # Node 24, pnpm 11
pnpm install
pnpm typecheck
pnpm lint # biome check: lint, formatting, import order; warnings fail
pnpm format # biome check --write: apply formatting and import order
pnpm test # unit, service (real git in temp dirs), and end-to-end suites
pnpm build # server to dist/, web UI to dist/uiWork on the web UI with hot reload: run a server on 127.0.0.1:8080 (for example pnpm build && node dist/cli.js serve --no-auth), then pnpm dev:web and open http://localhost:5173/ui/; Vite proxies /api, /.well-known, and /ui/config.json to the server. Without dist/ui the server starts with a warning and no /ui.
Run the npm CLI from a checkout:
pnpm build && node dist/cli.js --data-dir "$(mktemp -d)"Layout:
| Path | Responsibility |
|---|---|
src/okf/ |
Pure OKF logic: frontmatter round-trip, semantics, paths, links, index/log rendering, lint |
src/store/ |
Git, filesystem, catalog + search index, archives, remote sync |
src/service/ |
KnowledgeService: one method per operation, shared by MCP and REST |
src/auth/ |
OIDC discovery, JWT verification, bearer challenges |
src/mcp/, src/http/
|
MCP tools and REST routes |
src/server.ts |
Wiring: startServer (HTTP) and startLocalHost (local endpoint host) |
src/main.ts |
Container entry point |
src/cli.ts, src/cli-options.ts
|
npm CLI (ok-fine): stdio and serve
|
src/data-dir-lock.ts |
One CLI process per data directory |
src/http/ui.ts |
Serves the built web UI (dist/ui) from memory at /ui/ with its CSP and client config |
src/dev/ |
Development token issuer |
web/ |
Read-only web UI (React, Vite, Tailwind); built into dist/ui, talks only to /api/v1
|
charts/ok-fine/ |
Helm chart |
agents/ |
Agent package (skills, reminder hooks, pi/omp extension, harness manifests); mirrored to ferrule-io/ok-fine-agents
|
wiki/ |
GitHub wiki source; mirrored to the repository wiki on release |
-
Push to
developmentand PRs intodevelopment/mainrun.github/workflows/ci.yml:pnpm typecheck,pnpm lint,pnpm test,pnpm build,helm lint --strict, and (pushes todevelopmentonly) cache-warming Docker builds foramd64andarm64on native runners. Release skips these builds because it builds the real images itself. -
Push to
mainruns.github/workflows/release.yml: runs CI, then theplanjob computes next version (patch+1 over max ofChart.yamlversion and latestvX.Y.Ztag) and creates, without pushing, the commitchore(release): vX.Y.Zbumping server versions (charts/ok-fine/Chart.yamlversion + appVersion,package.json,src/version.ts) and, only whenagents/,scripts/build-claude-plugin.ts, orLICENSEchanged since the release tagged with the current agent version (v<agents/package.json version>), the agent manifests (agents/package.json,agents/plugin.json,agents/gemini-extension.json,agents/.claude-plugin/plugin.json), plus its tag, handed to later jobs as agit bundleartifact. The agent version can therefore lag the server version, but the four agent manifests always share one version (never hand-edit them). The per-arch images build natively from that exact commit and push by digest; only after both succeed doesrelease-commitatomically push the commit tomainwith its tag, so a failed image build leaves no tag. Then the images are merged into a multi-arch manifest (tagsX.Y.Z,sha-<short>, andlatestonly when it is the highest release), the chart is pushed tooci://ghcr.io/ferrule-io/charts, and the release commit is merged back intodevelopment(fails rather than force-pushing on conflict). Reruns reuse the existing release commit/tag. -
Agent package: the
agentsjob publishes the mirror (commit + tagv<agent version>) only when the mirror lacks that tag, and pushes mirrormainonly when that tag is the highest in the mirror (releases without plugin changes publish nothing toferrule-io/ok-fine-agents). When publishing, it replaces the contents offerrule-io/ok-fine-agentswithagents/plusLICENSE, generates the Claude Code plugin rootclaude-code/withscripts/build-claude-plugin.ts(the Claude manifest, skills, hook script, and ahooks.jsonwithout Gemini-only events, for Claude Desktop's stricter marketplace sync), commits, tagsv<agent version>, and pushes. CI runs the same script. The mirror is generated output; editagents/here. Reruns skip an existing tag. -
npm package: the
npmjob builds and publishes@ferrule-io/ok-finewith provenance via npm trusted publishing (OIDC, no token); the dist-tag islatestonly for the highest release,previousotherwise. Reruns skip a published version. -
Wiki: the
wikijob replaces the contents of the repository wiki withwiki/and commits only when something changed (highest release only). The wiki is generated output; editwiki/here. Prerequisite: save any first page in the wiki UI once so GitHub creates the wiki repository; until then only thewikijob fails. -
One release per run of pushes: releases are serialized (
concurrency: release). A push that lands while a release is running supersedes older queued pushes, and a run whose commit is no longermain's head fails withmain moved past <sha>; the newest push releases everything since the last tag, with a single patch bump. -
Prerequisites: if
main/developmenthave branch protection or rulesets, allow GitHub Actions to push to them; make the GHCRok-fineandcharts/ok-finepackages public after the first release. For the agent package, create the public repositoryferrule-io/ok-fine-agentswith an initial commit onmain, add a deploy key with write access there, and store its private key as theAGENTS_DEPLOY_KEYsecret in this repository; until then only theagentsjob fails. For the npm package, publish the first version manually from a release checkout (pnpm install && pnpm build && npm publish --access public), then in the package's npm Settings → Trusted publishing add GitHub Actions with organizationferrule-io, repositoryok-fine, workflowrelease.yml, allowingnpm publish; until then only thenpmjob fails. -
Caching: buildx GHA cache per arch shared by CI and release (
mainreads caches from the default branchdevelopment), mise toolchain cache, and pnpm store cache keyed onpnpm-lock.yaml.
Generated from wiki/ in ferrule-io/ok-fine on every release. Edit pages there; changes made in the wiki UI are overwritten.