@clossys/writer 0.3.2
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 +196 -0
- package/LICENSE +21 -0
- package/README.md +593 -0
- package/dist/addressability.d.ts +245 -0
- package/dist/addressability.d.ts.map +1 -0
- package/dist/addressability.js +567 -0
- package/dist/addressability.js.map +1 -0
- package/dist/checker.d.ts +159 -0
- package/dist/checker.d.ts.map +1 -0
- package/dist/checker.js +177 -0
- package/dist/checker.js.map +1 -0
- package/dist/cli.d.ts +149 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +1049 -0
- package/dist/cli.js.map +1 -0
- package/dist/copy-gate.d.ts +107 -0
- package/dist/copy-gate.d.ts.map +1 -0
- package/dist/copy-gate.js +132 -0
- package/dist/copy-gate.js.map +1 -0
- package/dist/fingerprint.d.ts +61 -0
- package/dist/fingerprint.d.ts.map +1 -0
- package/dist/fingerprint.js +64 -0
- package/dist/fingerprint.js.map +1 -0
- package/dist/index.d.ts +47 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +63 -0
- package/dist/index.js.map +1 -0
- package/dist/locale-coverage.d.ts +227 -0
- package/dist/locale-coverage.d.ts.map +1 -0
- package/dist/locale-coverage.js +414 -0
- package/dist/locale-coverage.js.map +1 -0
- package/dist/passage.d.ts +294 -0
- package/dist/passage.d.ts.map +1 -0
- package/dist/passage.js +463 -0
- package/dist/passage.js.map +1 -0
- package/dist/path-exclusions.d.ts +114 -0
- package/dist/path-exclusions.d.ts.map +1 -0
- package/dist/path-exclusions.js +213 -0
- package/dist/path-exclusions.js.map +1 -0
- package/dist/registry.d.ts +61 -0
- package/dist/registry.d.ts.map +1 -0
- package/dist/registry.js +64 -0
- package/dist/registry.js.map +1 -0
- package/dist/resolve.d.ts +33 -0
- package/dist/resolve.d.ts.map +1 -0
- package/dist/resolve.js +133 -0
- package/dist/resolve.js.map +1 -0
- package/dist/scan.d.ts +457 -0
- package/dist/scan.d.ts.map +1 -0
- package/dist/scan.js +1698 -0
- package/dist/scan.js.map +1 -0
- package/dist/schema.d.ts +81 -0
- package/dist/schema.d.ts.map +1 -0
- package/dist/schema.js +482 -0
- package/dist/schema.js.map +1 -0
- package/dist/types.d.ts +268 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +40 -0
- package/dist/types.js.map +1 -0
- package/dist/voice/checker.d.ts +186 -0
- package/dist/voice/checker.d.ts.map +1 -0
- package/dist/voice/checker.js +483 -0
- package/dist/voice/checker.js.map +1 -0
- package/dist/voice/derivation-coverage.d.ts +168 -0
- package/dist/voice/derivation-coverage.d.ts.map +1 -0
- package/dist/voice/derivation-coverage.js +181 -0
- package/dist/voice/derivation-coverage.js.map +1 -0
- package/dist/voice/fields.d.ts +107 -0
- package/dist/voice/fields.d.ts.map +1 -0
- package/dist/voice/fields.js +144 -0
- package/dist/voice/fields.js.map +1 -0
- package/dist/voice/index.d.ts +19 -0
- package/dist/voice/index.d.ts.map +1 -0
- package/dist/voice/index.js +24 -0
- package/dist/voice/index.js.map +1 -0
- package/dist/voice/internal/parse-template.d.ts +27 -0
- package/dist/voice/internal/parse-template.d.ts.map +1 -0
- package/dist/voice/internal/parse-template.js +111 -0
- package/dist/voice/internal/parse-template.js.map +1 -0
- package/dist/voice/internal/pattern-safety.d.ts +111 -0
- package/dist/voice/internal/pattern-safety.d.ts.map +1 -0
- package/dist/voice/internal/pattern-safety.js +278 -0
- package/dist/voice/internal/pattern-safety.js.map +1 -0
- package/dist/voice/schema.d.ts +65 -0
- package/dist/voice/schema.d.ts.map +1 -0
- package/dist/voice/schema.js +535 -0
- package/dist/voice/schema.js.map +1 -0
- package/dist/voice/types.d.ts +282 -0
- package/dist/voice/types.d.ts.map +1 -0
- package/dist/voice/types.js +37 -0
- package/dist/voice/types.js.map +1 -0
- package/package.json +72 -0
- package/src/addressability.ts +664 -0
- package/src/checker.ts +293 -0
- package/src/cli.ts +1166 -0
- package/src/copy-gate.ts +197 -0
- package/src/fingerprint.ts +66 -0
- package/src/index.ts +163 -0
- package/src/locale-coverage.ts +512 -0
- package/src/passage.ts +644 -0
- package/src/path-exclusions.ts +265 -0
- package/src/registry.ts +103 -0
- package/src/resolve.ts +172 -0
- package/src/scan.ts +1959 -0
- package/src/schema.ts +528 -0
- package/src/types.ts +301 -0
- package/src/voice/checker.ts +590 -0
- package/src/voice/derivation-coverage.ts +217 -0
- package/src/voice/fields.ts +160 -0
- package/src/voice/index.ts +55 -0
- package/src/voice/internal/parse-template.ts +114 -0
- package/src/voice/internal/pattern-safety.ts +336 -0
- package/src/voice/schema.ts +585 -0
- package/src/voice/types.ts +329 -0
- package/templates/voice-record.template.jsonc +135 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this package are documented here. Format follows
|
|
4
|
+
[Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
|
5
|
+
|
|
6
|
+
## [0.3.2] - 2026-08-30
|
|
7
|
+
|
|
8
|
+
### Changed
|
|
9
|
+
|
|
10
|
+
- Updated the package's public repository, issue-tracker, and homepage metadata to the canonical Foundry repository. This change is not a publication or qualification claim.
|
|
11
|
+
|
|
12
|
+
## [0.3.1] - 2026-08-24
|
|
13
|
+
|
|
14
|
+
### Fixed
|
|
15
|
+
|
|
16
|
+
- Added a current lifecycle note to the historical donor availability record.
|
|
17
|
+
|
|
18
|
+
## [0.3.0] - 2026-08-21
|
|
19
|
+
|
|
20
|
+
### Added — the passage layer (issue #373)
|
|
21
|
+
|
|
22
|
+
**A `Passage` composes `CopyEntry`/glossary-term REFERENCES the way a UI
|
|
23
|
+
block composes atoms.** `@vespeneventures/writer` already had terms (a
|
|
24
|
+
glossary) and entries (single addressable strings) and nothing between
|
|
25
|
+
them — in practice nobody reuses one string; they reuse a whole
|
|
26
|
+
empty-state (title + body + action), a whole FAQ item (question + answer),
|
|
27
|
+
a whole error (message + recovery). This release adds that missing
|
|
28
|
+
middle: terms ≈ tokens, entries ≈ atoms, passages ≈ blocks. Documents
|
|
29
|
+
(the composition layer, mirroring how a view composes blocks) remain out
|
|
30
|
+
of scope for this release — see the issue.
|
|
31
|
+
|
|
32
|
+
- **`PassageRecord`/`Passage`** (`passage.ts`): a `Passage` has a stable
|
|
33
|
+
dot-separated `id`, a required `context` (an unlocatable passage is not
|
|
34
|
+
reviewable, mirroring `CopyEntry.context`'s own rule), and `fields` — a
|
|
35
|
+
set of named slots (`title`, `body`, `action`, ...) each of which should
|
|
36
|
+
hold a `PassageReference`: `{ ref: "entry", id }` or `{ ref: "term",
|
|
37
|
+
term }`.
|
|
38
|
+
- **`validatePassageRecordShape`/`parsePassageRecord`** — structural
|
|
39
|
+
validation, in the same dependency-free, accumulate-and-keep-going style
|
|
40
|
+
every other schema in this package uses. Deliberately does NOT validate
|
|
41
|
+
a field's own value shape (whether it's a literal or a reference) — see
|
|
42
|
+
below.
|
|
43
|
+
- **`readPassageRecord`** — the one place in `passage.ts` that touches a
|
|
44
|
+
filesystem; never throws, mirrors `registry.ts`'s `readCopyRecord`
|
|
45
|
+
exactly.
|
|
46
|
+
- **`classifyPassageField`/`checkPassageComposition`** — the passage
|
|
47
|
+
COMPOSITION gate, wired to a new CLI subcommand, `writer-check passages
|
|
48
|
+
<registry-file>`, dispatched the identical way `writer-check
|
|
49
|
+
addressability` already is (a fully separate top-level branch, its own
|
|
50
|
+
exported `mainPassagesCheck`, never folded through `main()`). THE
|
|
51
|
+
TERNARY:
|
|
52
|
+
- **`0` (satisfied)** — every passage references only entries and
|
|
53
|
+
terms, at least one passage evaluated.
|
|
54
|
+
- **`1` (violated)** — a passage inlines a literal string instead of
|
|
55
|
+
referencing an entry (the verbal equivalent of a hardcoded value
|
|
56
|
+
instead of a token), or references another passage's own internals
|
|
57
|
+
(`{ ref: "passage", ... }`) rather than composing entries/terms the
|
|
58
|
+
way a block composes atoms. Wins over an incomplete picture in the
|
|
59
|
+
same run — the identical "a real violation must outrank an incomplete
|
|
60
|
+
scan" precedence this package's own `addressability` gate settled on
|
|
61
|
+
for issue #407/#433, applied here from the start.
|
|
62
|
+
- **`2` (indeterminate)** — the registry could not be
|
|
63
|
+
read/parsed/validated, zero passages were registered, or a field's
|
|
64
|
+
value could not be confidently classified, with zero violations found.
|
|
65
|
+
Fails CLOSED with a machine-readable reason; never a silent pass.
|
|
66
|
+
- **What this gate deliberately does not do**: verify a referenced entry
|
|
67
|
+
id or term actually exists in a real `CopyRecord`/glossary. That is a
|
|
68
|
+
different, weaker question than the one this gate answers (composition
|
|
69
|
+
purity: is this field a reference at all, never mind whether it
|
|
70
|
+
resolves) — the same split `addressability.ts` already draws from
|
|
71
|
+
`copy-gate.ts`'s traceability check. See
|
|
72
|
+
`passage.adversarial.test.ts` for the proof: a weaker
|
|
73
|
+
"every referenced entry id exists" tool passes a passage built entirely
|
|
74
|
+
from inline literals (it has zero references to check), while
|
|
75
|
+
`writer-check passages`, spawned as the compiled CLI, correctly exits 1
|
|
76
|
+
on the identical fixture.
|
|
77
|
+
- Not ported from `@vespeneventures/designer/tokens`: the `brandable` boolean.
|
|
78
|
+
See `passage.ts`'s own top doc comment, "WHERE THE MIRROR STOPS", for
|
|
79
|
+
why forcing that field into this layer would be false symmetry.
|
|
80
|
+
|
|
81
|
+
`checkPassageComposition`, `classifyPassageField`, `parsePassageRecord`,
|
|
82
|
+
`readPassageRecord`, `validatePassageRecordShape`, and every associated
|
|
83
|
+
type are exported from this package's root entry point.
|
|
84
|
+
|
|
85
|
+
## [0.2.0] - 2026-08-21
|
|
86
|
+
|
|
87
|
+
### Changed — BEHAVIOURAL, read this before upgrading (issue #407)
|
|
88
|
+
|
|
89
|
+
**`writer-check addressability`'s exit-code precedence flipped.** A run that
|
|
90
|
+
finds at least one violation now exits `1` REGARDLESS of how many string
|
|
91
|
+
positions are unclassified. Previously, any unclassified ("unchecked")
|
|
92
|
+
position forced exit `2` ("indeterminate") even when the same run had
|
|
93
|
+
already found and named real violations — and on any real tree, hundreds of
|
|
94
|
+
positions are token data this gate cannot classify by design, so the old
|
|
95
|
+
precedence made `1` unreachable outside a fixture: every real run had *some*
|
|
96
|
+
unclassified positions and therefore always read `2`, silently discarding
|
|
97
|
+
every violation it had actually found.
|
|
98
|
+
|
|
99
|
+
- **`violated` (exit `1`)** — at least one violation, regardless of
|
|
100
|
+
unclassified count. The coverage gap is not hidden by this: `unchecked`
|
|
101
|
+
and `reasons` are still populated and `writer-check addressability`
|
|
102
|
+
still prints them unconditionally; only the verdict changed.
|
|
103
|
+
- **`indeterminate` (exit `2`)** — zero violations AND at least one
|
|
104
|
+
unclassified position (or the tree could not be read, or zero components
|
|
105
|
+
were scanned). The honest "found nothing, but did not see everything"
|
|
106
|
+
case — unchanged, and still never a pass.
|
|
107
|
+
- **`satisfied` (exit `0`)** — zero violations, zero unclassified, over at
|
|
108
|
+
least one scanned file. Unchanged.
|
|
109
|
+
|
|
110
|
+
**If your CI treats `writer-check addressability`'s exit `2` as
|
|
111
|
+
non-blocking or "flaky, coverage is never complete, ignore it": stop.** A
|
|
112
|
+
tree that used to report `2` will now correctly report `1` whenever it
|
|
113
|
+
contains a real violation, and that is the point of this release, not a
|
|
114
|
+
regression — those trees always had the violation, this exit code was
|
|
115
|
+
previously the only thing hiding it.
|
|
116
|
+
|
|
117
|
+
`checkAddressability`'s `AddressabilityGateResult.verdict`/`.reasons` and
|
|
118
|
+
`mainAddressabilityCheck`'s exit code both changed together; no other
|
|
119
|
+
export's shape changed. See `addressability.ts`'s top doc comment ("THE
|
|
120
|
+
TERNARY") and `README.md`'s "Copy addressability" section for the full
|
|
121
|
+
precedence.
|
|
122
|
+
|
|
123
|
+
## [0.1.0] - 2026-08-21
|
|
124
|
+
|
|
125
|
+
First release. This package is the writer role, recut from
|
|
126
|
+
`@vespeneventures/copy` per
|
|
127
|
+
[decision 10](../../docs/DECISIONS.md#10-recutting-the-expression-surface-into-role-shaped-packages).
|
|
128
|
+
|
|
129
|
+
This changelog starts here rather than carrying the donor's history, which
|
|
130
|
+
cites decisions and issues that would mean nothing — or the wrong thing — to
|
|
131
|
+
a reader who arrives at this package first.
|
|
132
|
+
|
|
133
|
+
### Added
|
|
134
|
+
|
|
135
|
+
- A consumer-owned language system: voice rules (glossary terms and
|
|
136
|
+
regex-safe pattern rules), claims validation, addressable and
|
|
137
|
+
locale-aware copy records (`CopyRegistry`, `CopyRef`), source
|
|
138
|
+
traceability scanning, and computed content fingerprints.
|
|
139
|
+
- `readCopyRecord` and the `checkCopy` voice checker, unchanged from the
|
|
140
|
+
donor.
|
|
141
|
+
- Four gates, all reachable from the single `writer-check` bin: the
|
|
142
|
+
default traceability command, `addressability`, `voice-derivation-coverage`,
|
|
143
|
+
and `locale-coverage`. Each dispatches on `argv[0]` matching exactly —
|
|
144
|
+
never on `basename(process.argv[1])`, which would see `cli.js` and
|
|
145
|
+
silently run the wrong command wherever a gate is invoked by compiled
|
|
146
|
+
path.
|
|
147
|
+
- Zero runtime dependencies, unchanged from the donor.
|
|
148
|
+
- The `voice-record.template.jsonc` template, still reachable at the
|
|
149
|
+
`@vespeneventures/writer/voice-record.template.jsonc` export subpath.
|
|
150
|
+
- **The published tarball carries this changelog.** `files` includes
|
|
151
|
+
`CHANGELOG.md`, following the convention the operation packages adopted in
|
|
152
|
+
#417. A consumer reading the installed package should not have to leave it
|
|
153
|
+
to find out what changed; a new package should be born with the current
|
|
154
|
+
convention rather than inheriting its donor's gap.
|
|
155
|
+
|
|
156
|
+
### Changed from `@vespeneventures/copy`
|
|
157
|
+
|
|
158
|
+
- **The package is named for the job, not the artifact.** The role's
|
|
159
|
+
exclusive question is *is it well said?* A name that describes a thing
|
|
160
|
+
rather than a doer is an artifact, and an artifact belongs inside a role.
|
|
161
|
+
- **The bin is `writer-check`, not `copy-check`.** Same program, same four
|
|
162
|
+
subcommands, renamed to match the package.
|
|
163
|
+
- **Nothing else was renamed.** `CopyRegistry`, `CopyRef`, `checkCopyRecord`,
|
|
164
|
+
`CopyEntry`, `checkCopyTraceability`, the `copy-record` vocabulary, and
|
|
165
|
+
every voice/glossary/claim term keep their names. A role owns artifacts;
|
|
166
|
+
renaming the role does not rename what it reasons about. A sweep that also
|
|
167
|
+
renamed the vocabulary would have made the diff unreviewable while
|
|
168
|
+
changing no behaviour.
|
|
169
|
+
- Self-referential `@vespeneventures/copy` package-name mentions in doc
|
|
170
|
+
comments — including the `/voice` subpath — were updated to
|
|
171
|
+
`@vespeneventures/writer`, the same treatment `strategist` gave its own
|
|
172
|
+
self-references to `@vespeneventures/strategy`.
|
|
173
|
+
|
|
174
|
+
### On the donor, and why it is not deprecated yet
|
|
175
|
+
|
|
176
|
+
> **Current lifecycle note:** `@vespeneventures/copy` and
|
|
177
|
+
> `@vespeneventures/surface` are now retired. This release note records their
|
|
178
|
+
> state at 0.1.0; the lifecycle contract is the authority for current
|
|
179
|
+
> availability.
|
|
180
|
+
|
|
181
|
+
`@vespeneventures/copy` stays `published` for now. It cannot be marked
|
|
182
|
+
deprecated while `@vespeneventures/surface` still declares it as a runtime
|
|
183
|
+
dependency — `check:package-governance` reports a lifecycle finding for a live
|
|
184
|
+
package depending on a deprecated one, and it is right to. The donors are
|
|
185
|
+
deprecated once `publisher` replaces `surface` and depends on this package
|
|
186
|
+
instead.
|
|
187
|
+
|
|
188
|
+
This is a deferral with a trigger, not an omission.
|
|
189
|
+
|
|
190
|
+
### Not included
|
|
191
|
+
|
|
192
|
+
- **No forwarding stub in the donor.** `@vespeneventures/copy` is
|
|
193
|
+
deprecated-and-retained: still installable for a consumer already pinned
|
|
194
|
+
to it, with no re-export pointing here. A stub would keep the old name
|
|
195
|
+
importable, and a supersession check could then never reach zero — the
|
|
196
|
+
forwarding layer would defeat the gate built to prove the swap completed.
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Calvin Hung
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|