@natjswenson/devlog 0.14.0 → 0.14.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/CHANGELOG.md +7 -0
- package/README.md +2 -2
- package/SKILL.md +21 -21
- package/bin/devlog.js +9 -6
- package/image-style/style-guide.example.md +19 -16
- package/package.json +1 -1
- package/skill-invariants.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,13 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@natjswenson/devlog` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.14.1 (2026-09-10) — native branded cover generation
|
|
6
|
+
|
|
7
|
+
- Require Codex covers to use native generated raster artwork in the established
|
|
8
|
+
monochrome technical-engraving PRESS style; reject wireframes and SVG substitutes.
|
|
9
|
+
- Require copyable agent handoffs and validated covers before publication.
|
|
10
|
+
- Fix cover backfills when the target repository stores entries below `targetDir`.
|
|
11
|
+
|
|
5
12
|
## 0.14.0 (2026-09-09) — verified concept guides and AI cover composition
|
|
6
13
|
|
|
7
14
|
- Add an explicit concept-guide draft workflow: select one transferable reader
|
package/README.md
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
# devlog
|
|
2
2
|
|
|
3
|
-
<!-- >>> press:masthead v0.
|
|
4
|
-
**NS** · NATE SWENSON · CLAUDE CODE + CODEX SKILL · PRESS v0.
|
|
3
|
+
<!-- >>> press:masthead v0.10.0 sha256:b950ecf78f98 GENERATED by @natjswenson/press, do not edit -->
|
|
4
|
+
**NS** · NATE SWENSON · CLAUDE CODE + CODEX SKILL · PRESS v0.10.0 · linkedin.com/in/natejswenson
|
|
5
5
|
|
|
6
6
|
---
|
|
7
7
|
<!-- <<< press:masthead -->
|
package/SKILL.md
CHANGED
|
@@ -19,6 +19,10 @@ apps by capability rather than assuming Claude MCP tool names exist.
|
|
|
19
19
|
|
|
20
20
|
# /devlog — Release How-To Generator
|
|
21
21
|
|
|
22
|
+
<!-- press:runtime -->
|
|
23
|
+
In Claude Code, load `/press`; in Codex, load `$press`; then follow the shared PRESS terminal/UI contract from `brand/agent-ui.md`. Do not copy or override that contract here.
|
|
24
|
+
<!-- press:runtime -->
|
|
25
|
+
|
|
22
26
|
In the default Generate mode, you turn each **new version release** (a semver git tag) in the user's projects into a
|
|
23
27
|
published blog post, written in **the user's own voice**, and pushed to the GitHub repo
|
|
24
28
|
configured in `~/.claude/skills/devlog/config.json`.
|
|
@@ -392,9 +396,12 @@ The `--clone` flag always points at the CONTENT ROOT: `<abs-tmp>/<repo-name>` wh
|
|
|
392
396
|
`targetDir` is empty, `<abs-tmp>/<repo-name>/<targetDir>` when it's set. Git commands
|
|
393
397
|
always run against the clone root `<abs-tmp>/<repo-name>` regardless.
|
|
394
398
|
|
|
395
|
-
In this
|
|
396
|
-
release's own `publish-entry` call
|
|
397
|
-
|
|
399
|
+
In this Generate path, each release also gets a cover image, created inline in this same loop right before that
|
|
400
|
+
release's own `publish-entry` call. In Codex, the dominant artwork MUST come from the native
|
|
401
|
+
image-generation tool as a persisted raster source; wireframes, hand-authored SVG, CSS drawings,
|
|
402
|
+
and title-only placeholders are not covers. The deterministic compositor may add PRESS typography
|
|
403
|
+
around that generated artwork, but it must never substitute for native image generation.
|
|
404
|
+
The cover must carry a custom illustration or other meaningful visual material; a cover that just re-renders the title in large text is a failure.
|
|
398
405
|
|
|
399
406
|
```bash
|
|
400
407
|
mktemp -d # → record the absolute path, e.g. /var/folders/.../tmp.abc
|
|
@@ -415,24 +422,17 @@ Per release:
|
|
|
415
422
|
returns the style guide, icon catalog, and up to 3 reference cover paths. **Read
|
|
416
423
|
only the single most recent reference image** (image reads are the expensive part;
|
|
417
424
|
open another only if you're genuinely unsure the new cover is distinct). On
|
|
418
|
-
`{"error": "style-guide-missing"}`:
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
(render-cover mechanically enforces this), one of two slots (single centered hero,
|
|
430
|
-
or two-node before/after), interior points snapped to a 25px grid; catalog icons
|
|
431
|
-
never go inside `#hero-zone` (optional small accent glyph near the kicker only,
|
|
432
|
-
bottom edge above y:400). Write the document with the Write tool to
|
|
433
|
-
`'<abs-scratch>/<key>/<version>.html'` — full `<!DOCTYPE html>` document, sized
|
|
434
|
-
`html, body { margin:0; width:1600px; height:900px; }`, font referenced only as
|
|
435
|
-
`font-family: 'DevlogCoverFont', sans-serif`.
|
|
425
|
+
`{"error": "style-guide-missing"}`: stop this release and report that publication is
|
|
426
|
+
blocked. A release entry is not publishable without a cover and agent handoff.
|
|
427
|
+
2. **Generate and compose.** Use ONLY this release's title/tags/summary/`## Shipped` text
|
|
428
|
+
(never the raw draft file, never `## Changelog`) plus the style guide and icon catalog to
|
|
429
|
+
brief the native image-generation tool. Request artwork only: one concrete mechanism,
|
|
430
|
+
no lettering, labels, numbers, logos, fake code, UI, wireframe, gradients, or watermark.
|
|
431
|
+
Persist and inspect the exact returned raster, then use `compose-art-cover` to add local
|
|
432
|
+
PRESS typography. Do not draw the dominant art as inline SVG or CSS. A cover that just
|
|
433
|
+
re-renders the title in large text is a failure. Match the established backfill look:
|
|
434
|
+
flat cream paper, monochrome technical engraving, black/gray ink, restrained crosshatching,
|
|
435
|
+
a quiet left field for the headline, and at most one small orange accent.
|
|
436
436
|
3. **Rasterize.**
|
|
437
437
|
`npx -y @natjswenson/devlog@latest render-cover '<abs-scratch>/<key>/<version>.html' --project '<key>' --slug '<version>' --out '<abs-scratch>'`
|
|
438
438
|
The HTML is the source of truth and **survives the render**: to fix a visual
|
package/bin/devlog.js
CHANGED
|
@@ -1126,15 +1126,18 @@ async function cmdCommitCovers(rest) {
|
|
|
1126
1126
|
// routinely runs well after the backfill/review session that produced the staging dir,
|
|
1127
1127
|
// and reusing an hours-or-days-old clone would risk mutating a manifest that's since
|
|
1128
1128
|
// moved on.
|
|
1129
|
-
const
|
|
1129
|
+
const repoDir = mkdtempSync(join(tmpdir(), 'devlog-commit-covers-'));
|
|
1130
1130
|
const branch = config.branch || 'main';
|
|
1131
1131
|
const cloneUrl = `https://github.com/${config.targetRepo}.git`;
|
|
1132
|
-
const cloneResult = spawnSync('git', ['clone', '--depth=1', '--branch', branch, cloneUrl,
|
|
1132
|
+
const cloneResult = spawnSync('git', ['clone', '--depth=1', '--branch', branch, cloneUrl, repoDir], { encoding: 'utf8' });
|
|
1133
1133
|
if (cloneResult.status !== 0) {
|
|
1134
|
-
rmSync(
|
|
1134
|
+
rmSync(repoDir, { recursive: true, force: true });
|
|
1135
1135
|
emitJSON({ error: 'clone-failed', message: cloneResult.stderr || 'git clone failed' }, 1);
|
|
1136
1136
|
return;
|
|
1137
1137
|
}
|
|
1138
|
+
// Manifests live under the configured content root; git operations still run
|
|
1139
|
+
// from the repository root.
|
|
1140
|
+
const cloneDir = join(repoDir, config.targetDir || '');
|
|
1138
1141
|
|
|
1139
1142
|
const summary = { written: [], skipped: [], failed: [], missingManifest: [] };
|
|
1140
1143
|
let bulkForceOverwriteCount = 0;
|
|
@@ -1199,20 +1202,20 @@ async function cmdCommitCovers(rest) {
|
|
|
1199
1202
|
['commit', '-m', `chore(devlog): add ${summary.written.length} cover image(s)`],
|
|
1200
1203
|
];
|
|
1201
1204
|
for (const args of steps) {
|
|
1202
|
-
const r = spawnSync('git', ['-C',
|
|
1205
|
+
const r = spawnSync('git', ['-C', repoDir, ...args], { encoding: 'utf8' });
|
|
1203
1206
|
if (r.status !== 0) {
|
|
1204
1207
|
emitJSON({ ok: false, ...summary, bulkForceOverwriteCount, error: 'git-commit-failed', message: r.stderr }, 1);
|
|
1205
1208
|
return;
|
|
1206
1209
|
}
|
|
1207
1210
|
}
|
|
1208
|
-
const push = spawnSync('git', ['-C',
|
|
1211
|
+
const push = spawnSync('git', ['-C', repoDir, 'push', '--no-tags', 'origin', branch], { encoding: 'utf8' });
|
|
1209
1212
|
if (push.status !== 0) {
|
|
1210
1213
|
emitJSON({ ok: false, ...summary, bulkForceOverwriteCount, error: 'git-push-failed', message: push.stderr }, 1);
|
|
1211
1214
|
return;
|
|
1212
1215
|
}
|
|
1213
1216
|
}
|
|
1214
1217
|
|
|
1215
|
-
rmSync(
|
|
1218
|
+
rmSync(repoDir, { recursive: true, force: true });
|
|
1216
1219
|
emitJSON({ ok: summary.failed.length === 0, ...summary, bulkForceOverwriteCount });
|
|
1217
1220
|
}
|
|
1218
1221
|
|
|
@@ -11,8 +11,9 @@ are how a from-scratch visual language stays consistent from post to post.
|
|
|
11
11
|
|
|
12
12
|
## What you're composing
|
|
13
13
|
|
|
14
|
-
A single
|
|
15
|
-
|
|
14
|
+
A single PRESS editorial cover that renders, at exactly 1600×900px, as a cover image for
|
|
15
|
+
one dev log entry. In Codex, the dominant image is a native generated raster illustration;
|
|
16
|
+
the local compositor adds the typography and layout. Compose from these
|
|
16
17
|
fields only — never open the post's raw markdown file, never reference any section other
|
|
17
18
|
than `## Shipped` (no `## Changelog`, no gotchas, no sources):
|
|
18
19
|
- `title`
|
|
@@ -34,11 +35,11 @@ Before writing any HTML, do this thinking step explicitly:
|
|
|
34
35
|
key that doesn't fit, a git tag being distrusted like any other user input, one broken
|
|
35
36
|
link in a chain, a filter separating signal from noise, a clock catching a stale
|
|
36
37
|
timestamp, two paths diverging and one being cut off.
|
|
37
|
-
3. Design ONE illustration
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
38
|
+
3. Design ONE native raster illustration that depicts that concept. Not a photo, stock
|
|
39
|
+
icon, screenshot, UI, wireframe, or geometric placeholder: a detailed original
|
|
40
|
+
**monochrome technical engraving in black and warm gray ink on flat cream paper**, in
|
|
41
|
+
the spirit of a historical engineering plate or newspaper field illustration, with at
|
|
42
|
+
most one small vermilion/orange focal accent. The art must look printed, not painterly.
|
|
42
43
|
4. That illustration is the dominant visual element of the cover — roughly half the
|
|
43
44
|
canvas, not a thumbnail in the corner. Title, kicker, and summary text support it;
|
|
44
45
|
they do not replace it.
|
|
@@ -151,10 +152,10 @@ For the two-node slot specifically: the accent icon's presence must not be read
|
|
|
151
152
|
`DevlogCoverFont` finishes loading. That's resolving a name the browser already has, not
|
|
152
153
|
embedding or fetching a file — no different in kind from the fallback this rule already
|
|
153
154
|
requires.
|
|
154
|
-
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
155
|
+
- The final cover must be self-contained and offline-renderable. Native raster artwork is
|
|
156
|
+
persisted locally and embedded by `compose-art-cover`; no remote images or web fonts.
|
|
157
|
+
Typography is rendered locally and the generated artwork is never replaced by inline
|
|
158
|
+
SVG, CSS shapes, a wireframe, or a title-only placeholder.
|
|
158
159
|
|
|
159
160
|
## Visual direction
|
|
160
161
|
|
|
@@ -165,7 +166,7 @@ site, not a marketing graphic and not a repeated template.
|
|
|
165
166
|
|
|
166
167
|
### Palette
|
|
167
168
|
|
|
168
|
-
<!-- >>> press:palette v0.
|
|
169
|
+
<!-- >>> press:palette v0.10.0 sha256:5904c52d4168 GENERATED by @natjswenson/press, do not edit -->
|
|
169
170
|
- **Paper** `#F5F0E6` — Warm cream. Flat — never gradiented, never textured.
|
|
170
171
|
- **Ink** `#181510` — Near-black. Text, headlines, and every structural rule.
|
|
171
172
|
- **Dim** `#6E675C` — Muted secondary text; the serif commentary voice's color.
|
|
@@ -176,9 +177,10 @@ site, not a marketing graphic and not a repeated template.
|
|
|
176
177
|
survives, and only inside a terminal element. Never on paper.
|
|
177
178
|
<!-- <<< press:palette -->
|
|
178
179
|
|
|
179
|
-
Prefer flat, limited color and solid/line fills over gradients or smooth shading
|
|
180
|
-
|
|
181
|
-
|
|
180
|
+
Prefer flat, limited color and solid/line fills over gradients or smooth shading. Native
|
|
181
|
+
art should be predominantly cream paper plus black/gray engraving lines, with no broad
|
|
182
|
+
color wash, no saturated palette, and no painterly digital lighting. The only bright color
|
|
183
|
+
is the single small orange accent permitted by the accent law below.
|
|
182
184
|
|
|
183
185
|
### The accent law, carried to covers
|
|
184
186
|
|
|
@@ -304,7 +306,8 @@ summary as on-image text.
|
|
|
304
306
|
cursor, no bare `_` suffix, no stray `$` prompt as decoration. The dark palette now
|
|
305
307
|
belongs to exactly one place, the `.term` panel, and only when it's real code.
|
|
306
308
|
- Don't embed a photograph, stock image, or anything requiring an external fetch — the
|
|
307
|
-
illustration is
|
|
309
|
+
illustration is native-generated raster artwork persisted locally and embedded by the
|
|
310
|
+
compositor, never a hand-authored SVG substitute.
|
|
308
311
|
- Don't reference any font file other than the bundled `'DevlogCoverFont'` — the serif
|
|
309
312
|
and display voices lean on this rendering host's own system fonts, never a file you
|
|
310
313
|
fetch or embed yourself.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@natjswenson/devlog",
|
|
3
|
-
"version": "0.14.
|
|
3
|
+
"version": "0.14.1",
|
|
4
4
|
"description": "Release dev log generator — Claude Code skill + preview app for publishing version-release dev logs, written in your voice, to your site",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "Nate Swenson",
|
package/skill-invariants.json
CHANGED
|
@@ -72,9 +72,9 @@
|
|
|
72
72
|
"rationale": "Cover composition must draw only from title/tags/summary/## Shipped \u2014 never the raw draft or Changelog \u2014 losing this line reopens off-scope content leaking into an auto-composed image."
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
|
-
"id": "cover-
|
|
76
|
-
"pattern": "
|
|
77
|
-
"rationale": "A missing/uninstalled style guide must
|
|
75
|
+
"id": "cover-required-before-publish",
|
|
76
|
+
"pattern": "publication is[\\s\\S]{0,5}blocked",
|
|
77
|
+
"rationale": "A missing/uninstalled style guide must stop the release so Generate mode cannot publish an entry without its required cover."
|
|
78
78
|
},
|
|
79
79
|
{
|
|
80
80
|
"id": "cover-review-gate",
|