@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 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](https://img.shields.io/badge/security-audited-green)](./SECURITY.md)
6
6
  [![vulnerabilities](https://img.shields.io/badge/npm%20audit-0%20issues-brightgreen)](#security)
7
7
 
8
- A Claude Code skill that turns your daily git commits into a published dev log — and a React example for displaying it on your site.
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, automatically.** Make commits like you always do. Run `/devlog`. Today's work shows up on your site as a narrative entry, not raw commit messages.
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 commit code** in your projects, like you already do.
19
- 2. **Run `/devlog` in Claude Code.** The skill reads today's commits, writes a narrative markdown entry, and pushes it to your dev-log GitHub repo.
20
- 3. **Your site fetches it.** Static `manifest.json` + per-day markdown files served from `raw.githubusercontent.com` — no backend needed.
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
- └── config.json # Your settings (mode 0600)
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
- │ ├── 2026-05-01.md
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
- ├── 2026-05-01.md # One entry per day
120
- ├── 2026-04-30.md
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-05-01", "file": "2026-05-01.md", "title": "...", "summary": "..." }
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 day summary"
143
- date: 2026-05-01
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 I Built
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
- ## Public Commits
155
- - [myproject] commit message ([abc1234](https://github.com/.../commit/abc1234567...))
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 | Used as `git log --author=...` to find your commits. Whitespace OK; no shell metacharacters. |
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 4 — generate the entry).
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