@cosyte/script-utils 0.1.6 → 0.1.8

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
@@ -1,5 +1,19 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.8
4
+
5
+ ### Patch Changes
6
+
7
+ - 7dee328: The catalog carries `@cosyte/cli`'s description from its latest npm release, which no longer ends
8
+ with the sentence on value-free diagnostics and the exit-code contract.
9
+
10
+ ## 0.1.7
11
+
12
+ ### Patch Changes
13
+
14
+ - 9d0d69f: Deprecated: the agent-notes checker, `@cosyte/script-utils/agent-notes` and its bin `cosyte-agent-notes`. The agent notes, `documentation/agent-notes.md`, were removed from every Cosyte repository (D62), so remove the package script or CI step that runs it. Until a minor release removes the entry point and the bin, a repository with no notes file (not tracked, or deleted from the working tree) passes: the checker exits 0 with one line, `agent notes: OK, no agent notes (retired, D62)`, where it used to fail on a pointer left in the card, a source comment or a changelog. A repository that still has the file is checked as before, and a failing run ends with a line saying the notes are retired. `--help`, the `script-utils` command list, the declarations and the README say it is deprecated.
15
+ - 9d0d69f: The CLAUDE.md card checker no longer sends detail to `documentation/agent-notes.md`, which was removed from every repository (D62). A card over 5,120 bytes, or with a level-2 heading other than Gate, Hazard and Rules, is told to move the detail to where it is used: a test, a comment at the code it guards, an ADR, the README or docs, or a runbook. What the checker checks, and its exit codes, are unchanged.
16
+
3
17
  ## 0.1.6
4
18
 
5
19
  ### Patch Changes
package/README.md CHANGED
@@ -188,20 +188,6 @@ catalogEntry("@cosyte/hl7")?.docs; // => "https://docs.cosyte.com/hl7"
188
188
  CATALOG.engine.displayName; // => "Pathways"
189
189
  ```
190
190
 
191
- The agent-notes checker is the eighth. It resolves every pointer into a repository's one notes
192
- file against that file's headings, slugged the way GitHub slugs them:
193
-
194
- ```ts runnable
195
- import { checkAgentNotes, slugify } from "@cosyte/script-utils/agent-notes";
196
-
197
- slugify("Why `attw` exits 0"); // => "why-attw-exits-0"
198
-
199
- const claude = "# demo\n\nSee documentation/agent-notes.md#setup.\n";
200
- const notes = "# Notes\n\n## Setup\n\nRun it.\n";
201
- checkAgentNotes({ claude, notes, files: [] }); // => []
202
- checkAgentNotes({ claude, notes: notes.replace("Setup", "Install"), files: [] })[0]?.rule; // => "dangling"
203
- ```
204
-
205
191
  ## Entry points
206
192
 
207
193
  | entry point | what it is |
@@ -213,7 +199,7 @@ checkAgentNotes({ claude, notes: notes.replace("Setup", "Install"), files: [] })
213
199
  | `@cosyte/script-utils/readme` | `runReadmeGate(options)` and `checkReadme(text, manifest)`, the README gate |
214
200
  | `@cosyte/script-utils/claude-card` | `runClaudeCardGate(options)` and `checkClaudeCard(text)`, the CLAUDE.md card checker |
215
201
  | `@cosyte/script-utils/catalog` | `CATALOG`, `catalogEntry(name)` and `runCatalogCheck(options)`, the catalog of our libraries |
216
- | `@cosyte/script-utils/agent-notes` | `runAgentNotesCheck(options)` and `checkAgentNotes(input)`, the agent-notes checker |
202
+ | `@cosyte/script-utils/agent-notes` | deprecated (D62): `runAgentNotesCheck(options)` and `checkAgentNotes(input)` |
217
203
 
218
204
  They are separate subpaths because they are separately adoptable: a repo can take the entry-point
219
205
  guard without taking a position on PHI scanning, a repo can take the internal-reference gate without
@@ -258,16 +244,16 @@ npx -y @cosyte/script-utils@0.1 no-emdash # the dispatcher: script-util
258
244
  npx -y -p @cosyte/script-utils@0.1 cosyte-readme # or one gate's own bin
259
245
  ```
260
246
 
261
- | bin | `script-utils` command | the gate |
262
- | ---------------------- | ---------------------- | --------------------------------------------- |
263
- | `cosyte-no-emdash` | `no-emdash` | the em and en dash gate, over files and names |
264
- | `cosyte-attw` | `attw` | the attw publish gate, for the package here |
265
- | `cosyte-phi-scan` | `phi-scan` | the PHI commit-gate |
266
- | `cosyte-internal-refs` | `internal-refs` | the internal-reference gate |
267
- | `cosyte-readme` | `readme` | the README gate |
268
- | `cosyte-claude-card` | `claude-card` | the CLAUDE.md card checker |
269
- | `cosyte-agent-notes` | `agent-notes` | the agent-notes checker |
270
- | `cosyte-catalog` | `catalog` | the catalog check |
247
+ | bin | `script-utils` command | the gate |
248
+ | ---------------------- | ---------------------- | ------------------------------------------------- |
249
+ | `cosyte-no-emdash` | `no-emdash` | the em and en dash gate, over files and names |
250
+ | `cosyte-attw` | `attw` | the attw publish gate, for the package here |
251
+ | `cosyte-phi-scan` | `phi-scan` | the PHI commit-gate |
252
+ | `cosyte-internal-refs` | `internal-refs` | the internal-reference gate |
253
+ | `cosyte-readme` | `readme` | the README gate |
254
+ | `cosyte-claude-card` | `claude-card` | the CLAUDE.md card checker |
255
+ | `cosyte-agent-notes` | `agent-notes` | deprecated (D62): the retired agent-notes checker |
256
+ | `cosyte-catalog` | `catalog` | the catalog check |
271
257
 
272
258
  Each runs over the working directory, takes the arguments its gate takes, exits with the gate's own
273
259
  code, and prints what it does with `--help`. `script-utils` with no command prints the list and exits 2.
@@ -398,26 +384,32 @@ release, because config's check against npm picks the change up once the library
398
384
  2 means the check could not run (no package.json, or an argument it does not accept). `--strict`
399
385
  restores the gate: 1 for a disagreement, 2 for an unlisted package.
400
386
 
401
- ### The agent-notes checker
387
+ ### The agent-notes checker, deprecated
402
388
 
403
- `@cosyte/script-utils/agent-notes` checks a repository's agent notes (RD4): what does not fit on the
404
- CLAUDE.md card lives in one file, `documentation/agent-notes.md`, and the card points into it in one
405
- form, `documentation/agent-notes.md#<anchor>`. A repository runs it with no file of its own:
389
+ `@cosyte/script-utils/agent-notes` and its bin, `cosyte-agent-notes`, are deprecated. They check a
390
+ repository's agent notes, `documentation/agent-notes.md`, and every
391
+ `documentation/agent-notes.md#<anchor>` pointer into them. On 2026-11-08 the notes were removed from
392
+ every Cosyte repository (D62): a CLAUDE.md card stands on its own, and what does not fit on it goes
393
+ where it is used, in a test, a comment at the code it guards, an ADR, the README or docs, or a
394
+ runbook (`documentation/claude-card.md` in cosyte/config). Remove the package script or CI step that
395
+ runs the checker.
406
396
 
407
- ```sh
408
- node node_modules/@cosyte/script-utils/agent-notes.js # this repository
409
- node node_modules/@cosyte/script-utils/agent-notes.js --dir <path> # another repository
410
- ```
397
+ Until a minor release removes them, the entry point and the bin keep a repository that still runs
398
+ the checker green while its notes are removed. With no `documentation/agent-notes.md` (not tracked,
399
+ or deleted from the working tree) the checker exits 0 with one line,
400
+ `agent notes: OK, no agent notes (retired, D62)`, whatever still points at the file. A repository
401
+ that still has the file is checked as before: exit 0 clean, 1 a finding (file, line and rule from
402
+ `AGENT_NOTES_RULES`, then a line saying the notes are retired), and 2 that the check could not run.
403
+
404
+ ```ts runnable
405
+ import { checkAgentNotes, NOTES_PATH } from "@cosyte/script-utils/agent-notes";
406
+
407
+ // The file it checks, which no repository keeps any more.
408
+ NOTES_PATH; // => "documentation/agent-notes.md"
411
409
 
412
- It reads every file `git ls-files` lists, skipping and counting a binary file or anything that is not
413
- a regular file. Every pointer in any of them must name a heading of the notes (its GitHub slug) or an
414
- explicit `<a id>` or `<a name>` target. In CLAUDE.md the pointer must take the one form, not a bare
415
- backticked `#anchor` or `agent-notes.md#` without its directory. A `documentation/agent-notes/`
416
- directory is a finding, and so is a notes file CLAUDE.md never points into, a blank one, an empty
417
- section (a heading followed by a deeper one is a container, not empty), and a citation of the
418
- umbrella's deleted ADR 0023 or its doc-budget hook. A repository with no notes and no pointers
419
- passes. Exit 0 means clean, 1 a finding (file, line and rule from `AGENT_NOTES_RULES`), and 2 that
420
- the check could not run.
410
+ // A card with no notes and nothing pointing at them has no findings.
411
+ checkAgentNotes({ claude: "# demo\n\nOur demo.\n", notes: null, files: [] }); // => []
412
+ ```
421
413
 
422
414
  ## Overrides
423
415
 
package/agent-notes.d.ts CHANGED
@@ -2,12 +2,24 @@
2
2
  * Types for `@cosyte/script-utils/agent-notes`: the checker for a repository's agent notes, one
3
3
  * file at `documentation/agent-notes.md` that CLAUDE.md points into as
4
4
  * `documentation/agent-notes.md#<anchor>` (RD4).
5
+ *
6
+ * Deprecated (D62): the agent notes were removed from every Cosyte repository. A repository with no
7
+ * notes file passes `runAgentNotesCheck` with one line, and one that still has the file is checked
8
+ * as before. This entry point stays until a minor release removes it.
5
9
  */
6
10
 
7
- /** The one place the notes live. */
11
+ /**
12
+ * The one place the notes live.
13
+ *
14
+ * @deprecated Retired with the agent notes (D62).
15
+ */
8
16
  export declare const NOTES_PATH: "documentation/agent-notes.md";
9
17
 
10
- /** A rule id a finding can carry. */
18
+ /**
19
+ * A rule id a finding can carry.
20
+ *
21
+ * @deprecated Retired with the agent notes (D62).
22
+ */
11
23
  export type AgentNotesRule =
12
24
  | "layout"
13
25
  | "pointer-form"
@@ -18,19 +30,39 @@ export type AgentNotesRule =
18
30
  | "empty-section"
19
31
  | "stale-citation";
20
32
 
21
- /** Every rule id, with what it requires. */
33
+ /**
34
+ * Every rule id, with what it requires.
35
+ *
36
+ * @deprecated Retired with the agent notes (D62).
37
+ */
22
38
  export declare const AGENT_NOTES_RULES: Readonly<Record<AgentNotesRule, string>>;
23
39
 
24
- /** Raised when the check cannot run; the CLI turns it into exit 2. */
40
+ /**
41
+ * Raised when the check cannot run; the CLI turns it into exit 2.
42
+ *
43
+ * @deprecated Retired with the agent notes (D62).
44
+ */
25
45
  export declare class AgentNotesRefusal extends Error {}
26
46
 
27
- /** GitHub's heading slug, as github-slugger writes it. */
47
+ /**
48
+ * GitHub's heading slug, as github-slugger writes it.
49
+ *
50
+ * @deprecated Retired with the agent notes (D62).
51
+ */
28
52
  export declare function slugify(text: string): string;
29
53
 
30
- /** A slugger that suffixes repeats as GitHub does: the second `Setup` is `setup-1`. */
54
+ /**
55
+ * A slugger that suffixes repeats as GitHub does: the second `Setup` is `setup-1`.
56
+ *
57
+ * @deprecated Retired with the agent notes (D62).
58
+ */
31
59
  export declare function makeSlugger(): (text: string) => string;
32
60
 
33
- /** One heading of the notes. */
61
+ /**
62
+ * One heading of the notes.
63
+ *
64
+ * @deprecated Retired with the agent notes (D62).
65
+ */
34
66
  export interface NotesHeading {
35
67
  level: number;
36
68
  text: string;
@@ -46,10 +78,15 @@ export interface NotesHeading {
46
78
  * its headings.
47
79
  *
48
80
  * @throws {AgentNotesRefusal} On an HTML comment that never closes.
81
+ * @deprecated Retired with the agent notes (D62).
49
82
  */
50
83
  export declare function readNotes(text: string): { targets: Set<string>; headings: NotesHeading[] };
51
84
 
52
- /** One place the notes or a pointer depart from RD4. */
85
+ /**
86
+ * One place the notes or a pointer depart from RD4.
87
+ *
88
+ * @deprecated Retired with the agent notes (D62).
89
+ */
53
90
  export interface AgentNotesFinding {
54
91
  rule: AgentNotesRule;
55
92
  file: string;
@@ -58,6 +95,11 @@ export interface AgentNotesFinding {
58
95
  message: string;
59
96
  }
60
97
 
98
+ /**
99
+ * What `checkAgentNotes` reads.
100
+ *
101
+ * @deprecated Retired with the agent notes (D62).
102
+ */
61
103
  export interface AgentNotesInput {
62
104
  /** CLAUDE.md's contents, or `null` when the repository has none. */
63
105
  claude: string | null;
@@ -75,9 +117,15 @@ export interface AgentNotesInput {
75
117
  * Check the notes and every pointer into them.
76
118
  *
77
119
  * @throws {AgentNotesRefusal} When the notes cannot be read to the end.
120
+ * @deprecated Retired with the agent notes (D62).
78
121
  */
79
122
  export declare function checkAgentNotes(input: AgentNotesInput): AgentNotesFinding[];
80
123
 
124
+ /**
125
+ * What `runAgentNotesCheck` takes.
126
+ *
127
+ * @deprecated Retired with the agent notes (D62).
128
+ */
81
129
  export interface AgentNotesCheckOptions {
82
130
  /** The repository root. Default: the working directory. */
83
131
  dir?: string;
@@ -87,6 +135,9 @@ export interface AgentNotesCheckOptions {
87
135
 
88
136
  /**
89
137
  * Run the checker over one repository's tracked files and return the exit code: 0 clean, 1 at
90
- * least one finding, 2 the check could not run. It never exits the process.
138
+ * least one finding, 2 the check could not run. A repository with no notes file is clean: it gets
139
+ * one line, `agent notes: OK, no agent notes (retired, D62)`. It never exits the process.
140
+ *
141
+ * @deprecated Retired with the agent notes (D62).
91
142
  */
92
143
  export declare function runAgentNotesCheck(options?: AgentNotesCheckOptions): 0 | 1 | 2;
package/agent-notes.js CHANGED
@@ -1,10 +1,22 @@
1
1
  // @cosyte/script-utils/agent-notes
2
2
  //
3
- // THE AGENT-NOTES CHECKER (RD4). A repository's CLAUDE.md card stays short, and what does not fit in
4
- // it lives in ONE file, `documentation/agent-notes.md`, which the card points into with ONE form:
5
- // `documentation/agent-notes.md#<anchor>`. This checker replaces the eight per-repository checkers
6
- // (mllp, ccda, ncpdp, astm, terminology, transform, deid and cli), keeping every rule they shared and
7
- // resolving the ones they disagreed on; the README section "The agent-notes checker" lists both.
3
+ // DEPRECATED (D62, 2026-11-08). The agent notes were removed from every Cosyte repository, and the
4
+ // card spec (documentation/claude-card.md in cosyte/config) has no pointer form any more: a card
5
+ // stands on its own. This checker stays only so that a repository still running it keeps passing
6
+ // while its notes are removed:
7
+ //
8
+ // - with no notes file (not tracked, or deleted from the working tree) it exits 0 with one line,
9
+ // `agent notes: OK, no agent notes (retired, D62)`, whatever still points at the file;
10
+ // - with one, it checks the notes and every pointer into them as it always has (below).
11
+ //
12
+ // Removing it (this file, its declarations, the `./agent-notes` export and the `cosyte-agent-notes`
13
+ // bin) is a breaking change, so it waits for a minor release, which the operator approves (D56).
14
+ //
15
+ // THE AGENT-NOTES CHECKER (RD4, as it stood before D62). A repository's CLAUDE.md card stays short,
16
+ // and what does not fit in it lives in ONE file, `documentation/agent-notes.md`, which the card
17
+ // points into with ONE form: `documentation/agent-notes.md#<anchor>`. This checker replaced the eight
18
+ // per-repository checkers (mllp, ccda, ncpdp, astm, terminology, transform, deid and cli), keeping
19
+ // every rule they shared and resolving the ones they disagreed on.
8
20
  //
9
21
  // THE RULES, each one id a finding names:
10
22
  //
@@ -40,6 +52,9 @@ import { isCliEntrypoint } from "./index.js";
40
52
  /** The one place the notes live. */
41
53
  export const NOTES_PATH = "documentation/agent-notes.md";
42
54
 
55
+ /** What a repository with no notes file is told, and passes on (D62). */
56
+ const RETIRED = "no agent notes (retired, D62)";
57
+
43
58
  /** The directory layout the one-file rule retires. */
44
59
  const NOTES_DIRECTORY = "documentation/agent-notes/";
45
60
 
@@ -406,8 +421,8 @@ export function checkAgentNotes(input) {
406
421
  return findings;
407
422
  }
408
423
 
409
- /** The tracked files of a repository: regular files read, everything else counted. */
410
- function trackedFiles(dir) {
424
+ /** The tracked paths of a repository, each with whether git records it as a regular file. */
425
+ function listTracked(dir) {
411
426
  let listing;
412
427
  try {
413
428
  listing = execFileSync("git", ["ls-files", "-z", "-s"], {
@@ -419,14 +434,24 @@ function trackedFiles(dir) {
419
434
  } catch (err) {
420
435
  throw new AgentNotesRefusal(`could not list the tracked files of ${dir}: ${err.message}`);
421
436
  }
422
- const files = [];
423
- const skipped = [];
437
+ const entries = [];
424
438
  for (const record of listing.split("\0")) {
425
439
  if (record === "") continue;
426
- const tab = record.indexOf("\t");
427
440
  const mode = record.slice(0, 6);
428
- const path = record.slice(tab + 1);
429
- if (mode !== "100644" && mode !== "100755") {
441
+ entries.push({
442
+ path: record.slice(record.indexOf("\t") + 1),
443
+ regular: mode === "100644" || mode === "100755",
444
+ });
445
+ }
446
+ return entries;
447
+ }
448
+
449
+ /** The tracked files of a repository: regular files read, everything else counted. */
450
+ function readTracked(dir, entries) {
451
+ const files = [];
452
+ const skipped = [];
453
+ for (const { path, regular } of entries) {
454
+ if (!regular) {
430
455
  skipped.push(path);
431
456
  continue;
432
457
  }
@@ -469,10 +494,20 @@ export function runAgentNotesCheck(options = {}) {
469
494
  }
470
495
  dir = resolve(dir);
471
496
  try {
472
- const { files, skipped } = trackedFiles(dir);
497
+ const entries = listTracked(dir);
498
+ // Retired (D62): with no notes file there is nothing to check, so nothing else is read, and a
499
+ // pointer left in the card, a source comment or a changelog is not a finding.
500
+ const hasNotes =
501
+ entries.some((entry) => entry.path === NOTES_PATH && entry.regular) &&
502
+ existsSync(join(dir, NOTES_PATH));
503
+ const { files, skipped } = hasNotes ? readTracked(dir, entries) : { files: [], skipped: [] };
473
504
  const byPath = new Map(files.map((file) => [file.path, file.text]));
474
505
  const claude = byPath.get("CLAUDE.md") ?? null;
475
506
  const notes = byPath.get(NOTES_PATH) ?? null;
507
+ if (notes === null) {
508
+ process.stdout.write(`agent notes: OK, ${RETIRED}\n`);
509
+ return 0;
510
+ }
476
511
  const others = files.filter((f) => f.path !== "CLAUDE.md" && f.path !== NOTES_PATH);
477
512
  const decisions = join(dir, "documentation", "decisions");
478
513
  const findings = checkAgentNotes({
@@ -495,7 +530,9 @@ export function runAgentNotesCheck(options = {}) {
495
530
  findings
496
531
  .map((f) => ` ${f.file}${f.line > 0 ? `:${f.line}` : ""} [${f.rule}] ${f.message}`)
497
532
  .join("\n") +
498
- "\n",
533
+ `\nagent notes: the notes are retired (D62). Rather than fix these, delete ${NOTES_PATH}, ` +
534
+ `which passes this check, and move what still binds to where it is used ` +
535
+ `(documentation/claude-card.md in cosyte/config).\n`,
499
536
  );
500
537
  return 1;
501
538
  } catch (err) {
@@ -1,5 +1,7 @@
1
1
  #!/usr/bin/env node
2
2
  // cosyte-agent-notes: the agent-notes checker for the repository in the working directory.
3
+ // Deprecated (D62): the agent notes were removed from every repository, so it passes a repository
4
+ // with no notes file, and stays only until a minor release removes it.
3
5
  // A bin of @cosyte/script-utils (D56), so a repository with no package.json can run it with
4
6
  // `npx -y -p @cosyte/script-utils cosyte-agent-notes`. It forwards every argument to the gate and exits with
5
7
  // the gate's own code; `--help` prints what it does and exits 0, or 2 under CI.
@@ -7,13 +9,20 @@
7
9
  import { runAgentNotesCheck } from "../agent-notes.js";
8
10
  import { answerHelp } from "./help.js";
9
11
 
10
- const HELP = `cosyte-agent-notes: check a repository's agent notes and every pointer into them.
12
+ const HELP = `cosyte-agent-notes: deprecated (D62). Remove the step that runs it.
11
13
 
12
14
  cosyte-agent-notes [--dir <repository root>]
13
15
 
14
- The notes are one file, documentation/agent-notes.md, and CLAUDE.md points into it as
15
- documentation/agent-notes.md#<anchor>. Every pointer in a tracked file must name a heading or an
16
- explicit anchor. Exit 0 clean, 1 a finding, 2 the check could not run.
16
+ The agent notes, documentation/agent-notes.md, were removed from every Cosyte repository on
17
+ 2026-11-08 (D62). A CLAUDE.md card stands on its own, and what does not fit on it goes where it is
18
+ used: a test, a comment at the code it guards, an ADR, the README or docs, or a runbook
19
+ (documentation/claude-card.md in cosyte/config).
20
+
21
+ Until a minor release removes this bin, a repository with no documentation/agent-notes.md passes
22
+ with one line, "no agent notes (retired, D62)", whatever still points at the file. One that still
23
+ has the file is checked as before: every documentation/agent-notes.md#<anchor> pointer in a tracked
24
+ file must name a heading or an explicit anchor. Exit 0 clean, 1 a finding, 2 the check could not
25
+ run.
17
26
  `;
18
27
 
19
28
  const args = process.argv.slice(2);
@@ -19,7 +19,7 @@ const COMMANDS = {
19
19
  ],
20
20
  readme: ["cosyte-readme", "the README gate, for the library here"],
21
21
  "claude-card": ["cosyte-claude-card", "the CLAUDE.md card checker"],
22
- "agent-notes": ["cosyte-agent-notes", "the agent-notes checker"],
22
+ "agent-notes": ["cosyte-agent-notes", "the agent-notes checker, deprecated by D62"],
23
23
  catalog: ["cosyte-catalog", "the catalog check, for the library here"],
24
24
  };
25
25
 
package/catalog.json CHANGED
@@ -181,7 +181,7 @@
181
181
  {
182
182
  "name": "@cosyte/cli",
183
183
  "slug": "cli",
184
- "description": "The Cosyte command line for Node.js and TypeScript: one command over HL7 v2, FHIR R4, X12, ASTM, NCPDP, C-CDA, DICOM, and MLLP, with HL7 v2 to FHIR conversion from transform, code mapping from terminology, and the cosyte-mcp MCP server for agents. Value-free diagnostics and a documented exit-code contract.",
184
+ "description": "The Cosyte command line for Node.js and TypeScript: one command over HL7 v2, FHIR R4, X12, ASTM, NCPDP, C-CDA, DICOM, and MLLP, with HL7 v2 to FHIR conversion from transform, code mapping from terminology, and the cosyte-mcp MCP server for agents.",
185
185
  "line": "0.1",
186
186
  "engines": {
187
187
  "node": ">=22.0.0"
package/claude-card.js CHANGED
@@ -49,6 +49,14 @@ export const CARD_SECTIONS = Object.freeze(["Gate", "Hazard", "Rules"]);
49
49
  /** The line that imports AGENTS.md into the card. */
50
50
  export const AGENTS_IMPORT = "@AGENTS.md";
51
51
 
52
+ /**
53
+ * Where what does not fit on the card goes, from the spec's "Where the detail goes". The card stands
54
+ * on its own: there is no notes file beside it to send detail to (D62).
55
+ */
56
+ const DETAIL_GOES =
57
+ "where it is used: a test, a comment at the code it guards, an ADR, the README or docs, or a " +
58
+ "runbook";
59
+
52
60
  /** Every rule id a finding can carry, with what it requires. */
53
61
  export const CARD_RULES = Object.freeze({
54
62
  title: "The card opens with `# <name>`, after a YAML front matter block if it has one.",
@@ -140,7 +148,8 @@ export function checkClaudeCard(text, context = {}) {
140
148
  "bytes",
141
149
  0,
142
150
  `the card is ${bytes.toLocaleString("en-US")} bytes; the limit is ` +
143
- `${CARD_MAX_BYTES.toLocaleString("en-US")}. Move detail to documentation/agent-notes.md.`,
151
+ `${CARD_MAX_BYTES.toLocaleString("en-US")}. Move detail to ${DETAIL_GOES}; git and the ` +
152
+ `PRs keep the history.`,
144
153
  );
145
154
  }
146
155
  lines.forEach((line, index) => {
@@ -185,7 +194,7 @@ export function checkClaudeCard(text, context = {}) {
185
194
  "section-extra",
186
195
  heading.line + 1,
187
196
  `"## ${heading.text}" is not one of the card's sections (${CARD_SECTIONS.join(", ")}); ` +
188
- `make it a ### inside one of them, or move it to the agent notes.`,
197
+ `make it a ### inside one of them, or move it to ${DETAIL_GOES}.`,
189
198
  );
190
199
  } else if (!found.has(word)) {
191
200
  found.set(word, heading);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cosyte/script-utils",
3
- "version": "0.1.6",
3
+ "version": "0.1.8",
4
4
  "description": "Zero-dependency helpers for the repo-local gate scripts in @cosyte/* repos.",
5
5
  "keywords": [
6
6
  "cli",