okf-cli 0.1.2__tar.gz → 0.4.1__tar.gz
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.
- okf_cli-0.4.1/.github/workflows/test.yml +17 -0
- okf_cli-0.4.1/.last-update.json +5 -0
- okf_cli-0.4.1/AGENTS.md +205 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/OKF_SPEC.md +27 -27
- okf_cli-0.4.1/PKG-INFO +257 -0
- okf_cli-0.4.1/README.md +226 -0
- okf_cli-0.4.1/example/.okfignore +3 -0
- okf_cli-0.4.1/example/loose/deep/no-heading.md +4 -0
- okf_cli-0.4.1/example/loose/no-desc.md +6 -0
- okf_cli-0.4.1/example/loose/no-title.md +5 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/example/playbooks/incident-response.md +3 -3
- okf_cli-0.4.1/example/smoke-ignore.md +5 -0
- okf_cli-0.4.1/example/tables/customers.md +16 -0
- okf_cli-0.4.1/example/tables/orders.md +17 -0
- okf_cli-0.4.1/example/tables/partitions/daily.md +12 -0
- okf_cli-0.4.1/openwiki/architecture.md +72 -0
- okf_cli-0.4.1/openwiki/domain-model.md +108 -0
- okf_cli-0.4.1/openwiki/operations.md +60 -0
- okf_cli-0.4.1/openwiki/quickstart.md +40 -0
- okf_cli-0.4.1/openwiki/testing.md +61 -0
- okf_cli-0.4.1/openwiki/workflows.md +104 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/pyproject.toml +10 -4
- okf_cli-0.4.1/skills/okf-cli-manual/SKILL.md +110 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/SKILL.md +127 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/README.md +12 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/datasets/sales.md +7 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/domain.md +6 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/loose/deep/no-heading.md +4 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/loose/no-desc.md +6 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/loose/no-title.md +5 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/playbooks/incident-response.md +14 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/playbooks/oncall-guide.md +13 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/tables/customers.md +16 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/tables/orders.md +16 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/tables/partitions/2026/q1/jan/january.md +5 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/example/tables/partitions/daily.md +12 -0
- okf_cli-0.4.1/skills/writing-knowledge-base/reference/knowledge-base.md +65 -0
- okf_cli-0.4.1/src/okf/cli.py +45 -0
- okf_cli-0.4.1/src/okf/commands/__init__.py +0 -0
- okf_cli-0.4.1/src/okf/commands/bundle.py +307 -0
- okf_cli-0.4.1/src/okf/commands/list.py +41 -0
- okf_cli-0.4.1/src/okf/commands/show.py +53 -0
- okf_cli-0.4.1/src/okf/commands/validate.py +47 -0
- okf_cli-0.4.1/src/okf/core.py +188 -0
- okf_cli-0.4.1/tests/cli/test_bundle.py +459 -0
- okf_cli-0.4.1/tests/cli/test_list.py +93 -0
- okf_cli-0.4.1/tests/cli/test_show.py +90 -0
- okf_cli-0.4.1/tests/cli/test_validate.py +225 -0
- okf_cli-0.4.1/tests/e2e/test_e2e.py +840 -0
- okf_cli-0.4.1/tests/test_core.py +216 -0
- okf_cli-0.4.1/uv.lock +238 -0
- okf_cli-0.1.2/PKG-INFO +0 -156
- okf_cli-0.1.2/README.md +0 -126
- okf_cli-0.1.2/example/tables/customers.md +0 -16
- okf_cli-0.1.2/example/tables/orders.md +0 -16
- okf_cli-0.1.2/example/tables/partitions/daily.md +0 -12
- okf_cli-0.1.2/src/okf/cli.py +0 -233
- okf_cli-0.1.2/tests/test_cli.py +0 -304
- okf_cli-0.1.2/uv.lock +0 -150
- {okf_cli-0.1.2 → okf_cli-0.4.1}/.gitignore +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/LICENSE +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/example/README.md +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/example/datasets/sales.md +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/example/domain.md +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/example/playbooks/oncall-guide.md +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/example/tables/partitions/2026/q1/jan/january.md +0 -0
- {okf_cli-0.1.2 → okf_cli-0.4.1}/src/okf/__init__.py +0 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
name: Test
|
|
2
|
+
|
|
3
|
+
on: [push, pull_request]
|
|
4
|
+
|
|
5
|
+
jobs:
|
|
6
|
+
test:
|
|
7
|
+
runs-on: ubuntu-latest
|
|
8
|
+
strategy:
|
|
9
|
+
matrix:
|
|
10
|
+
python-version: ["3.11"]
|
|
11
|
+
steps:
|
|
12
|
+
- uses: actions/checkout@v4
|
|
13
|
+
- uses: astral-sh/setup-uv@v3
|
|
14
|
+
with:
|
|
15
|
+
python-version: ${{ matrix.python-version }}
|
|
16
|
+
- run: uv sync
|
|
17
|
+
- run: uv run pytest -q
|
okf_cli-0.4.1/AGENTS.md
ADDED
|
@@ -0,0 +1,205 @@
|
|
|
1
|
+
# AGENTS.md — okf-cli contributor context
|
|
2
|
+
|
|
3
|
+
This file is for AI agents (and humans) picking up work on `okf-cli`.
|
|
4
|
+
|
|
5
|
+
## OpenWiki (read first)
|
|
6
|
+
|
|
7
|
+
This repository has docs in `openwiki/`.
|
|
8
|
+
|
|
9
|
+
Start here:
|
|
10
|
+
|
|
11
|
+
- [OpenWiki quickstart](openwiki/quickstart.md)
|
|
12
|
+
|
|
13
|
+
Then follow links to architecture, workflows, domain model, operations, and testing notes relevant to task.
|
|
14
|
+
|
|
15
|
+
## Project overview
|
|
16
|
+
|
|
17
|
+
`okf-cli` is a Python CLI that converts plain markdown directories into
|
|
18
|
+
[Open Knowledge Format (OKF)](OKF_SPEC.md) bundles and provides tools to
|
|
19
|
+
inspect/validate them.
|
|
20
|
+
|
|
21
|
+
- **Input:** plain `.md` files starting with `# Title` and a `>` description block.
|
|
22
|
+
`bundle` also supports optional `.okfignore` in input root.
|
|
23
|
+
- **Output:** OKF-conformant markdown with YAML frontmatter, per-directory `index.md` files.
|
|
24
|
+
- **Operations:** `bundle`, `list`, `show`, `validate`.
|
|
25
|
+
|
|
26
|
+
## Tech stack
|
|
27
|
+
|
|
28
|
+
- Python 3.11+
|
|
29
|
+
- Package/venv manager: **uv**
|
|
30
|
+
- CLI framework: **typer**
|
|
31
|
+
- YAML parsing: **pyyaml**
|
|
32
|
+
- Tests: **pytest**
|
|
33
|
+
- Lint/format: **ruff** (via `uvx ruff check .` / `uvx ruff format .`)
|
|
34
|
+
- Build: hatchling (configured in `pyproject.toml`)
|
|
35
|
+
|
|
36
|
+
Always use `uv` for dependency sync and running commands:
|
|
37
|
+
|
|
38
|
+
```bash
|
|
39
|
+
uv sync # install/sync deps
|
|
40
|
+
uv run pytest -q # run tests
|
|
41
|
+
uv run okf --help # run CLI
|
|
42
|
+
uv run okf bundle example bundled --default-type reference --force
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Project layout
|
|
46
|
+
|
|
47
|
+
```
|
|
48
|
+
okf-cli
|
|
49
|
+
├── .github/workflows/test.yml # CI (pytest on 3.11)
|
|
50
|
+
├── OKF_SPEC.md # OKF v0.1 specification
|
|
51
|
+
├── README.md # user-facing docs
|
|
52
|
+
├── AGENTS.md # this file
|
|
53
|
+
├── pyproject.toml # project metadata + deps
|
|
54
|
+
├── uv.lock # uv lockfile
|
|
55
|
+
├── src/okf/
|
|
56
|
+
│ ├── cli.py # Typer entrypoint, registers commands
|
|
57
|
+
│ ├── core.py # shared parsing/formatting/conformance
|
|
58
|
+
│ └── commands/
|
|
59
|
+
│ ├── bundle.py # plain markdown → OKF bundle
|
|
60
|
+
│ ├── list.py # list concept IDs
|
|
61
|
+
│ ├── show.py # print concept by ID
|
|
62
|
+
│ └── validate.py # conformance check
|
|
63
|
+
└── tests/test_cli.py # pytest suite
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
## Architecture
|
|
67
|
+
|
|
68
|
+
### `src/okf/cli.py`
|
|
69
|
+
|
|
70
|
+
- Creates the `typer.Typer` app named `okf`.
|
|
71
|
+
- Registers `bundle`, `list`, `show`, `validate`.
|
|
72
|
+
- No business logic here.
|
|
73
|
+
|
|
74
|
+
### `src/okf/core.py`
|
|
75
|
+
|
|
76
|
+
- `RESERVED` — filenames `bundle` skips: `index.md`, `log.md`, `README.md`.
|
|
77
|
+
- `SPEC_RESERVED` — filenames reserved by the OKF spec: `index.md`, `log.md`.
|
|
78
|
+
- `build_frontmatter(...)` — generates YAML frontmatter using JSON-escaped strings.
|
|
79
|
+
- `parse_md(...)` — extracts title/description/body from plain markdown. Tries strict format first (line 1 `# Title`, `>` block); falls back leniently (title from line 0 only, description from first 80 chars of body). Never raises.
|
|
80
|
+
- `parse_frontmatter(...)` — parses YAML frontmatter with `yaml.safe_load`.
|
|
81
|
+
- `check_conformance(...)` — validates a directory against OKF §9, returns `(errors, warnings)`. Now enforces:
|
|
82
|
+
- §9.1: Non-reserved `.md` must have parseable frontmatter.
|
|
83
|
+
- §9.2: Frontmatter must have non-empty `type`.
|
|
84
|
+
- §9.3: `index.md` must not contain frontmatter (§6), except root `index.md` may have only `okf_version` (§11). `log.md` must not contain frontmatter (§7).
|
|
85
|
+
- Non-UTF-8 files are flagged as errors.
|
|
86
|
+
|
|
87
|
+
### Commands
|
|
88
|
+
|
|
89
|
+
| Command | Input expected | Behavior |
|
|
90
|
+
| ---------- | --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
|
91
|
+
| `bundle` | non-conformant plain markdown dir | generates OKF bundle; skips `index.md`, `log.md`, `README.md` with warnings; skips `.okfignore`-matched files; checks local `.md` links (warn by default, fail with `--strict-links`); root files need `--default-type`; requires `--force` to overwrite existing output |
|
|
92
|
+
| `list` | OKF-conformant bundle | prints concept IDs; exits 1 if dir is not conformant |
|
|
93
|
+
| `show` | OKF-conformant bundle | prints concept file by ID; exits 1 if dir is not conformant |
|
|
94
|
+
| `validate` | any directory | prints conformance errors and summary per §9 |
|
|
95
|
+
|
|
96
|
+
## Key conventions
|
|
97
|
+
|
|
98
|
+
### Reserved filenames
|
|
99
|
+
|
|
100
|
+
- `bundle` treats `index.md`, `log.md`, `README.md` as reserved because it
|
|
101
|
+
often runs against raw repo directories that may contain these files.
|
|
102
|
+
- `list`, `show`, `validate` operate on already-conformant OKF bundles, so
|
|
103
|
+
they only treat `index.md` and `log.md` as reserved per the spec.
|
|
104
|
+
- `README.md` can be a valid concept in an OKF bundle.
|
|
105
|
+
|
|
106
|
+
### Link checks in `bundle`
|
|
107
|
+
|
|
108
|
+
- `bundle` scans markdown body links for local `.md` targets.
|
|
109
|
+
- Supports relative (`./x.md`, `../x.md`) and bundle-root (`/dir/x.md`) links.
|
|
110
|
+
- Ignores external links (scheme URLs like `https:`/`mailto:`), fragment-only links, directory links, and non-`.md` targets.
|
|
111
|
+
- Default behavior: emit warnings for missing local targets or targets outside bundle.
|
|
112
|
+
- `--strict-links`: treat those link issues as fatal and exit non-zero.
|
|
113
|
+
|
|
114
|
+
### `.okfignore` (bundle only)
|
|
115
|
+
|
|
116
|
+
- Location: input directory root (`<input-dir>/.okfignore`).
|
|
117
|
+
- Format: one bundle-relative markdown path per line.
|
|
118
|
+
- Example: `tables/orders.md`, `smoke-ignore.md`
|
|
119
|
+
- Blank lines and lines starting with `#` are ignored.
|
|
120
|
+
- Matching is exact path match only (no glob, no negation).
|
|
121
|
+
- If `.okfignore` is non-UTF-8, `bundle` exits with error.
|
|
122
|
+
|
|
123
|
+
### OKF conformance (§9)
|
|
124
|
+
|
|
125
|
+
1. Every non-reserved `.md` must have parseable YAML frontmatter.
|
|
126
|
+
1. Every frontmatter must contain a non-empty `type` string.
|
|
127
|
+
1. Reserved filenames (`index.md`, `log.md`) follow structure per §6/§7 when present.
|
|
128
|
+
- `index.md` must not contain frontmatter (§6), except root `index.md` may contain only `okf_version` (§11).
|
|
129
|
+
- `log.md` must not contain frontmatter (§7).
|
|
130
|
+
1. All files must be valid UTF-8.
|
|
131
|
+
|
|
132
|
+
`check_conformance()` is the source of truth for this logic.
|
|
133
|
+
|
|
134
|
+
### Frontmatter
|
|
135
|
+
|
|
136
|
+
`build_frontmatter()` outputs JSON-escaped YAML values, e.g.:
|
|
137
|
+
|
|
138
|
+
```yaml
|
|
139
|
+
---
|
|
140
|
+
type: "tables"
|
|
141
|
+
title: "Customer Orders"
|
|
142
|
+
---
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
`parse_frontmatter()` uses `yaml.safe_load()` and returns `None` for missing,
|
|
146
|
+
malformed, or non-dict frontmatter.
|
|
147
|
+
|
|
148
|
+
## Testing
|
|
149
|
+
|
|
150
|
+
Run the full suite before finishing:
|
|
151
|
+
|
|
152
|
+
```bash
|
|
153
|
+
uv run pytest -q
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
Add tests for new behavior in `tests/test_cli.py`. Existing patterns:
|
|
157
|
+
|
|
158
|
+
- Unit tests for `core.py` helpers.
|
|
159
|
+
- CLI integration tests using `typer.testing.CliRunner` and `tmp_path`.
|
|
160
|
+
- Conformance tests for `validate`, `list`, `show`.
|
|
161
|
+
|
|
162
|
+
## Common tasks
|
|
163
|
+
|
|
164
|
+
### Regenerate the example bundle
|
|
165
|
+
|
|
166
|
+
```bash
|
|
167
|
+
uv run okf bundle example bundled --default-type reference --force
|
|
168
|
+
uv run okf bundle example bundled --default-type reference --force --strict-links
|
|
169
|
+
uv run okf validate bundled
|
|
170
|
+
uv run okf list bundled
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
`bundled/` is gitignored; it is only a local artifact. Use `--force` for re-runs.
|
|
174
|
+
If `example/.okfignore` exists, `bundle` will skip matched files.
|
|
175
|
+
|
|
176
|
+
### Add a new CLI command
|
|
177
|
+
|
|
178
|
+
1. Create `src/okf/commands/<name>.py` with a function taking `typer` arguments.
|
|
179
|
+
1. Import and register it in `src/okf/cli.py` with `app.command()(fn)` or
|
|
180
|
+
`app.command("alias")(fn)`.
|
|
181
|
+
1. Add tests in `tests/test_cli.py`.
|
|
182
|
+
|
|
183
|
+
### Modify conformance behavior
|
|
184
|
+
|
|
185
|
+
Update `check_conformance()` in `src/okf/core.py`, then ensure
|
|
186
|
+
`validate`, `list`, and `show` all behave consistently.
|
|
187
|
+
|
|
188
|
+
## Style guidelines
|
|
189
|
+
|
|
190
|
+
- Keep changes minimal. Prefer stdlib/installed dependencies over new ones.
|
|
191
|
+
- Do not add abstractions "for later".
|
|
192
|
+
- Use `Path` from `pathlib`, not string path manipulation.
|
|
193
|
+
- Use `uv` for all package/runtime commands.
|
|
194
|
+
|
|
195
|
+
## OpenWiki
|
|
196
|
+
|
|
197
|
+
This repository has documentation located in the /openwiki directory.
|
|
198
|
+
|
|
199
|
+
Start here:
|
|
200
|
+
|
|
201
|
+
- [OpenWiki quickstart](openwiki/quickstart.md)
|
|
202
|
+
|
|
203
|
+
OpenWiki includes repository overview, architecture notes, workflows, domain concepts, operations, integrations, testing guidance, and source maps.
|
|
204
|
+
|
|
205
|
+
When working in this repository, read the OpenWiki quickstart first, then follow its links to the relevant architecture, workflow, domain, operation, and testing notes.
|
|
@@ -12,7 +12,7 @@ YAML frontmatter. There is no schema registry, no central authority, and
|
|
|
12
12
|
no required tooling. If you can `cat` a file, you can read OKF; if you
|
|
13
13
|
can `git clone` a repo, you can ship it.
|
|
14
14
|
|
|
15
|
-
|
|
15
|
+
______________________________________________________________________
|
|
16
16
|
|
|
17
17
|
## 1. Motivation
|
|
18
18
|
|
|
@@ -33,9 +33,9 @@ of structural conventions needed to make a knowledge corpus
|
|
|
33
33
|
### Goals
|
|
34
34
|
|
|
35
35
|
1. Define a universal format that **enrichment agents** can write into.
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
36
|
+
1. Inform how **consumption agents** should read and traverse it.
|
|
37
|
+
1. Facilitate **exchange** of knowledge across systems and organizations.
|
|
38
|
+
1. Standardize the small number of **required** fields that must be
|
|
39
39
|
present for content to be meaningfully consumed.
|
|
40
40
|
|
|
41
41
|
### Non-goals
|
|
@@ -45,7 +45,7 @@ of structural conventions needed to make a knowledge corpus
|
|
|
45
45
|
- Replacing domain-specific schemas (Avro, Protobuf, OpenAPI, etc.) —
|
|
46
46
|
OKF *references* them; it does not subsume them.
|
|
47
47
|
|
|
48
|
-
|
|
48
|
+
______________________________________________________________________
|
|
49
49
|
|
|
50
50
|
## 2. Terminology
|
|
51
51
|
|
|
@@ -66,7 +66,7 @@ of structural conventions needed to make a knowledge corpus
|
|
|
66
66
|
- **Citation** — A link from a concept to an external source that
|
|
67
67
|
supports a claim in the body.
|
|
68
68
|
|
|
69
|
-
|
|
69
|
+
______________________________________________________________________
|
|
70
70
|
|
|
71
71
|
## 3. Bundle Structure
|
|
72
72
|
|
|
@@ -97,10 +97,10 @@ A bundle MAY be distributed as:
|
|
|
97
97
|
The following filenames have defined meaning at any level of the
|
|
98
98
|
hierarchy and MUST NOT be used for concept documents:
|
|
99
99
|
|
|
100
|
-
| Filename
|
|
101
|
-
|
|
102
|
-
| `index.md`
|
|
103
|
-
| `log.md`
|
|
100
|
+
| Filename | Purpose |
|
|
101
|
+
| ---------- | -------------------------- |
|
|
102
|
+
| `index.md` | Directory listing. See §6. |
|
|
103
|
+
| `log.md` | Update history. See §7. |
|
|
104
104
|
|
|
105
105
|
All other `.md` files are concept documents.
|
|
106
106
|
|
|
@@ -109,7 +109,7 @@ frontmatter field in §4.1. OKF does not specify a separate file format
|
|
|
109
109
|
for aggregating documents by tag; producers that want a tag-browsing
|
|
110
110
|
view can synthesize one at consumption time by scanning frontmatter.
|
|
111
111
|
|
|
112
|
-
|
|
112
|
+
______________________________________________________________________
|
|
113
113
|
|
|
114
114
|
## 4. Concept Documents
|
|
115
115
|
|
|
@@ -117,7 +117,7 @@ Every concept is a UTF-8 markdown file. It has two parts:
|
|
|
117
117
|
|
|
118
118
|
1. A **YAML frontmatter block**, delimited by `---` on its own line at
|
|
119
119
|
the start of the file and a closing `---` on its own line.
|
|
120
|
-
|
|
120
|
+
1. A **markdown body**, containing free-form content.
|
|
121
121
|
|
|
122
122
|
### 4.1 Frontmatter
|
|
123
123
|
|
|
@@ -170,11 +170,11 @@ prose, since structure aids both human reading and agent retrieval.
|
|
|
170
170
|
There are no required body sections. The following section headings have
|
|
171
171
|
**conventional** meaning and SHOULD be used when applicable:
|
|
172
172
|
|
|
173
|
-
| Heading
|
|
174
|
-
|
|
175
|
-
| `# Schema`
|
|
176
|
-
| `# Examples`
|
|
177
|
-
| `# Citations`
|
|
173
|
+
| Heading | Purpose |
|
|
174
|
+
| ------------- | ----------------------------------------------------- |
|
|
175
|
+
| `# Schema` | Structured description of an asset's columns/fields. |
|
|
176
|
+
| `# Examples` | Concrete usage examples, often as fenced code blocks. |
|
|
177
|
+
| `# Citations` | External sources backing claims in the body. See §8. |
|
|
178
178
|
|
|
179
179
|
### 4.3 Example: a concept bound to a resource
|
|
180
180
|
|
|
@@ -228,7 +228,7 @@ its expected SLA. See the [orders table](/tables/orders.md).
|
|
|
228
228
|
2. …
|
|
229
229
|
```
|
|
230
230
|
|
|
231
|
-
|
|
231
|
+
______________________________________________________________________
|
|
232
232
|
|
|
233
233
|
## 5. Cross-linking
|
|
234
234
|
|
|
@@ -266,7 +266,7 @@ Consumers MUST tolerate broken links — a link whose target does not
|
|
|
266
266
|
exist in the bundle is not malformed; it may simply represent
|
|
267
267
|
not-yet-written knowledge.
|
|
268
268
|
|
|
269
|
-
|
|
269
|
+
______________________________________________________________________
|
|
270
270
|
|
|
271
271
|
## 6. Index Files
|
|
272
272
|
|
|
@@ -293,7 +293,7 @@ Entries SHOULD include the description from the linked concept's
|
|
|
293
293
|
frontmatter. Producers MAY generate `index.md` automatically; consumers
|
|
294
294
|
MAY synthesize one on the fly when none is present.
|
|
295
295
|
|
|
296
|
-
|
|
296
|
+
______________________________________________________________________
|
|
297
297
|
|
|
298
298
|
## 7. Log Files (optional)
|
|
299
299
|
|
|
@@ -317,7 +317,7 @@ Date headings MUST use ISO 8601 `YYYY-MM-DD` form. Log entries are
|
|
|
317
317
|
prose; the leading bold word (`**Update**`, `**Creation**`,
|
|
318
318
|
`**Deprecation**`, etc.) is a convention, not a requirement.
|
|
319
319
|
|
|
320
|
-
|
|
320
|
+
______________________________________________________________________
|
|
321
321
|
|
|
322
322
|
## 8. Citations
|
|
323
323
|
|
|
@@ -336,7 +336,7 @@ Citation links MAY be absolute URLs, bundle-relative paths, or paths
|
|
|
336
336
|
into a `references/` subdirectory that mirrors external material as
|
|
337
337
|
first-class OKF concepts.
|
|
338
338
|
|
|
339
|
-
|
|
339
|
+
______________________________________________________________________
|
|
340
340
|
|
|
341
341
|
## 9. Conformance
|
|
342
342
|
|
|
@@ -344,8 +344,8 @@ A bundle is **conformant** with OKF v0.1 if:
|
|
|
344
344
|
|
|
345
345
|
1. Every non-reserved `.md` file in the tree contains a parseable YAML
|
|
346
346
|
frontmatter block.
|
|
347
|
-
|
|
348
|
-
|
|
347
|
+
1. Every frontmatter block contains a non-empty `type` field.
|
|
348
|
+
1. Every reserved filename (`index.md`, `log.md`) follows the structure
|
|
349
349
|
described in §6 and §7 respectively when present.
|
|
350
350
|
|
|
351
351
|
Consumers SHOULD treat all other constraints as soft guidance. In
|
|
@@ -361,7 +361,7 @@ This permissive consumption model is intentional: OKF is meant to
|
|
|
361
361
|
remain useful as bundles grow, get refactored, and are partially
|
|
362
362
|
generated by agents.
|
|
363
363
|
|
|
364
|
-
|
|
364
|
+
______________________________________________________________________
|
|
365
365
|
|
|
366
366
|
## 10. Relationship to other formats
|
|
367
367
|
|
|
@@ -377,7 +377,7 @@ OKF is intentionally close to several established patterns:
|
|
|
377
377
|
OKF differs primarily in being **specified** — pinning down the small
|
|
378
378
|
set of rules needed for interoperability without dictating tooling.
|
|
379
379
|
|
|
380
|
-
|
|
380
|
+
______________________________________________________________________
|
|
381
381
|
|
|
382
382
|
## 11. Versioning
|
|
383
383
|
|
|
@@ -395,7 +395,7 @@ only place frontmatter is permitted in an `index.md`). Consumers that
|
|
|
395
395
|
do not understand the declared version SHOULD attempt best-effort
|
|
396
396
|
consumption rather than refusing the bundle.
|
|
397
397
|
|
|
398
|
-
|
|
398
|
+
______________________________________________________________________
|
|
399
399
|
|
|
400
400
|
## Appendix A — Minimal example bundle
|
|
401
401
|
|
okf_cli-0.4.1/PKG-INFO
ADDED
|
@@ -0,0 +1,257 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: okf-cli
|
|
3
|
+
Version: 0.4.1
|
|
4
|
+
Summary: Open Knowledge Format tooling
|
|
5
|
+
License: MIT License
|
|
6
|
+
|
|
7
|
+
Copyright (c) 2026 Dheerapat Tookkane
|
|
8
|
+
|
|
9
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
10
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
11
|
+
in the Software without restriction, including without limitation the rights
|
|
12
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
13
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
14
|
+
furnished to do so, subject to the following conditions:
|
|
15
|
+
|
|
16
|
+
The above copyright notice and this permission notice shall be included in all
|
|
17
|
+
copies or substantial portions of the Software.
|
|
18
|
+
|
|
19
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
20
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
21
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
22
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
23
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
24
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
25
|
+
SOFTWARE.
|
|
26
|
+
License-File: LICENSE
|
|
27
|
+
Requires-Python: >=3.11
|
|
28
|
+
Requires-Dist: pyyaml>=6
|
|
29
|
+
Requires-Dist: typer>=0.15
|
|
30
|
+
Description-Content-Type: text/markdown
|
|
31
|
+
|
|
32
|
+
# okf-cli — Open Knowledge Format tooling
|
|
33
|
+
|
|
34
|
+
Converts plain markdown into [OKF](https://github.com/GoogleCloudPlatform/knowledge-catalog/blob/main/okf/SPEC.md)-conformant knowledge bundles. Domain experts write `# Title` then `> description` — `okf bundle` generates frontmatter, type, timestamps, and index files. Files without strict formatting are parsed leniently: title from line 0 if present, description from body text.
|
|
35
|
+
|
|
36
|
+
Also validates bundles and lists concept IDs for consumption by other tools.
|
|
37
|
+
|
|
38
|
+
## Install
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
uv tool install okf-cli
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
### Dev quickstart
|
|
45
|
+
|
|
46
|
+
```bash
|
|
47
|
+
uv sync
|
|
48
|
+
uv run okf --help
|
|
49
|
+
```
|
|
50
|
+
|
|
51
|
+
## Commands
|
|
52
|
+
|
|
53
|
+
### `okf bundle` — convert plain markdown to OKF bundle
|
|
54
|
+
|
|
55
|
+
```
|
|
56
|
+
okf bundle <input-dir> [output-dir] [--default-type <name>] [--force] [--strict-links]
|
|
57
|
+
```
|
|
58
|
+
|
|
59
|
+
| Argument | Description |
|
|
60
|
+
| ---------------- | ---------------------------------------------------------------------------- |
|
|
61
|
+
| `input-dir` | Directory of plain `.md` files |
|
|
62
|
+
| `output-dir` | Target directory (default: `bundled`) |
|
|
63
|
+
| `--default-type` | Type for root-level files (skip root files if omitted) |
|
|
64
|
+
| `--force`, `-f` | Overwrite output directory if it exists |
|
|
65
|
+
| `--strict-links` | Fail if local markdown links point outside bundle or to missing `.md` target |
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
okf bundle example --default-type reference # first run → bundled/
|
|
69
|
+
okf bundle example --default-type reference --force # re-run
|
|
70
|
+
okf bundle example --default-type reference --force --strict-links # fail on broken local .md links
|
|
71
|
+
cat bundled/tables/orders.md
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
`.okfignore` (bundle only):
|
|
75
|
+
|
|
76
|
+
- Put `.okfignore` in `input-dir`.
|
|
77
|
+
- Add bundle-relative markdown paths to skip, one per line.
|
|
78
|
+
- Blank lines and `#` comments ignored.
|
|
79
|
+
- Matching is exact path match (no glob, no negation).
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
# example/.okfignore
|
|
83
|
+
smoke-ignore.md
|
|
84
|
+
tables/orders.md
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Local link checks during `bundle`:
|
|
88
|
+
|
|
89
|
+
- Scans markdown body links to local `.md` targets.
|
|
90
|
+
- Supports relative links (`./x.md`, `../x.md`) and bundle-root links (`/tables/x.md`).
|
|
91
|
+
- Ignores external links (`https:`, `mailto:`), fragment-only links (`#section`), directory links, and non-`.md` targets.
|
|
92
|
+
- Default mode prints warnings for missing targets or links resolving outside bundle.
|
|
93
|
+
- `--strict-links` turns those warnings into a non-zero exit (`Error: strict link check failed`).
|
|
94
|
+
|
|
95
|
+
### `okf list` — list concept IDs in a bundle
|
|
96
|
+
|
|
97
|
+
```
|
|
98
|
+
okf list <directory>
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Prints concept IDs (bundle-relative path with `.md` stripped) for every
|
|
102
|
+
concept file in the bundle. Reserved filenames (`index.md`, `log.md`)
|
|
103
|
+
are excluded. `README.md` is not reserved by the OKF spec and is listed
|
|
104
|
+
as a concept if present.
|
|
105
|
+
|
|
106
|
+
Requires the directory to be a valid OKF bundle; fails if any
|
|
107
|
+
non-reserved `.md` is missing frontmatter or a non-empty `type`.
|
|
108
|
+
|
|
109
|
+
```bash
|
|
110
|
+
okf list bundled/
|
|
111
|
+
# datasets/sales
|
|
112
|
+
# playbooks/incident-response
|
|
113
|
+
# tables/orders
|
|
114
|
+
# …
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
Useful for piping OKF bundles into other tooling:
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
okf list bundled/ | xargs -I{} okf show bundled/ {}
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### `okf show` — read a concept by ID
|
|
124
|
+
|
|
125
|
+
```
|
|
126
|
+
okf show <directory> <concept-id>
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
Prints the full contents (frontmatter + body) of a concept file.
|
|
130
|
+
Concept IDs are the bundle-relative path with `.md` stripped — exactly
|
|
131
|
+
as printed by `okf list`.
|
|
132
|
+
|
|
133
|
+
Requires the directory to be a valid OKF bundle.
|
|
134
|
+
|
|
135
|
+
```bash
|
|
136
|
+
okf show bundled/ tables/orders
|
|
137
|
+
# ---
|
|
138
|
+
# type: "tables"
|
|
139
|
+
# title: "Customer Orders"
|
|
140
|
+
# ...
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
Guards against path traversal and rejects reserved filenames.
|
|
144
|
+
|
|
145
|
+
### `okf validate` — check OKF conformance
|
|
146
|
+
|
|
147
|
+
```
|
|
148
|
+
okf validate <directory>
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
Checks OKF v0.1 §9 conformance:
|
|
152
|
+
|
|
153
|
+
- Every non-reserved `.md` has parseable YAML frontmatter with non-empty `type`.
|
|
154
|
+
- Reserved filenames (`index.md`, `log.md`) follow spec structure (§6/§7).
|
|
155
|
+
- Non-UTF-8 files are flagged.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
okf validate bundled/
|
|
159
|
+
# 16 files: 16 ok
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Writing input files (for `bundle`)
|
|
163
|
+
|
|
164
|
+
### Strict format (recommended)
|
|
165
|
+
|
|
166
|
+
Every `.md` file starts with:
|
|
167
|
+
|
|
168
|
+
```markdown
|
|
169
|
+
# Title
|
|
170
|
+
|
|
171
|
+
> Description
|
|
172
|
+
> Second optional description line.
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
Everything after the description block is preserved unchanged.
|
|
176
|
+
|
|
177
|
+
### Lenient fallback
|
|
178
|
+
|
|
179
|
+
Files that don't follow the strict format are still bundled best-effort:
|
|
180
|
+
|
|
181
|
+
| Condition | Behavior |
|
|
182
|
+
| ---------------------------------------- | ------------------------------------------------------------------ |
|
|
183
|
+
| No `# Title` on line 1 | Title omitted from frontmatter |
|
|
184
|
+
| No `>` description block | Description derived from first 80 chars of body ("…" if truncated) |
|
|
185
|
+
| Root-level file without `--default-type` | Skip file, warn, continue |
|
|
186
|
+
|
|
187
|
+
**Rules:**
|
|
188
|
+
|
|
189
|
+
| Rule | Why |
|
|
190
|
+
| ----------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
191
|
+
| Folder name = concept type | `tables/orders.md` → `type: "tables"` |
|
|
192
|
+
| Only `.md` files processed | Non-`.md` files ignored |
|
|
193
|
+
| `index.md`, `log.md`, `README.md` skipped in `bundle` | Input may contain repo artifacts; these are not concepts. `bundle` warns when it skips them. Other commands (`list`, `show`, `validate`) operate on conformant OKF bundles where only `index.md` and `log.md` are reserved. |
|
|
194
|
+
| `.okfignore` entries skipped in `bundle` | Add bundle-relative markdown paths (e.g. `tables/orders.md`) to skip conversion for selected files. Blank lines and `#` comments are ignored. |
|
|
195
|
+
|
|
196
|
+
Root files need `--default-type`. Otherwise put files in named folders.
|
|
197
|
+
|
|
198
|
+
See the [`example/`](example/) directory for a sample of how to structure files.
|
|
199
|
+
|
|
200
|
+
## How `bundle` works
|
|
201
|
+
|
|
202
|
+
1. Walk `input-dir` for `.md` files (skip `.okfignore` matches and reserved names)
|
|
203
|
+
1. Extract `title` from `#` on line 1, `description` from `>` block. If strict format not met, falls back: title omitted if absent, description from first 80 chars of body
|
|
204
|
+
1. Check local markdown links against planned bundle targets (warn by default, or fail with `--strict-links`)
|
|
205
|
+
1. Set `type` from parent dir name, `timestamp` from file mtime
|
|
206
|
+
1. Write concept files with YAML frontmatter (title field omitted if empty)
|
|
207
|
+
1. Generate `index.md` per directory — `# Contents` for files, `# Directories` for subdirs (recursive)
|
|
208
|
+
|
|
209
|
+
## Output
|
|
210
|
+
|
|
211
|
+
Each concept becomes a markdown file with YAML frontmatter:
|
|
212
|
+
|
|
213
|
+
```yaml
|
|
214
|
+
---
|
|
215
|
+
type: "tables"
|
|
216
|
+
title: "Customer Orders"
|
|
217
|
+
description: "One row per completed customer order across all channels."
|
|
218
|
+
timestamp: "2026-07-04T15:06:51+00:00"
|
|
219
|
+
---
|
|
220
|
+
|
|
221
|
+
Original body preserved as-is.
|
|
222
|
+
```
|
|
223
|
+
|
|
224
|
+
Every directory gets its own `index.md`:
|
|
225
|
+
|
|
226
|
+
```markdown
|
|
227
|
+
# Contents
|
|
228
|
+
|
|
229
|
+
* [Customer Orders](orders.md) - One row per completed customer order across all channels.
|
|
230
|
+
|
|
231
|
+
# Directories
|
|
232
|
+
|
|
233
|
+
* [partitions](partitions/)
|
|
234
|
+
```
|
|
235
|
+
|
|
236
|
+
## OKF Conformance
|
|
237
|
+
|
|
238
|
+
Generated bundles conform to [OKF v0.1](OKF_SPEC.md) (§9):
|
|
239
|
+
|
|
240
|
+
- Every non-reserved `.md` has parseable YAML frontmatter with non-empty `type` ✓
|
|
241
|
+
- Reserved filenames follow spec structure ✓
|
|
242
|
+
- Consumers MUST tolerate missing optional fields, unknown types, broken links ✓
|
|
243
|
+
|
|
244
|
+
## Project layout
|
|
245
|
+
|
|
246
|
+
```
|
|
247
|
+
okf-cli
|
|
248
|
+
├── .github/workflows/test.yml # CI
|
|
249
|
+
├── OKF_SPEC.md # OKF specification
|
|
250
|
+
├── pyproject.toml # uv-managed Python project
|
|
251
|
+
├── src/okf/
|
|
252
|
+
│ ├── cli.py # Typer entrypoint
|
|
253
|
+
│ ├── core.py # Shared parsing/formatting
|
|
254
|
+
│ └── commands/ # bundle, list, show, validate
|
|
255
|
+
├── tests/test_cli.py # Tests
|
|
256
|
+
└── example/ # Sample input markdown
|
|
257
|
+
```
|