plugins/inkwell/skills/doc/SKILL.md
Scaffold a new doc under `docs/` from a Diátaxis template, or update an existing one and bump its `updated:` date. Suggests `## Related` candidates and refreshes the FTS5 index on write.
npx skillsauth add acostanzo/quickstop docInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Write or update a doc under the repo's docs/ tree. The skill is the
writer's primary scaffolding surface: it picks a Diátaxis template,
substitutes the topic into the headline placeholders, seeds a ## Related
block from the link suggester, and refreshes the FTS5 index so the new
doc is immediately searchable via /inkwell:search.
<topic> — required. Free-form topic title. Used both to derive the
filename slug and to substitute the template's headline placeholders
(<Topic>, <Goal>, <Surface>, <What you'll learn>).--template <name> — optional. One of concept, how-to,
reference, tutorial. Overrides the auto-pick.--from-code <path> — optional. Source file to draft a
reference-shaped doc from. Forces --template reference if no
explicit template was given.Call the resolver with the raw topic:
bash "${CLAUDE_PLUGIN_ROOT}/bin/inkwell-doc-resolve.sh" \
"<topic>" "<REPO_ROOT>"
The resolver emits one of three outputs on a single line:
match <relative-path> — exactly one existing doc matches by
filename slug or by frontmatter title: (case-insensitive). Take
the update path (§2a) against this file.ambiguous <path1> <path2> ... — two or more docs share a title:
matching <topic> and no slug match exists. Surface the candidates
to the user and stop; do not scaffold a third copy. The author
resolves the ambiguity (e.g. by re-running with a more specific
topic, or by editing one of the candidates manually first).none — no existing doc to update. Take the scaffold path (§2b).The resolver checks slug first (the strongest signal — it's the
write-target the scaffold path would otherwise create) and falls
back to a title: scan so a topic like Authentication finds an
existing docs/concepts/auth.md rather than scaffolding a duplicate
at docs/authentication.md.
If the resolver returned match <path>:
Read the file.Edit the updated: line in the frontmatter to today's date
(UTC, YYYY-MM-DD). Today's date is available as the
{{ today }} substitution in the conversation context, or
compute via Bash: date -u +%Y-%m-%d./inkwell:doc updates the updated: stamp,
not the prose. Semantic rewrites belong to /inkwell:tidy --apply-semantic (T4).If the resolver returned none:
Pick the template. If --template <name> was supplied, use it.
Otherwise auto-pick from the topic shape:
how-toconcepttutorial( and ) (function signature shape) or contains a
path separator (/ between non-space tokens, suggesting a file)
→ referenceconcept (conservative default).--from-code <path> overrides the auto-pick to reference (a
doc generated from source code is reference-shaped by definition,
unless the author explicitly asks for another template).
Read the chosen template at ${CLAUDE_PLUGIN_ROOT}/templates/<template>.md.
Substitute placeholders. In the template body, replace:
<Topic> → the user's <topic> (concept/reference)<Goal> → the user's <topic> (how-to)<Surface> → the user's <topic> (reference)<What you'll learn> → the user's <topic> (tutorial)updated: frontmatter value → today's date.--from-code enrichment. If --from-code <path> is given:
Read the source file.## Parameters table with the
exported function signatures (Python def, JS/TS export function, Go func). The reference template's table is four
columns — Name | Type | Default | Description — so each row
must be | name | — | — | — | <one-line meaning> | (5 pipes,
4 cells). Populate type/default if you can extract them from
source; otherwise leave the em-dash placeholders. Leave the
meaning blank if you can't extract a docstring — the author
fills it in.## Description paragraph naming the source path
so the doc is self-locating.Write the new file at
<REPO_ROOT>/docs/<template-dir>/<slug>.md with the substituted
body and an empty ## Related block (the heading followed by the
placeholder). <template-dir> is the conventional Diátaxis
directory name, mapped from the chosen template:
| Template | Directory |
|---|---|
| concept | concepts/ |
| how-to | howtos/ |
| reference | reference/ |
| tutorial | tutorials/ |
The template files are named singular (concept.md, how-to.md,
reference.md, tutorial.md); the on-disk neighbourhoods are
plural (concepts/, howtos/, tutorials/) where natural and
un-hyphenated (howtos). The mapping above is the source of
truth — keep both halves in sync.
Run mkdir -p <REPO_ROOT>/docs/<template-dir> before the write so
the destination directory exists. The file must exist on disk
before the suggester runs because the suggester reads the
target's frontmatter tags: to score peers — it refuses a
non-existent target.
The resolver (inkwell-doc-resolve.sh) scans docs/**/*.md
recursively, so existing docs at any depth continue to be found
on the update path; only the scaffold path picks the subdirectory.
Suggest ## Related. Call the suggester against the
now-existent path:
bash "${CLAUDE_PLUGIN_ROOT}/bin/inkwell-suggest-links.sh" \
"docs/<template-dir>/<slug>.md" "<REPO_ROOT>"
The script returns either path score=... rationale: ... lines
on stdout or no automatic suggestion on stderr.
Edit the ## Related block. Templates ship with the
<!-- inkwell:related — populate when the doc earns siblings -->
placeholder. If the suggester emitted candidates, replace that
comment with one bullet per candidate (- [path](path)). If the
suggester emitted "no automatic suggestion", leave the comment in
place — inkwell-tidy.sh treats it as writer-acknowledged-empty
and won't fire missing-related against fresh scaffolds.
Always run, regardless of update or create path:
bash "${CLAUDE_PLUGIN_ROOT}/bin/inkwell-index.sh" "<REPO_ROOT>"
The indexer is mtime-cached and idempotent — touching only the file
just written. The on-write index refresh is what makes
/inkwell:search reflect the new doc immediately, no manual reindex.
The doc you write must match the inkwell voice (see plugin README § "Documentation voice"):
The templates ship with <!-- comment --> guidance under each
section. Delete those guidance comments before saving — they're
authoring scaffolding, not output content.
score-template-compliance.sh, not this skill's concern./inkwell:query (T3) at inference
time, per ADR-007.docs/<slug>.md and the gitignored
index file. ADR-006 §2 holds: no silent mutation of consumer
artefacts.documentation
Surface (and optionally fix) doc-tree drift — duplicates, dead links, stale docs, template non-compliance, missing `## Related` blocks. Read-only by default; `--apply` does mechanical fixes; `--apply-semantic` emits diffs for human review.
documentation
Full-text search over the repo's `docs/` tree (FTS5-backed). Returns ranked hits with file paths, tags, and matching snippets.
testing
Retrieval-augmented Q&A over the repo's `docs/` tree. Returns a one-paragraph synthesis plus citations (doc path + heading anchor) and per-citation corroboration verdicts. Field shape and ordering are locked at M3; M5 populates the verdicts.
data-ai
Strip Co-Authored-By trailers and "Generated with/by Claude" footers from a text blob. Read-only capability — emits cleaned text on stdout.