@cosyte/script-utils 0.1.1 → 0.1.3
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 +36 -11
- package/LICENSE +1 -1
- package/README.md +198 -17
- package/agent-notes.d.ts +92 -0
- package/agent-notes.js +512 -0
- package/attw.d.ts +18 -0
- package/attw.js +188 -8
- package/catalog.d.ts +110 -0
- package/catalog.js +251 -0
- package/catalog.json +210 -0
- package/check-no-emdash.sh +46 -23
- package/claude-card.d.ts +64 -0
- package/claude-card.js +296 -0
- package/internal-refs.d.ts +12 -2
- package/internal-refs.js +131 -6
- package/package.json +27 -1
- package/phi-scan.d.ts +22 -0
- package/phi-scan.js +152 -4
- package/readme.d.ts +81 -0
- package/readme.js +489 -0
package/catalog.json
ADDED
|
@@ -0,0 +1,210 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$comment": "GENERATED by cosyte/config scripts/catalog.mjs from each package's package.json and catalog/tiers.json. Do not edit by hand: change the package.json or the tiers file, then run `node scripts/catalog.mjs write` from the umbrella.",
|
|
3
|
+
"libraries": [
|
|
4
|
+
{
|
|
5
|
+
"name": "@cosyte/hl7",
|
|
6
|
+
"slug": "hl7",
|
|
7
|
+
"description": "Developer-focused HL7 v2 toolkit for Node.js and TypeScript, message parsing and building, mutation and serialization, and one-line helpers.",
|
|
8
|
+
"line": "0.1",
|
|
9
|
+
"engines": {
|
|
10
|
+
"node": ">=22.0.0"
|
|
11
|
+
},
|
|
12
|
+
"repository": "https://github.com/cosyte/hl7",
|
|
13
|
+
"docs": "https://docs.cosyte.com/hl7",
|
|
14
|
+
"npm": "https://www.npmjs.com/package/@cosyte/hl7",
|
|
15
|
+
"tier": "standard",
|
|
16
|
+
"standard": "HL7 v2"
|
|
17
|
+
},
|
|
18
|
+
{
|
|
19
|
+
"name": "@cosyte/mllp",
|
|
20
|
+
"slug": "mllp",
|
|
21
|
+
"description": "MLLP transport for HL7 v2 in Node.js and TypeScript: client and server, framing, ACK correlation, auto-reconnect, TLS, and an in-memory transport for tests.",
|
|
22
|
+
"line": "0.1",
|
|
23
|
+
"engines": {
|
|
24
|
+
"node": ">=22.0.0"
|
|
25
|
+
},
|
|
26
|
+
"repository": "https://github.com/cosyte/mllp",
|
|
27
|
+
"docs": "https://docs.cosyte.com/mllp",
|
|
28
|
+
"npm": "https://www.npmjs.com/package/@cosyte/mllp",
|
|
29
|
+
"tier": "standard",
|
|
30
|
+
"standard": "MLLP"
|
|
31
|
+
},
|
|
32
|
+
{
|
|
33
|
+
"name": "@cosyte/fhir",
|
|
34
|
+
"slug": "fhir",
|
|
35
|
+
"description": "FHIR R4 for Node.js and TypeScript: a resource model that keeps every value exactly as written, JSON and XML codecs, layered validation, and a safety readout for status and negation.",
|
|
36
|
+
"line": "0.1",
|
|
37
|
+
"engines": {
|
|
38
|
+
"node": ">=22.0.0"
|
|
39
|
+
},
|
|
40
|
+
"repository": "https://github.com/cosyte/fhir",
|
|
41
|
+
"docs": "https://docs.cosyte.com/fhir",
|
|
42
|
+
"npm": "https://www.npmjs.com/package/@cosyte/fhir",
|
|
43
|
+
"tier": "standard",
|
|
44
|
+
"standard": "FHIR"
|
|
45
|
+
},
|
|
46
|
+
{
|
|
47
|
+
"name": "@cosyte/ccda",
|
|
48
|
+
"slug": "ccda",
|
|
49
|
+
"description": "C-CDA parser, serializer, and builder for Node.js and TypeScript: lenient on parse, spec-clean on emit.",
|
|
50
|
+
"line": "0.1",
|
|
51
|
+
"engines": {
|
|
52
|
+
"node": ">=22.0.0"
|
|
53
|
+
},
|
|
54
|
+
"repository": "https://github.com/cosyte/ccda",
|
|
55
|
+
"docs": "https://docs.cosyte.com/ccda",
|
|
56
|
+
"npm": "https://www.npmjs.com/package/@cosyte/ccda",
|
|
57
|
+
"tier": "standard",
|
|
58
|
+
"standard": "C-CDA"
|
|
59
|
+
},
|
|
60
|
+
{
|
|
61
|
+
"name": "@cosyte/x12",
|
|
62
|
+
"slug": "x12",
|
|
63
|
+
"description": "Developer-focused ASC X12 healthcare EDI parser, serializer, and builder for Node.js and TypeScript: lenient on parse, spec-clean on emit.",
|
|
64
|
+
"line": "0.1",
|
|
65
|
+
"engines": {
|
|
66
|
+
"node": ">=22.0.0"
|
|
67
|
+
},
|
|
68
|
+
"repository": "https://github.com/cosyte/x12",
|
|
69
|
+
"docs": "https://docs.cosyte.com/x12",
|
|
70
|
+
"npm": "https://www.npmjs.com/package/@cosyte/x12",
|
|
71
|
+
"tier": "standard",
|
|
72
|
+
"standard": "X12"
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
"name": "@cosyte/ncpdp",
|
|
76
|
+
"slug": "ncpdp",
|
|
77
|
+
"description": "NCPDP parser, serializer, and builder for Node.js and TypeScript: SCRIPT ePrescribing and Telecom pharmacy claims, lenient on parse, spec-clean on emit.",
|
|
78
|
+
"line": "0.1",
|
|
79
|
+
"engines": {
|
|
80
|
+
"node": ">=22.0.0"
|
|
81
|
+
},
|
|
82
|
+
"repository": "https://github.com/cosyte/ncpdp",
|
|
83
|
+
"docs": "https://docs.cosyte.com/ncpdp",
|
|
84
|
+
"npm": "https://www.npmjs.com/package/@cosyte/ncpdp",
|
|
85
|
+
"tier": "standard",
|
|
86
|
+
"standard": "NCPDP"
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
"name": "@cosyte/astm",
|
|
90
|
+
"slug": "astm",
|
|
91
|
+
"description": "ASTM parser, serializer, and builder for Node.js and TypeScript: lenient on parse, spec-clean on emit.",
|
|
92
|
+
"line": "0.1",
|
|
93
|
+
"engines": {
|
|
94
|
+
"node": ">=22.0.0"
|
|
95
|
+
},
|
|
96
|
+
"repository": "https://github.com/cosyte/astm",
|
|
97
|
+
"docs": "https://docs.cosyte.com/astm",
|
|
98
|
+
"npm": "https://www.npmjs.com/package/@cosyte/astm",
|
|
99
|
+
"tier": "standard",
|
|
100
|
+
"standard": "ASTM"
|
|
101
|
+
},
|
|
102
|
+
{
|
|
103
|
+
"name": "@cosyte/dicom",
|
|
104
|
+
"slug": "dicom",
|
|
105
|
+
"description": "DICOM Part 10 parser + utility library for Node.js and TypeScript: metadata-first, vendor-quirky-tolerant, dual ESM/CJS.",
|
|
106
|
+
"line": "0.1",
|
|
107
|
+
"engines": {
|
|
108
|
+
"node": ">=22.0.0"
|
|
109
|
+
},
|
|
110
|
+
"repository": "https://github.com/cosyte/dicom",
|
|
111
|
+
"docs": "https://docs.cosyte.com/dicom",
|
|
112
|
+
"npm": "https://www.npmjs.com/package/@cosyte/dicom",
|
|
113
|
+
"tier": "standard",
|
|
114
|
+
"standard": "DICOM"
|
|
115
|
+
},
|
|
116
|
+
{
|
|
117
|
+
"name": "@cosyte/terminology",
|
|
118
|
+
"slug": "terminology",
|
|
119
|
+
"description": "Terminology engine for US healthcare code systems in Node.js and TypeScript: FHIR $translate, $lookup, $validate-code and $expand over code systems, value sets and maps you supply.",
|
|
120
|
+
"line": "0.1",
|
|
121
|
+
"engines": {
|
|
122
|
+
"node": ">=22.0.0"
|
|
123
|
+
},
|
|
124
|
+
"repository": "https://github.com/cosyte/terminology",
|
|
125
|
+
"docs": "https://docs.cosyte.com/terminology",
|
|
126
|
+
"npm": "https://www.npmjs.com/package/@cosyte/terminology",
|
|
127
|
+
"tier": "built-on"
|
|
128
|
+
},
|
|
129
|
+
{
|
|
130
|
+
"name": "@cosyte/transform",
|
|
131
|
+
"slug": "transform",
|
|
132
|
+
"description": "HL7 v2 → FHIR R4 transformation library for Node.js and TypeScript: IG-grounded, fail-safe, value-free diagnostics; never a confident wrong FHIR value.",
|
|
133
|
+
"line": "0.1",
|
|
134
|
+
"engines": {
|
|
135
|
+
"node": ">=22.0.0"
|
|
136
|
+
},
|
|
137
|
+
"repository": "https://github.com/cosyte/transform",
|
|
138
|
+
"docs": "https://docs.cosyte.com/transform",
|
|
139
|
+
"npm": "https://www.npmjs.com/package/@cosyte/transform",
|
|
140
|
+
"tier": "built-on"
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
"name": "@cosyte/deid",
|
|
144
|
+
"slug": "deid",
|
|
145
|
+
"description": "Healthcare de-identification for Node.js and TypeScript: applies a HIPAA Safe Harbor policy to HL7 v2, C-CDA, FHIR R4, X12, NCPDP Telecom and DICOM, fails closed, and emits a value-free manifest.",
|
|
146
|
+
"line": "0.1",
|
|
147
|
+
"engines": {
|
|
148
|
+
"node": ">=22.0.0"
|
|
149
|
+
},
|
|
150
|
+
"repository": "https://github.com/cosyte/deid",
|
|
151
|
+
"docs": "https://docs.cosyte.com/deid",
|
|
152
|
+
"npm": "https://www.npmjs.com/package/@cosyte/deid",
|
|
153
|
+
"tier": "built-on"
|
|
154
|
+
},
|
|
155
|
+
{
|
|
156
|
+
"name": "@cosyte/synth",
|
|
157
|
+
"slug": "synth",
|
|
158
|
+
"description": "Deterministic, seedable synthetic healthcare test fixtures for Node.js and TypeScript: HL7 v2, FHIR R4 and US Core, C-CDA, X12, NCPDP and ASTM, spec-clean by construction and never real PHI.",
|
|
159
|
+
"line": "0.1",
|
|
160
|
+
"engines": {
|
|
161
|
+
"node": ">=22.0.0"
|
|
162
|
+
},
|
|
163
|
+
"repository": "https://github.com/cosyte/synth",
|
|
164
|
+
"docs": "https://docs.cosyte.com/synth",
|
|
165
|
+
"npm": "https://www.npmjs.com/package/@cosyte/synth",
|
|
166
|
+
"tier": "built-on"
|
|
167
|
+
},
|
|
168
|
+
{
|
|
169
|
+
"name": "@cosyte/dates",
|
|
170
|
+
"slug": "dates",
|
|
171
|
+
"description": "Date and time utilities for the @cosyte/* healthcare parsers: precision-preserving conversion and validation that never guesses a timezone.",
|
|
172
|
+
"line": "0.1",
|
|
173
|
+
"engines": {
|
|
174
|
+
"node": ">=22.0.0"
|
|
175
|
+
},
|
|
176
|
+
"repository": "https://github.com/cosyte/dates",
|
|
177
|
+
"docs": "https://docs.cosyte.com/dates",
|
|
178
|
+
"npm": "https://www.npmjs.com/package/@cosyte/dates",
|
|
179
|
+
"tier": "built-on"
|
|
180
|
+
},
|
|
181
|
+
{
|
|
182
|
+
"name": "@cosyte/cli",
|
|
183
|
+
"slug": "cli",
|
|
184
|
+
"description": "The cosyte CLI: a PHI-safe developer front door over the @cosyte/* healthcare parsers. Parse HL7 v2 / FHIR from a file or stdin to typed JSON, with a documented exit-code contract.",
|
|
185
|
+
"line": "0.1",
|
|
186
|
+
"engines": {
|
|
187
|
+
"node": ">=22.0.0 <26.0.0"
|
|
188
|
+
},
|
|
189
|
+
"repository": "https://github.com/cosyte/cli",
|
|
190
|
+
"docs": "https://docs.cosyte.com/cli",
|
|
191
|
+
"npm": "https://www.npmjs.com/package/@cosyte/cli",
|
|
192
|
+
"tier": "built-on"
|
|
193
|
+
}
|
|
194
|
+
],
|
|
195
|
+
"engine": {
|
|
196
|
+
"name": "@cosyte/pathways",
|
|
197
|
+
"slug": "pathways",
|
|
198
|
+
"description": "A code-first healthcare integration engine for Node.js: channels in YAML, transforms in TypeScript. Early and not yet released.",
|
|
199
|
+
"line": "0.0",
|
|
200
|
+
"engines": {
|
|
201
|
+
"node": ">=24.0.0"
|
|
202
|
+
},
|
|
203
|
+
"repository": "https://github.com/cosyte/pathways",
|
|
204
|
+
"docs": "https://docs.cosyte.com/pathways",
|
|
205
|
+
"tier": "engine",
|
|
206
|
+
"displayName": "Pathways",
|
|
207
|
+
"status": "in development",
|
|
208
|
+
"onNpm": false
|
|
209
|
+
}
|
|
210
|
+
}
|
package/check-no-emdash.sh
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
#!/usr/bin/env bash
|
|
2
2
|
# scripts/check-no-emdash.sh
|
|
3
|
-
# Brand rule (founder directive, 2026-07-24):
|
|
3
|
+
# Brand rule (founder directive, 2026-07-24): we never use the em dash.
|
|
4
4
|
# The em dash (U+2014) reads as an AI tell, so it is banned outright across every
|
|
5
|
-
#
|
|
6
|
-
#
|
|
5
|
+
# Cosyte surface. The en dash (U+2013) is banned with it (operator decision,
|
|
6
|
+
# 2026-11-07), and this gate refuses both. Source of truth:
|
|
7
|
+
# `knowledgebase/06-brand/voice-and-tone.md`, which names COMMIT MESSAGES explicitly.
|
|
7
8
|
#
|
|
8
9
|
# THIS FILE IS THE ONE IMPLEMENTATION OF THE EM-DASH GATE FOR THIS ESTATE, and config
|
|
9
10
|
# owns it. Every other repo EXECUTES THESE EXACT BYTES and tracks no implementation of
|
|
@@ -57,8 +58,8 @@
|
|
|
57
58
|
# over a tree that was cleared rather than green over a tree nobody looked at. A gate
|
|
58
59
|
# without the sweep reds CI on arrival; a sweep without the gate lets it grow back.
|
|
59
60
|
#
|
|
60
|
-
# The fix is never to re-encode the character:
|
|
61
|
-
# colon, a comma, or parentheses.
|
|
61
|
+
# The fix is never to re-encode the character: write a range with "to", and rewrite a
|
|
62
|
+
# pause with a period, a colon, a comma, or parentheses.
|
|
62
63
|
#
|
|
63
64
|
# ---------------------------------------------------------------------------
|
|
64
65
|
# THE SURFACE. Four modes, and the exit vocabulary is CLOSED AT TWO CODES.
|
|
@@ -146,7 +147,7 @@
|
|
|
146
147
|
# hardcoded name would have excluded a consuming repo's `scripts/check-no-emdash.sh`
|
|
147
148
|
# whether or not one existed, which is an exclusion granted to a file nobody reviewed.
|
|
148
149
|
#
|
|
149
|
-
# Nothing checks the checker, so keep this file free of
|
|
150
|
+
# Nothing checks the checker, so keep this file free of either literal character: it
|
|
150
151
|
# matches by codepoint and by encoding and never spells one out.
|
|
151
152
|
# ---------------------------------------------------------------------------
|
|
152
153
|
# BINARY POSTURE. This repo scans EVERY tracked file with NO binary partition and
|
|
@@ -230,12 +231,16 @@ export LC_ALL=C.UTF-8
|
|
|
230
231
|
# Matches U+2014 as the literal character and as its encodings: %E2%80%94 (URL), the
|
|
231
232
|
# JS backslash-u escape, and the — / — / — HTML entities. The
|
|
232
233
|
# escape is not theoretical in this repo: it is what the parser-template manifest
|
|
233
|
-
# carried, and a literal-only sweep passed straight over it.
|
|
234
|
-
#
|
|
235
|
-
#
|
|
236
|
-
#
|
|
237
|
-
#
|
|
234
|
+
# carried, and a literal-only sweep passed straight over it. Matches U+2013 the same
|
|
235
|
+
# way: %E2%80%93, the backslash-u escape, and the – / – / – HTML
|
|
236
|
+
# entities.
|
|
237
|
+
#
|
|
238
|
+
# THE MATCH VOCABULARY IS FROZEN at these twelve forms, six for each dash. A consumer
|
|
239
|
+
# may narrow WHAT IS SCANNED through the declaration above; nothing may narrow WHAT IS
|
|
240
|
+
# MATCHED, and widening it is a change every consuming repo inherits at once and is
|
|
241
|
+
# specced as one. The en dash's six were that change (operator decision, 2026-11-07).
|
|
238
242
|
PATTERN='\x{2014}|%E2%80%94|\\u2014|—|—|—'
|
|
243
|
+
PATTERN+='|\x{2013}|%E2%80%93|\\u2013|–|–|–'
|
|
239
244
|
|
|
240
245
|
# The declaration's path, relative to the top level of the repo under scan. Deliberately
|
|
241
246
|
# NOT relative to this file: in a consuming repo this file lives under `node_modules/`
|
|
@@ -671,10 +676,11 @@ fi
|
|
|
671
676
|
|
|
672
677
|
if [ "$MODE" = files ] || [ "$MODE" = stdin ]; then
|
|
673
678
|
# SELF-TEST: prove the scanner can still MATCH what it is meant to catch before any
|
|
674
|
-
# clean result is believed
|
|
675
|
-
#
|
|
676
|
-
#
|
|
677
|
-
#
|
|
679
|
+
# clean result is believed, and that it leaves alone what the rule allows. `printf`
|
|
680
|
+
# emits U+2014, U+2013 and U+2212 as their UTF-8 bytes, so this file still never
|
|
681
|
+
# contains any of those characters. Scope the claim honestly: this proves the PATTERN
|
|
682
|
+
# compiles and matches, not that the scan reached every tracked file. The probe below
|
|
683
|
+
# and the refusals further down cover the second half.
|
|
678
684
|
if ! printf 'a\xe2\x80\x94b\n' | grep -qP "$PATTERN"; then
|
|
679
685
|
echo "ERROR: check-no-emdash - the scanner cannot match a known em dash." >&2
|
|
680
686
|
echo " grep -P is unavailable, not in UTF-8 mode (LC_ALL=${LC_ALL}), or has" >&2
|
|
@@ -683,6 +689,22 @@ if [ "$MODE" = files ] || [ "$MODE" = stdin ]; then
|
|
|
683
689
|
echo " Refusing to report a clean tree on a scanner that cannot see." >&2
|
|
684
690
|
exit 1
|
|
685
691
|
fi
|
|
692
|
+
if ! printf 'a\xe2\x80\x93b\n' | grep -qP "$PATTERN"; then
|
|
693
|
+
echo "ERROR: check-no-emdash - the scanner cannot match a known en dash." >&2
|
|
694
|
+
echo " grep -P is unavailable, not in UTF-8 mode (LC_ALL=${LC_ALL}), or has" >&2
|
|
695
|
+
echo " been forced to basic regular expressions, under which the alternations" >&2
|
|
696
|
+
echo " in PATTERN are literals and match nothing." >&2
|
|
697
|
+
echo " Refusing to report a clean tree on a scanner that cannot see." >&2
|
|
698
|
+
exit 1
|
|
699
|
+
fi
|
|
700
|
+
# The clean fixture: hyphens, a range written with "to", and the minus sign (U+2212),
|
|
701
|
+
# none of which the rule bans. A scanner that matched it would fail every tree, so its
|
|
702
|
+
# findings could not be told from noise.
|
|
703
|
+
if printf 'a-b, 2 to 3 tiers, \xe2\x88\x921\n' | grep -qP "$PATTERN"; then
|
|
704
|
+
echo "ERROR: check-no-emdash - the scanner matched clean text (hyphens and a minus sign)." >&2
|
|
705
|
+
echo " Refusing to report findings from a scanner that flags what the rule allows." >&2
|
|
706
|
+
exit 1
|
|
707
|
+
fi
|
|
686
708
|
|
|
687
709
|
# SCANNER VISIBILITY PROBE: prove the scanner can still READ a file before believing a
|
|
688
710
|
# word it says about one. The self-test above asserts what the tool MATCHES; this
|
|
@@ -708,7 +730,7 @@ if [ "$MODE" = files ] || [ "$MODE" = stdin ]; then
|
|
|
708
730
|
echo " NUL byte and a seeded em dash: no hit on stdout, no diagnostic on stderr," >&2
|
|
709
731
|
echo " exit 0. That is a scanner that cannot see its subject, and it is" >&2
|
|
710
732
|
echo " indistinguishable from a clean tree." >&2
|
|
711
|
-
echo " The known cause is a \`grep\` interposed with -I forced (the
|
|
733
|
+
echo " The known cause is a \`grep\` interposed with -I forced (the Cosyte dev" >&2
|
|
712
734
|
echo " container ships one as a shell function; \`export -f grep\` reaches a child" >&2
|
|
713
735
|
echo " script). Run this gate with a real GNU grep." >&2
|
|
714
736
|
exit 1
|
|
@@ -719,9 +741,10 @@ fail_with_hits() {
|
|
|
719
741
|
local what="$1" hits="$2"
|
|
720
742
|
echo "$hits" >&2
|
|
721
743
|
echo "" >&2
|
|
722
|
-
echo "ERROR: check-no-emdash - em dash (U+2014, or an encoded form) found in ${what}." >&2
|
|
723
|
-
echo "
|
|
724
|
-
echo "
|
|
744
|
+
echo "ERROR: check-no-emdash - em or en dash (U+2014 or U+2013, or an encoded form) found in ${what}." >&2
|
|
745
|
+
echo " We never use em or en dashes (founder directive; 06-brand/voice-and-tone.md)." >&2
|
|
746
|
+
echo " Write a range with \"to\"; rewrite a pause with a period, colon, comma, or" >&2
|
|
747
|
+
echo " parentheses. Never re-encode it." >&2
|
|
725
748
|
exit 1
|
|
726
749
|
}
|
|
727
750
|
|
|
@@ -738,7 +761,7 @@ refuse_if_incomplete() {
|
|
|
738
761
|
if grep -qi 'binary file' "$ERRLOG"; then
|
|
739
762
|
echo "ERROR: check-no-emdash - the input named above MATCHED the banned pattern, but" >&2
|
|
740
763
|
echo " grep classifies it as binary, so the hit is reported without a line" >&2
|
|
741
|
-
echo " number. Treat it as a real em dash." >&2
|
|
764
|
+
echo " number. Treat it as a real em or en dash." >&2
|
|
742
765
|
if [ "$SCAN_MODE" = stdin ]; then
|
|
743
766
|
echo " The text piped in is not valid UTF-8. Fix the encoding of whatever" >&2
|
|
744
767
|
echo " produced it, then rewrite the sentence." >&2
|
|
@@ -749,7 +772,7 @@ refuse_if_incomplete() {
|
|
|
749
772
|
echo " has ever tracked. If it is the latter, read the BINARY POSTURE note in" >&2
|
|
750
773
|
echo " this script's header before changing anything." >&2
|
|
751
774
|
fi
|
|
752
|
-
echo "
|
|
775
|
+
echo " We never use em or en dashes (founder directive; 06-brand/voice-and-tone.md)." >&2
|
|
753
776
|
fi
|
|
754
777
|
if grep -qiv 'binary file' "$ERRLOG"; then
|
|
755
778
|
echo "ERROR: check-no-emdash - the scan reported errors, so it did not read all of" >&2
|
|
@@ -776,7 +799,7 @@ if [ "$MODE" = stdin ]; then
|
|
|
776
799
|
HITS=$(grep -nP -e "$PATTERN" -- "$STDINBUF" 2>> "$ERRLOG" || true)
|
|
777
800
|
refuse_if_incomplete
|
|
778
801
|
[ -n "$HITS" ] && fail_with_hits "$LABEL" "$HITS"
|
|
779
|
-
echo "check-no-emdash: OK (no em dashes in ${LABEL})"
|
|
802
|
+
echo "check-no-emdash: OK (no em or en dashes in ${LABEL})"
|
|
780
803
|
exit 0
|
|
781
804
|
fi
|
|
782
805
|
|
|
@@ -869,6 +892,6 @@ refuse_if_incomplete
|
|
|
869
892
|
|
|
870
893
|
[ -n "$HITS" ] && fail_with_hits "the tracked files listed above" "$HITS"
|
|
871
894
|
|
|
872
|
-
echo "check-no-emdash: OK (no em dashes in ${scanned} of ${#TRACKED[@]} tracked file(s);" \
|
|
895
|
+
echo "check-no-emdash: OK (no em or en dashes in ${scanned} of ${#TRACKED[@]} tracked file(s);" \
|
|
873
896
|
"${gitlinks} gitlink(s) skipped, ${self_excluded} excluded as the implementation under" \
|
|
874
897
|
"scan, ${declared_excluded} excluded by ${DECLARATION})"
|
package/claude-card.d.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Types for `@cosyte/script-utils/claude-card`: the checker for the CLAUDE.md card every Cosyte
|
|
3
|
+
* repository keeps. The spec is `documentation/claude-card.md` in cosyte/config.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/** The most lines a card may have, counted as `wc -l` counts them. */
|
|
7
|
+
export declare const CARD_MAX_LINES: 60;
|
|
8
|
+
|
|
9
|
+
/** The most characters (code points) a line may have, code blocks included. */
|
|
10
|
+
export declare const CARD_MAX_LINE_LENGTH: 100;
|
|
11
|
+
|
|
12
|
+
/** The most bytes of UTF-8 a card may have. */
|
|
13
|
+
export declare const CARD_MAX_BYTES: 5120;
|
|
14
|
+
|
|
15
|
+
/** The three sections, in order. */
|
|
16
|
+
export declare const CARD_SECTIONS: readonly ["Gate", "Hazard", "Rules"];
|
|
17
|
+
|
|
18
|
+
/** The line that imports AGENTS.md into the card. */
|
|
19
|
+
export declare const AGENTS_IMPORT: "@AGENTS.md";
|
|
20
|
+
|
|
21
|
+
/** A rule id a finding can carry. */
|
|
22
|
+
export type CardRule =
|
|
23
|
+
| "title"
|
|
24
|
+
| "intro"
|
|
25
|
+
| "section-missing"
|
|
26
|
+
| "section-order"
|
|
27
|
+
| "section-extra"
|
|
28
|
+
| "section-empty"
|
|
29
|
+
| "lines"
|
|
30
|
+
| "width"
|
|
31
|
+
| "bytes"
|
|
32
|
+
| "agents-import";
|
|
33
|
+
|
|
34
|
+
/** Every rule id, with what it requires. */
|
|
35
|
+
export declare const CARD_RULES: Readonly<Record<CardRule, string>>;
|
|
36
|
+
|
|
37
|
+
/** One place a card departs from the spec. */
|
|
38
|
+
export interface CardFinding {
|
|
39
|
+
rule: CardRule;
|
|
40
|
+
/** 1-based line, or 0 when the finding is about the whole file. */
|
|
41
|
+
line: number;
|
|
42
|
+
message: string;
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
export interface CardContext {
|
|
46
|
+
/** Whether an AGENTS.md sits beside the card. Left out, the import rule is not checked. */
|
|
47
|
+
agentsMd?: boolean;
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/** Check a CLAUDE.md card against the spec. Returns no findings when it follows it. */
|
|
51
|
+
export declare function checkClaudeCard(text: string, context?: CardContext): CardFinding[];
|
|
52
|
+
|
|
53
|
+
export interface ClaudeCardGateOptions {
|
|
54
|
+
/** The repository root holding CLAUDE.md. Default: the working directory. */
|
|
55
|
+
dir?: string;
|
|
56
|
+
/** CLI arguments; only `--dir <path>` is accepted. */
|
|
57
|
+
argv?: string[];
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
/**
|
|
61
|
+
* Run the checker over one repository and return the exit code: 0 the card follows the spec, 1 at
|
|
62
|
+
* least one finding, 2 CLAUDE.md could not be read. It never exits the process.
|
|
63
|
+
*/
|
|
64
|
+
export declare function runClaudeCardGate(options?: ClaudeCardGateOptions): 0 | 1 | 2;
|