@natjswenson/press 0.5.1 → 0.6.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 +38 -0
- package/SKILL.md +12 -7
- package/lib/propagate.mjs +33 -11
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,42 @@ All notable changes to the **press** skill are documented here.
|
|
|
5
5
|
The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and
|
|
6
6
|
this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [0.6.1] - 2026-08-01
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Every propagate push failed on missing git credentials, and the job still
|
|
13
|
+
reported success.** `gh` authenticates its own API calls from `GH_TOKEN`, so
|
|
14
|
+
cloning and PR listing worked, but a plain `git push` has no credential helper
|
|
15
|
+
and fails with `could not read Username for 'https://github.com'`. All four
|
|
16
|
+
consumers failed this way on the 0.6.0 release. `gh auth setup-git` now wires
|
|
17
|
+
gh in as git's credential helper.
|
|
18
|
+
- **A failed fan-out now fails the job.** Failures were a warning, on the
|
|
19
|
+
reasoning that the release had already happened and the weekly run would
|
|
20
|
+
retry. That was wrong: a fan-out that silently does nothing is worse than one
|
|
21
|
+
that never ran, because the green tick claims the brand reached everywhere
|
|
22
|
+
when it reached nowhere.
|
|
23
|
+
|
|
24
|
+
## [0.6.0] - 2026-08-01
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- **A consumer's pin, its region receipt and the current release are now kept
|
|
29
|
+
equal.** Previously propagation acted only when generated *values* moved, so
|
|
30
|
+
a repo could show three different version numbers at once — natejswenson.io
|
|
31
|
+
read pin 0.2.0, receipt 0.1.0, latest 0.5.1 — and there was no way to tell a
|
|
32
|
+
healthy consumer from a stale one without knowing the rule. Every release now
|
|
33
|
+
opens a PR in every consumer.
|
|
34
|
+
|
|
35
|
+
What keeps that readable is that the PR says which kind it is: a **brand
|
|
36
|
+
change** (`press vX — BRAND VALUES CHANGED`) is reviewed as a design change,
|
|
37
|
+
while a **version-only adoption** (`adopt press vX`) is a one-line diff where
|
|
38
|
+
nothing renders differently. `propagate --json` reports the two separately as
|
|
39
|
+
`brand` and `stale`.
|
|
40
|
+
|
|
41
|
+
The trade is deliberate: a few no-op pull requests per release, in exchange
|
|
42
|
+
for state anyone can read at a glance.
|
|
43
|
+
|
|
8
44
|
## [0.5.1] - 2026-08-01
|
|
9
45
|
|
|
10
46
|
### Fixed
|
|
@@ -228,6 +264,8 @@ source of truth and a CI drift gate.
|
|
|
228
264
|
rasterised cards, whose eyebrow legitimately runs at `.16em`. Scoped rather
|
|
229
265
|
than waived, and caught by linting the real shipped corpus.
|
|
230
266
|
|
|
267
|
+
[0.6.1]: https://github.com/natejswenson/claude-skills/releases/tag/press-v0.6.1
|
|
268
|
+
[0.6.0]: https://github.com/natejswenson/claude-skills/releases/tag/press-v0.6.0
|
|
231
269
|
[0.5.1]: https://github.com/natejswenson/claude-skills/releases/tag/press-v0.5.1
|
|
232
270
|
[0.5.0]: https://github.com/natejswenson/claude-skills/releases/tag/press-v0.5.0
|
|
233
271
|
[0.4.1]: https://github.com/natejswenson/claude-skills/releases/tag/press-v0.4.1
|
package/SKILL.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
name: press
|
|
3
3
|
description: The one brand system for everything produced in Claude — design tokens, the visual laws, the run-presentation contract, and the universal voice core. Use when composing or restyling any artifact (report, résumé, card, cover, PDF, HTML page, chart), when asked about brand colors, fonts, the accent law or "the PRESS look", when adding a new skill that renders anything, or when a brand value needs to change everywhere at once. Also handles "check the brand is in sync", "why do my colors differ", and onboarding a new consumer repo.
|
|
4
4
|
user_invocable: true
|
|
5
|
-
version: 0.
|
|
5
|
+
version: 0.6.1
|
|
6
6
|
---
|
|
7
7
|
|
|
8
8
|
# /press — the brand system
|
|
@@ -108,13 +108,18 @@ node bin/press.js propagate --repo ../budget # re-emit + bump its pi
|
|
|
108
108
|
what moved. The caller turns that into a pull request, so nothing lands
|
|
109
109
|
unreviewed — but nobody has to *remember*.
|
|
110
110
|
|
|
111
|
-
|
|
111
|
+
**One version per repo.** A consumer's CI pin, its region receipt and the
|
|
112
|
+
current release are kept equal, so "is this repo up to date?" is answerable by
|
|
113
|
+
looking. The earlier rule — only act when values move — left three divergent
|
|
114
|
+
version numbers per repo and no way to tell a healthy consumer from a stale one.
|
|
112
115
|
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
116
|
+
Every release therefore opens a PR in every consumer. What keeps that readable
|
|
117
|
+
is that the PR says which kind it is:
|
|
118
|
+
|
|
119
|
+
| Kind | Title | Review |
|
|
120
|
+
|---|---|---|
|
|
121
|
+
| **Brand values moved** | `press vX — BRAND VALUES CHANGED` | read the diff as a design change |
|
|
122
|
+
| **Version only** | `adopt press vX` | one line; nothing renders differently |
|
|
118
123
|
|
|
119
124
|
`.github/workflows/press-propagate.yml` runs this on every release and weekly,
|
|
120
125
|
opening a PR in each consumer repo whose bytes actually moved.
|
package/lib/propagate.mjs
CHANGED
|
@@ -52,19 +52,35 @@ export function propagate({ tokens, targets, root, version, dryRun = false }) {
|
|
|
52
52
|
}
|
|
53
53
|
const body = emitBody(tokens, target.emitter, target.params ?? {});
|
|
54
54
|
const after = spliceRegion(before, target.region, target.syntax, body, version);
|
|
55
|
-
//
|
|
56
|
-
//
|
|
57
|
-
//
|
|
58
|
-
|
|
55
|
+
// Two different kinds of "changed", kept apart on purpose.
|
|
56
|
+
//
|
|
57
|
+
// brand the generated VALUES moved — something renders differently and
|
|
58
|
+
// the diff must be reviewed as a design change.
|
|
59
|
+
// version only the marker's recorded version moved. Nothing renders
|
|
60
|
+
// differently; the repo is adopting a newer press.
|
|
61
|
+
//
|
|
62
|
+
// Both are written. Skipping the write when only the version moved is what
|
|
63
|
+
// produced three divergent version numbers per repo — pin, region receipt
|
|
64
|
+
// and current release all disagreeing, with no way to tell a healthy
|
|
65
|
+
// consumer from a stale one at a glance.
|
|
66
|
+
const brandChanged = found.body.replace(/\s+$/, '') !== body.replace(/\s+$/, '');
|
|
67
|
+
const versionChanged = found.version !== version;
|
|
68
|
+
const changed = brandChanged || versionChanged;
|
|
59
69
|
if (changed && !dryRun) writeFileSync(path, after, 'utf8');
|
|
60
70
|
regions.push({
|
|
61
71
|
id: target.id,
|
|
62
72
|
path: target.path,
|
|
63
|
-
//
|
|
64
|
-
//
|
|
65
|
-
//
|
|
73
|
+
// Carried as booleans, never re-derived from the status string: matching
|
|
74
|
+
// /updated$/ once silently missed "would update", so a dry run reported
|
|
75
|
+
// "nothing to do" while showing a changed region.
|
|
66
76
|
changed,
|
|
67
|
-
|
|
77
|
+
brandChanged,
|
|
78
|
+
versionChanged,
|
|
79
|
+
status: brandChanged
|
|
80
|
+
? (dryRun ? 'would change brand' : 'brand updated')
|
|
81
|
+
: versionChanged
|
|
82
|
+
? (dryRun ? 'would adopt' : 'adopted')
|
|
83
|
+
: 'current',
|
|
68
84
|
wroteBy: found.version,
|
|
69
85
|
});
|
|
70
86
|
}
|
|
@@ -76,9 +92,15 @@ export function propagate({ tokens, targets, root, version, dryRun = false }) {
|
|
|
76
92
|
version,
|
|
77
93
|
regions,
|
|
78
94
|
pins,
|
|
79
|
-
// A repo
|
|
80
|
-
//
|
|
81
|
-
|
|
95
|
+
// A repo needs a pull request if anything moved at all — values or version
|
|
96
|
+
// — so that its pin, its region receipt and the current release stay one
|
|
97
|
+
// readable number. Letting the receipt lag "because the body did not
|
|
98
|
+
// change" produced three divergent versions per repo and no way to tell a
|
|
99
|
+
// healthy consumer from a stale one at a glance.
|
|
100
|
+
changed: regions.some((r) => r.changed) || pins.some((p) => p.status !== 'current'),
|
|
101
|
+
// The subset a human must actually look at: these change what renders.
|
|
102
|
+
// Everything else is routine adoption and reviews in seconds.
|
|
103
|
+
brand: regions.filter((r) => r.brandChanged).map((r) => r.id),
|
|
82
104
|
stale: regions.filter((r) => r.changed).map((r) => r.id),
|
|
83
105
|
missing: regions.filter((r) => r.status === 'missing').map((r) => r.id),
|
|
84
106
|
};
|
package/package.json
CHANGED