@natjswenson/devlog 0.11.2 → 0.13.0
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 +83 -15
- package/SKILL.md +72 -7
- package/image-style/style-guide.example.md +37 -2
- package/lib/config_ops.mjs +1 -0
- package/lib/core.mjs +13 -0
- package/lib/publish_entry.mjs +15 -1
- package/lib/scan.mjs +5 -0
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -2,21 +2,89 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@natjswenson/devlog` are documented here.
|
|
4
4
|
|
|
5
|
-
## 0.
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
## 0.13.0 (2026-07-29) — a publish run now proves the entry is live
|
|
6
|
+
|
|
7
|
+
Publishing reported success on a post that was never reachable. The content, cover
|
|
8
|
+
and manifest all landed correctly, the push succeeded, every command returned `ok`,
|
|
9
|
+
and the entry 404'd for an hour because the site's own project registry had never
|
|
10
|
+
been told the project existed. A push is not a route, and this release stops the
|
|
11
|
+
skill treating the two as the same thing.
|
|
12
|
+
|
|
13
|
+
- **Added: `publish-entry` returns `firstEntryForProject`.** True when the call
|
|
14
|
+
created a project's first live entry, which is exactly when a rendering site needs
|
|
15
|
+
a new registry row. A project holding only tombstones still counts as first, since
|
|
16
|
+
a retired entry never implied a route. Previously nothing distinguished a project's
|
|
17
|
+
first publish from its fiftieth, so the one moment registration is required looked
|
|
18
|
+
identical to every run where it isn't.
|
|
19
|
+
- **Added: `siteUrl` config field** (settable, optional, trailing slash stripped,
|
|
20
|
+
http(s) only) plus `siteUrl` in the scan output. The repo name is not the site name
|
|
21
|
+
— a repo named `example.io` is commonly served at `example.com` — so a publish run
|
|
22
|
+
had no way to reach the page it had just published.
|
|
23
|
+
- **Added: SKILL.md Generate step 5b (register a project the site has never
|
|
24
|
+
rendered).** Find the site's registry, add the project, and *build the clone to
|
|
25
|
+
confirm the route exists* before pushing. Also warns that registry position can
|
|
26
|
+
decide feed order: a site sorting by date alone falls back to load order for
|
|
27
|
+
same-date entries, so a project appended last can render its newest entry last.
|
|
28
|
+
- **Added: SKILL.md Generate step 6 (verify the entry is live).** Poll the published
|
|
29
|
+
URL until it returns 200 before reporting success; on a persistent 404, check the
|
|
30
|
+
registry first, then the host's build log, and report it as **not live**. With no
|
|
31
|
+
`siteUrl` configured, the run must say the entry is pushed but unverified rather
|
|
32
|
+
than call it published.
|
|
33
|
+
- **Changed: the confirmation block leads with the verified live URL**, with the repo
|
|
34
|
+
blob URL demoted to secondary, and prints the failure on the `Live:` line rather
|
|
35
|
+
than a URL that may 404.
|
|
36
|
+
|
|
37
|
+
## 0.12.0 (2026-07-28) — five composition slots; stop defaulting to before/after
|
|
38
|
+
|
|
39
|
+
Minor rather than patch: this adds three new named composition slots, so covers
|
|
40
|
+
generated after it will legitimately look different from covers generated before.
|
|
41
|
+
Style-guide prose only — no code changed.
|
|
42
|
+
|
|
43
|
+
- **Added: three composition slots**, taking the set from two to five. *Axis /
|
|
44
|
+
timeline* for posts about ordering, timing or a race; *nested / containment*
|
|
45
|
+
for scope, sandboxing, or a thing living inside a thing; *field / distribution*
|
|
46
|
+
for many items, sampling, coverage, or one anomaly among many.
|
|
47
|
+
- **Fixed: compositional monoculture across a run.** Two-node before/after fits
|
|
48
|
+
almost any post *badly*, because nearly anything can be framed as a
|
|
49
|
+
transformation — so it was the slot the model kept reaching for. Fifty covers
|
|
50
|
+
that are each individually fine but all split-scene-with-a-connecting-line read
|
|
51
|
+
as one template with the labels swapped. That is the anti-similarity failure at
|
|
52
|
+
the level of the whole publication rather than the individual cover, which
|
|
53
|
+
nothing was checking for. The guide now requires identifying which slot each
|
|
54
|
+
reference cover from `cover-context` used, and picking a different one if two or
|
|
55
|
+
more already share the intended slot.
|
|
56
|
+
- **Added: no rounded incidental shapes.** The no-rounded-corners rule now names
|
|
57
|
+
the shapes reached for without thinking — speech bubbles, callout balloons, pill
|
|
58
|
+
badges, tooltips, rounded terminal chrome — and says to check every `rx`/`ry`
|
|
59
|
+
and `border-radius` before rendering. One rounded bubble in an otherwise square
|
|
60
|
+
composition collapses the cover into web-app chrome.
|
|
61
|
+
- **Added: never print a number the post did not state.** A figure that looks like
|
|
62
|
+
a measurement ("0 edits left", "3x faster", "~40ms") must appear literally in the
|
|
63
|
+
`## Shipped` text or the summary; fair entailment is not enough, because set in
|
|
64
|
+
mono on a cover it reads as something measured, and a reader who goes looking
|
|
65
|
+
for it will not find it. When the point is zero, draw the absence rather than
|
|
66
|
+
asserting a count.
|
|
67
|
+
|
|
68
|
+
## 0.11.2 (2026-07-28) — attempted npm-page fix; did NOT work
|
|
69
|
+
|
|
70
|
+
- **Attempted and failed: making npmjs.com render the README.** 0.11.1 put
|
|
71
|
+
README.md, LICENSE and CHANGELOG.md into the tarball (verified by downloading
|
|
72
|
+
the published artifact), which fixed what `npm install` delivers. This release
|
|
73
|
+
additionally staged those files into the package directory before
|
|
74
|
+
`npm publish` was invoked, on the theory that npm populates the registry
|
|
75
|
+
manifest's `readme` field from disk at that point. **It did not work.** After
|
|
76
|
+
publishing, `npm view <pkg> readme` still returns the literal string
|
|
77
|
+
`ERROR: No README data found!` for both packages.
|
|
78
|
+
That field appears to be sticky: it was set once by an early release that had
|
|
79
|
+
no README, and republishing with one present does not overwrite it. Since
|
|
80
|
+
npmjs.com only falls back to reading the tarball when the field is *absent*
|
|
81
|
+
(compare `zod`, which renders fine with none at all), the stale error string
|
|
82
|
+
keeps winning.
|
|
83
|
+
The ineffective staging step was reverted in the release workflow; the
|
|
84
|
+
`prepack` hook stays, because the tarball fix is real and verified. **The npm
|
|
85
|
+
web page for both packages is still blank** — an open issue, likely needing
|
|
86
|
+
npm support to clear the cached field.
|
|
87
|
+
Code unchanged in both skills.
|
|
20
88
|
|
|
21
89
|
## 0.11.1 (2026-07-28) — publish the README, LICENSE and CHANGELOG to npm
|
|
22
90
|
|
package/SKILL.md
CHANGED
|
@@ -41,12 +41,19 @@ Map the user's request onto the CLI — never hand-edit `config.json`:
|
|
|
41
41
|
| Show config | `npx -y @natjswenson/devlog@latest config --json` |
|
|
42
42
|
| Add a project | `npx -y @natjswenson/devlog@latest 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@latest remove-project <key> --yes` |
|
|
44
|
-
| Change a setting | `npx -y @natjswenson/devlog@latest set <field> <value>` (settable: `targetRepo`, `branch`, `targetDir`, `gitAuthor`, `githubUser`, `voicePath`, `deepDive.minSources`, `deepDive.topicDomains`) |
|
|
44
|
+
| Change a setting | `npx -y @natjswenson/devlog@latest set <field> <value>` (settable: `targetRepo`, `branch`, `targetDir`, `gitAuthor`, `githubUser`, `siteUrl`, `voicePath`, `deepDive.minSources`, `deepDive.topicDomains`) |
|
|
45
45
|
|
|
46
46
|
`targetDir` is the subdirectory of `targetRepo` that holds the devlog content tree
|
|
47
47
|
(e.g. `content/devlog` when the target is the site repo itself); unset/empty means the
|
|
48
48
|
repo root. Set it with `set targetDir content/devlog`, clear it with `set targetDir ''`.
|
|
49
49
|
|
|
50
|
+
`siteUrl` is the public base URL that repo is *served* at, with no trailing slash — used
|
|
51
|
+
to verify a published entry actually renders (Generate step 6). **The repo name is not the
|
|
52
|
+
site name**: a repo called `example.io` is commonly served at `example.com`, so take this
|
|
53
|
+
from a working page, not from the repo. Without it a run can push but cannot confirm
|
|
54
|
+
anything went live. Set with `set siteUrl 'https://example.com'`, clear with
|
|
55
|
+
`set siteUrl ''`.
|
|
56
|
+
|
|
50
57
|
For **add-project**: resolve the path first (the repo the user named, or the cwd), then
|
|
51
58
|
detect what the CLI will use — key = directory basename, remote = `git -C '<path>' remote
|
|
52
59
|
get-url origin`. In a monorepo, suggest a `--path-filter` (the project's subdir) and a
|
|
@@ -412,7 +419,65 @@ rm -rf '<abs-tmp>'
|
|
|
412
419
|
|
|
413
420
|
If the push fails, report the error and stop — do not retry automatically.
|
|
414
421
|
|
|
415
|
-
### Step
|
|
422
|
+
### Step 5b: Register a project the site has never rendered before
|
|
423
|
+
|
|
424
|
+
`publish-entry` returns **`firstEntryForProject: true`** when the call created that
|
|
425
|
+
project's first live entry. **A push is not a route.** A site that renders the devlog
|
|
426
|
+
almost always keeps its own registry deciding *which* content directories become pages;
|
|
427
|
+
content on disk that the registry doesn't list is built right past, and the entry 404s
|
|
428
|
+
while every command in this skill reports success. Publishing a project's first entry is
|
|
429
|
+
therefore a two-part job, and the CLI can only do the first part.
|
|
430
|
+
|
|
431
|
+
When `firstEntryForProject` is true, **before the push**:
|
|
432
|
+
|
|
433
|
+
1. Find the registry in the clone. It is a source file, not content — grep the site's
|
|
434
|
+
`src/` for the existing project keys (`grep -rn '<a-known-project-key>' <clone>/src`).
|
|
435
|
+
In an Astro/Next-style site it is typically a `PROJECTS` array the entry loader maps
|
|
436
|
+
over.
|
|
437
|
+
2. Add the new project, matching the shape of the neighbouring rows exactly.
|
|
438
|
+
3. **Build the site in the clone and confirm the route exists** (`npm ci && npx astro
|
|
439
|
+
build`, then check the output directory contains the new `<project>/<version>` path).
|
|
440
|
+
A registry edit that doesn't produce a route is not done.
|
|
441
|
+
4. Run the site's own test suite if it has one, and commit the registry change together
|
|
442
|
+
with the content in the same push.
|
|
443
|
+
|
|
444
|
+
If you cannot find a registry, say so plainly rather than assuming there isn't one; the
|
|
445
|
+
verification in Step 6 is what actually settles it.
|
|
446
|
+
|
|
447
|
+
**Registry position can decide feed order, not just visibility.** If the site sorts
|
|
448
|
+
entries by date alone, same-date entries fall back to their load order, which is registry
|
|
449
|
+
order — so a project appended to the end can render its newest entry last. After the build
|
|
450
|
+
in step 3, check that the new entry appears where its date and publish numeral say it
|
|
451
|
+
should, and report it if not.
|
|
452
|
+
|
|
453
|
+
### Step 6: Verify the entry is actually live
|
|
454
|
+
|
|
455
|
+
**Do not report a publish as successful until the published URL returns 200.** The push
|
|
456
|
+
succeeding, the manifest updating, and the site serving the post are three different
|
|
457
|
+
things, and this skill has previously reported success on all of the first two while the
|
|
458
|
+
post 404'd.
|
|
459
|
+
|
|
460
|
+
When `siteUrl` is set in config (it is echoed in the scan output):
|
|
461
|
+
|
|
462
|
+
```bash
|
|
463
|
+
curl -s -o /dev/null -w '%{http_code}' -L '<siteUrl>/devlog/<project>/<version>/'
|
|
464
|
+
```
|
|
465
|
+
|
|
466
|
+
Poll every ~45s for up to ~5 minutes; deploys are not instant. Then:
|
|
467
|
+
|
|
468
|
+
- **200** → done, report the live URL as the primary link.
|
|
469
|
+
- **Still 404 after the window** → the deploy failed or the entry is not routed. Check
|
|
470
|
+
`firstEntryForProject`/the registry from Step 5b first, since that is the most common
|
|
471
|
+
cause, then the host's build log. Report it as **not live**, with what you checked.
|
|
472
|
+
- **`siteUrl` unset** → say the entry is pushed but unverified, give the repo URL, and
|
|
473
|
+
offer to set it: `npx -y @natjswenson/devlog@latest set siteUrl 'https://example.com'`.
|
|
474
|
+
Never describe an unverified push as published.
|
|
475
|
+
|
|
476
|
+
The `/devlog/<project>/<version>/` path is this skill's default convention. If the site
|
|
477
|
+
routes differently, take the pattern from a URL of an already-published entry rather than
|
|
478
|
+
assuming this one.
|
|
479
|
+
|
|
480
|
+
### Step 7: Confirm
|
|
416
481
|
|
|
417
482
|
```
|
|
418
483
|
Release dev log entries published
|
|
@@ -420,13 +485,13 @@ Release dev log entries published
|
|
|
420
485
|
Project: <key>
|
|
421
486
|
Releases: <version>, ...
|
|
422
487
|
Judged weaknesses: <residuals from Step 4, or "none">
|
|
423
|
-
|
|
488
|
+
Live: <siteUrl>/devlog/<key>/<version>/ (verified 200)
|
|
489
|
+
Source: https://github.com/<targetRepo>/blob/<branch>/<targetDir-prefix><key>/<version>.md
|
|
424
490
|
```
|
|
425
491
|
|
|
426
|
-
(`<targetDir-prefix>` is `<targetDir>/` when set, empty otherwise.)
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
next deploy.
|
|
492
|
+
(`<targetDir-prefix>` is `<targetDir>/` when set, empty otherwise.) Report the **verified
|
|
493
|
+
live URL** as the primary link; the repo blob URL is the secondary one. If Step 6 could
|
|
494
|
+
not verify, say so on the `Live:` line instead of printing a URL that may 404.
|
|
430
495
|
|
|
431
496
|
## Security rules
|
|
432
497
|
|
|
@@ -82,15 +82,39 @@ Never leave the band empty under a one-line headline. Whitespace is part of the
|
|
|
82
82
|
only when it's *between* composed elements — a gap with nothing on either side of it is
|
|
83
83
|
just a hole.
|
|
84
84
|
|
|
85
|
-
**
|
|
85
|
+
**Five named composition slots** — pick one per post:
|
|
86
86
|
- **Single centered hero** — one freehand mechanism, nothing else, inside the hero zone.
|
|
87
87
|
- **Two-node before/after** — a left node, a right node, and a connecting line, all
|
|
88
88
|
three freehand shapes (never catalog icons) — for a post about a transformation or a
|
|
89
89
|
fix.
|
|
90
|
+
- **Axis / timeline** — one horizontal (or vertical) run with marks, labels, and events
|
|
91
|
+
positioned along it. For anything about *ordering*, *timing*, or *a race*: what fired
|
|
92
|
+
when, what arrived late, what overlapped. The marks carry the meaning, not boxes.
|
|
93
|
+
- **Nested / containment** — one shape inside another, or a stack of layers, showing
|
|
94
|
+
what wraps what, what's isolated from what, or where a boundary sits. For posts about
|
|
95
|
+
scope, sandboxing, encapsulation, or a thing living inside a thing.
|
|
96
|
+
- **Field / distribution** — many small marks whose *arrangement* is the point: a
|
|
97
|
+
scatter, a cluster with an outlier, a grid with holes, a shape emerging from noise.
|
|
98
|
+
For posts about many items, sampling, coverage, or one anomaly among many.
|
|
90
99
|
|
|
91
100
|
These are placement/proportion guidance, not literal templates — the actual shapes
|
|
92
101
|
inside each slot are still freehand per post.
|
|
93
102
|
|
|
103
|
+
**Do not default to two-node.** It is the easiest slot to reach for and it fits almost
|
|
104
|
+
any post *badly*, because nearly everything can be framed as before/after. That framing
|
|
105
|
+
is the single biggest threat to this set: fifty covers that are each individually fine
|
|
106
|
+
but all split-scene-with-a-connecting-line read as one template with the labels swapped,
|
|
107
|
+
which is the anti-similarity failure at the level of the whole publication rather than
|
|
108
|
+
the individual cover.
|
|
109
|
+
|
|
110
|
+
So, before you commit to a slot: **look at the reference covers `cover-context` handed
|
|
111
|
+
you and identify which slot each one used.** If two or more of them used the slot you
|
|
112
|
+
were about to pick, pick a different one — and only override that if the post's mechanism
|
|
113
|
+
genuinely cannot be drawn any other way, which is rarer than it feels. Reach for
|
|
114
|
+
single-centered-hero more often than instinct suggests; one well-drawn mechanism with
|
|
115
|
+
nothing beside it is usually stronger than a comparison, and it is the slot most likely
|
|
116
|
+
to be under-used across a long run.
|
|
117
|
+
|
|
94
118
|
**A third option, when the post is genuinely about code or a terminal session:** the
|
|
95
119
|
`.term` panel treatment (see Palette below) may fill some or all of `#hero-zone` instead
|
|
96
120
|
of a freehand mechanism — a real, believable command/output snippet drawn from the
|
|
@@ -258,13 +282,24 @@ summary as on-image text.
|
|
|
258
282
|
edges, fold lines, or any texture overlay — the paper is a flat hex, not a vintage
|
|
259
283
|
poster prop.
|
|
260
284
|
- Don't round any corner or drop any shadow, on the illustration or anywhere else on the
|
|
261
|
-
cover — PRESS structure comes from rules and whitespace, never rounded chrome.
|
|
285
|
+
cover — PRESS structure comes from rules and whitespace, never rounded chrome. This
|
|
286
|
+
includes *incidental* shapes you reach for without thinking: speech bubbles, callout
|
|
287
|
+
balloons, pill badges, tooltips, rounded terminal chrome. A speech bubble is a
|
|
288
|
+
rectangle with a triangular tail, not a lozenge. Check every `rx`/`ry` on an SVG rect
|
|
289
|
+
and every `border-radius` before you render — a single rounded bubble in an otherwise
|
|
290
|
+
square composition is the tell that collapses the whole cover into web-app chrome.
|
|
262
291
|
- Don't let orange spread across the cover — one signature moment (see The accent law),
|
|
263
292
|
never orange as a fill color for multiple shapes, never a background wash.
|
|
264
293
|
- Don't set the headline, eyebrow, or numerals in the serif voice — that voice is for
|
|
265
294
|
commentary only; structure is always the display face.
|
|
266
295
|
- Don't invent editorial props that aren't backed by real data: no fabricated issue
|
|
267
296
|
numbers, no barcodes, no pull-quotes that aren't an actual quote from the post.
|
|
297
|
+
- Don't print a number the post didn't state. A figure that *looks* like a measurement
|
|
298
|
+
("0 edits left", "3x faster", "~40ms") must appear literally in the `## Shipped` text
|
|
299
|
+
or the summary. A fair entailment is not enough: once it's set in mono on the cover it
|
|
300
|
+
reads as something that was measured, and a reader who goes looking for it in the post
|
|
301
|
+
won't find it. If the point is "none" or "zero," draw the absence — an empty frame, a
|
|
302
|
+
severed line, a gap where marks used to be — rather than asserting a count.
|
|
268
303
|
- Don't leave old terminal furniture lying around outside a `.term` panel — no blinking
|
|
269
304
|
cursor, no bare `_` suffix, no stray `$` prompt as decoration. The dark palette now
|
|
270
305
|
belongs to exactly one place, the `.term` panel, and only when it's real code.
|
package/lib/config_ops.mjs
CHANGED
|
@@ -34,6 +34,7 @@ const SETTERS = {
|
|
|
34
34
|
targetDir: (c, v) => (v === '' ? omit(c, 'targetDir') : { ...c, targetDir: v }),
|
|
35
35
|
gitAuthor: (c, v) => ({ ...c, gitAuthor: v }),
|
|
36
36
|
githubUser: (c, v) => ({ ...c, githubUser: v }),
|
|
37
|
+
siteUrl: (c, v) => (v === '' ? omit(c, 'siteUrl') : { ...c, siteUrl: v.replace(/\/+$/, '') }),
|
|
37
38
|
voicePath: (c, v) => (v === '' ? omit(c, 'voicePath') : { ...c, voicePath: expandHome(v) }),
|
|
38
39
|
'deepDive.minSources': (c, v) => {
|
|
39
40
|
const n = Number(v);
|
package/lib/core.mjs
CHANGED
|
@@ -125,6 +125,19 @@ export function validateConfig(config) {
|
|
|
125
125
|
throw new Error(`targetDir must be a relative path like "content/devlog" (no leading/trailing slash, no '..'): got ${JSON.stringify(config.targetDir)}`);
|
|
126
126
|
}
|
|
127
127
|
}
|
|
128
|
+
if ('siteUrl' in config) {
|
|
129
|
+
// Optional: the public base URL the target repo is served at, used only to
|
|
130
|
+
// confirm a published entry actually renders. The repo name is not the site
|
|
131
|
+
// name (a repo called `example.io` can be served at `example.com`), and
|
|
132
|
+
// pushing content is not the same as the site serving it, so this is the
|
|
133
|
+
// only way a publish run can verify itself rather than assume.
|
|
134
|
+
// Interpolated into a shell curl, hence the tight charset.
|
|
135
|
+
if (typeof config.siteUrl !== 'string'
|
|
136
|
+
|| !/^https?:\/\/[A-Za-z0-9.-]+(:\d+)?(\/[A-Za-z0-9._~/-]*)?$/.test(config.siteUrl)
|
|
137
|
+
|| config.siteUrl.endsWith('/')) {
|
|
138
|
+
throw new Error(`siteUrl must be an http(s) URL with no trailing slash, e.g. "https://example.com": got ${JSON.stringify(config.siteUrl)}`);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
128
141
|
if ('voicePath' in config) {
|
|
129
142
|
// Optional: directory holding the voice profile used to write entries. Read by
|
|
130
143
|
// the skill with the Read tool only — never shell-interpolated — so the only
|
package/lib/publish_entry.mjs
CHANGED
|
@@ -221,6 +221,14 @@ export function publishEntry({ cloneDir, project, version, entryPath, coverImage
|
|
|
221
221
|
}
|
|
222
222
|
|
|
223
223
|
const file = `${version}.md`;
|
|
224
|
+
// Whether this project had any live entry before this call. A site that
|
|
225
|
+
// renders the devlog typically keeps its own registry of which projects to
|
|
226
|
+
// render (content on disk is not the same as a route), and that registry is
|
|
227
|
+
// the thing a first-ever publish silently misses: the entry lands, the build
|
|
228
|
+
// walks past it, and the post 404s while every check reports success.
|
|
229
|
+
// Reported back so the caller can require registration exactly once per
|
|
230
|
+
// project, instead of relying on whoever is publishing to remember.
|
|
231
|
+
const hadLiveEntries = manifest.entries.some((e) => e && !e.removed);
|
|
224
232
|
// Idempotent: legacy manifests may already reference this file/version even
|
|
225
233
|
// when the .md was missing — never duplicate an index row.
|
|
226
234
|
const already = manifest.entries.some((e) => e && (e.file === file || e.version === version));
|
|
@@ -247,7 +255,13 @@ export function publishEntry({ cloneDir, project, version, entryPath, coverImage
|
|
|
247
255
|
manifestUpdated = true;
|
|
248
256
|
}
|
|
249
257
|
|
|
250
|
-
return {
|
|
258
|
+
return {
|
|
259
|
+
written: destPath,
|
|
260
|
+
manifestUpdated,
|
|
261
|
+
coverWritten: !!coverFile,
|
|
262
|
+
no,
|
|
263
|
+
firstEntryForProject: manifestUpdated && !hadLiveEntries,
|
|
264
|
+
};
|
|
251
265
|
}
|
|
252
266
|
|
|
253
267
|
// Editorially retire a release: after an entry is manually moved, consolidated,
|
package/lib/scan.mjs
CHANGED
|
@@ -288,6 +288,11 @@ export function scanAll(config, { projectKey = null, fetch = true, getExisting =
|
|
|
288
288
|
// skill appends it to the publish clone path (`--clone <clone>/<targetDir>`).
|
|
289
289
|
targetDir: config.targetDir || '',
|
|
290
290
|
branch,
|
|
291
|
+
// Public base URL the target repo is served at, when configured — the skill
|
|
292
|
+
// uses it to confirm a published entry actually renders. null means the run
|
|
293
|
+
// can push but cannot verify, which the skill has to say out loud rather
|
|
294
|
+
// than report an unverified publish as a success.
|
|
295
|
+
siteUrl: config.siteUrl || null,
|
|
291
296
|
deepDive: resolveDeepDive(config),
|
|
292
297
|
voicePath: config.voicePath || null,
|
|
293
298
|
projects: results,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@natjswenson/devlog",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.13.0",
|
|
4
4
|
"description": "Release dev log generator \u2014 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",
|