From projekt-skills
Write and maintain Projekt project documentation (projekt.3xa.es) idempotently: title-keyed UPSERT of project/sprint docs from markdown into EditorJS blocks (create-or-update, never duplicate), nest pages under a parent, regenerate per-issue AI bitácora (logbook), and export issues to a PDF/markdown artifact. Use whenever the user asks to write/update project docs, a runbook, sprint notes, a wiki page, the bitácora / HdU of an issue, or to export issues as a PDF. Soporta español: documentación, página de proyecto, runbook, notas de sprint, bitácora, historia de usuario, exportar incidencias a PDF.
How this skill is triggered — by the user, by Claude, or both
Slash command
/projekt-skills:projekt-docsThis skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
UPSERT project docs by title (create-or-update), regenerate issue bitácoras, and export issues to PDF —
UPSERT project docs by title (create-or-update), regenerate issue bitácoras, and export issues to PDF —
all idempotent and dry-run-first. This is the DOCUMENT step of the projekt pipeline.
SK="${CLAUDE_SKILL_DIR}/scripts" — use it for every command below.
Run the orchestrator's connect steps so the token + org + .projekt-run/context.json exist:
bash "${CLAUDE_SKILL_DIR}/../projekt/scripts/auth_check.sh"
bash "${CLAUDE_SKILL_DIR}/../projekt/scripts/context_sync.sh"
Read .projekt-run/context.json to resolve a project name → its id (and members). Never re-query.
No token? → projekt/references/auth-setup.md.
All three are dry-run by default: they print a plan and write nothing until you add --apply.
Markdown/plain text → minimal EditorJS blocks, then create-or-update by title:
# dry-run (shows CREATE vs UPDATE, parent, block counts)
python3 "$SK/doc_generator.py" upsert \
--project <PID|KEY|name> --title "Runbook — Deploy" --body-file ./runbook.md
# apply
python3 "$SK/doc_generator.py" upsert \
--project <PID|KEY|name> --title "Runbook — Deploy" --body-file ./runbook.md --apply
--body "## text", --body - (stdin), or --body-file path.md.--parent "Runbook — Deploy" (a title or a UUID, resolved from the doc list).--icon 📘 is applied on CREATE only.Markdown supported: #..###### headers, -/*/+ bullets, 1./1) ordered lists, blank-line
paragraphs. Other lines become paragraphs (no inline-formatting parsing — EditorJS keeps the raw text).
python3 "$SK/doc_generator.py" bitacora --issue-ids <IID1>,<IID2> # dry-run
python3 "$SK/doc_generator.py" bitacora --issue-ids <IID1>,<IID2> --locale es --apply
503 (AI quota / model unavailable) = SOFT-SKIP: the prior bitácora is left intact and reported as skipped — never overwritten with an error. The run still exits 0 if the only failures were 503s.
python3 "$SK/doc_generator.py" pdf --issue-ids <IID1>,<IID2> # dry-run
python3 "$SK/doc_generator.py" pdf --issue-ids <IID1>,<IID2> \
--format pdf --title "Sprint 12 report" --out ./sprint12.pdf --apply
Saves the binary stream to a file (--out, default issues-export.<format>). Do NOT try to render
the PDF in the model — point the user at the saved path. --format md, --mode claude,
--no-comments, --no-attachments available.
Verified the accepted body with bash projekt/scripts/spec_lookup.sh "/projects/{projectId}/docs" post
(schemas ProjectDoc.blocks and EditorJsBlock). The wire format is EditorJS OutputData:
{ "time": 1700000000000, "version": "2.30.6",
"blocks": [ { "type": "header", "data": { "text": "Title", "level": 2 } },
{ "type": "paragraph", "data": { "text": "Body." } },
{ "type": "list", "data": { "style": "unordered", "items": ["a", "b"] } } ] }
Both POST and PATCH accept blocks as oneOf: [object, string] — a parsed object or a JSON-encoded
string; reads always return the parsed object. This script sends the object form. PATCH leaves any field
not in the body untouched (so we send title + blocks, plus parent_doc_id only when --parent is given).
GET /issues/export-pdf, but the spec
defines it as POST with a required issue_ids body that streams application/pdf/text/markdown.
This script uses POST and reads raw bytes (the shared client decodes text, which would corrupt a PDF).projekt/references/errors.md.include_archived=1) so an UPSERT updates a doc you
archived rather than creating a duplicate.PATCH is_archived; not exposed here).projekt/scripts/spec_lookup.sh if needed.projekt/references/endpoints.md (Docs section) · errors.md (422/429/503/403) · auth-setup.md.
Slim projections + ledger come from the shared projekt_api client; .projekt-run/*.jsonl is the resume log.
Guides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub valfiguer/projekt-skills --plugin projekt-skills