@natjswenson/devlog 0.13.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 +30 -0
- package/README.md +230 -120
- package/SKILL.md +74 -24
- package/bin/devlog.js +108 -6
- package/config.example.json +1 -0
- package/image-style/style-guide.example.md +29 -26
- package/lib/compose_art_cover.mjs +144 -0
- package/lib/config_ops.mjs +1 -0
- package/lib/core.mjs +3 -0
- package/lib/guide_draft.mjs +134 -0
- package/lib/guide_preview.css +3 -0
- package/lib/publish_guide.mjs +124 -0
- package/package.json +4 -3
- package/references/codex-cover-art.md +119 -0
- package/references/concept-guides.md +148 -0
- package/references/cover-spec.md +40 -0
- package/references/guide-publishing.md +245 -0
- package/skill-invariants.json +34 -13
package/CHANGELOG.md
CHANGED
|
@@ -2,6 +2,36 @@
|
|
|
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
|
+
|
|
12
|
+
## 0.14.0 (2026-09-09) — verified concept guides and AI cover composition
|
|
13
|
+
|
|
14
|
+
- Add an explicit concept-guide draft workflow: select one transferable reader
|
|
15
|
+
outcome, include a copyable implementation prompt and complete reference, exercise
|
|
16
|
+
the build, and independently test adaptation in an existing project.
|
|
17
|
+
- Add `lint-guide` and `prepare-guide` for strict handoff structure and a standalone
|
|
18
|
+
local reading preview with exact full-guide clipboard and manual fallback.
|
|
19
|
+
- Add `compose-art-cover` for offline composition of local raster artwork with
|
|
20
|
+
adopted brand tokens, true-color PNG output, bounded typography and hashed receipts.
|
|
21
|
+
Codex native image generation remains session orchestration; no new credentials,
|
|
22
|
+
image API calls or paid fallback are introduced in the CLI.
|
|
23
|
+
- Package the workflow references for both hosts and install them beside standalone
|
|
24
|
+
SKILL.md copies. Existing Claude generation uses its local cover renderer.
|
|
25
|
+
- Update Sharp from 0.35.3 to 0.35.4 to resolve the dependency audit's
|
|
26
|
+
[libheif advisory](https://github.com/advisories/GHSA-rgj7-g3m4-5g8c).
|
|
27
|
+
- Add optional `generationMode: concept` for at most one complete guide per normal
|
|
28
|
+
run, with `release` and missing settings preserving existing generation behavior.
|
|
29
|
+
- Add `publish-guide` to bind the article, full agent payload, executed output,
|
|
30
|
+
independent adaptation and review records before writing a new entry. Reviewed
|
|
31
|
+
cover hashes and decoded geometry are checked when art is provided.
|
|
32
|
+
- Keep legacy scanning, assembly, rendering, publication identities and existing
|
|
33
|
+
content unchanged. Explicit drafts remain local; catalog backfill is separate.
|
|
34
|
+
|
|
5
35
|
## 0.13.0 (2026-07-29) — a publish run now proves the entry is live
|
|
6
36
|
|
|
7
37
|
Publishing reported success on a post that was never reachable. The content, cover
|
package/README.md
CHANGED
|
@@ -1,71 +1,171 @@
|
|
|
1
1
|
# devlog
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
[](./SECURITY.md)
|
|
6
|
-
[](#security)
|
|
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
|
|
7
5
|
|
|
8
|
-
|
|
6
|
+
---
|
|
7
|
+
<!-- <<< press:masthead -->
|
|
9
8
|
|
|
10
|
-
|
|
9
|
+
*Turn each release into a published how-to guide, written in your own voice.*
|
|
11
10
|
|
|
12
|
-
|
|
11
|
+
> **Never write a detail you did not read from the repository.** Every command, hash and quote in an entry is checked against git, because a plausible one is a fabricated one.
|
|
13
12
|
|
|
14
|
-
|
|
13
|
+
[](https://www.npmjs.com/package/@natjswenson/devlog) [](./LICENSE) [](./SECURITY.md)
|
|
15
14
|
|
|
16
|
-
##
|
|
15
|
+
## Why install this
|
|
16
|
+
|
|
17
|
+
"Build in public" usually means either nothing, or a changelog nobody reads.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
19
|
+
Tag a release like you always do. Run `/devlog`. Each new version shows up on
|
|
20
|
+
your site as a polished, end-to-end implementation guide — in your voice, with
|
|
21
|
+
cited sources and the gotchas you actually hit — not raw commit messages.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
+
Each post is a **detailed how-to**: a reader who has never seen your repo can
|
|
24
|
+
follow it. Every draft passes a deterministic lint plus a quality self-review
|
|
25
|
+
before it publishes, and a published entry is never overwritten.
|
|
23
26
|
|
|
24
|
-
|
|
27
|
+
It is in production at [natejswenson.com/devlog](https://natejswenson.com/devlog),
|
|
28
|
+
publishing to
|
|
29
|
+
[github.com/natejswenson/daily-dev-log](https://github.com/natejswenson/daily-dev-log).
|
|
30
|
+
What you see on that page is exactly what `devlog preview` renders locally.
|
|
31
|
+
|
|
32
|
+
## What you get
|
|
33
|
+
|
|
34
|
+
| Path | What it provides |
|
|
35
|
+
|---|---|
|
|
36
|
+
| `skills/devlog/SKILL.md` | The how-to contract every entry must satisfy. |
|
|
37
|
+
| `skills/devlog/bin/` | The CLI: `init`, `scan`, `lint-post`, `publish-entry`, `preview`, `config`. |
|
|
38
|
+
| `skills/devlog/lib/` | The deterministic core: scanning, linting, publishing, config validation. |
|
|
39
|
+
| `skills/devlog/examples/react/` | A drop-in React page for your own site. |
|
|
40
|
+
| `skills/devlog/preview/` | A complete deployable Vite app, if you have no site yet. |
|
|
41
|
+
| `skills/devlog/image-style/` | The PRESS cover-image palette and style guide. |
|
|
42
|
+
| [`SECURITY.md`](skills/devlog/SECURITY.md) | The full threat model and audit history. |
|
|
25
43
|
|
|
26
44
|
## Quick start
|
|
27
45
|
|
|
28
|
-
|
|
29
|
-
|
|
46
|
+
Claude Code — run in chat:
|
|
47
|
+
|
|
48
|
+
```text
|
|
49
|
+
/plugin marketplace add natejswenson/claude-skills
|
|
50
|
+
/plugin install devlog@claude-skills
|
|
51
|
+
/devlog
|
|
30
52
|
```
|
|
31
53
|
|
|
32
|
-
|
|
33
|
-
- Creates `<your-username>/daily-dev-log` on GitHub (or uses an existing one)
|
|
34
|
-
- Installs the skill at `~/.claude/skills/devlog/`
|
|
35
|
-
- Writes `~/.claude/skills/devlog/config.json` with your answers
|
|
36
|
-
- Lets you register one or more projects in a single run
|
|
54
|
+
Codex — run in a terminal from the root of this repository checkout:
|
|
37
55
|
|
|
38
|
-
|
|
56
|
+
```bash
|
|
57
|
+
codex plugin marketplace add "$PWD"
|
|
58
|
+
codex plugin add devlog@claude-skills
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Start a new Codex session, then invoke in chat:
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
$devlog
|
|
65
|
+
```
|
|
39
66
|
|
|
40
67
|
```sh
|
|
41
|
-
npx @natjswenson/devlog
|
|
68
|
+
npx @natjswenson/devlog init # create the repo, install the skill, write config
|
|
69
|
+
npx @natjswenson/devlog preview # see it rendered at http://localhost:5173
|
|
42
70
|
```
|
|
43
71
|
|
|
44
|
-
|
|
72
|
+
`init` creates `<your-username>/daily-dev-log` on GitHub (or uses an existing
|
|
73
|
+
repo), installs the skill at `~/.claude/skills/devlog/`, writes its config, and
|
|
74
|
+
lets you register one or more projects in a single run.
|
|
75
|
+
|
|
76
|
+
> **Run from any directory *outside* a clone of this repo.** Running inside it
|
|
77
|
+
> causes a `package.json` name collision and `npx` fails with
|
|
78
|
+
> `command not found`.
|
|
79
|
+
|
|
80
|
+
## Triggers
|
|
81
|
+
|
|
82
|
+
- "/devlog", or "write a devlog entry".
|
|
83
|
+
- A release you just tagged that should become a post.
|
|
84
|
+
- Managing devlog config conversationally: "add this repo to devlog", "stop
|
|
85
|
+
tracking X", "set min sources to 4", "/devlog status".
|
|
86
|
+
- "Draft one concept guide using the agent-friendly method" or "consolidate these
|
|
87
|
+
posts into one guide" selects the new local draft workflow.
|
|
88
|
+
- "Create an AI cover draft for this article" selects the Codex artwork workflow
|
|
89
|
+
without scanning or publishing.
|
|
90
|
+
|
|
91
|
+
## Requirements
|
|
45
92
|
|
|
46
|
-
|
|
93
|
+
- **Claude Code:** Authenticate `gh` in the shell and allow web research for release guides.
|
|
94
|
+
- **Codex:** Use the same authenticated `gh` CLI and available web tools. `init` still writes its legacy Claude skill copy; the Codex plugin is installed separately above.
|
|
95
|
+
- **Personal data:** Both hosts retain config, voice fallback and image-style assets in `~/.claude/skills/devlog/`; an existing `~/.claude/ghostwriter/voice` can also supply the voice.
|
|
47
96
|
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
- **
|
|
97
|
+
See [Codex migration notes](../../docs/codex-migration.md) for host tools and retained data paths.
|
|
98
|
+
|
|
99
|
+
- **Node 18+** for the CLI and preview app.
|
|
100
|
+
- **GitHub CLI** (`gh`), authenticated with `gh auth login` — used to create your
|
|
101
|
+
dev-log repo and push entries.
|
|
102
|
+
- **Claude Code** (`/devlog`) or **Codex** (`$devlog`) to run the skill.
|
|
103
|
+
- Concept drafts use independent agents for review/adaptation when available;
|
|
104
|
+
missing capabilities retain the draft with explicit uncompleted checks.
|
|
105
|
+
- AI artwork requires the session's native image tool. No implicit API fallback.
|
|
106
|
+
|
|
107
|
+
## How it works
|
|
108
|
+
|
|
109
|
+
1. **You ship a release** — tag it, like you already do.
|
|
110
|
+
2. **Run `/devlog` in Claude Code.** The skill runs `devlog scan` to find tags
|
|
111
|
+
with no entry, researches the engineering topic behind each release, and
|
|
112
|
+
writes a full setup → build → use → verify guide, with a required
|
|
113
|
+
`## Gotchas` section mined from your real fix commits and 3+ cited sources.
|
|
114
|
+
It is idempotent: re-running does nothing until you cut a new release.
|
|
115
|
+
3. **Your site fetches it.** Static `manifest.json` plus per-release markdown
|
|
116
|
+
served from `raw.githubusercontent.com`. No backend needed.
|
|
117
|
+
|
|
118
|
+
**In your voice.** Entries use a voice profile resolved in this order: your
|
|
119
|
+
`config.voicePath` → [ghostwriter](../ghostwriter)'s `voice/` dir if installed →
|
|
120
|
+
a bundled default. devlog reads `voice-profile.md` and `voice-notes.md`
|
|
121
|
+
overrides, never ghostwriter's `algorithm.md`, since LinkedIn reach tuning does
|
|
122
|
+
not apply to a dev log.
|
|
51
123
|
|
|
52
124
|
## Commands
|
|
53
125
|
|
|
54
126
|
| Command | What it does |
|
|
55
127
|
|---|---|
|
|
56
|
-
| `
|
|
57
|
-
| `
|
|
58
|
-
| `
|
|
59
|
-
| `
|
|
60
|
-
| `
|
|
61
|
-
| `
|
|
62
|
-
| `
|
|
63
|
-
| `
|
|
64
|
-
| `
|
|
65
|
-
| `
|
|
66
|
-
| `
|
|
67
|
-
|
|
68
|
-
|
|
128
|
+
| `devlog init` | One-time setup: create dev-log repo, install skill, write config |
|
|
129
|
+
| `devlog add-project` | Register a project (interactive; `--yes --path <p>` for agent use) |
|
|
130
|
+
| `devlog remove-project <key> --yes` | Unregister a project (published entries stay) |
|
|
131
|
+
| `devlog set <field> <value>` | Update one config field |
|
|
132
|
+
| `devlog config [--json]` | Show current config with validation status |
|
|
133
|
+
| `devlog scan [--project <key>]` | JSON plan of new releases needing entries |
|
|
134
|
+
| `devlog lint-post <file>` | Deterministic post-contract check |
|
|
135
|
+
| `devlog lint-guide <file> [--voice]` | Post checks plus a unique top-of-post implementation handoff |
|
|
136
|
+
| `devlog prepare-guide --article <md> --brand <json> --out <new-dir> [--cover <png>]` | Standalone local preview and complete copyable prompt/reference |
|
|
137
|
+
| `devlog compose-art-cover --spec <json> --out <new-dir>` | Offline raster artwork composition and hashed result; no image-service call |
|
|
138
|
+
| `devlog publish-entry ...` | Copy a drafted entry into a clone and update the manifest; never overwrites |
|
|
139
|
+
| `devlog preview` | Run a local preview at `http://localhost:5173` |
|
|
140
|
+
|
|
141
|
+
## Concept guides and cover drafts
|
|
142
|
+
|
|
143
|
+
Explicit concept requests produce at most one complete guide teaching implementation
|
|
144
|
+
in the reader's project. The draft includes the full code, verification commands and
|
|
145
|
+
a prompt that preserves the reader's APIs, saved state and supported runtimes. The
|
|
146
|
+
preview's **Copy prompt + guide** button includes the full Markdown reference; denied
|
|
147
|
+
clipboard access provides a manual selection fallback.
|
|
148
|
+
|
|
149
|
+
The [concept workflow](skills/devlog/references/concept-guides.md) separates mechanical
|
|
150
|
+
lint from executed examples and independent adaptation evidence. The
|
|
151
|
+
[art workflow](skills/devlog/references/codex-cover-art.md) uses native Codex generation
|
|
152
|
+
followed by local typography. [Composition specs](skills/devlog/references/cover-spec.md)
|
|
153
|
+
consume generated/adopted brand JSON and local artwork; no installed PRESS dependency
|
|
154
|
+
is required. Sources remain intact, output directories must be new, and result markers
|
|
155
|
+
are written last. Review hashes identify artifacts, not proof of beautiful or correct art.
|
|
156
|
+
|
|
157
|
+
Default `/devlog` and `$devlog` retain release generation. Opt in with
|
|
158
|
+
`devlog set generationMode concept` to produce at most one complete concept guide
|
|
159
|
+
per normal run, including executed examples, an independent adaptation trial,
|
|
160
|
+
reviewed art and deployment verification. `devlog set generationMode release`
|
|
161
|
+
restores the legacy workflow. Explicit draft requests remain local.
|
|
162
|
+
|
|
163
|
+
The [publishing workflow](skills/devlog/references/guide-publishing.md) uses
|
|
164
|
+
`publish-guide --clone <content-root> --article <md> --evidence <json> [--cover <png>]`
|
|
165
|
+
to validate matching evidence before writing an unoccupied release identity.
|
|
166
|
+
It never pushes by itself. Installation does not change user configuration,
|
|
167
|
+
rewrite old posts or add a suppression ledger. Existing-post consolidation and
|
|
168
|
+
backfill remain separate explicitly scoped work.
|
|
69
169
|
|
|
70
170
|
## What you end up with
|
|
71
171
|
|
|
@@ -86,21 +186,9 @@ github.com/<you>/daily-dev-log/ # Created by init, populated by /devlog
|
|
|
86
186
|
└── ...
|
|
87
187
|
```
|
|
88
188
|
|
|
89
|
-
## Manual setup (if you prefer)
|
|
90
|
-
|
|
91
|
-
```sh
|
|
92
|
-
gh repo create <you>/daily-dev-log --public --add-readme
|
|
93
|
-
mkdir -p ~/.claude/skills/devlog/voice
|
|
94
|
-
curl -o ~/.claude/skills/devlog/SKILL.md https://raw.githubusercontent.com/natejswenson/devlog/main/SKILL.md
|
|
95
|
-
# Optional fallback voice profile (used when voicePath and ghostwriter are both absent):
|
|
96
|
-
curl -o ~/.claude/skills/devlog/voice/voice-profile.md https://raw.githubusercontent.com/natejswenson/devlog/main/voice/voice-profile.example.md
|
|
97
|
-
curl -o ~/.claude/skills/devlog/voice/voice-notes.md https://raw.githubusercontent.com/natejswenson/devlog/main/voice/voice-notes.example.md
|
|
98
|
-
# Then copy config.example.json → ~/.claude/skills/devlog/config.json and fill it in
|
|
99
|
-
```
|
|
100
|
-
|
|
101
189
|
## Add to your site
|
|
102
190
|
|
|
103
|
-
|
|
191
|
+
**React (drop-in):**
|
|
104
192
|
|
|
105
193
|
```sh
|
|
106
194
|
cp -r examples/react/ your-site/src/devlog/
|
|
@@ -114,30 +202,30 @@ import DevLogPage from './devlog/DevLogPage.jsx';
|
|
|
114
202
|
<DevLogPage project="myproject" />
|
|
115
203
|
```
|
|
116
204
|
|
|
117
|
-
Full instructions: [`examples/react/README.md`](
|
|
205
|
+
Full instructions: [`examples/react/README.md`](skills/devlog/examples/react/README.md).
|
|
118
206
|
|
|
119
|
-
|
|
207
|
+
**No site yet?** The `preview/` directory is a complete deployable Vite app. Set
|
|
208
|
+
`VITE_DEVLOG_OWNER` / `VITE_DEVLOG_REPO` / `VITE_DEVLOG_PROJECTS` on Vercel,
|
|
209
|
+
Netlify or Cloudflare Pages, build with `vite build`, deploy `dist/`.
|
|
120
210
|
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
### Other stacks (Next, Astro, plain HTML)
|
|
124
|
-
|
|
125
|
-
It's static JSON and Markdown on GitHub. Build whatever UI you want — see the **Data contract** below.
|
|
211
|
+
**Other stacks (Next, Astro, plain HTML):** it is static JSON and Markdown on
|
|
212
|
+
GitHub. Build whatever UI you want against the data contract below.
|
|
126
213
|
|
|
127
214
|
## Data contract
|
|
128
215
|
|
|
129
|
-
The dev-log repo has this layout, all served as raw files from
|
|
216
|
+
The dev-log repo has this layout, all served as raw files from
|
|
217
|
+
`https://raw.githubusercontent.com/<owner>/<repo>/<branch>/`:
|
|
130
218
|
|
|
131
219
|
```
|
|
132
220
|
<repo>/
|
|
133
221
|
└── <project-key>/
|
|
134
222
|
├── manifest.json # Index of all entries (newest first)
|
|
135
223
|
├── v0.3.0.md # One entry per release (named by version)
|
|
136
|
-
├── v0.2.0.md
|
|
137
224
|
└── ...
|
|
138
225
|
```
|
|
139
226
|
|
|
140
|
-
|
|
227
|
+
`manifest.json`:
|
|
228
|
+
|
|
141
229
|
```json
|
|
142
230
|
{
|
|
143
231
|
"entries": [
|
|
@@ -146,13 +234,15 @@ The dev-log repo has this layout, all served as raw files from `https://raw.gith
|
|
|
146
234
|
}
|
|
147
235
|
```
|
|
148
236
|
|
|
149
|
-
Strict validation rules
|
|
237
|
+
Strict validation rules — entries that do not match are silently dropped by the
|
|
238
|
+
React example:
|
|
239
|
+
|
|
150
240
|
- `date` matches `YYYY-MM-DD` (the release/tag date)
|
|
151
241
|
- `file` matches `^[a-zA-Z0-9._-]+\.md$`
|
|
152
242
|
- `title` and `summary` are non-empty strings
|
|
153
243
|
- `version` (optional) matches `^[a-zA-Z0-9._-]+$`
|
|
154
244
|
|
|
155
|
-
|
|
245
|
+
Entry markdown:
|
|
156
246
|
|
|
157
247
|
```markdown
|
|
158
248
|
---
|
|
@@ -181,7 +271,8 @@ Real traps from the release's history, each: trap → symptom → escape.
|
|
|
181
271
|
- commit message ([abc1234](https://github.com/.../commit/abc1234567...))
|
|
182
272
|
```
|
|
183
273
|
|
|
184
|
-
That
|
|
274
|
+
That is the entire contract — `devlog lint-post <file>` checks the mechanical
|
|
275
|
+
parts of it.
|
|
185
276
|
|
|
186
277
|
## Configuration reference
|
|
187
278
|
|
|
@@ -189,84 +280,103 @@ That's the entire contract — `npx @natjswenson/devlog lint-post <file>` checks
|
|
|
189
280
|
|
|
190
281
|
| Field | Type | Description |
|
|
191
282
|
|---|---|---|
|
|
192
|
-
| `targetRepo` | `"<owner>/<repo>"` | Repo where
|
|
283
|
+
| `targetRepo` | `"<owner>/<repo>"` | Repo where entries are published. Must match `^[a-z0-9][a-z0-9._-]*\/[a-z0-9][a-z0-9._-]*$`. |
|
|
193
284
|
| `branch` | string (optional) | Branch in the dev-log repo. Defaults to `main`. Must not contain `..` or start with `-`. |
|
|
194
|
-
| `gitAuthor` | string | Your name. Retained for backward compatibility;
|
|
285
|
+
| `gitAuthor` | string | Your name. Retained for backward compatibility; **not** currently rendered on entries, but still **required** by config validation. Whitespace OK; no shell metacharacters. |
|
|
195
286
|
| `githubUser` | string | Your GitHub username. |
|
|
196
|
-
| `voicePath` | string (optional) | Directory holding `voice-profile.md` (and optionally `voice-notes.md`)
|
|
287
|
+
| `voicePath` | string (optional) | Directory holding `voice-profile.md` (and optionally `voice-notes.md`). A leading `~` is expanded. Read only, never shell-interpolated. |
|
|
197
288
|
| `projects` | array | One entry per project you want dev logs for. |
|
|
198
289
|
| `projects[].key` | string | Subdirectory name in the dev-log repo. Strict token: `^[a-z0-9][a-z0-9._-]*$`, no `..`. |
|
|
199
290
|
| `projects[].label` | string (optional) | Display name for the tab. Defaults to `key`. |
|
|
200
291
|
| `projects[].path` | string | Local filesystem path to the project. Whitespace OK. |
|
|
201
|
-
| `projects[].remote` | `"<owner>/<repo>"` | The project's GitHub remote
|
|
202
|
-
| `projects[].pathFilter` | string (optional) | Repo-relative subdir scoping this project's commits in a monorepo
|
|
203
|
-
| `projects[].tagPrefix` | string (optional) | Prefix of the git tags
|
|
204
|
-
| `deepDive` | object (optional) |
|
|
292
|
+
| `projects[].remote` | `"<owner>/<repo>"` | The project's GitHub remote, used to mark public commits and link them. |
|
|
293
|
+
| `projects[].pathFilter` | string (optional) | Repo-relative subdir scoping this project's commits in a monorepo. |
|
|
294
|
+
| `projects[].tagPrefix` | string (optional) | Prefix of the git tags marking this project's releases. Defaults to `v`. |
|
|
295
|
+
| `deepDive` | object (optional) | `topicDomains` steers topic selection; `minSources` (1–10, default 3) is the floor of **distinct** cited source URLs per post. |
|
|
296
|
+
|
|
297
|
+
See [`config.example.json`](skills/devlog/config.example.json) for a complete
|
|
298
|
+
template, or run `devlog config` to inspect yours with validation.
|
|
205
299
|
|
|
206
|
-
|
|
300
|
+
## Customization
|
|
301
|
+
|
|
302
|
+
- **Tweak the entry template:** edit `~/.claude/skills/devlog/SKILL.md` (Generate
|
|
303
|
+
mode, Step 3 — the how-to contract).
|
|
304
|
+
- **Tweak your voice:** edit `voice-profile.md` / `voice-notes.md` in your
|
|
305
|
+
`voicePath`.
|
|
306
|
+
- **Tune research depth:** `devlog set deepDive.minSources 4`, or
|
|
307
|
+
`set deepDive.topicDomains "security, platform engineering"`.
|
|
308
|
+
- **Tweak the UI:** override the `--devlog-*` CSS variables in
|
|
309
|
+
`examples/react/DevLogPage.css`.
|
|
310
|
+
- **Add or remove projects:** `devlog add-project` / `remove-project <key> --yes`,
|
|
311
|
+
or just tell Claude.
|
|
207
312
|
|
|
208
313
|
## Security
|
|
209
314
|
|
|
210
|
-
The package is designed to be safe to install on a developer's machine
|
|
315
|
+
The package is designed to be safe to install on a developer's machine holding
|
|
316
|
+
ambient `gh`/git credentials. See
|
|
317
|
+
[`SECURITY.md`](skills/devlog/SECURITY.md) for the full threat model.
|
|
318
|
+
|
|
319
|
+
- All shell calls in the CLI use `spawnSync` with argv arrays — no shell, no
|
|
320
|
+
injection surface.
|
|
321
|
+
- The skill validates every config field against an allowlist before
|
|
322
|
+
interpolating it into a shell command.
|
|
323
|
+
- Markdown rendering uses `react-markdown` with `skipHtml` and an allowlist
|
|
324
|
+
`urlTransform`; `data:`, `javascript:`, `vbscript:`, `file:` and `blob:` are all
|
|
325
|
+
neutralized.
|
|
326
|
+
- Frontmatter parsing uses `Object.create(null)` plus a key allowlist — no
|
|
327
|
+
prototype pollution.
|
|
328
|
+
- All external JSON is schema-validated before use.
|
|
329
|
+
- `config.json` is written atomically, mode 0600. All dependencies are pinned to
|
|
330
|
+
exact versions.
|
|
331
|
+
|
|
332
|
+
**To report a vulnerability:** open a
|
|
333
|
+
[GitHub security advisory](https://github.com/natejswenson/devlog/security/advisories/new).
|
|
334
|
+
Do not open a public issue.
|
|
211
335
|
|
|
212
|
-
|
|
213
|
-
- ✓ All shell calls in the CLI use `spawnSync` with argv arrays (no shell, no injection surface)
|
|
214
|
-
- ✓ The skill validates every config field against an allowlist before interpolating into shell commands; instructs the LLM to single-quote interpolated values
|
|
215
|
-
- ✓ Markdown rendering uses `react-markdown` with `skipHtml` and an allowlist `urlTransform` (only http(s)/mailto allowed; data:, javascript:, vbscript:, file:, blob: all neutralized)
|
|
216
|
-
- ✓ Frontmatter parser uses `Object.create(null)` + key allowlist (no prototype pollution)
|
|
217
|
-
- ✓ All external JSON is schema-validated before use (manifest, env-var projects array)
|
|
218
|
-
- ✓ Vite dev server bound to `localhost`, CORS off
|
|
219
|
-
- ✓ Demo-mode `window.fetch` override gated to dev builds only
|
|
220
|
-
- ✓ `config.json` written atomically (tmp + rename), mode 0600
|
|
221
|
-
- ✓ All dependencies pinned to exact versions
|
|
222
|
-
- ✓ `npm audit`: 0 known vulnerabilities
|
|
336
|
+
## Troubleshooting
|
|
223
337
|
|
|
224
|
-
|
|
338
|
+
**`sh: devlog: command not found` when running `npx`:** you are inside a checkout
|
|
339
|
+
of this repo. The local `package.json` name collides with the published one. Run
|
|
340
|
+
`npx` from somewhere else.
|
|
225
341
|
|
|
226
|
-
|
|
342
|
+
**Preview is blank, no tabs, no entries:** check the browser console. CJS interop
|
|
343
|
+
errors on `react-dom/client`, `style-to-js` or `react-markdown` mean a pre-0.1.6
|
|
344
|
+
release — `npm cache clean --force && rm -rf ~/.npm/_npx && npx --yes @natjswenson/devlog@latest preview`.
|
|
345
|
+
|
|
346
|
+
**Init cannot find `gh`:** install it from [cli.github.com](https://cli.github.com/)
|
|
347
|
+
and run `gh auth login`.
|
|
227
348
|
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
- **Tweak the UI:** override the `--devlog-*` CSS variables in `examples/react/DevLogPage.css` to match your theme.
|
|
232
|
-
- **Add or remove projects:** `npx @natjswenson/devlog add-project` / `remove-project <key> --yes` — or just tell Claude ("add this repo to devlog").
|
|
349
|
+
**`Config validation failed`:** run `devlog config` for a detailed diagnosis.
|
|
350
|
+
Common causes are shell metacharacters in a field, a project key containing `..`
|
|
351
|
+
or `/`, or a path that does not exist.
|
|
233
352
|
|
|
234
|
-
|
|
353
|
+
**Preview shows "Setup required":** you deployed the preview app standalone
|
|
354
|
+
without setting `VITE_DEVLOG_OWNER`, `VITE_DEVLOG_REPO` and
|
|
355
|
+
`VITE_DEVLOG_PROJECTS`.
|
|
235
356
|
|
|
236
|
-
|
|
237
|
-
run against real throwaway git repos). The non-deterministic half — post quality — is
|
|
238
|
-
covered by a cost-capped eval harness:
|
|
357
|
+
## Development
|
|
239
358
|
|
|
240
359
|
```sh
|
|
360
|
+
cd skills/devlog/skills/devlog
|
|
361
|
+
npm test # deterministic core; scan tests use real throwaway git repos
|
|
241
362
|
node evals/run_eval.mjs --mock # $0, runs in CI; deterministic layer only
|
|
242
363
|
node evals/run_eval.mjs --live # LLM judge on golden fixtures; quotes spend, hard cap $0.50
|
|
243
364
|
```
|
|
244
365
|
|
|
245
|
-
The judge scores reproducibility, code completeness, gotcha quality,
|
|
246
|
-
and scope honesty (pass ≥ 7/10). Without `ANTHROPIC_API_KEY` in
|
|
247
|
-
mode is forced
|
|
248
|
-
|
|
249
|
-
## Troubleshooting
|
|
250
|
-
|
|
251
|
-
**`sh: devlog: command not found` when running `npx`:** you're inside a checkout of this repo. The local `package.json` name collides with the published one. Run `npx` from somewhere else, e.g. `cd ~ && npx @natjswenson/devlog ...`.
|
|
366
|
+
Node skill. The judge scores reproducibility, code completeness, gotcha quality,
|
|
367
|
+
citations, voice and scope honesty (pass ≥ 7/10). Without `ANTHROPIC_API_KEY` in
|
|
368
|
+
the environment, mock mode is forced, so **CI can never spend money**.
|
|
252
369
|
|
|
253
|
-
|
|
370
|
+
The baseline is pinned against 8 entries actually published to natejswenson.io —
|
|
371
|
+
a curated subset on purpose, since only 17 of 61 published entries satisfy
|
|
372
|
+
today's contract and asserting over all 61 would encode "the linter must accept
|
|
373
|
+
its own history".
|
|
254
374
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
**Init can't find `gh`:** install via [cli.github.com](https://cli.github.com/) and run `gh auth login`.
|
|
258
|
-
|
|
259
|
-
**`Config validation failed: ...`** — the validator rejected something in your `config.json`. Run `npx @natjswenson/devlog config` for a detailed diagnosis. Common causes:
|
|
260
|
-
- A field has shell metacharacters (`;` `&` `|` `` ` `` `$` etc) — see SKILL.md for the full list
|
|
261
|
-
- A project key contains `..` or `/`
|
|
262
|
-
- A path doesn't exist on disk
|
|
263
|
-
|
|
264
|
-
**Preview shows "Setup required":** you deployed the preview app standalone but didn't set the env vars. Set `VITE_DEVLOG_OWNER`, `VITE_DEVLOG_REPO`, `VITE_DEVLOG_PROJECTS` (JSON-stringified array) in your hosting environment.
|
|
265
|
-
|
|
266
|
-
## Versioning
|
|
375
|
+
## Changelog
|
|
267
376
|
|
|
268
|
-
|
|
377
|
+
See [`CHANGELOG.md`](CHANGELOG.md). Releases are cut by a version bump, tagged
|
|
378
|
+
`devlog-v<version>`, and published to npm.
|
|
269
379
|
|
|
270
380
|
## License
|
|
271
381
|
|
|
272
|
-
MIT
|
|
382
|
+
MIT — see [`LICENSE`](LICENSE).
|