okf-catalog 0.1.1 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,19 @@
|
|
|
2
2
|
|
|
3
3
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/). The version in `package.json` names the release. 0.1.0 was published on 2026-10-07, before the clean-account run of the acceptance list in `docs/acceptance/version-0.md`, by the maintainer's choice; what that run finds goes into a later patch release.
|
|
4
4
|
|
|
5
|
+
## [0.1.3] - 2026-10-07
|
|
6
|
+
|
|
7
|
+
### Fixed
|
|
8
|
+
|
|
9
|
+
- The publish recipe (`recipes/publish/publish.yml`, the file a company copies) installs the server from npm at the exact version it came from, on Node 24, the line the CLI requires; it used to name a placeholder git commit and Node 22, on which the installed CLI refuses to run. Its actions are pinned to their current releases, and the recipe's README no longer describes a shipped lock file.
|
|
10
|
+
- `pack.sh`'s second okflint pass, on the packed folder, crashed okflint 0.5.0 with a Python error because the manifest's root does not cover that folder; the integration test's stub checkers could not see it. The pass now runs on a copy of the manifest beside a copy of the pack at the manifest's first root path. Found by running the real checkers on the acceptance fixture bundle.
|
|
11
|
+
|
|
12
|
+
## [0.1.2] - 2026-10-07
|
|
13
|
+
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- The README carries the npm badge, the measured install size and how releases are published. This is the first version published by the release workflow itself, through npm's trusted publishing with a provenance statement; the code is that of 0.1.1.
|
|
17
|
+
|
|
5
18
|
## [0.1.1] - 2026-10-07
|
|
6
19
|
|
|
7
20
|
### Fixed
|
package/README.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# okf-catalog
|
|
2
2
|
|
|
3
|
+
[](https://www.npmjs.com/package/okf-catalog)
|
|
4
|
+
|
|
3
5
|
A small-company hosted knowledge catalog for AI agents.
|
|
4
6
|
|
|
5
7
|
okf-catalog is an MCP server that serves a company's [Open Knowledge Format](https://github.com/GoogleCloudPlatform/open-knowledge-format) bundle to agents. It runs on a developer's machine today and from a cheap cloud recipe later, so that local coding agents (Claude Code, Codex, Grok Build) and the web versions of Claude and ChatGPT answer from the same cited knowledge.
|
|
6
8
|
|
|
7
9
|
What it adds: **qmd done right for OKF.** [qmd](https://github.com/tobi/qmd) is the best Markdown search engine there is. okf-catalog makes it understand OKF's fields: titles, descriptions and tags ranked as they should be, status and recheck dates respected, trust and provenance returned with every answer, deprecated pages pointing to their replacements.
|
|
8
10
|
|
|
9
|
-
**Status: version 0 (0.1.
|
|
11
|
+
**Status: version 0 (0.1.2) on npm, not yet accepted.** Every item of the version 0 acceptance list that a test can prove is proven on every run; the items that need a person on a clean account (a signed-in Claude Code answering from a bundle, a real publish, the network off) are pending, with their runbook in [docs/acceptance/version-0.md](docs/acceptance/version-0.md). The package is public on npm as `okf-catalog`; releases are tagged `v<version>` and published by the repository's release workflow through npm's trusted publishing, each with a provenance statement, and `CHANGELOG.md` has the entries. The licence is Apache-2.0 (decision D1). Start with [docs/intent.md](docs/intent.md); the implementation plan and its execution record are under [docs/plans/](docs/plans/).
|
|
10
12
|
|
|
11
13
|
## Quickstart
|
|
12
14
|
|
|
@@ -23,7 +25,7 @@ git clone https://github.com/drathm/okf-catalog.git && cd okf-catalog
|
|
|
23
25
|
NODE_LLAMA_CPP_SKIP_DOWNLOAD=1 npm ci
|
|
24
26
|
```
|
|
25
27
|
|
|
26
|
-
`npm ci` builds `dist/` on its way out (the `prepare` script), and the flag keeps qmd's native dependency from downloading or compiling anything: lexical mode needs no model. Check the install and a bundle (`node dist/cli.js` in a checkout stands in for `okf-catalog`, or `npm install -g .` puts the command on PATH):
|
|
28
|
+
`npm ci` builds `dist/` on its way out (the `prepare` script), and the flag keeps qmd's native dependency from downloading or compiling anything: lexical mode needs no model. Either install pulls about 230 MB of dependencies, most of it qmd's search engine and its native packages. Check the install and a bundle (`node dist/cli.js` in a checkout stands in for `okf-catalog`, or `npm install -g .` puts the command on PATH):
|
|
27
29
|
|
|
28
30
|
```bash
|
|
29
31
|
okf-catalog --version
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okf-catalog",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "An MCP server that serves a company's Open Knowledge Format (OKF) bundle to AI agents, with citations, provenance and a publish loop: qmd done right for OKF.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"okf",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "okf-catalog",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "Serves a company's Open Knowledge Format bundle to Claude: search, read pages whole, cite path, trust and recheck date. Needs the okf-catalog command on PATH (npm install -g okf-catalog) and an okf-catalog.yaml in the project folder or named by OKF_CATALOG_CONFIG.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "Bitfusion PR LLC",
|
|
@@ -4,10 +4,10 @@ The server reads a `published` branch: the admitted pages, their index files and
|
|
|
4
4
|
|
|
5
5
|
## What runs
|
|
6
6
|
|
|
7
|
-
1. `pack.sh` runs the OKF checkers you enable on the bundle folder, runs `okf-catalog pack`, and runs them again on the packed folder. It prints the commit it recorded. It never pushes. The checkers are the company's gates, each switched on by a setting: `OKFLINT_MANIFEST` names okflint's own manifest file (okflint 0.5.0 exits 2 without one, so it is left out when unset); `OKF_SCHEMA` is `1`, or `strict` to fail on warnings, or empty to leave okf-schema out. Note that okf-schema 0.12.0 fails the specification's own example bundle (its `log.md` carries frontmatter, which that checker calls an error), so whether to run it is your call; `okf-catalog pack` itself applies the intake contract either way.
|
|
7
|
+
1. `pack.sh` runs the OKF checkers you enable on the bundle folder, runs `okf-catalog pack`, and runs them again on the packed folder. It prints the commit it recorded. It never pushes. okflint 0.5.0 resolves its manifest's roots against the manifest's folder and fails on a folder outside them, so the second okflint pass runs on a copy of the manifest beside a copy of the pack placed at the manifest's first root path; that root must be a relative path (`kb`, `../kb`), which is how the manifests in the wild are written. The checkers are the company's gates, each switched on by a setting: `OKFLINT_MANIFEST` names okflint's own manifest file (okflint 0.5.0 exits 2 without one, so it is left out when unset); `OKF_SCHEMA` is `1`, or `strict` to fail on warnings, or empty to leave okf-schema out. Note that okf-schema 0.12.0 fails the specification's own example bundle (its `log.md` carries frontmatter, which that checker calls an error), so whether to run it is your call; `okf-catalog pack` itself applies the intake contract either way.
|
|
8
8
|
2. `push.sh` commits the packed folder onto the published branch, with the current tip as the parent, and pushes without force. A push that loses a race is rejected and the next run follows. It stages the files as plain blobs with git's plumbing (`hash-object --no-filters`, `update-index`), so no line-ending rule, filter or ignore rule of the machine it runs on can change the bytes `pack` hashed. The commit message carries the source commit through a variable; no event text ever reaches a shell.
|
|
9
9
|
|
|
10
|
-
`publish.yml` is the GitHub Actions workflow, and the only file a company copies: to `.github/workflows/publish.yml` in the repository that holds the bundle. The scripts and the checker lock travel inside the server package, which the workflow installs from
|
|
10
|
+
`publish.yml` is the GitHub Actions workflow, and the only file a company copies: to `.github/workflows/publish.yml` in the repository that holds the bundle. The scripts and the checker lock travel inside the server package, which the workflow installs from npm at the exact version the file came from (`OKF_CATALOG_SOURCE`, `okf-catalog@<version>`) and finds under `npm root -g`. Set the values under `env`: the bundle folder (`BUNDLE_PATH`, the folder with the pages, never the repository root), the configuration file (`CONFIG_PATH`), the published branch's name, the checker settings, and `OKF_CATALOG_SOURCE`. Set the source branch under `on.push.branches`; it must never be the published branch, or the workflow would run on its own push.
|
|
11
11
|
|
|
12
12
|
The workflow has two jobs. `build` holds `contents: read` only and does not keep the checkout's credentials, so the third-party code it installs (the checkers, the server package) never sees a write token; it hands the packed bundle over as one archive, so file names the artifact store would refuse travel untouched. `publish` holds `contents: write` and runs git alone. Every action is pinned to a commit, as is `uv`. One run at a time: a running one is never cancelled, and a queued one is replaced by a newer queued one.
|
|
13
13
|
|
|
@@ -15,7 +15,7 @@ The workflow has two jobs. `build` holds `contents: read` only and does not keep
|
|
|
15
15
|
|
|
16
16
|
- A ruleset or branch protection that lets the workflow push `published` and nothing else. The `contents: write` permission is repository-wide, so the rule is what limits it.
|
|
17
17
|
- Protection on the source branch as the company sees fit; the workflow only reads it.
|
|
18
|
-
- The checkers' versions are in `checkers.txt`; `checkers.lock` is their hash-pinned resolution, which the workflow installs with `--require-hashes` into a Python 3.12 environment, the interpreter the lock was built for. Regenerate the lock after changing a version (the command is in `checkers.txt`). The server package
|
|
18
|
+
- The checkers' versions are in `checkers.txt`; `checkers.lock` is their hash-pinned resolution, which the workflow installs with `--require-hashes` into a Python 3.12 environment, the interpreter the lock was built for. Regenerate the lock after changing a version (the command is in `checkers.txt`). The server package is installed at an exact version from npm; every published version carries a provenance statement that ties it to its source commit and its build on GitHub Actions, and `npm audit signatures` verifies it. Unpinned: the runner's Node is whatever `setup-node` gives for "24", the line the server requires.
|
|
19
19
|
|
|
20
20
|
## Running by hand
|
|
21
21
|
|
package/recipes/publish/pack.sh
CHANGED
|
@@ -4,7 +4,8 @@
|
|
|
4
4
|
#
|
|
5
5
|
# usage: pack.sh --config <path> --source <bundle folder> --out <folder> [--commit <sha>]
|
|
6
6
|
# needs: sh, git, okf-catalog (or OKF_CATALOG_BIN, such as "node dist/cli.js"), and the checkers you enable on PATH.
|
|
7
|
-
# settings: OKFLINT_MANIFEST (okflint's manifest file; unset leaves okflint out),
|
|
7
|
+
# settings: OKFLINT_MANIFEST (okflint's manifest file, whose first root is a relative path; unset leaves okflint out),
|
|
8
|
+
# OKF_SCHEMA (1, strict, or unset).
|
|
8
9
|
set -eu
|
|
9
10
|
|
|
10
11
|
usage() {
|
|
@@ -49,7 +50,27 @@ fi
|
|
|
49
50
|
# shellcheck disable=SC2086
|
|
50
51
|
$OKF_CATALOG_BIN pack --config "$CONFIG" --from "$SOURCE" --out "$OUT" --commit "$COMMIT" >&2
|
|
51
52
|
if [ -n "${OKFLINT_MANIFEST:-}" ]; then
|
|
52
|
-
okflint
|
|
53
|
+
# okflint 0.5.0 resolves the manifest's roots against the manifest's own folder and fails (a Python error) on a
|
|
54
|
+
# target outside them, so the packed folder is checked through a copy of the manifest in a scratch folder that
|
|
55
|
+
# holds a copy of the pack at the manifest's first root path. The root must be relative; the copy of the manifest
|
|
56
|
+
# sits four folders deep so that a root such as ../kb still lands inside the scratch folder.
|
|
57
|
+
ROOT_REL=$(sed -n 's/^[[:space:]]*-[[:space:]]*path:[[:space:]]*//p' "$OKFLINT_MANIFEST" | head -n 1 \
|
|
58
|
+
| sed 's/[[:space:]]*#.*$//; s/^["'"'"']//; s/["'"'"']$//; s/[[:space:]]*$//; s|/*$||')
|
|
59
|
+
case "$ROOT_REL" in
|
|
60
|
+
""|/*) echo "pack.sh: the okflint manifest's first root must be a relative path (found '${ROOT_REL}')" >&2; exit 2 ;;
|
|
61
|
+
esac
|
|
62
|
+
MIRROR=$(mktemp -d "${TMPDIR:-/tmp}/okf-catalog-okflint.XXXXXX")
|
|
63
|
+
trap 'rm -rf "$MIRROR"' EXIT
|
|
64
|
+
MIRROR_DIR="$MIRROR/.m/.m/.m/.m"
|
|
65
|
+
MIRROR_ROOT="$MIRROR_DIR/$ROOT_REL"
|
|
66
|
+
mkdir -p "$MIRROR_DIR" "$MIRROR_ROOT"
|
|
67
|
+
cp "$OKFLINT_MANIFEST" "$MIRROR_DIR/"
|
|
68
|
+
cp -R "$OUT"/. "$MIRROR_ROOT"/
|
|
69
|
+
case "$(cd "$MIRROR_ROOT" && pwd -P)" in
|
|
70
|
+
"$(cd "$MIRROR" && pwd -P)"/*) ;;
|
|
71
|
+
*) echo "pack.sh: the okflint manifest's first root '${ROOT_REL}' leaves the scratch folder" >&2; exit 2 ;;
|
|
72
|
+
esac
|
|
73
|
+
okflint validate --manifest "$MIRROR_DIR/$(basename "$OKFLINT_MANIFEST")" "$MIRROR_ROOT" >&2
|
|
53
74
|
fi
|
|
54
75
|
if [ "${OKF_SCHEMA:-}" = 1 ]; then
|
|
55
76
|
okf-schema validate --path "$OUT" >&2
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Copy this file into the repository that holds the company's bundle, as .github/workflows/publish.yml, and set the
|
|
2
|
-
#
|
|
2
|
+
# values under `env`. It runs on a push to the source branch, never on the published branch; a read-only job
|
|
3
3
|
# checks and packs, and a second job with the write token runs git alone. See README.md beside this file.
|
|
4
4
|
name: publish knowledge bundle
|
|
5
5
|
|
|
@@ -22,8 +22,9 @@ env:
|
|
|
22
22
|
# strict to fail on warnings, or empty to leave okf-schema out.
|
|
23
23
|
OKFLINT_MANIFEST: okf-base.yaml
|
|
24
24
|
OKF_SCHEMA: "1"
|
|
25
|
-
# The server package from
|
|
26
|
-
|
|
25
|
+
# The server package from npm, at the exact version this file came from. Every published version carries a
|
|
26
|
+
# provenance statement that ties it to its source commit and its build (`npm audit signatures` verifies it).
|
|
27
|
+
OKF_CATALOG_SOURCE: "okf-catalog@0.1.3"
|
|
27
28
|
|
|
28
29
|
jobs:
|
|
29
30
|
build:
|
|
@@ -33,19 +34,19 @@ jobs:
|
|
|
33
34
|
outputs:
|
|
34
35
|
commit: ${{ steps.pack.outputs.commit }}
|
|
35
36
|
steps:
|
|
36
|
-
- uses: actions/checkout@
|
|
37
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
37
38
|
with:
|
|
38
39
|
persist-credentials: false
|
|
39
|
-
- uses: actions/setup-node@
|
|
40
|
+
- uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
|
|
40
41
|
with:
|
|
41
|
-
node-version: "
|
|
42
|
-
- uses: astral-sh/setup-uv@
|
|
42
|
+
node-version: "24"
|
|
43
|
+
- uses: astral-sh/setup-uv@c18668ad3cf93ea998bef934396af7bb5c839dc7 # v10.2.0
|
|
43
44
|
with:
|
|
44
|
-
version: "0.
|
|
45
|
+
version: "0.12.23"
|
|
45
46
|
- name: install the server package from its pinned source, then the checkers from its lock
|
|
46
47
|
run: |
|
|
47
|
-
# The server package carries the recipe's scripts and the hash-pinned checker lock; this
|
|
48
|
-
# only thing a company copies.
|
|
48
|
+
# The server package carries the built code, the recipe's scripts and the hash-pinned checker lock; this
|
|
49
|
+
# file is the only thing a company copies. Nothing compiles on the runner.
|
|
49
50
|
NODE_LLAMA_CPP_SKIP_DOWNLOAD=1 npm install --global "$OKF_CATALOG_SOURCE"
|
|
50
51
|
RECIPE="$(npm root -g)/okf-catalog/recipes/publish"
|
|
51
52
|
echo "RECIPE=$RECIPE" >> "$GITHUB_ENV"
|
|
@@ -61,7 +62,7 @@ jobs:
|
|
|
61
62
|
# push.sh rides along, so the publish job installs nothing and runs git alone.
|
|
62
63
|
cp "$RECIPE/push.sh" "$RUNNER_TEMP/push.sh"
|
|
63
64
|
tar -C "$RUNNER_TEMP" -cf "$RUNNER_TEMP/bundle.tar" bundle push.sh
|
|
64
|
-
- uses: actions/upload-artifact@
|
|
65
|
+
- uses: actions/upload-artifact@cf430e030ddbb5b0abf93d22962f4752f3646cd9 # v7.0.2
|
|
65
66
|
with:
|
|
66
67
|
name: bundle
|
|
67
68
|
path: ${{ runner.temp }}/bundle.tar
|
|
@@ -73,10 +74,10 @@ jobs:
|
|
|
73
74
|
permissions:
|
|
74
75
|
contents: write
|
|
75
76
|
steps:
|
|
76
|
-
- uses: actions/checkout@
|
|
77
|
+
- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
|
|
77
78
|
with:
|
|
78
79
|
fetch-depth: 1
|
|
79
|
-
- uses: actions/download-artifact@
|
|
80
|
+
- uses: actions/download-artifact@9000827ccba6bdab643e8b6fd33ac0654aef8333 # v8.0.2
|
|
80
81
|
with:
|
|
81
82
|
name: bundle
|
|
82
83
|
path: ${{ runner.temp }}
|