@natjswenson/devlog 0.5.2 → 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md CHANGED
@@ -39,7 +39,7 @@ Map the user's request onto the CLI — never hand-edit `config.json`:
39
39
  | Intent | Command |
40
40
  |---|---|
41
41
  | Show config | `npx -y @natjswenson/devlog config --json` |
42
- | Add a project | `npx -y @natjswenson/devlog add-project --yes --path <abs-path> [--key K] [--remote O/R] [--label L] [--tag-prefix P] [--path-filter F]` |
42
+ | Add a project | `npx -y @natjswenson/devlog add-project --yes --path <abs-path> [--key K] [--remote O/R] [--label L] [--tag-prefix P] [--path-filter F] [--private]` |
43
43
  | Remove a project | `npx -y @natjswenson/devlog remove-project <key> --yes` |
44
44
  | Change a setting | `npx -y @natjswenson/devlog set <field> <value>` (settable: `targetRepo`, `branch`, `gitAuthor`, `githubUser`, `voicePath`, `deepDive.minSources`, `deepDive.topicDomains`) |
45
45
 
@@ -51,6 +51,16 @@ get-url origin`. In a monorepo, suggest a `--path-filter` (the project's subdir)
51
51
  and show the resulting project list. For **remove-project**, confirm once before running;
52
52
  tell the user published entries are not deleted.
53
53
 
54
+ **Private repos.** If the user says the repo is private (or a source repo happens to be
55
+ private on GitHub even though it's configured normally), pass `--private`. A private
56
+ project's commits are never marked public in the scan (see Generate mode), so no post ever
57
+ links a commit for it, `## Changelog` is always omitted, and `--remote` is optional — the
58
+ tool has no reason to know or use the repo's GitHub location. This is a declared project
59
+ *type*, not something auto-detected from the GitHub API: `remoteMatches` + "on the
60
+ published branch" alone doesn't imply the repo is public, so a project with a real, correctly
61
+ configured remote that happens to sit in a private repo needs this flag or its commits would
62
+ otherwise scan as public.
63
+
54
64
  If any command prints `{"error": "config-missing", ...}`, tell the user to run
55
65
  `npx @natjswenson/devlog init` first. On `config-invalid`, show the message and offer to
56
66
  fix the named field via `set`.
@@ -109,30 +119,55 @@ For each new release, in order:
109
119
 
110
120
  **3a. Understand what actually shipped.** The scan gives you commit subjects and a
111
121
  diffstat. When you need more, read the real changes — validate every hash matches
112
- `^[0-9a-f]{7,40}$` first, then:
122
+ `^[0-9a-f]{7,40}$` first, then (when a commit message and its diff disagree on a
123
+ specific fact — a count, a filename, a behavior — the diff wins):
113
124
 
114
125
  ```bash
115
126
  git -C '<project.path>' show --stat '<hash>'
116
127
  git -C '<project.path>' show '<hash>' -- '<project.pathFilter>'
117
128
  ```
118
129
 
130
+ Teach the code **as it existed at this tag**, not as it looks today — the repo may have
131
+ moved on since the release. When you need a file's state rather than a diff, use
132
+ `git -C '<project.path>' show '<tag>:<file>'` instead of reading the working tree.
133
+ This anchors the **facts** (what shipped, what it did); the teaching implementation may
134
+ still be a cleaner generalization per the how-to contract — anchor claims at the tag,
135
+ generalize the code.
136
+
119
137
  **3b. Derive the topic.** Identify the **one** substantive engineering topic the work
120
138
  touched (occasionally more, only when the work genuinely spans them) within
121
139
  `deepDive.topicDomains`. The topic is the general concept *behind* what shipped (e.g.
122
140
  shipping a `feature→dev→main` flow → branching strategy and release engineering). Never
123
141
  pad with topics the work didn't touch.
124
142
 
143
+ Between candidate topics, pick the one the reader can most plausibly **use**: a
144
+ transferable technique they could apply to their own project this week beats project
145
+ trivia or niche internals. If the obvious topic is repo-specific, step up one level to
146
+ the general pattern behind it — the test is "could a reader finish this how-to and have
147
+ something working of their own?" When a release spans two candidate topics (or two
148
+ releases in one run share one), don't write the same guide twice: give each post the
149
+ most usable topic the run hasn't already covered. In a monorepo, one commit can appear
150
+ in several projects' ranges — it belongs to the post whose release story it is; other
151
+ posts leave it out of their narrative and `## Changelog` (check what sibling entries
152
+ already cover, across all projects).
153
+
125
154
  **3c. Research before writing.** Use web search/fetch to gather at least
126
155
  `deepDive.minSources` **distinct** reputable sources: official docs and release notes,
127
156
  standards bodies, primary research, well-regarded engineering writing. Avoid SEO farms.
128
157
  Every specific external claim (a version, a behavior, a study, a definition) must be
129
158
  backed by a source you actually verified — if you can't source it, don't claim it. Don't
130
- lean on one URL for most claims. Keep a working `(claim, url)` list.
159
+ lean on one URL for most claims. Keep a working `(claim, url)` list. Fetch tools can
160
+ summarize a page into quote-shaped text that isn't on it: before putting anything in
161
+ quotation marks, re-fetch asking for the verbatim wording and drop the quotes (paraphrase
162
+ instead) if it can't be confirmed.
131
163
 
132
164
  **3d. Mine the gotchas.** Gotchas are the post's signature — **real traps from the
133
165
  user's own experience**, never invented. Look for them in: fix commits that follow the
134
166
  feature commits in the range, revert commits, `CHANGELOG` "Fixed" entries for this
135
- version, and corrections visible in the diffs (an approach that changed mid-range). Each
167
+ version, and corrections visible in the diffs (an approach that changed mid-range).
168
+ Also follow the code this release introduced **forward** in history (`git log '<tag>..'
169
+ -- <files it touched>`): a later fix to that same code is prime gotcha material, as long
170
+ as the post says plainly when it was discovered ("this bit us a few weeks later"). Each
136
171
  gotcha is written as **trap → symptom → escape**, concretely. If the history genuinely
137
172
  shows none, the `## Gotchas` section instead covers the sourced failure modes a reader
138
173
  will hit first, clearly framed as "what to watch for" rather than as personal war stories.
@@ -141,11 +176,13 @@ will hit first, clearly framed as "what to watch for" rather than as personal wa
141
176
 
142
177
  ```markdown
143
178
  ---
144
- title: "<essay-style title; NOT 'release vX.Y.Z'>"
179
+ title: "<essay-style title in sentence case (capitalize only the first word and proper nouns); NOT 'release vX.Y.Z'>"
145
180
  date: <release date from scan>
146
181
  project: <project key>
147
182
  version: <version from scan>
148
- tags: [<2-5 lowercase topic tags>]
183
+ tags: [<5-10 specific, lowercase tags — tools, techniques, and concepts actually
184
+ present in the post, not just broad topic labels, e.g. git, ci-cd,
185
+ release-engineering, github-actions, semver, changelog-automation>]
149
186
  summary: "<1-2 sentence hook that frames the how-to, not just what shipped>"
150
187
  ---
151
188
 
@@ -154,6 +191,11 @@ summary: "<1-2 sentence hook that frames the how-to, not just what shipped>"
154
191
  <2-4 sentences: what this release delivered, plainly, then pivot to the topic the guide
155
192
  teaches. The only purely-changelog part.>
156
193
 
194
+ <!-- Between Shipped and Gotchas, the headings below are the default shape, not a
195
+ requirement — only Shipped, Gotchas, and Sources are mandatory. Merge or reorder the
196
+ middle sections when the walkthrough flows better that way. Fence command OUTPUT
197
+ blocks as `text`. -->
198
+
157
199
  ## <Descriptive heading: setup / prerequisites>
158
200
 
159
201
  <What a reader needs before the core build: dependencies, config, data model. Code block
@@ -189,11 +231,17 @@ the wiring between pieces, not just the interesting line.>
189
231
  2. **Complete code.** Every symbol a code block references is defined in an earlier
190
232
  block or explicitly stubbed with a one-line note ("`load_fixtures()` returns your test
191
233
  DB handle"). The blocks compose into a runnable whole — no phantom fixtures or elided
192
- helpers. Aim for the essential blocks (roughly 3-6 for a substantive feature); a clean,
234
+ helpers, and if a later block revises an earlier function, show the complete new
235
+ function, never a fragment calling helpers no block defines. Aim for the essential blocks (roughly 3-6 for a substantive feature); a clean,
193
236
  general version of the concept is the goal, and never claim illustrative code is
194
237
  verbatim production source.
195
238
  3. **Reader-side verification.** The verify step gives commands the READER runs against
196
239
  THEIR implementation, with expected output — not proof that the author's repo works.
240
+ When the blocks are cheap to execute (scratch dir, no external services), actually
241
+ run them and paste the real output. Never present output as observed if you didn't
242
+ run the command; if you can't run it, frame the expectation ("you should see…").
243
+ Verbose real output (tracebacks, long logs) may be trimmed to the signal lines or
244
+ whitespace-normalized when the post says so.
197
245
  4. **Real gotchas** per 3d.
198
246
  5. **Source diversity** per 3c, cited inline as markdown links AND in `## Sources`.
199
247
  6. **Honest scope.** A single test file is not "end-to-end". Size the title, summary, and
@@ -202,12 +250,21 @@ the wiring between pieces, not just the interesting line.>
202
250
  teaser.
203
251
  7. **No leaked repo-specific artifacts.** Genericize or explain anything a stranger
204
252
  would trip on (`.example` suffixes, monorepo nesting, internal tool names).
253
+ 8. **Fun to follow.** The guide reads like a generous colleague walking the reader
254
+ through a build they'll actually finish: give an early runnable win, keep momentum
255
+ between steps, and make the payoff visible at each stage (show real output, not just
256
+ code). Fun comes from quick wins and concrete results — never forced jokes, hype, or
257
+ exclamation points.
205
258
 
206
259
  **Separate fact from concept.** What the user *did* comes only from commits/diffs —
207
260
  never invent metrics, motivations, or outcomes. What the topic *is* comes from the cited
208
261
  sources. Keep the two distinguishable. Match the voice profile + `voice-notes.md`
209
- (authenticity, anti-AI-tell, and punctuation rules), but NOT any length/reach rules
210
- target ~900-1600 words for a substantive feature, shorter for a small change. Only link
262
+ (authenticity, anti-AI-tell, and punctuation rules these govern the PROSE; the em dash
263
+ in the `## Sources` template line is fixed template punctuation, and verbatim quoted
264
+ data such as commit subjects in `## Changelog` keeps its original punctuation),
265
+ but NOT any length/reach rules —
266
+ target ~900-1600 words of prose (code blocks don't count) for a substantive feature,
267
+ shorter for a small change. Only link
211
268
  commits where `public: true` in the scan; omit `## Changelog` if none are.
212
269
 
213
270
  ### Step 4: Self-check before publishing
@@ -217,10 +274,15 @@ Write each draft with the **Write tool** (never a bash heredoc) to a temp dir
217
274
  calls). Name it `<version>.md`. Then:
218
275
 
219
276
  1. **Lint:** `npx -y @natjswenson/devlog lint-post '<abs-draft-path>'` — fix every
220
- finding (missing sections, thin gotchas, too few distinct sources, untagged fences).
221
- 2. **Self-review against the how-to contract**, honestly, as a skeptical reader: walk
222
- points 1-7 above plus voice adherence. Revise the draft for any point that fails.
223
- 3. At most **two** revision passes; then proceed with the best version and carry any
277
+ finding (missing sections, thin gotchas, too few distinct sources, sources listed
278
+ but never cited inline, untagged fences).
279
+ 2. **Assemble-and-run check:** when the post's code is runnable without external
280
+ services, copy its code blocks in order into a scratch dir and execute them exactly
281
+ as a reader would. Anything undefined, out of order, or missing an entrypoint fails
282
+ the stranger test mechanically — fix the post, not just the scratch copy.
283
+ 3. **Self-review against the how-to contract**, honestly, as a skeptical reader: walk
284
+ points 1-8 above plus voice adherence. Revise the draft for any point that fails.
285
+ 4. At most **two** revision passes; then proceed with the best version and carry any
224
286
  residual weakness into the final summary (e.g. "v0.5.0: only 2 gotchas had commit
225
287
  evidence").
226
288
 
@@ -232,15 +294,51 @@ critique, not a rubber stamp.
232
294
  Clone once, publish each entry through the CLI, push once. `targetRepo` and `branch` come
233
295
  from validated config — still single-quote every interpolated value.
234
296
 
297
+ Each release also gets a cover image, composed inline in this same loop right before that
298
+ release's own `publish-entry` call — a self-contained HTML/CSS (or inline SVG) document,
299
+ rasterized locally, never sent to any external service:
300
+
235
301
  ```bash
236
302
  mktemp -d # → record the absolute path, e.g. /var/folders/.../tmp.abc
237
303
  git -C '<abs-tmp>' clone --depth=1 'https://github.com/<targetRepo>.git'
238
304
 
239
305
  # Per release (refuses to overwrite an existing entry — on {"error": ...,
240
306
  # "message": "... immutable ..."} skip that release and note it):
307
+
308
+ # 1. Style guide + up to 3 reference images of recently published covers.
309
+ npx -y @natjswenson/devlog cover-context '<key>' '<version>' \
310
+ --clone '<abs-tmp>/<repo-name>'
311
+ # On {"error": "style-guide-missing", ...}: skip cover composition for this release
312
+ # entirely — proceed straight to publish-entry with no --cover flag. Never block
313
+ # publish on a missing style guide.
314
+
315
+ # 2. Compose the cover using ONLY this release's title/tags/summary/`## Shipped` text
316
+ # (never the raw draft file, never `## Changelog`) plus the returned style guide and
317
+ # reference images. A cover that just re-renders the title in large text is a failure —
318
+ # find the one concrete mechanism this release is actually about (not the project name,
319
+ # not "a bug fix") and draw ONE custom inline-SVG illustration of it, sized as the
320
+ # dominant visual element of the canvas; title/kicker stay secondary. Two different
321
+ # releases should never produce visually similar covers — see the style guide's "one
322
+ # custom illustration per post" section before composing. Write the result with the
323
+ # Write tool to '<abs-scratch>/<key>/<version>.html' — a full document starting with
324
+ # `<!DOCTYPE html>`, sized `html, body { margin:0; width:1600px; height:900px; }`,
325
+ # referencing the bundled font only as `font-family: 'DevlogCoverFont', sans-serif`.
326
+
327
+ # 3. Rasterize it. On failure (render timeout / Chromium not installed / font missing),
328
+ # the .html is left in place for debugging — retry composing once with the error text
329
+ # fed back, or give up and proceed with no --cover flag.
330
+ npx -y @natjswenson/devlog render-cover '<abs-scratch>/<key>/<version>.html' \
331
+ --project '<key>' --slug '<version>' --out '<abs-scratch>'
332
+ # Show the rendered <abs-scratch>/<key>/<version>.png in this session before continuing —
333
+ # this interactive review IS the quality gate for the cover, the same way Step 4 is for
334
+ # the prose.
335
+
241
336
  npx -y @natjswenson/devlog publish-entry \
242
337
  --clone '<abs-tmp>/<repo-name>' --project '<key>' \
243
- --version '<version>' --entry '<abs-draft-path>'
338
+ --version '<version>' --entry '<abs-draft-path>' \
339
+ --cover '<abs-scratch>/<key>/<version>.png'
340
+ # Omit --cover entirely if no cover was produced for this release (missing style guide,
341
+ # a render failure not worth a second attempt) — publish still proceeds normally.
244
342
 
245
343
  git -C '<abs-tmp>/<repo-name>' add .
246
344
  git -C '<abs-tmp>/<repo-name>' commit -m 'devlog: add release entries'