@natjswenson/devlog 0.1.9 → 0.4.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 +72 -0
- package/README.md +35 -20
- package/SKILL.md +322 -71
- package/bin/devlog.js +140 -44
- package/config.example.json +9 -4
- package/examples/react/README.md +1 -1
- package/examples/react/useDevLogEntries.js +10 -6
- package/package.json +6 -3
- package/preview/demo.js +32 -25
- package/voice/voice-notes.example.md +16 -0
- package/voice/voice-profile.example.md +37 -0
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,78 @@
|
|
|
2
2
|
|
|
3
3
|
All notable changes to `@natjswenson/devlog` are documented here.
|
|
4
4
|
|
|
5
|
+
## 0.4.0 (2026-06-28) — researched, end-to-end implementation-guide posts
|
|
6
|
+
|
|
7
|
+
**Changed**
|
|
8
|
+
- `/devlog` now writes each release entry as a researched, cited, end-to-end
|
|
9
|
+
implementation guide rather than a narrative summary of what shipped. Step 6
|
|
10
|
+
derives the engineering topic(s) the work touched, researches them against
|
|
11
|
+
reputable outside sources (cited inline and in a `## Sources` section), and
|
|
12
|
+
writes a setup → build → use → verify walkthrough with multiple
|
|
13
|
+
copy-paste-reusable, language-tagged code blocks that together form a complete,
|
|
14
|
+
runnable whole (right-sized: roughly 3-6 essential blocks for a substantive
|
|
15
|
+
feature, fewer for a small change, never padded). A short `## Shipped` hook
|
|
16
|
+
still opens the post and `## Changelog` still closes it. Updated the skill
|
|
17
|
+
description and the Step 6 / 6a-6c guidance accordingly.
|
|
18
|
+
|
|
19
|
+
**Added**
|
|
20
|
+
- `deepDive` config block: `topicDomains` (default: AI, DevOps/SRE, software
|
|
21
|
+
engineering) and `minSources` (default 2) to steer topic selection and the
|
|
22
|
+
citation floor. Repo-agnostic; user-supplied values live in `config.json`.
|
|
23
|
+
|
|
24
|
+
## 0.3.1 (2026-06-20) — fetch tags before discovering releases
|
|
25
|
+
|
|
26
|
+
**Fixed**
|
|
27
|
+
- `/devlog` now runs a best-effort `git fetch --tags --quiet` per project at the
|
|
28
|
+
start of release discovery (Step 3), before listing tags. Releases are
|
|
29
|
+
commonly cut by CI on the remote (a version-driven GitHub Release on green
|
|
30
|
+
`main`/`master`), so the tag is born on the remote; a local clone that hadn't
|
|
31
|
+
fetched would list only stale local tags and silently report "no new release"
|
|
32
|
+
for a release that was already live. The fetch is best-effort: on failure
|
|
33
|
+
(offline, no remote, auth prompt) it notes the failure and proceeds on local
|
|
34
|
+
tags rather than aborting. `--tags` takes no untrusted input and `project.path`
|
|
35
|
+
is validated + single-quoted per Step 0.5.
|
|
36
|
+
|
|
37
|
+
## 0.3.0 (2026-06-18) — release-focused entries, written in your voice
|
|
38
|
+
|
|
39
|
+
**Changed (behavior)**
|
|
40
|
+
- `/devlog` now generates one entry **per version release** (a semver git tag) instead of
|
|
41
|
+
one entry per day. An entry summarizes the commits in a release's tag range
|
|
42
|
+
(`<prevTag>..<thisTag>`), scoped by `pathFilter` when present. The run is **idempotent**:
|
|
43
|
+
a release's entry is written once and never overwritten, and re-running produces nothing
|
|
44
|
+
until a new tag is cut. The per-day "Update — HH:MM" append mode is removed.
|
|
45
|
+
- Entries are keyed by version: `<project-key>/<version>.md` (e.g. `v0.2.0.md`), with a
|
|
46
|
+
`version` field added to the frontmatter and to each `manifest.json` entry. Entry sections
|
|
47
|
+
are now **What Shipped / What's Next / Commits**. The entry `date` is the tag's commit date.
|
|
48
|
+
|
|
49
|
+
**Added**
|
|
50
|
+
- **Voice-driven publishing.** Entries are written in the user's voice using a voice profile
|
|
51
|
+
resolved in this order: `config.voicePath` → `~/.claude/skills/ghostwriter/voice` (if
|
|
52
|
+
installed) → a bundled fallback at `~/.claude/skills/devlog/voice/`. devlog reads
|
|
53
|
+
`voice-profile.md` and `voice-notes.md` (overrides) — and never `algorithm.md`, since
|
|
54
|
+
LinkedIn reach tuning does not apply to a dev log.
|
|
55
|
+
- `voicePath` (top-level, optional) and `projects[].tagPrefix` (optional, default `v`) config
|
|
56
|
+
fields, with security validation in both `bin/devlog.js` and SKILL.md. `tagPrefix` lets each
|
|
57
|
+
project in a monorepo detect its own releases (e.g. `devlog-v`, `ghostwriter-v`).
|
|
58
|
+
- `init` prompts for the voice directory and release tag prefix, and installs the bundled
|
|
59
|
+
voice template. `config` shows the voice path and each project's tag pattern.
|
|
60
|
+
- The React example carries the optional `version` field through frontmatter parsing and
|
|
61
|
+
manifest validation.
|
|
62
|
+
|
|
63
|
+
**Migration note:** existing per-day `YYYY-MM-DD.md` entries are left untouched; new entries
|
|
64
|
+
are per-release. To detect a monorepo project's releases, set its `tagPrefix`.
|
|
65
|
+
|
|
66
|
+
## 0.2.0 (2026-06-08) — monorepo subdirectory filtering
|
|
67
|
+
|
|
68
|
+
**Added**
|
|
69
|
+
- `projects[].pathFilter` config field: scope a project's commits to a repo-relative
|
|
70
|
+
subdirectory (e.g. `skills/devlog`). Lets several logical projects share one monorepo
|
|
71
|
+
`path`/`remote` while each collects only its own subtree's commits. `git log` gains a
|
|
72
|
+
`-- <pathFilter>` pathspec; commit links still resolve to `<remote>/commit/<hash>`.
|
|
73
|
+
- SKILL.md documents the field, its security validation (no leading `-`/`/`, no `..`,
|
|
74
|
+
single-quoted), and the multi-skill monorepo workflow.
|
|
75
|
+
- `bin/devlog.js` validates `pathFilter` and shows it as `scope:` in `devlog config`.
|
|
76
|
+
|
|
5
77
|
## 0.1.9 (2026-06-05) — accessibility fix
|
|
6
78
|
|
|
7
79
|
**Accessibility**
|
package/README.md
CHANGED
|
@@ -5,9 +5,9 @@
|
|
|
5
5
|
[](./SECURITY.md)
|
|
6
6
|
[](#security)
|
|
7
7
|
|
|
8
|
-
A Claude Code skill that turns
|
|
8
|
+
A Claude Code skill that turns each version release (a git tag) into a published dev log entry, written in your own voice — and a React example for displaying it on your site.
|
|
9
9
|
|
|
10
|
-
> **Build in public,
|
|
10
|
+
> **Build in public, by release.** Tag a release like you always do. Run `/devlog`. Each new version shows up on your site as a narrative entry — in your voice — not raw commit messages.
|
|
11
11
|
|
|
12
12
|
## Live example
|
|
13
13
|
|
|
@@ -15,9 +15,11 @@ The skill is in production at [natejswenson.com/devlog](https://natejswenson.com
|
|
|
15
15
|
|
|
16
16
|
## How it works
|
|
17
17
|
|
|
18
|
-
1. **You
|
|
19
|
-
2. **Run `/devlog` in Claude Code.** The skill
|
|
20
|
-
3. **Your site fetches it.** Static `manifest.json` + per-
|
|
18
|
+
1. **You ship a release** — tag it (e.g. `git tag v0.3.0`), like you already do.
|
|
19
|
+
2. **Run `/devlog` in Claude Code.** The skill finds tags that don't yet have an entry, summarizes each release's changes into a narrative markdown entry written in your voice, and pushes it to your dev-log GitHub repo. It's idempotent — re-running does nothing until you cut a new release.
|
|
20
|
+
3. **Your site fetches it.** Static `manifest.json` + per-release markdown files served from `raw.githubusercontent.com` — no backend needed.
|
|
21
|
+
|
|
22
|
+
**In your voice.** Entries are written using a voice profile, resolved in this order: your `config.voicePath` → [ghostwriter](../ghostwriter)'s `voice/` dir if installed → a bundled default. devlog reads `voice-profile.md` (and `voice-notes.md` overrides) — never ghostwriter's `algorithm.md`, since LinkedIn reach tuning doesn't apply to a dev log.
|
|
21
23
|
|
|
22
24
|
## Quick start
|
|
23
25
|
|
|
@@ -63,12 +65,16 @@ to see your dev log rendered locally at `http://localhost:5173`.
|
|
|
63
65
|
```
|
|
64
66
|
~/.claude/skills/devlog/
|
|
65
67
|
├── SKILL.md # The /devlog slash-command instructions
|
|
66
|
-
|
|
68
|
+
├── config.json # Your settings (mode 0600)
|
|
69
|
+
└── voice/ # Bundled fallback voice profile (last resort)
|
|
70
|
+
├── voice-profile.md
|
|
71
|
+
└── voice-notes.md
|
|
67
72
|
|
|
68
73
|
github.com/<you>/daily-dev-log/ # Created by init, populated by /devlog
|
|
69
74
|
├── myproject/
|
|
70
75
|
│ ├── manifest.json
|
|
71
|
-
│ ├──
|
|
76
|
+
│ ├── v0.3.0.md
|
|
77
|
+
│ ├── v0.2.0.md
|
|
72
78
|
│ └── ...
|
|
73
79
|
└── ...
|
|
74
80
|
```
|
|
@@ -77,8 +83,11 @@ github.com/<you>/daily-dev-log/ # Created by init, populated by /devlog
|
|
|
77
83
|
|
|
78
84
|
```sh
|
|
79
85
|
gh repo create <you>/daily-dev-log --public --add-readme
|
|
80
|
-
mkdir -p ~/.claude/skills/devlog
|
|
86
|
+
mkdir -p ~/.claude/skills/devlog/voice
|
|
81
87
|
curl -o ~/.claude/skills/devlog/SKILL.md https://raw.githubusercontent.com/natejswenson/devlog/main/SKILL.md
|
|
88
|
+
# Optional fallback voice profile (used when voicePath and ghostwriter are both absent):
|
|
89
|
+
curl -o ~/.claude/skills/devlog/voice/voice-profile.md https://raw.githubusercontent.com/natejswenson/devlog/main/voice/voice-profile.example.md
|
|
90
|
+
curl -o ~/.claude/skills/devlog/voice/voice-notes.md https://raw.githubusercontent.com/natejswenson/devlog/main/voice/voice-notes.example.md
|
|
82
91
|
# Then copy config.example.json → ~/.claude/skills/devlog/config.json and fill it in
|
|
83
92
|
```
|
|
84
93
|
|
|
@@ -116,8 +125,8 @@ The dev-log repo has this layout, all served as raw files from `https://raw.gith
|
|
|
116
125
|
<repo>/
|
|
117
126
|
└── <project-key>/
|
|
118
127
|
├── manifest.json # Index of all entries (newest first)
|
|
119
|
-
├──
|
|
120
|
-
├──
|
|
128
|
+
├── v0.3.0.md # One entry per release (named by version)
|
|
129
|
+
├── v0.2.0.md
|
|
121
130
|
└── ...
|
|
122
131
|
```
|
|
123
132
|
|
|
@@ -125,34 +134,36 @@ The dev-log repo has this layout, all served as raw files from `https://raw.gith
|
|
|
125
134
|
```json
|
|
126
135
|
{
|
|
127
136
|
"entries": [
|
|
128
|
-
{ "date": "2026-
|
|
137
|
+
{ "date": "2026-06-08", "file": "v0.2.0.md", "title": "...", "summary": "...", "version": "v0.2.0" }
|
|
129
138
|
]
|
|
130
139
|
}
|
|
131
140
|
```
|
|
132
141
|
|
|
133
142
|
Strict validation rules (entries that don't match are silently dropped by the React example):
|
|
134
|
-
- `date` matches `YYYY-MM-DD`
|
|
143
|
+
- `date` matches `YYYY-MM-DD` (the release/tag date)
|
|
135
144
|
- `file` matches `^[a-zA-Z0-9._-]+\.md$`
|
|
136
145
|
- `title` and `summary` are non-empty strings
|
|
146
|
+
- `version` (optional) matches `^[a-zA-Z0-9._-]+$`
|
|
137
147
|
|
|
138
148
|
**Entry markdown:**
|
|
139
149
|
|
|
140
150
|
```markdown
|
|
141
151
|
---
|
|
142
|
-
title: "Concise
|
|
143
|
-
date: 2026-
|
|
152
|
+
title: "Concise release summary"
|
|
153
|
+
date: 2026-06-08
|
|
144
154
|
project: myproject
|
|
155
|
+
version: v0.2.0
|
|
145
156
|
summary: "1-2 sentence summary"
|
|
146
157
|
---
|
|
147
158
|
|
|
148
|
-
## What
|
|
149
|
-
Narrative paragraphs.
|
|
159
|
+
## What Shipped
|
|
160
|
+
Narrative paragraphs, written in your voice.
|
|
150
161
|
|
|
151
162
|
## What's Next
|
|
152
163
|
Forward-looking note.
|
|
153
164
|
|
|
154
|
-
##
|
|
155
|
-
-
|
|
165
|
+
## Commits
|
|
166
|
+
- commit message ([abc1234](https://github.com/.../commit/abc1234567...))
|
|
156
167
|
```
|
|
157
168
|
|
|
158
169
|
That's the entire contract.
|
|
@@ -165,13 +176,16 @@ That's the entire contract.
|
|
|
165
176
|
|---|---|---|
|
|
166
177
|
| `targetRepo` | `"<owner>/<repo>"` | Repo where dev log entries are published. Must match `^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$`. |
|
|
167
178
|
| `branch` | string (optional) | Branch in the dev-log repo. Defaults to `main`. Must not contain `..` or start with `-`. |
|
|
168
|
-
| `gitAuthor` | string |
|
|
179
|
+
| `gitAuthor` | string | Your name. Retained for backward compatibility; it is **not** currently rendered on entries (the author filter was removed, and release notes summarize all commits in a tag range). Still **required** by config validation — it must be present and non-empty (don't drop it). Whitespace OK; no shell metacharacters. |
|
|
169
180
|
| `githubUser` | string | Your GitHub username. |
|
|
181
|
+
| `voicePath` | string (optional) | Directory holding `voice-profile.md` (and optionally `voice-notes.md`) used to write entries in your voice. A leading `~` is expanded. If unset, devlog uses ghostwriter's `voice/` if installed, else the bundled default. Read only — never shell-interpolated. |
|
|
170
182
|
| `projects` | array | One entry per project you want dev logs for. |
|
|
171
183
|
| `projects[].key` | string | Subdirectory name in the dev-log repo. Strict token: `^[a-z0-9][a-z0-9._-]*$`, no `..`. |
|
|
172
184
|
| `projects[].label` | string (optional) | Display name for the tab. Defaults to `key`. |
|
|
173
185
|
| `projects[].path` | string | Local filesystem path to the project. Whitespace OK. |
|
|
174
186
|
| `projects[].remote` | `"<owner>/<repo>"` | The project's GitHub remote. Used to mark public commits and link them. |
|
|
187
|
+
| `projects[].pathFilter` | string (optional) | Repo-relative subdir scoping this project's commits in a monorepo (e.g. `skills/devlog`). |
|
|
188
|
+
| `projects[].tagPrefix` | string (optional) | Prefix of the git tags that mark this project's releases (e.g. `devlog-v`). Defaults to `v`. Used in `git tag --list '<tagPrefix>*'`. |
|
|
175
189
|
|
|
176
190
|
See [`config.example.json`](./config.example.json) for a complete template, or run `npx @natjswenson/devlog config` to inspect your current config with validation.
|
|
177
191
|
|
|
@@ -195,7 +209,8 @@ The package is designed to be safe to install on a developer's machine and have
|
|
|
195
209
|
|
|
196
210
|
## Customization
|
|
197
211
|
|
|
198
|
-
- **Tweak the entry template:** edit `~/.claude/skills/devlog/SKILL.md` (Step
|
|
212
|
+
- **Tweak the entry template:** edit `~/.claude/skills/devlog/SKILL.md` (Step 6 — generate the entry).
|
|
213
|
+
- **Tweak your voice:** edit the `voice-profile.md` / `voice-notes.md` in your `voicePath` (or `~/.claude/skills/devlog/voice/`).
|
|
199
214
|
- **Tweak the UI:** override the `--devlog-*` CSS variables in `examples/react/DevLogPage.css` to match your theme.
|
|
200
215
|
- **Add more projects:** `npx @natjswenson/devlog add-project` (no manual JSON editing required).
|
|
201
216
|
|