Files
librenotes/.wave/pipelines/blog-draft.yaml
Michael Czechowski fc24f9a8ab Add Wave general-purpose pipelines
ADR, changelog, code-review, debug, doc-sync, explain, feature,
hotfix, improve, onboard, plan, prototype, refactor, security-scan,
smoke-test, speckit-flow, supervise, test-gen, and more.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-25 17:02:36 +01:00

169 lines
5.5 KiB
YAML

kind: WavePipeline
metadata:
name: blog-draft
description: "Draft a blog post from Zettelkasten notes and web research"
release: true
input:
source: cli
examples:
- "Context Economy | context windows, token economics, agent memory"
- "The Frame Problem in Code | divergent thinking, convergent thinking, planner worker"
- "Temporal Code Graphs | git history, co-modification, relevance signals"
steps:
- id: zettel-search
persona: navigator
workspace:
mount:
- source: ./
target: /project
mode: readonly
exec:
type: prompt
source: |
Search the Zettelkasten for notes relevant to a blog post.
Input: {{ input }}
The input format is "Title | keyword1, keyword2, keyword3".
Parse the title and keywords from the input.
## Steps
1. For each keyword, search with: `notesium lines --filter="keyword"`
2. Read the index note to find entry points for related sections
3. Read the most relevant notes found (up to 15 notes)
4. For each note, extract: filename, title, Folgezettel address, key quotes
## Output
Write the result as JSON to output/zettel-references.json matching the contract schema.
Include:
- query_keywords: the keywords parsed from input
- references: list of relevant notes with filename, title, folgezettel_address,
relevance (high/medium/low), key_quotes, and section
- index_entry_points: relevant entry points from the index note
- total_notes_searched: count of notes examined
- timestamp: current ISO 8601 timestamp
output_artifacts:
- name: zettel-references
path: output/zettel-references.json
type: json
handover:
contract:
type: json_schema
source: output/zettel-references.json
schema_path: .wave/contracts/zettel-references.schema.json
on_failure: retry
max_retries: 2
- id: web-research
persona: scout
workspace:
mount:
- source: ./
target: /project
mode: readonly
exec:
type: prompt
source: |
Research the web for recent information on a blog post topic.
Input: {{ input }}
The input format is "Title | keyword1, keyword2, keyword3".
Parse the title and keywords from the input.
## Steps
1. WebSearch for the topic title + recent developments
2. WebSearch for each keyword individually
3. Fetch the top 3-5 most relevant and credible sources
4. Extract key ideas, direct quotes with attribution, and URLs
5. Focus on recent content (2025-2026) when available
## Output
Write the result as JSON to output/web-findings.json matching the contract schema.
Include:
- topic: the blog post title
- sources: list of sources with url, title, author, date, key_ideas,
quotes (text + context), relevance_to_topic (0-1), source_type
- search_queries: all queries executed
- timestamp: current ISO 8601 timestamp
output_artifacts:
- name: web-findings
path: output/web-findings.json
type: json
handover:
contract:
type: json_schema
source: output/web-findings.json
schema_path: .wave/contracts/web-findings.schema.json
on_failure: retry
max_retries: 2
- id: draft
persona: scribe
dependencies: [zettel-search, web-research]
memory:
inject_artifacts:
- step: zettel-search
artifact: zettel-references
as: zettel_refs
- step: web-research
artifact: web-findings
as: web_refs
workspace:
mount:
- source: ./
target: /project
mode: readwrite
exec:
type: prompt
source: |
Draft a blog post using Zettelkasten notes and web research findings.
Input: {{ input }}
Parse the title from the input (format: "Title | keywords").
Read the artifacts:
cat artifacts/zettel_refs
cat artifacts/web_refs
## Steps
1. **Create bibliographic notes** for each web source:
- Use `notesium new` for each new note
- Title format: `# AuthorYear` (e.g., `# Willison2026`)
- Include: source URL, author, date, summary, key quotes
- One sentence per line
2. **Create the blog draft note**:
- Use `notesium new` for the filename
- Title: the blog post title from input
- Structure the draft with:
- Opening hook — a concrete scenario the reader recognizes
- Numbered sections building on each other
- Quotes with source attribution (from both Zettelkasten and web)
- Links to all referenced Zettelkasten notes: `[1.2 Linking](filename.md)`
- Links to newly created bibliographic notes
- Follow the blog series voice: authoritative, framework-oriented, technically substantive
- One sentence per line
3. **Commit all new notes**:
- `git add *.md`
- `git commit -m "blog-draft: {title in lowercase}"`
4. **Write a summary** to output/draft-summary.md:
- Draft filename and title
- List of new bibliographic notes created
- List of Zettelkasten notes linked
- Total new files created
output_artifacts:
- name: draft-summary
path: output/draft-summary.md
type: markdown