| name | iwiki-ingest |
| description | Generate or update a wiki page in docs/wiki/ from a source file or folder, then refresh the embedding index. Use when asked to document code, add to the wiki, or after changing functionality. GUARDED: always show a diff and log. |
iwiki-ingest
Turn source into a wiki page under docs/wiki/ (markdown + [[refs]]), then index it.
Works in any project: the wiki is written to the current project's docs/wiki/,
and the embedding engine ships inside this plugin
(resolved via IWIKI_ENGINE_DIR โ see Engine invocation above).
You do NOT need iclaude's lib/ โ only the plugin and IWIKI_LLM_* config.
Engine invocation (read first)
The engine is a Python module, not a binary on PATH โ do not treat it as a
shell command (probing with command -v or --help will fail). The launcher
exports IWIKI_ENGINE_DIR; resolve $ENG /
$UV once with the block below (it falls back to the in-repo / newest-cached
engine and exits loud if none is found), then reuse them in the steps:
ENG="${IWIKI_ENGINE_DIR:-}"
[ -f "$ENG/pyproject.toml" ] || ENG="plugin/iwiki/engine"
[ -f "$ENG/pyproject.toml" ] || ENG="$(ls -d "$CLAUDE_CONFIG_DIR"/plugins/cache/*/iwiki/*/engine 2>/dev/null | sort -V | tail -1)"
[ -f "$ENG/pyproject.toml" ] || { echo "iwiki: engine not found โ run ./iclaude.sh --install-iwiki" >&2; exit 1; }
UV="${UV_BIN:-}"; [ -x "$UV" ] || UV="$(command -v uv)"; [ -x "$UV" ] || UV="$CLAUDE_CONFIG_DIR/../bin/uv"
"$UV" run --project "$ENG" python3 -m iwiki_engine --wiki-dir docs/wiki <cmd>
Guardrails (autonomy zone: guarded)
- ALWAYS show the diff of the wiki page before/after writing.
- Sending source/doc content to the embedding API is a consented egress path โ
proceed only for the explicitly named source path.
- NEVER delete an existing wiki page. If ingest would remove one, STOP and ask.
- The engine reads only
docs/wiki/ + the named source; never .env/secrets.
Steps
- Read the source path the user named.
- Decide the target wiki page:
docs/wiki/<topic>.md (create or update).
Page structure (REQUIRED โ the engine and the section-formation hook depend on it):
- Use only
## for sections โ never ### or deeper. Deeper headings are not
indexed as separate units and the validation hook blocks them; flatten them into
the ## section's prose.
- Put no content before the first
## except a single # H1 title โ text
before the first ## is dropped from the index.
- Lead with
# Title, then a first ## Overview section that summarizes all of
the page's sections in โโค400 characters. You author this Overview yourself as part
of writing the page (no separate summarizer). The engine reuses the Overview body
to give every other section's vectors whole-article context, and the Overview
section itself is NOT indexed as its own searchable section.
- One
## section per concept; lead each section with a โค250-char paragraph stating
what the section covers and why it matters (intent, not just mechanics) โ a wiki
documents the what and the why. This lead doubles as the section summary that binds
the section's chunks.
- Prefer a standard section name where one fits, instead of an ad-hoc heading โ a
familiar name is a signal, a creative name is noise. Pick the applicable subset;
never force-fit a section that does not apply:
## Purpose (why it exists),
## Interface / ## API (public surface โ functions, types, flags), ## Dependencies,
## Data flow, ## Errors (failure modes), ## Usage (how to invoke).
- Wrap every code symbol โ function name, file path, CLI flag, command, config key โ
in backticks, never bare prose. Precise references read cleanly and tokenize cleanly
for the embedding index.
Cross-link related pages with
[[file#Heading]].
- Write/update the page (Write/Edit tool). Show the user the diff.
- Refresh the index (run from the current project root):
[ -d docs/wiki ] || { echo "iwiki: no docs/wiki/ here โ run /iwiki-init to create one."; exit 0; }
"$UV" run --project "$ENG" python3 -m iwiki_engine --wiki-dir docs/wiki index
Expected: indexed: N chunks (... reused, ... embedded), <bytes>.
- Append an operation record to
docs/wiki/.iwiki/log.jsonl:
printf '{"op":"ingest","source":"<src>","page":"<page>","date":"<YYYY-MM-DD>","src_hash":"%s"}\n' \
"$(sha256sum '<src>' | cut -c1-16)" \
>> docs/wiki/.iwiki/log.jsonl
Substitute <src> (same path in both the source field and the sha256sum
argument), <page>, and <YYYY-MM-DD> literally; src_hash is filled by the
shell. Canonical log record: {op, source, page, date, src_hash} (note
optional). src_hash is the sha256 of the source's raw bytes, first 16 hex
chars โ lint's stale check prefers it over mtime. Use exactly these keys;
do not introduce alternatives (e.g. scope).
- Report which page changed and the index size (warn if over the 8 MB cap).
Stop rule
If the engine prints HALT:, report it and stop.