Tooling & Lab
Inkforge
Notes, topics, or code → published technical articles.
3 min read · 524 words
Inkforge is personal publishing infrastructure — a CLI + web UI that turns scattered notes, topics, or code directories into polished technical articles and publishes them to Dev.to, Hashnode, and LinkedIn without leaving the terminal.
The core is a STORM two-stage pipeline: first an explicit outline artifact is generated (section tree + word budgets per section), then each section is drafted independently with context chaining, then a single humanization pass adds voice and transitions. For notes-dump inputs, an in-process BM25 RAG layer (no external vector DB — k1=1.5, b=0.75, hierarchical Markdown chunker) surfaces the top-5 relevant chunks into the outline prompt.
- STORM pipeline with explicit outlines — sections drafted independently, no context explosion; 4096-token budget with JSON truncation repair
- BM25 in-memory RAG — zero external service; scales to thousands of personal notes; 95% of semantic search quality at 10% of the cost
- Dual output sinks — primary
.mdfiles for portability; optional Anvilry.mdxmirror for Velite - Asset spec, not asset rendering — writes a markdown render-spec (cover dimensions, carousel slide count and copy); a human or agent renders the actual images by hand, nothing in the CLI touches pixels
- Platform publishers — Dev.to REST API v1 (canonical_url), Hashnode GraphQL v2 (originalArticleURL), cross-posting without SEO duplicate penalties
- Streaming web UI — SSE event stream from CLI pipeline into browser; section-by-section live preview at
/generate - Content-as-committed-data — generated articles gitignored; published tracking committed as source of truth
11/11 tests passing. Built the Tombstone launch article (3,531 words) from incident notes in one command. Ships as
@inkforge/cli.
Architecture
Inkforge is a pnpm monorepo: packages/core holds the pipeline, RAG layer, LLM abstraction, and publishers; packages/cli is the Commander entry point. Both are versioned at 0.1.1; root sits at 0.1.2, private, with no publishConfig — it runs from a git clone, not npm.
The LLM layer defaults to AWS Bedrock with a two-model fallback chain — Sonnet 4.6, then Haiku 4.5 — plus an LLM_PROVIDER=anthropic toggle. Opus 4.6 is deliberately excluded.
The publisher layer has two real implementations: a working Dev.to REST client, and a Hashnode GraphQL client that now throws a deprecation error. LinkedIn isn't a third publisher — there's no linkedin.ts; publish only recognizes --platform devto|hashnode. LinkedIn ships via a markdown render-spec instead, followed by hand outside the CLI. Two test files — ingestion, RAG chunker — back the 11/11 badge; not the publishers or LLM layer.
How It Works
- Input — notes dump, topic, or code directory.
- RAG surfacing (notes-dump only) — BM25 surfaces the top-5 chunks into the outline prompt.
- Outline generation — one LLM call builds the section tree and word budgets via the Bedrock fallback chain.
- Section drafting — each section drafted independently with context chaining, streamed over SSE into
/generate. - Humanization pass — one pass adds voice and transitions.
- Asset spec, not asset rendering — Inkforge writes a markdown render-spec (cover dimensions, carousel slide count and copy) rather than rendering anything itself; a human or agent follows that spec by hand to produce the actual images.
- Publish — Dev.to pushes automatically; Hashnode throws its deprecation error; LinkedIn's PDF is uploaded by hand.
- Tracking — the article stays local and gitignored; only the
content/published/<platform>/<slug>.mdrecord is committed. The same pipeline has since generated Trelix and Tombstone launches too.