Files
chemenu/docs/reference/commands/exports.md
T
torbenandClaude Opus 5.5 52078bb4b0
CI / verify (push) Successful in 7m54s
CI / pwsh (push) Successful in 2m42s
Release / converters (push) Successful in 26s
Release / release (push) Successful in 36s
Release / wiki-mirror (push) Skipped
export run: commit= im Marker je Seite statt je Ziel - jede Datei nennt den letzten Commit ihrer eigenen Seite, ermittelt in einem git log über alle ausgewählten Pfade (Pfade über stdin und wörtlich), das Manifest behält den neuesten Commit über alle; ein Commit schreibt nur die Dateien der Seiten neu, die er berührt hat, plus Dateien, deren Links sich ändern. Erster Lauf nach dem Update schreibt jede Datei einmal neu (#221); 10.1.0-beta.12
Files changed:
- CHANGES.md
- VERSION
- docs/how-to/export-to-a-synced-folder.md
- docs/reference/commands/exports.md
- docs/reference/configuration.md
- tools/CONTRACT.md
- tools/chemenu/commands/export_cmd.py
- tools/chemenu/guideline_export.py
- tools/chemenu/page_export.py
- tools/chemenu/tests/test_export_run.py

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01SnAJ7Z3CpVD3PRbN73QtU2
2026-10-15 22:53:29 +02:00

143 lines
11 KiB
Markdown

# Exports
Derived, read-only versions of `kb/`: the generated `GUIDELINES.md` for the repositories the wiki has captured, and the pages exported into configured folders.
<!-- wikitool:toc -->
## Contents
- [`export guidelines`](#export-guidelines)
- [`export run`](#export-run)
<!-- /wikitool:toc -->
<!-- wikitool:reference-commands -->
## `export guidelines`
Render the guideline pages into one generated `GUIDELINES.md`, or push it into the captured repositories that opted in (**Guideline Push Gate**).
**Synopsis**
- `wikitool export guidelines [--field <predicate> ...] [--kind/--subtype/--collection/--tag <v>]` - Prints the file to stdout; no network.
- `wikitool export guidelines <predicates> --push [--bundle <raw-bundle> ...] [--confirm TOKEN]` - Writes it into the captured repositories, behind the gate.
**Options**
```text
-f, --field <str> Frontmatter predicate, repeatable (AND) - the same forms
as `search --field`.
--kind <str> Shorthand for --field kind=<value>.
--subtype <str> Shorthand for --field subtype=<value>.
--collection <str> Shorthand for --field collection=<value>.
--tag <str> Shorthand for --field tags=<value>.
--push Write the file into the captured repositories (Guideline
Push Gate).
--bundle <path> Only the repository of this captured bundle under raw/;
repeatable.
--confirm <str> The token from a prior exit 42, once a human has approved
it.
-h, --help Show this message and exit.
```
**Examples**
```bash
tools/wikitool export guidelines --tag guideline
tools/wikitool export guidelines --tag guideline --push
tools/wikitool export guidelines --confirm <token> --push --field tags=guideline # re-run after exit 42, once the user approved every diff
```
**Behaviour**
- Selects pages with `search`'s own predicates and no text: `--field` (repeatable, AND), `--kind`, `--subtype`, `--collection`, `--tag`. Which filter selects this instance's guidelines is written down in `kb/CONVENTIONS.md`.
- Renders mechanically: line 1 is `<!-- wikitool:export kind=guidelines instance=<origin URL without userinfo, or local> commit=<newest commit touching a selected page> - generated, do not edit by hand -->`; then each page sorted by title, as `# <title>` and its text without frontmatter, the generated links and footnote blocks, citation markers (`[^id]`, legacy `^[[...]]`), with `[[Title|Text]]` as `Text` and `[[Title]]` as `Title`. A leading H1 of the page is replaced by the title heading. Code is never rewritten. LF endings, no timestamp: the same pages give the same bytes.
- Refuses before printing or pushing anything: no predicate, no match, an unknown field, any page under `kb/` with unreadable frontmatter, uncommitted changes in `kb/` or `types/` (untracked files included), or no git checkout.
- `--push` targets every captured repository - each `(repo, ref)` from a `_capture.json` under `raw/`, `--bundle` narrowing it. A target is skipped with its reason when its ref rule is a tag pattern, it cannot be reached or has no such branch, its root has no `GUIDELINES.md` (not opted in), its `GUIDELINES.md` has no export header (hand-written), or the header names another `instance=`. A header line alone is the opt-in.
- Guideline Push Gate: `--push` without a matching `--confirm` fetches and builds everything, pushes nothing, and exits 42 with each target's status (`new`, `changed`, `unchanged`, `skipped`), the diff for every target it would write, and the re-run line. The token digests URL, branch, old tip and new blob of every target to write.
- With a matching token, each target gets exactly one commit on the fetched tip changing only `GUIDELINES.md`, authored as the instance checkout's `user.name`/`user.email`, pushed without force; one line per target: `unchanged`, `written <old> -> <new>`, `skipped (<reason>)`, `rejected (<reason>)` or `failed (<reason>)`.
- Nothing to write (every target unchanged or skipped) ends with exit 0 and no gate. A second run after a successful one finds every target unchanged.
- The target repository's own `AGENTS.md` points at the file (Claude Code: `@GUIDELINES.md`); that belongs to the repository, not to this command.
**Properties**
- Changes files: yes
- Idempotent: yes
- Atomic: Per target - one commit pushed without force, or nothing; targets already written stay written when a later one fails
- Counts toward the session call budget: yes
- Can reach the network: yes
- Gates: guideline-push - see [exit codes and gates](../exit-codes.md)
**Exit codes**
- `0` - success
- `0` - A target was skipped - tag rule, not reachable, not opted in, hand-written file, another instance's file
- `1` - No predicate, no page matches, a malformed predicate or an unknown field
- `1` - A page under `kb/` has unreadable frontmatter, `kb/` or `types/` has uncommitted changes, or the instance is not a git checkout
- `1` - `--push` with no `user.name` or `user.email` in the instance checkout's git configuration - checked before any target is fetched
- `1` - `--bundle` names no captured bundle under `raw/`, or `--bundle`/`--confirm` was given without `--push`
- `1` - A target rejected the push (its branch moved since the fetch) or a git call failed - the other targets were still served
- `42` - Guideline Push Gate: `--push` without `--confirm`, or with a token that does not match the current set of targets
**See also**
- `wikitool search` - the same predicates, to preview the selection
- `wikitool raw capture` - how a repository becomes a target
- `instructions/gates.md` - the gate procedure
## `export run`
Write the derived, read-only reading copy of `kb/` into the folders the `export` section configures - the selected pages as Markdown, or converted by a program of this checkout.
**Synopsis**
- `wikitool export run [<target> ...]` - Every configured target, or the named ones. Needs an `export` section in `.wikitool-local.json`; the user writes it by hand.
**Options**
```text
Arguments:
[TARGET]... Targets to run; default: every configured target.
Options:
-h, --help Show this message and exit.
```
**Examples**
```bash
tools/wikitool export run
tools/wikitool export run work-notes
```
**Behaviour**
- An export is derived: regenerated from `kb/` on every run, never edited, never read back into the wiki. Each target names its pages with an allowlist of `search --field` predicates (`include`: a list of selections, AND within one, OR across them), a handler (`markdown`, or `command` for the operator's converter) and the folder (`path`, outside the instance). Nothing is exported that no selection names.
- Every Markdown file starts with a frontmatter block whose `wikitool_export` line says `kind=pages instance=<origin URL without userinfo, or local> commit=<newest commit touching this page>`, followed by `title`, `type`, `summary`, `modified` where the page has them (`frontmatter: summary`, the default; `minimal` keeps only the marker, `full` the whole frontmatter), then the page text. A file keeps its path below `kb/`. A wikilink to an exported page becomes a relative Markdown link (`links: relative`, the default) or plain text (`links: text`); a link to a page that is not exported is always plain text. Footnote markers stay; code is never rewritten. LF endings, no timestamp: the same pages give the same bytes, and a commit that touches one page rewrites that page's file alone - plus any file whose links change because a page entered or left the selection. The manifest's `commit` is the newest commit touching any selected page; all of them come from one `git log`, however many pages are selected.
- Handler `command`: the Markdown is rendered into a staging directory, the program of `export.commands` runs with no shell, stdin closed and a timeout of 300 s, and receives the Markdown directory and an empty output directory as its last two arguments. On exit 0 the regular files in the output directory (recursively) become the target's content; any other end leaves the target unchanged and prints the end of its stderr. The staging directory is always removed.
- The folder is only ever touched by what it holds in its manifest, `.wikitool-export.json`: the files an earlier run wrote, each with its sha256. A run removes only manifest files that are no longer exported (and folders it created, once empty), rewrites a manifest file that is missing, leaves every other file byte for byte as it was, and writes nothing - not even a modification time - for a file that did not change. A run that changes nothing writes nothing at all.
- Refuses a target, before writing anything into it: a non-empty folder with no manifest (it is somebody's, not an export), a manifest file that was changed in the folder since the last run (naming it), a foreign file where an exported one belongs, an empty selection (it would delete the earlier export), an unknown field in a predicate. A missing folder is created.
- Refuses everything, before any target: uncommitted changes in `kb/` or `types/` (untracked files included), no git checkout, a page under `kb/` with unreadable frontmatter, an unknown target name, a broken `export` section.
- Output per target: `new` (with the page titles), `changed`, `removed`, the count `unchanged`, or `failed` with the reason. A page that newly enters a selection is reported as new, not gated. Exit 0 when every target ran; exit 1 when any failed - the others were still served.
- A target with `after_publish: true` is also refreshed by every `publish` that committed, `--no-push` included; a failure there is a warning, the commit stands, and this command is the repeat.
- `raw accept` refuses a file whose sha256 a target's manifest lists, and one that carries the marker: an export never goes back into `raw/`.
**Properties**
- Changes files: yes
- Idempotent: yes
- Atomic: Per file within a target (a temporary file in the target, then a move over its place), the manifest last; targets are independent, so a failed target does not undo another
- Counts toward the session call budget: yes
- Can reach the network: no
**Exit codes**
- `0` - success
- `1` - No `export` section, an unknown target name, or a broken section (a predicate that does not parse, a path inside the instance or in the way of another target, an `intake` folder or the backup target)
- `1` - `kb/` or `types/` has uncommitted changes, the instance is not a git checkout, or a page under `kb/` has unreadable frontmatter
- `1` - A target failed: a foreign folder, a file changed in the target, an empty selection, an unknown field, a converter that did not exit 0
**See also**
- `wikitool search` - the same predicates, to preview a selection
- `wikitool backup run` - the same kind of folder, for this machine's own files
- `docs/how-to/export-to-a-synced-folder.md`
<!-- /wikitool:reference-commands -->