plan: md-to-pdf skill implementation plan
This commit is contained in:
602
docs/superpowers/plans/2026-05-04-md-to-pdf-skill.md
Normal file
602
docs/superpowers/plans/2026-05-04-md-to-pdf-skill.md
Normal file
@@ -0,0 +1,602 @@
|
||||
# md-to-pdf Skill Implementation Plan
|
||||
|
||||
> **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking.
|
||||
|
||||
**Goal:** Build a Claude Code plugin (publishable via Gitea) that exposes an `md-to-pdf` skill, triggered by natural language, which regenerates PDF from a Markdown file using the user's bundled style — with project-local config override.
|
||||
|
||||
**Architecture:** A Gitea-hosted repo in Claude Code's plugin-marketplace format. The marketplace exposes one plugin (`md-to-pdf`) containing a single skill. The skill is prompt-content that instructs Claude to (1) resolve the source `.md`, (2) walk upward for a project-local `.md-to-pdf.config.js`, falling back to the bundled `default.config.js` at `${CLAUDE_PLUGIN_ROOT}`, and (3) shell out to `npx --yes md-to-pdf`. No runtime code beyond the JS config.
|
||||
|
||||
**Tech Stack:** Claude Code plugin/marketplace format (`marketplace.json`, `plugin.json`), `md-to-pdf` (npm), Node.js, Gitea for hosting.
|
||||
|
||||
---
|
||||
|
||||
## File Structure
|
||||
|
||||
Working directory: `~/Development/claude-md-to-pdf` (already initialized as a git repo with the spec committed).
|
||||
|
||||
Files to create:
|
||||
|
||||
| Path | Responsibility |
|
||||
|------|----------------|
|
||||
| `.claude-plugin/marketplace.json` | Marketplace manifest. Declares the marketplace and lists the `md-to-pdf` plugin pointing to `./plugins/md-to-pdf`. |
|
||||
| `plugins/md-to-pdf/.claude-plugin/plugin.json` | Plugin manifest. Name, description, author, version. |
|
||||
| `plugins/md-to-pdf/skills/md-to-pdf/SKILL.md` | The skill itself: frontmatter (name, description that triggers on natural language), then step-by-step instructions for Claude. |
|
||||
| `plugins/md-to-pdf/skills/md-to-pdf/default.config.js` | Verbatim copy of the user's existing `.md-to-pdf.config.js` (A4 / 5pt fixed-layout tables / system sans-serif). |
|
||||
| `README.md` | Install instructions (`/plugin marketplace add …`), usage examples, project-local override docs. |
|
||||
| `LICENSE` | MIT. |
|
||||
|
||||
Already in place: `docs/superpowers/specs/2026-05-04-md-to-pdf-skill-design.md` (committed at `ea49946`).
|
||||
|
||||
---
|
||||
|
||||
## Task 1: Bundled default config
|
||||
|
||||
**Files:**
|
||||
- Create: `plugins/md-to-pdf/skills/md-to-pdf/default.config.js`
|
||||
|
||||
- [ ] **Step 1: Create the directory structure**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
mkdir -p plugins/md-to-pdf/.claude-plugin plugins/md-to-pdf/skills/md-to-pdf
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Write the bundled default config**
|
||||
|
||||
Create `plugins/md-to-pdf/skills/md-to-pdf/default.config.js` with this exact content (verbatim copy of the user's working config from the Databases project):
|
||||
|
||||
```js
|
||||
module.exports = {
|
||||
pdf_options: {
|
||||
format: 'A4',
|
||||
margin: '15mm 12mm',
|
||||
printBackground: true,
|
||||
},
|
||||
css: `
|
||||
@page { size: A4; margin: 15mm 12mm; }
|
||||
html, body { width: 186mm; max-width: 186mm; margin: 0; padding: 0; }
|
||||
body { font-family: -apple-system, "Segoe UI", Helvetica, Arial, sans-serif; font-size: 11pt; }
|
||||
h1 { font-size: 18pt; }
|
||||
h2 { font-size: 14pt; margin-top: 1.2em; }
|
||||
h3 { font-size: 12pt; }
|
||||
h4 { font-size: 11pt; }
|
||||
table {
|
||||
border-collapse: collapse;
|
||||
font-size: 5pt;
|
||||
margin: 0.6em 0;
|
||||
table-layout: fixed;
|
||||
width: 100%;
|
||||
}
|
||||
th, td {
|
||||
border: 1px solid #888;
|
||||
padding: 1px 3px;
|
||||
white-space: nowrap;
|
||||
vertical-align: top;
|
||||
letter-spacing: -0.1px;
|
||||
overflow: hidden;
|
||||
}
|
||||
code { font-size: 0.9em; background: #f4f4f4; padding: 0 2px; border-radius: 2px; }
|
||||
td code, th code { font-size: 0.85em; padding: 0 1px; }
|
||||
th { background: #f0f0f0; }
|
||||
blockquote { border-left: 3px solid #ccc; margin: 0.5em 0; padding: 0.2em 0.8em; color: #444; }
|
||||
`,
|
||||
};
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Verify the config loads as valid CommonJS**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
node -e "const c = require('./plugins/md-to-pdf/skills/md-to-pdf/default.config.js'); if (!c.pdf_options || !c.css) throw new Error('config missing required fields'); console.log('ok')"
|
||||
```
|
||||
|
||||
Expected output:
|
||||
|
||||
```
|
||||
ok
|
||||
```
|
||||
|
||||
If you see `SyntaxError` or "config missing required fields" — re-check the file content matches Step 2 exactly.
|
||||
|
||||
- [ ] **Step 4: Smoke-test md-to-pdf with this config on a temporary sample**
|
||||
|
||||
```bash
|
||||
cd /tmp
|
||||
printf '# Test\n\n| A | B |\n|---|---|\n| 1 | 2 |\n' > md2pdf-smoke.md
|
||||
npx --yes md-to-pdf md2pdf-smoke.md --config-file ~/Development/claude-md-to-pdf/plugins/md-to-pdf/skills/md-to-pdf/default.config.js
|
||||
ls -la md2pdf-smoke.pdf
|
||||
rm md2pdf-smoke.md md2pdf-smoke.pdf
|
||||
```
|
||||
|
||||
Expected: `md2pdf-smoke.pdf` is created with non-zero size before deletion.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git add plugins/md-to-pdf/skills/md-to-pdf/default.config.js
|
||||
git commit -m "feat: bundled default md-to-pdf config (homework style)"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 2: Plugin manifest
|
||||
|
||||
**Files:**
|
||||
- Create: `plugins/md-to-pdf/.claude-plugin/plugin.json`
|
||||
|
||||
- [ ] **Step 1: Write the plugin manifest**
|
||||
|
||||
Create `plugins/md-to-pdf/.claude-plugin/plugin.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"name": "md-to-pdf",
|
||||
"description": "Regenerate a PDF from a Markdown file on natural-language request (e.g. 'exportier mal das PDF', 'regenerate the PDF'). Uses project-local .md-to-pdf.config.js when present, otherwise a bundled default styled for A4 with small tables.",
|
||||
"version": "0.1.0",
|
||||
"author": {
|
||||
"name": "Jean-Luc Makiola",
|
||||
"email": "mail@jeanlucmakiola.de"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Validate JSON**
|
||||
|
||||
Run:
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
jq empty plugins/md-to-pdf/.claude-plugin/plugin.json && echo "ok"
|
||||
```
|
||||
|
||||
Expected: `ok`. If `jq` is missing, install it (`pacman -S jq` on Arch) before proceeding — the plan uses it for validation in later tasks too.
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git add plugins/md-to-pdf/.claude-plugin/plugin.json
|
||||
git commit -m "feat: plugin manifest for md-to-pdf"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 3: Marketplace manifest
|
||||
|
||||
**Files:**
|
||||
- Create: `.claude-plugin/marketplace.json`
|
||||
|
||||
- [ ] **Step 1: Create the marketplace directory**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
mkdir -p .claude-plugin
|
||||
```
|
||||
|
||||
- [ ] **Step 2: Write the marketplace manifest**
|
||||
|
||||
Create `.claude-plugin/marketplace.json`:
|
||||
|
||||
```json
|
||||
{
|
||||
"$schema": "https://anthropic.com/claude-code/marketplace.schema.json",
|
||||
"name": "claude-md-to-pdf",
|
||||
"description": "Self-hosted marketplace for the md-to-pdf skill — natural-language Markdown to PDF conversion.",
|
||||
"owner": {
|
||||
"name": "Jean-Luc Makiola",
|
||||
"email": "mail@jeanlucmakiola.de"
|
||||
},
|
||||
"plugins": [
|
||||
{
|
||||
"name": "md-to-pdf",
|
||||
"description": "Regenerate a PDF from a Markdown file on natural-language request. Uses project-local .md-to-pdf.config.js when present, otherwise a bundled default.",
|
||||
"category": "productivity",
|
||||
"source": "./plugins/md-to-pdf"
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Validate JSON**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
jq empty .claude-plugin/marketplace.json && echo "ok"
|
||||
```
|
||||
|
||||
Expected: `ok`.
|
||||
|
||||
- [ ] **Step 4: Verify the relative source path resolves**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
test -f plugins/md-to-pdf/.claude-plugin/plugin.json && echo "plugin source ok"
|
||||
```
|
||||
|
||||
Expected: `plugin source ok`.
|
||||
|
||||
- [ ] **Step 5: Commit**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git add .claude-plugin/marketplace.json
|
||||
git commit -m "feat: marketplace manifest"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 4: SKILL.md (the skill itself)
|
||||
|
||||
**Files:**
|
||||
- Create: `plugins/md-to-pdf/skills/md-to-pdf/SKILL.md`
|
||||
|
||||
- [ ] **Step 1: Write the skill**
|
||||
|
||||
Create `plugins/md-to-pdf/skills/md-to-pdf/SKILL.md`:
|
||||
|
||||
````markdown
|
||||
---
|
||||
name: md-to-pdf
|
||||
description: Use when the user asks to export, regenerate, build, or "make" a PDF from a Markdown file. Triggers on phrases like "exportier mal das PDF", "mach das als PDF", "regenerate the PDF", "PDF neu generieren", "convert this markdown to pdf". Do NOT trigger on requests to read, open, or display an existing PDF.
|
||||
version: 0.1.0
|
||||
---
|
||||
|
||||
# md-to-pdf
|
||||
|
||||
Regenerate a PDF from a Markdown file using the user's preferred styling. The skill walks upward for a project-local `.md-to-pdf.config.js`; if none is found it falls back to the bundled `default.config.js` shipped with this skill.
|
||||
|
||||
## When This Skill Applies
|
||||
|
||||
Trigger when the user wants a Markdown file converted to PDF — typical phrasings: "exportier mal", "mach mir das als PDF", "PDF regenerieren", "regenerate the PDF", "convert to pdf". Do **not** trigger when the user just wants to view, read, or open an existing PDF.
|
||||
|
||||
## Procedure
|
||||
|
||||
### 1. Identify the source `.md`
|
||||
|
||||
Resolve in this order — stop at the first that yields a single unambiguous file:
|
||||
|
||||
1. A `.md` path explicitly named in the user's most recent message.
|
||||
2. The `.md` file the assistant most recently read or wrote in this session.
|
||||
3. The single most-recently-modified `.md` file in the current working directory (`ls -t *.md | head -1` semantics).
|
||||
|
||||
If none of these resolves to one file, **ask** the user which file to convert. Do not guess.
|
||||
|
||||
### 2. Resolve the config
|
||||
|
||||
Walk from the source file's directory upward toward `/`, looking for `.md-to-pdf.config.js`. Use the first match.
|
||||
|
||||
If no project-local config is found, fall back to the bundled default:
|
||||
|
||||
```
|
||||
${CLAUDE_PLUGIN_ROOT}/skills/md-to-pdf/default.config.js
|
||||
```
|
||||
|
||||
`CLAUDE_PLUGIN_ROOT` is provided by Claude Code at runtime and points to this plugin's root directory.
|
||||
|
||||
### 3. Run the converter
|
||||
|
||||
```bash
|
||||
npx --yes md-to-pdf <source.md> --config-file <resolved-config>
|
||||
```
|
||||
|
||||
The PDF is written next to the source (`Loesung.md` → `Loesung.pdf`), overwriting any existing file.
|
||||
|
||||
### 4. Confirm
|
||||
|
||||
Tell the user:
|
||||
|
||||
- The output PDF path and file size (`ls -la` style).
|
||||
- Which config was used: project-local path, or "bundled default".
|
||||
|
||||
## Error Handling
|
||||
|
||||
- **`npx` / Node not on PATH** → tell the user Node.js is required and stop. Don't try to install it.
|
||||
- **`md-to-pdf` fetch or render fails** → relay the npx output verbatim. Don't retry silently.
|
||||
- **Source `.md` ambiguous** → ask, don't guess.
|
||||
- **Config file is syntactically broken** → relay the error from md-to-pdf. Don't try to "fix" the user's config.
|
||||
|
||||
## Examples
|
||||
|
||||
### Project-local config
|
||||
|
||||
User: *"exportier mal das PDF"* (after editing `Uebungen/03/Loesung.md`)
|
||||
|
||||
Skill:
|
||||
|
||||
1. Source: `Uebungen/03/Loesung.md` (most recently edited).
|
||||
2. Walks up; finds `.md-to-pdf.config.js` at the repo root.
|
||||
3. Runs `npx --yes md-to-pdf Uebungen/03/Loesung.md --config-file .md-to-pdf.config.js`.
|
||||
4. Reports: `Uebungen/03/Loesung.pdf (280K) — using project config .md-to-pdf.config.js`.
|
||||
|
||||
### Bundled default
|
||||
|
||||
User: *"convert this markdown to pdf"* (in a fresh directory with one `.md` file and no config).
|
||||
|
||||
Skill:
|
||||
|
||||
1. Source: `notes.md` (only `.md` in CWD).
|
||||
2. Walks up; no `.md-to-pdf.config.js` found.
|
||||
3. Runs `npx --yes md-to-pdf notes.md --config-file ${CLAUDE_PLUGIN_ROOT}/skills/md-to-pdf/default.config.js`.
|
||||
4. Reports: `notes.pdf (62K) — using bundled default`.
|
||||
````
|
||||
|
||||
- [ ] **Step 2: Verify the SKILL.md frontmatter parses**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
head -5 plugins/md-to-pdf/skills/md-to-pdf/SKILL.md | grep -E '^(name|description|version):' | wc -l
|
||||
```
|
||||
|
||||
Expected output: `3` (three frontmatter keys present).
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git add plugins/md-to-pdf/skills/md-to-pdf/SKILL.md
|
||||
git commit -m "feat: SKILL.md with natural-language trigger and procedure"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 5: README and LICENSE
|
||||
|
||||
**Files:**
|
||||
- Create: `README.md`
|
||||
- Create: `LICENSE`
|
||||
|
||||
- [ ] **Step 1: Write the README**
|
||||
|
||||
Create `README.md`:
|
||||
|
||||
````markdown
|
||||
# claude-md-to-pdf
|
||||
|
||||
A Claude Code plugin marketplace exposing the **md-to-pdf** skill — natural-language Markdown→PDF conversion using [`md-to-pdf`](https://www.npmjs.com/package/md-to-pdf).
|
||||
|
||||
## What it does
|
||||
|
||||
When you say things like *"exportier mal das PDF"*, *"regenerate the PDF"*, or *"convert this markdown to pdf"*, the skill picks up the relevant `.md`, finds the right style config, and runs `npx md-to-pdf`. No slash command required.
|
||||
|
||||
## Install
|
||||
|
||||
In Claude Code, on each device:
|
||||
|
||||
```
|
||||
/plugin marketplace add https://gitea.<your-domain>/jlmak/claude-md-to-pdf
|
||||
/plugin install md-to-pdf@claude-md-to-pdf
|
||||
```
|
||||
|
||||
(Replace `gitea.<your-domain>` with your Gitea host. The repo can also be installed from a local clone — see "Local install" below.)
|
||||
|
||||
## Requirements
|
||||
|
||||
- Node.js with `npx` on `PATH` (the skill calls `npx --yes md-to-pdf`).
|
||||
|
||||
## How style is chosen
|
||||
|
||||
The skill walks upward from the source `.md` file looking for a `.md-to-pdf.config.js`. If found, it's used. Otherwise the bundled default — A4, 15/12mm margins, 5pt fixed-layout tables, system sans-serif at 11pt — is used. The bundled default lives at:
|
||||
|
||||
```
|
||||
plugins/md-to-pdf/skills/md-to-pdf/default.config.js
|
||||
```
|
||||
|
||||
## Local install (no Gitea remote yet)
|
||||
|
||||
```
|
||||
/plugin marketplace add ~/Development/claude-md-to-pdf
|
||||
/plugin install md-to-pdf@claude-md-to-pdf
|
||||
```
|
||||
|
||||
## License
|
||||
|
||||
MIT — see `LICENSE`.
|
||||
````
|
||||
|
||||
- [ ] **Step 2: Write the LICENSE**
|
||||
|
||||
Create `LICENSE` with the standard MIT text:
|
||||
|
||||
```
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 Jean-Luc Makiola
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
```
|
||||
|
||||
- [ ] **Step 3: Commit**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git add README.md LICENSE
|
||||
git commit -m "docs: README + MIT LICENSE"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Task 6: Local install + end-to-end smoke test
|
||||
|
||||
**Goal:** Install the plugin from the local repo path, then verify Claude actually triggers the skill on natural language and produces a PDF.
|
||||
|
||||
This task requires the human to drive a Claude Code session. Document the exact sequence so it's repeatable.
|
||||
|
||||
- [ ] **Step 1: Add the local marketplace**
|
||||
|
||||
In a Claude Code session (any working directory):
|
||||
|
||||
```
|
||||
/plugin marketplace add ~/Development/claude-md-to-pdf
|
||||
```
|
||||
|
||||
Expected: Claude Code reports the marketplace was added with one plugin available.
|
||||
|
||||
- [ ] **Step 2: Install the plugin**
|
||||
|
||||
```
|
||||
/plugin install md-to-pdf@claude-md-to-pdf
|
||||
```
|
||||
|
||||
Expected: Plugin installs without error. The skill `md-to-pdf` is now available.
|
||||
|
||||
- [ ] **Step 3: Test trigger and project-local config path**
|
||||
|
||||
In a Claude Code session with cwd `~/Nextcloud/Documents/THB/2.Semester/Databases`:
|
||||
|
||||
1. Touch a file to create a recency signal:
|
||||
|
||||
```
|
||||
touch Uebungen/03/Loesung.md
|
||||
```
|
||||
|
||||
2. Tell Claude: *"exportier mal das PDF"*
|
||||
|
||||
Expected:
|
||||
- Claude invokes the `md-to-pdf` skill (visible in tool calls).
|
||||
- Claude resolves the source as `Uebungen/03/Loesung.md`.
|
||||
- Claude finds `.md-to-pdf.config.js` at the project root and uses it (not the bundled default).
|
||||
- `Uebungen/03/Loesung.pdf` is regenerated (check `mtime`).
|
||||
- Claude's confirmation mentions the project-local config.
|
||||
|
||||
- [ ] **Step 4: Test bundled-default fallback**
|
||||
|
||||
```bash
|
||||
mkdir -p /tmp/md2pdf-bundled-test
|
||||
cd /tmp/md2pdf-bundled-test
|
||||
printf '# Hello\n\nWorld.\n' > notes.md
|
||||
```
|
||||
|
||||
Open a Claude Code session in `/tmp/md2pdf-bundled-test` and say: *"convert this markdown to pdf"*
|
||||
|
||||
Expected:
|
||||
- Skill triggers.
|
||||
- No project-local config is found; bundled default is used.
|
||||
- `notes.pdf` exists.
|
||||
- Claude's confirmation mentions "bundled default".
|
||||
|
||||
- [ ] **Step 5: Cleanup**
|
||||
|
||||
```bash
|
||||
rm -rf /tmp/md2pdf-bundled-test
|
||||
```
|
||||
|
||||
- [ ] **Step 6: If anything failed, fix and re-commit**
|
||||
|
||||
If the skill didn't trigger, the description in `SKILL.md` likely needs more discriminative phrasing — edit it, reinstall the plugin (`/plugin uninstall md-to-pdf` then `/plugin install …`), and retry. Commit the fix:
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git add plugins/md-to-pdf/skills/md-to-pdf/SKILL.md
|
||||
git commit -m "fix: tighten SKILL.md trigger description"
|
||||
```
|
||||
|
||||
If file resolution misbehaved (e.g. picked the wrong `.md`), refine the resolution rules in the "Identify the source `.md`" section. Same commit cycle.
|
||||
|
||||
---
|
||||
|
||||
## Task 7: Push to Gitea
|
||||
|
||||
**Goal:** Make the marketplace installable from the user's Gitea host, so other devices can use the same `/plugin marketplace add` URL.
|
||||
|
||||
This task requires the user to have a Gitea instance reachable and an API token or SSH key configured. The plan documents the exact commands; the human runs them.
|
||||
|
||||
- [ ] **Step 1: Create the empty repo on Gitea**
|
||||
|
||||
In the Gitea web UI (or via the Gitea CLI if installed): create a new public repo named `claude-md-to-pdf` under the user's account. Do **not** initialize it with a README — the local repo already has commits.
|
||||
|
||||
- [ ] **Step 2: Add the remote**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git remote add origin https://gitea.<your-domain>/jlmak/claude-md-to-pdf.git
|
||||
git remote -v
|
||||
```
|
||||
|
||||
Expected: `origin` lists the Gitea URL for both `(fetch)` and `(push)`.
|
||||
|
||||
- [ ] **Step 3: Push**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git push -u origin main
|
||||
```
|
||||
|
||||
Expected: All commits land on Gitea. The web UI shows the spec, plan, manifests, skill, README, and LICENSE.
|
||||
|
||||
- [ ] **Step 4: Verify install from Gitea URL**
|
||||
|
||||
In a fresh Claude Code session (or after removing the local marketplace):
|
||||
|
||||
```
|
||||
/plugin marketplace remove claude-md-to-pdf
|
||||
/plugin marketplace add https://gitea.<your-domain>/jlmak/claude-md-to-pdf
|
||||
/plugin install md-to-pdf@claude-md-to-pdf
|
||||
```
|
||||
|
||||
Then re-run the smoke test from Task 6, Step 3 in the Databases project. Expected behavior identical to the local-install run.
|
||||
|
||||
- [ ] **Step 5: Tag a release**
|
||||
|
||||
```bash
|
||||
cd ~/Development/claude-md-to-pdf
|
||||
git tag -a v0.1.0 -m "Initial release: md-to-pdf skill"
|
||||
git push origin v0.1.0
|
||||
```
|
||||
|
||||
Expected: Tag visible on Gitea.
|
||||
|
||||
---
|
||||
|
||||
## Self-Review
|
||||
|
||||
(To be performed by the implementing agent before declaring the plan done — kept here so the engineer can re-check.)
|
||||
|
||||
**1. Spec coverage:**
|
||||
|
||||
| Spec section | Implemented in |
|
||||
|---|---|
|
||||
| Distribution via Gitea marketplace | Tasks 3, 7 |
|
||||
| Repo layout exactly as in spec | Tasks 1, 2, 3, 4 (file structure) |
|
||||
| Bundled default config (homework style) | Task 1 |
|
||||
| Natural-language trigger (DE+EN) | Task 4 (SKILL.md description) |
|
||||
| Source `.md` resolution rules | Task 4 (Procedure §1) |
|
||||
| Config resolution: project-local then bundled default | Task 4 (Procedure §2) |
|
||||
| `npx md-to-pdf` invocation, output next to source | Task 4 (Procedure §3) |
|
||||
| Confirmation with path/size/which config | Task 4 (Procedure §4) |
|
||||
| Error handling (npx missing, fetch fails, ambiguous source, broken config) | Task 4 (Error Handling section) |
|
||||
| Manual smoke test in Databases project | Task 6 Step 3 |
|
||||
| Smoke test for bundled-default fallback | Task 6 Step 4 |
|
||||
| Smoke test for ambiguous source | *Not in plan; out of v1 scope per spec — verifies "ask, don't guess" only via real-world use.* |
|
||||
| README with install instructions | Task 5 |
|
||||
|
||||
The "ambiguous source" smoke test from the spec's Testing Strategy is left to ad-hoc verification rather than a scripted task — it depends on Claude's judgment, not a deterministic command. Acceptable for v1.
|
||||
|
||||
**2. Placeholder scan:** None present. All steps contain concrete commands or full file content.
|
||||
|
||||
**3. Type/name consistency:**
|
||||
|
||||
- Plugin name: `md-to-pdf` everywhere (manifest, marketplace entry, install command, README, frontmatter).
|
||||
- Marketplace name: `claude-md-to-pdf` everywhere.
|
||||
- Bundled config path: `plugins/md-to-pdf/skills/md-to-pdf/default.config.js` and `${CLAUDE_PLUGIN_ROOT}/skills/md-to-pdf/default.config.js` — consistent (the latter is just the runtime form of the former).
|
||||
- Author identity (`Jean-Luc Makiola` / `mail@jeanlucmakiola.de`) consistent across plugin.json, marketplace.json, LICENSE.
|
||||
|
||||
No drift detected.
|
||||
Reference in New Issue
Block a user