@cosyte/cli 0.0.3 → 0.0.4
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 +213 -71
- package/dist/bin/cosyte-mcp.cjs +1 -1
- package/dist/bin/cosyte-mcp.cjs.map +1 -1
- package/dist/bin/cosyte-mcp.mjs +1 -1
- package/dist/bin/cosyte-mcp.mjs.map +1 -1
- package/dist/bin/cosyte.cjs +1 -1
- package/dist/bin/cosyte.cjs.map +1 -1
- package/dist/bin/cosyte.mjs +1 -1
- package/dist/bin/cosyte.mjs.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.mjs +1 -1
- package/dist/index.mjs.map +1 -1
- package/dist/mcp.cjs +1 -1
- package/dist/mcp.cjs.map +1 -1
- package/dist/mcp.mjs +1 -1
- package/dist/mcp.mjs.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -7,10 +7,167 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
Versions and publishing are managed with [Changesets](https://github.com/changesets/changesets);
|
|
8
8
|
this file is maintained by hand (Changesets handles the version bump and publish only).
|
|
9
9
|
|
|
10
|
+
The released sections below were reconstructed on 2026-08-04. Until then every entry sat under
|
|
11
|
+
`Unreleased`, including entries describing releases that had already shipped, so each published
|
|
12
|
+
tarball carried a changelog calling its own contents unreleased. Those tarballs are immutable and
|
|
13
|
+
still do. Each entry was assigned to the release whose tag first contains it, read off `v0.0.1`,
|
|
14
|
+
`v0.0.2` and `v0.0.3`; no entry text was rewritten to fit a section.
|
|
15
|
+
|
|
10
16
|
## [Unreleased]
|
|
11
17
|
|
|
12
18
|
### Fixed
|
|
13
19
|
|
|
20
|
+
- **The shipped documentation sidebar was off the canonical IA spine, and it was holding up the
|
|
21
|
+
docs site's deploy (CLI-SIDEBAR-IA-NONCANONICAL).** `docs-content/sidebars.json` declared two
|
|
22
|
+
top-level categories that are not on the spine, **"MCP server"** and **"Reference"**. The docs
|
|
23
|
+
site lints the sidebar it receives from each package's released `docs-content.tar.gz`, and in
|
|
24
|
+
strict mode a non-canonical top-level label grades as an error, so this package failed that gate
|
|
25
|
+
and the site stopped deploying. Pre-existing since the pages were authored; it surfaced only once
|
|
26
|
+
an unrelated build failure stopped masking it.
|
|
27
|
+
- Both categories are removed and their pages folded into categories this package already had, so
|
|
28
|
+
**no page left the navigation and none was orphaned** (verified: the nine documents in
|
|
29
|
+
`docs-content/` and the nine referenced by the sidebar are the same nine). **`mcp`** and
|
|
30
|
+
**`reference-commands`** join **Guides**, next to `guides-overview`, both being task-oriented:
|
|
31
|
+
what to run and what comes back. **`limitations`** joins **Troubleshooting**, next to
|
|
32
|
+
`troubleshooting`, which is where the documentation standard puts known limitations.
|
|
33
|
+
- The categories this package ships are now `Installation`, `Quickstart`, `Core Concepts`,
|
|
34
|
+
`Guides` and `Troubleshooting`, in that order, under the `intro` document.
|
|
35
|
+
- **"Reference" was deliberately NOT renamed to "API Reference".** That category is injected by
|
|
36
|
+
the docs site, and a hand-authored one is refused outright rather than warned about, so the
|
|
37
|
+
rename would have traded a failing check for a differently failing one. Whether and where the
|
|
38
|
+
site adds it is the site's decision, not this package's, and this package neither authors nor
|
|
39
|
+
positions it.
|
|
40
|
+
- Verified against the site's own linter rather than by inspection, with the sidebar shipped in
|
|
41
|
+
the previous release as a **negative control**: that one produces two errors and this one
|
|
42
|
+
produces no findings. **Only a new release can clear the gate**, because it reads the sidebar
|
|
43
|
+
out of the released artifact and published releases are immutable, so the previous release
|
|
44
|
+
keeps its non-canonical sidebar permanently. That is reported without gating once a release is
|
|
45
|
+
no longer current.
|
|
46
|
+
- Documentation-artifact change only: no command, flag, exit code, diagnostic code or export
|
|
47
|
+
moves, and no page content was rewritten.
|
|
48
|
+
|
|
49
|
+
- **The pre-commit PHI gate never saw a `git mv` into a scan root
|
|
50
|
+
(PHI-SCAN-RENAME-BLIND-AT-PRECOMMIT).** `scripts/phi-scan.ts --staged` listed the index with
|
|
51
|
+
`git diff --cached --name-only --diff-filter=AM`. Rename detection is on by default, so
|
|
52
|
+
`git mv <path> test/__fixtures__/<name>` stages as a **two-path `R100` record**, and `R` and `C`
|
|
53
|
+
are in neither `AM` nor `AMT`: the status filter deleted the record outright and the destination
|
|
54
|
+
was never enumerated. Measured on this repo, both shapes walking through the
|
|
55
|
+
`pnpm phi-scan --staged` pre-commit hook at **exit 0**: a regular file carrying a value this
|
|
56
|
+
scanner's own floor catches (`:100644 100644 <sha> <sha> R100`), and a symbolic link
|
|
57
|
+
(`:120000 120000 <sha> <sha> R100`, index mode `120000` under the scan root). `git mv` is an
|
|
58
|
+
ordinary developer action, not crafted input, and the pre-commit hook is the gate it walked
|
|
59
|
+
through.
|
|
60
|
+
- **`--no-renames` is the remedy, and it costs the record stride nothing.** The destination
|
|
61
|
+
arrives as a single-path `A` and the source as a `D` the filter drops, so the enumeration is a
|
|
62
|
+
strict **superset** of the previous one. Verified under `diff.renames` set to `true`, `copies`,
|
|
63
|
+
`false` and `1`, and under `diff.renameLimit=1`: no `R` or `C` record survives in any of them,
|
|
64
|
+
which makes the two-field record stride structural rather than conditional. `copies` is not
|
|
65
|
+
hypothetical; it produces a live `C100` here.
|
|
66
|
+
- **The destination mode was never read at all.** The route enumerated with `--name-only` and read
|
|
67
|
+
content with `git show :<path>`, and git stores a symbolic link as its **target path** under
|
|
68
|
+
mode `120000`, so the scan was handed the path text and never the target's bytes. It now lists
|
|
69
|
+
with `--raw -z` and **refuses** (exit `2`) any in-scope entry whose destination mode is not a
|
|
70
|
+
regular blob. A refusal names the entry's own repo-relative path and an engine-owned token for
|
|
71
|
+
its kind, and **never the link target**, which is working-tree text that can itself carry PHI.
|
|
72
|
+
Every offender is named, not just the first. That guarantee is about a **refusal** and does not
|
|
73
|
+
extend to a hit; see the linked-scan-root residual below.
|
|
74
|
+
- **`T` (typechange) is now in the filter**, because replacing a _tracked_ regular fixture with a
|
|
75
|
+
link is neither an add nor a modify (`:100644 120000 <sha> <sha> T`), so `--diff-filter=AM`
|
|
76
|
+
deleted the record before any mode could be read. The reverse direction, a link replaced by a
|
|
77
|
+
real file, is now scanned as the file it became.
|
|
78
|
+
- **Each scan root's own path is in scope**, not just its contents. Git records no index entry for
|
|
79
|
+
a directory, so an entry at exactly `test/__fixtures__` or `src` is that root replaced by a blob
|
|
80
|
+
or a link, and a prefix test requiring the trailing slash let it through while the whole corpus
|
|
81
|
+
went unscanned.
|
|
82
|
+
- **The all-mode walk gets the same refusal.** A scanner whose pre-commit half refuses a link
|
|
83
|
+
while its CI half silently drops one is not one a developer can reason about. The walk
|
|
84
|
+
enumerates `Dirent.isFile()`, an lstat answer, so a link (and a linked _directory_, which
|
|
85
|
+
`isDirectory()` also answers false for) fell out of the loop silently. The `.md` exemption
|
|
86
|
+
deliberately does not reach a link: it is a judgement about a file whose bytes the walk could
|
|
87
|
+
have read, and a link's name is no evidence about what is on the other side of it. A gitignored
|
|
88
|
+
entry stays out of scope, by the same rule that already excludes a gitignored fixture.
|
|
89
|
+
- **Two pre-existing exit-code defects fixed with it.** A missing or unreadable allow-list, and an
|
|
90
|
+
unreadable scan root, both threw past every handler and exited **1** with a raw stack trace. `1`
|
|
91
|
+
is this contract's code for _hits found_, so a caller branching on the exit code read a broken
|
|
92
|
+
invocation as a PHI finding and a caller branching on "not 0" read it as the gate working.
|
|
93
|
+
Neither was true. Both are now exit `2` with a diagnostic.
|
|
94
|
+
- **Stated rather than left to be inferred, both pre-existing and neither closed here.** The
|
|
95
|
+
staged route still does not enumerate `D` (a deletion has no staged blob to scan) or `U` (an
|
|
96
|
+
unmerged path has no single one). The `U` half costs nothing that can reach a commit, and that
|
|
97
|
+
was measured rather than assumed: `git commit` refuses an unmerged index outright. Under `src/`
|
|
98
|
+
the staged route still covers only `.ts` files while the all-mode walk covers every non-`.md`
|
|
99
|
+
file, so the CI sweep is what covers the difference; widening the staged half is a scope
|
|
100
|
+
decision and was not taken here.
|
|
101
|
+
- **The refusal rule is scoped to an _enumerated_ entry, and the unqualified version of it is
|
|
102
|
+
false.** It covers an entry the walk reached beneath a root it had already opened, and a staged
|
|
103
|
+
record in scope per the boundary rule, which under `src/` is `.ts` files only, so a staged link
|
|
104
|
+
at `src/notes.json` is under a scan root and `--staged` still exits 0 over it while the all-mode
|
|
105
|
+
sweep refuses it. Three shapes escape the rule, all pre-existing, all measured, none
|
|
106
|
+
closed here: **(1)** a scan root that is itself a **live** link is followed by the all-mode walk,
|
|
107
|
+
because `existsSync` and `readdirSync` both resolve, so the walk reads files no commit contains
|
|
108
|
+
and reports their values under a **fabricated in-repo path** that holds no such file (the
|
|
109
|
+
**dangling** direction is the mirror image: it reports clean over a corpus it never opened);
|
|
110
|
+
**(2)** an **ancestor** of a scan root is in neither route's scope, so staging `test` as a link
|
|
111
|
+
leaves `--staged` at exit 0 and the walk then follows it; **(3)** paths mode follows an
|
|
112
|
+
explicitly named link, because `statSync` resolves. The `--staged` half of shape (1) **is**
|
|
113
|
+
closed here. Closing the rest needs a refuse-a-scan-that-observed-nothing rule plus a decision
|
|
114
|
+
about how far above a scan root to look, which is its own change.
|
|
115
|
+
- `test/scripts/phi-scan.test.ts` builds throwaway git repositories for all of it, because these
|
|
116
|
+
are properties of what `git diff --cached` reports and cannot be reproduced by scanning a path.
|
|
117
|
+
**16 of its 34 tests run red against the scanner on `a7a92f8`**; the 18 that stay green are the
|
|
118
|
+
pre-existing floor tests, the deliberate controls (an ordinary staged hit, a clean pass, a
|
|
119
|
+
staged link outside both roots, an ignored link, and a check that the payload under test is
|
|
120
|
+
something this scanner would otherwise catch), and the four that **pin the disclosed residuals
|
|
121
|
+
above**. Those four are green on both trees by design: they pin behaviour this change does not
|
|
122
|
+
alter, so that the scoped wording of the refusal rule cannot quietly revert to the absolute one.
|
|
123
|
+
Synthetic values only.
|
|
124
|
+
- **No change to the CLI's runtime surface**: no command, flag, exit code, diagnostic code or
|
|
125
|
+
export moves. This is repository tooling.
|
|
126
|
+
|
|
127
|
+
## [0.0.3] - 2026-08-03
|
|
128
|
+
|
|
129
|
+
### Changed
|
|
130
|
+
|
|
131
|
+
- **FHIR support is unavailable in an npm-installed copy, and now says so instead of crashing.**
|
|
132
|
+
`@cosyte/fhir` is not on the npm registry, so it cannot be declared as a dependency at all;
|
|
133
|
+
measured, declaring it alongside `@cosyte/transform` (which requires it) fails the whole install
|
|
134
|
+
with `ERESOLVE`. `@cosyte/transform` is therefore skipped by npm as an unresolvable optional
|
|
135
|
+
dependency. Both were previously loaded with a bare `await import()`, which in an installed copy
|
|
136
|
+
would have surfaced a raw resolver error and a stack frame, so FHIR `parse`/`inspect`/`fmt`/`validate`
|
|
137
|
+
and `convert` now degrade to a value-free `CLI_PARSER_UNAVAILABLE` (exit `69`) with a diagnostic that
|
|
138
|
+
says the package is not on the registry rather than "install it". **Neither diagnostic says "install
|
|
139
|
+
it", and that is deliberate**: `npm install @cosyte/transform` fails `E404` on its own
|
|
140
|
+
`@cosyte/fhir` peer, so `loadOptional()`'s stock wording ("install it to use this format, it is an
|
|
141
|
+
optional dependency") would point a user at a command that cannot succeed. New
|
|
142
|
+
`loadOptionalPackage(detail, load)` under `loadOptional`, exported on the `.` subpath.
|
|
143
|
+
`@cosyte/fhir` is retained as a `devDependency` on the vendored tarball so this repo's own FHIR and
|
|
144
|
+
`convert` tests still run; note that `devDependencies` **are** published, so that one
|
|
145
|
+
`file:vendor/*.tgz` specifier does remain in the manifest, harmlessly, because a consumer never
|
|
146
|
+
installs a dependency's `devDependencies` (verified: the install exits `0`). HL7 v2, `map-codes` and
|
|
147
|
+
the six breadth formats are unaffected and work from a plain install.
|
|
148
|
+
|
|
149
|
+
- **Documented a pre-existing defect that this release makes reachable for the first time:
|
|
150
|
+
`--omit=optional` produces an install in which the `cosyte` command does not run at all.** The
|
|
151
|
+
install exits `0`, then every invocation, `--version` included, fails with `ERR_MODULE_NOT_FOUND` on
|
|
152
|
+
`@modelcontextprotocol/sdk` and a raw stack trace, because the built `dist/bin/cosyte.mjs` imports
|
|
153
|
+
the SDK statically at the top level rather than only on the `mcp` path. Verified identical on the
|
|
154
|
+
base commit, so it is not introduced here; it simply could not be hit before, because the package
|
|
155
|
+
could not be installed at all. `docs-content/` now says not to use that flag instead of implying it
|
|
156
|
+
is a supported way to slim the install. **The code defect is not fixed here** and needs its own
|
|
157
|
+
change: it also falsifies the "a plain `cosyte parse` never pulls it" claim in `src/bin/cosyte.ts`.
|
|
158
|
+
|
|
159
|
+
- **The docs no longer tell you to run `npx @cosyte/cli …`, which never worked.** Separate from the
|
|
160
|
+
packaging defect and not fixed by it: `npx` runs the executable whose name matches the package
|
|
161
|
+
name's last segment, which would be `cli`, and this package ships `cosyte` and `cosyte-mcp`, so the
|
|
162
|
+
short form fails with `could not determine executable to run`. Reproduced on the published `0.0.2`
|
|
163
|
+
and on the fixed tarball, whose `bin` block is byte-identical. `README.md`, `docs-content/installation.md`
|
|
164
|
+
and both MCP registration snippets now use `npx --package @cosyte/cli cosyte …` /
|
|
165
|
+
`npx -y --package @cosyte/cli cosyte-mcp`, each measured working. A `cli` bin alias would fix the
|
|
166
|
+
short form and is deliberately not added, because `npm install -g` would then claim a command named
|
|
167
|
+
`cli` on the user's `PATH`.
|
|
168
|
+
|
|
169
|
+
### Fixed
|
|
170
|
+
|
|
14
171
|
- **`@cosyte/cli` can be installed from npm again (CLI-UNINSTALLABLE-MANIFEST).** `0.0.1` and `0.0.2`
|
|
15
172
|
both published with all ten `@cosyte/*` sibling packages declared as `file:vendor/*.tgz` local
|
|
16
173
|
paths. `vendor/` is not in `files` and there is no `bundledDependencies`, so the tarball shipped
|
|
@@ -81,29 +238,6 @@ node_modules/@cosyte/cli/vendor/cosyte-fhir-0.0.0.tgz`. The siblings are now rea
|
|
|
81
238
|
with attw's own status, and that the profile flag survives the wrapper in both directions.
|
|
82
239
|
- `scripts/verify.sh` in the meta-repo is unchanged; its propagation was never at fault.
|
|
83
240
|
|
|
84
|
-
- **The public surface now states that `0.0.1` is published and uninstallable (ASSETS-P8).** `0.0.1`
|
|
85
|
-
published on 2026-07-29 with all ten `file:vendor/*.tgz` dependency specifiers intact. `vendor/` is
|
|
86
|
-
not in `files` and there is no `bundledDependencies`, so every install route (`npm i`, `npm i -g`,
|
|
87
|
-
`npx`) fails with `ENOENT` on `node_modules/@cosyte/cli/vendor/cosyte-fhir-0.0.0.tgz`. Reproduced
|
|
88
|
-
in a clean directory. A published version is immutable (ADR 0001), so `0.0.1` stays broken and the
|
|
89
|
-
fix must ship as a later version.
|
|
90
|
-
- `README.md` gains a **"Known issue"** section stating what fails, the exact error, why, and that
|
|
91
|
-
a source checkout is the only workaround. `docs-content/installation.md` gains the same under
|
|
92
|
-
**"Installing fails today"**. Both copies of the broken `npx`-based MCP registration snippet are
|
|
93
|
-
annotated (`README.md` and `docs-content/mcp.md`).
|
|
94
|
-
- **Four false claims corrected.** (1) `README.md` said "not yet published to npm"; it is
|
|
95
|
-
published. (2) It described swapping the vendored sibling deps for real `@cosyte/*` npm ranges as
|
|
96
|
-
a step still to come "at that flip"; the flip already happened without the swap, which is the
|
|
97
|
-
defect. (3) The same "not yet published" claim appeared in **three** `docs-content/` pages. (4)
|
|
98
|
-
The `redact`/`deid` terminal diagnostic, the `--help` text, three JSDoc blocks that compile into
|
|
99
|
-
`dist/*.d.ts`, and **five** docs pages said `@cosyte/deid` was unpublished, unshipped, or unbuilt;
|
|
100
|
-
it is published at `0.0.2`, and the accurate statement is that the CLI does not wire it yet. Every
|
|
101
|
-
count here was re-derived by census of the base tree, not estimated.
|
|
102
|
-
- **The "all eight formats" claim was checked and is correct**: `CosyteFormat` and `OP_SUPPORT` both
|
|
103
|
-
enumerate exactly eight.
|
|
104
|
-
- `RELEASING.md` records that the documented dependency-swap step was skipped, that a green
|
|
105
|
-
`npm publish --dry-run` cannot catch this (it packs a tarball but never resolves its deps from a
|
|
106
|
-
registry), and adds a checklist step to install the published version from outside the repo.
|
|
107
241
|
- **The route to an installable release, recorded in `RELEASING.md` and verified against the
|
|
108
242
|
registry.** `@cosyte/hl7` (`0.0.3`), `@cosyte/terminology` (`0.0.4`) and all six breadth parsers
|
|
109
243
|
would swap to real ranges today. `@cosyte/fhir` is unpublished (`FHIR-NPM-NAME`, an npm E403
|
|
@@ -114,53 +248,15 @@ node_modules/@cosyte/cli/vendor/cosyte-fhir-0.0.0.tgz`. The siblings are now rea
|
|
|
114
248
|
routed through a guarded loader to degrade to `CLI_PARSER_UNAVAILABLE` (exit `69`) rather than
|
|
115
249
|
crash. `loadOptional()` cannot be reused unchanged: it takes a `CosyteFormat`, and `"transform"` is
|
|
116
250
|
not one, and its diagnostic hardcodes the word "parser". Not undertaken here.
|
|
117
|
-
- **Superseded
|
|
118
|
-
|
|
251
|
+
- **Superseded by the two `0.0.3` entries above**: the swap and the loader change were both
|
|
252
|
+
carried out. Two claims that entry made did not survive
|
|
119
253
|
contact: the "name similarity" reading of the `@cosyte/fhir` `E403` was **retracted across the
|
|
120
254
|
ecosystem on 2026-08-03** (the cause is unexplained; do not assert one), and "npm tolerates an
|
|
121
255
|
`optionalDependency` that fails to resolve" is true only in isolation. Declaring **both**
|
|
122
256
|
`@cosyte/fhir` and `@cosyte/transform` optional fails the install outright with `ERESOLVE`, which
|
|
123
257
|
is why `@cosyte/fhir` ended up not declared at all rather than declared optional.
|
|
124
258
|
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
- **FHIR support is unavailable in an npm-installed copy, and now says so instead of crashing.**
|
|
128
|
-
`@cosyte/fhir` is not on the npm registry, so it cannot be declared as a dependency at all;
|
|
129
|
-
measured, declaring it alongside `@cosyte/transform` (which requires it) fails the whole install
|
|
130
|
-
with `ERESOLVE`. `@cosyte/transform` is therefore skipped by npm as an unresolvable optional
|
|
131
|
-
dependency. Both were previously loaded with a bare `await import()`, which in an installed copy
|
|
132
|
-
would have surfaced a raw resolver error and a stack frame, so FHIR `parse`/`inspect`/`fmt`/`validate`
|
|
133
|
-
and `convert` now degrade to a value-free `CLI_PARSER_UNAVAILABLE` (exit `69`) with a diagnostic that
|
|
134
|
-
says the package is not on the registry rather than "install it". **Neither diagnostic says "install
|
|
135
|
-
it", and that is deliberate**: `npm install @cosyte/transform` fails `E404` on its own
|
|
136
|
-
`@cosyte/fhir` peer, so `loadOptional()`'s stock wording ("install it to use this format, it is an
|
|
137
|
-
optional dependency") would point a user at a command that cannot succeed. New
|
|
138
|
-
`loadOptionalPackage(detail, load)` under `loadOptional`, exported on the `.` subpath.
|
|
139
|
-
`@cosyte/fhir` is retained as a `devDependency` on the vendored tarball so this repo's own FHIR and
|
|
140
|
-
`convert` tests still run; note that `devDependencies` **are** published, so that one
|
|
141
|
-
`file:vendor/*.tgz` specifier does remain in the manifest, harmlessly, because a consumer never
|
|
142
|
-
installs a dependency's `devDependencies` (verified: the install exits `0`). HL7 v2, `map-codes` and
|
|
143
|
-
the six breadth formats are unaffected and work from a plain install.
|
|
144
|
-
|
|
145
|
-
- **Documented a pre-existing defect that this release makes reachable for the first time:
|
|
146
|
-
`--omit=optional` produces an install in which the `cosyte` command does not run at all.** The
|
|
147
|
-
install exits `0`, then every invocation, `--version` included, fails with `ERR_MODULE_NOT_FOUND` on
|
|
148
|
-
`@modelcontextprotocol/sdk` and a raw stack trace, because the built `dist/bin/cosyte.mjs` imports
|
|
149
|
-
the SDK statically at the top level rather than only on the `mcp` path. Verified identical on the
|
|
150
|
-
base commit, so it is not introduced here; it simply could not be hit before, because the package
|
|
151
|
-
could not be installed at all. `docs-content/` now says not to use that flag instead of implying it
|
|
152
|
-
is a supported way to slim the install. **The code defect is not fixed here** and needs its own
|
|
153
|
-
change: it also falsifies the "a plain `cosyte parse` never pulls it" claim in `src/bin/cosyte.ts`.
|
|
154
|
-
|
|
155
|
-
- **The docs no longer tell you to run `npx @cosyte/cli …`, which never worked.** Separate from the
|
|
156
|
-
packaging defect and not fixed by it: `npx` runs the executable whose name matches the package
|
|
157
|
-
name's last segment, which would be `cli`, and this package ships `cosyte` and `cosyte-mcp`, so the
|
|
158
|
-
short form fails with `could not determine executable to run`. Reproduced on the published `0.0.2`
|
|
159
|
-
and on the fixed tarball, whose `bin` block is byte-identical. `README.md`, `docs-content/installation.md`
|
|
160
|
-
and both MCP registration snippets now use `npx --package @cosyte/cli cosyte …` /
|
|
161
|
-
`npx -y --package @cosyte/cli cosyte-mcp`, each measured working. A `cli` bin alias would fix the
|
|
162
|
-
short form and is deliberately not added, because `npm install -g` would then claim a command named
|
|
163
|
-
`cli` on the user's `PATH`.
|
|
259
|
+
## [0.0.2] - 2026-07-31
|
|
164
260
|
|
|
165
261
|
### Added
|
|
166
262
|
|
|
@@ -201,6 +297,36 @@ node_modules/@cosyte/cli/vendor/cosyte-fhir-0.0.0.tgz`. The siblings are now rea
|
|
|
201
297
|
would be a wasted line. The wording is the one eight sibling packages already carry, confirmed
|
|
202
298
|
against both rendered PNGs here rather than copied on trust.
|
|
203
299
|
|
|
300
|
+
### Fixed
|
|
301
|
+
|
|
302
|
+
- **The public surface now states that `0.0.1` is published and uninstallable (ASSETS-P8).** `0.0.1`
|
|
303
|
+
published on 2026-07-29 with all ten `file:vendor/*.tgz` dependency specifiers intact. `vendor/` is
|
|
304
|
+
not in `files` and there is no `bundledDependencies`, so every install route (`npm i`, `npm i -g`,
|
|
305
|
+
`npx`) fails with `ENOENT` on `node_modules/@cosyte/cli/vendor/cosyte-fhir-0.0.0.tgz`. Reproduced
|
|
306
|
+
in a clean directory. A published version is immutable (ADR 0001), so `0.0.1` stays broken and the
|
|
307
|
+
fix must ship as a later version.
|
|
308
|
+
- `README.md` gains a **"Known issue"** section stating what fails, the exact error, why, and that
|
|
309
|
+
a source checkout is the only workaround. `docs-content/installation.md` gains the same under
|
|
310
|
+
**"Installing fails today"**. Both copies of the broken `npx`-based MCP registration snippet are
|
|
311
|
+
annotated (`README.md` and `docs-content/mcp.md`).
|
|
312
|
+
- **Four false claims corrected.** (1) `README.md` said "not yet published to npm"; it is
|
|
313
|
+
published. (2) It described swapping the vendored sibling deps for real `@cosyte/*` npm ranges as
|
|
314
|
+
a step still to come "at that flip"; the flip already happened without the swap, which is the
|
|
315
|
+
defect. (3) The same "not yet published" claim appeared in **three** `docs-content/` pages. (4)
|
|
316
|
+
The `redact`/`deid` terminal diagnostic, the `--help` text, three JSDoc blocks that compile into
|
|
317
|
+
`dist/*.d.ts`, and **five** docs pages said `@cosyte/deid` was unpublished, unshipped, or unbuilt;
|
|
318
|
+
it is published at `0.0.2`, and the accurate statement is that the CLI does not wire it yet. Every
|
|
319
|
+
count here was re-derived by census of the base tree, not estimated.
|
|
320
|
+
- **The "all eight formats" claim was checked and is correct**: `CosyteFormat` and `OP_SUPPORT` both
|
|
321
|
+
enumerate exactly eight.
|
|
322
|
+
- `RELEASING.md` records that the documented dependency-swap step was skipped, that a green
|
|
323
|
+
`npm publish --dry-run` cannot catch this (it packs a tarball but never resolves its deps from a
|
|
324
|
+
registry), and adds a checklist step to install the published version from outside the repo.
|
|
325
|
+
|
|
326
|
+
## [0.0.1] - 2026-07-29
|
|
327
|
+
|
|
328
|
+
### Added
|
|
329
|
+
|
|
204
330
|
- **Phase 7: release hardening (the final roadmap phase; the CLI is feature-complete).** No new
|
|
205
331
|
runtime command surface: this phase is publish-readiness.
|
|
206
332
|
- **Fuzz gate over the two input boundaries.** `test/fuzz.property.test.ts` fuzzes the terminal
|
|
@@ -221,6 +347,7 @@ node_modules/@cosyte/cli/vendor/cosyte-fhir-0.0.0.tgz`. The siblings are now rea
|
|
|
221
347
|
honest per-(format, operation) support matrix, the PHI-default posture), a man-page-style
|
|
222
348
|
`docs-content/reference-commands.md`, and `RELEASING.md` (the one-package-two-bins publish,
|
|
223
349
|
provenance/OIDC, the vendored-`file:`→npm dep swap, and the two standing founder stops).
|
|
350
|
+
|
|
224
351
|
- **Phase 6: six more formats + streaming + shell completion (ADR 0025).** The `cosyte` CLI now wraps
|
|
225
352
|
**all eight cosyte formats**, routed through a single lazy **per-format adapter registry**
|
|
226
353
|
(`src/core/parsers.ts`) that replaces the old per-command `hl7 ? : fhir` branches and makes support
|
|
@@ -279,6 +406,7 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
279
406
|
(`createMcpServer`, `startStdioServer`, `dispatchTool`, `TOOL_DEFS`, and the MCP result types) on the
|
|
280
407
|
`./mcp` subpath. `redact`/`deid` (gated on `@cosyte/deid`) and `map-codes` are deliberately not
|
|
281
408
|
exposed as tools yet.
|
|
409
|
+
|
|
282
410
|
- **Phase 4: `convert` / `map-codes` (the consumer-of-consumers commands).** Two commands that wrap
|
|
283
411
|
the higher-layer libraries; the CLI adds **no** mapping or terminology logic of its own.
|
|
284
412
|
- **`convert <file|-> --to fhir [--json] [--quiet]`**: **HL7 v2 → FHIR R4** via
|
|
@@ -309,6 +437,7 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
309
437
|
lazy-loaded per command, so the `parse` fast path never loads them).
|
|
310
438
|
- **ADR `0023`**: wire `@cosyte/transform` + `@cosyte/terminology`; the deliberate 2 → 4 cap raise
|
|
311
439
|
(amends ADR 0021).
|
|
440
|
+
|
|
312
441
|
- **Phase 3: `validate` / `inspect` / `fmt`.** Three commands over the two wired parsers
|
|
313
442
|
(HL7 v2 + FHIR R4), each a thin wrapper that re-implements no library logic.
|
|
314
443
|
- **`validate <file|-> [--profile] [--json] [--quiet]`**: parse + run the wrapped parser's own
|
|
@@ -335,6 +464,7 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
335
464
|
helpers (behavior-preserving). New programmatic exports: `validateCommand`, `inspectCommand`,
|
|
336
465
|
`fmtCommand`, `resolveInput`, `parseFailureResult`, `formatHl7Position`, `errorResult`. No new
|
|
337
466
|
runtime dependencies: stays within the cap of 2.
|
|
467
|
+
|
|
338
468
|
- **Phase 2: PHI posture hardened + `redact`/`deid` + `--unsafe-show-values`.**
|
|
339
469
|
- **`--unsafe-show-values`**: a global, opt-in, PHI-exposing flag, resolved once and order-
|
|
340
470
|
independently and funnelled through a **single chokepoint** (`core/phi.ts`), so the "a value
|
|
@@ -355,28 +485,35 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
355
485
|
- New `CLI_NOT_IMPLEMENTED` diagnostic code and `EXIT.UNAVAILABLE` (`69`); new programmatic exports
|
|
356
486
|
(`PhiPosture`, `VALUE_FREE`/`SHOW_VALUES`, `extractPhiPosture`, `unsafeInputSuffix`, `deidStatus`,
|
|
357
487
|
`redactCommand`).
|
|
488
|
+
|
|
358
489
|
- **Phase 1: the `cosyte parse` foundation.** Reshaped the scaffold from a library skeleton into a
|
|
359
490
|
**`bin` package**: `package.json#bin` maps `cosyte` → `dist/bin/cosyte.mjs` (a shebang entry over a
|
|
360
491
|
testable `core`), argument-parsed with Node's built-in `util.parseArgs` + a hand-rolled subcommand
|
|
361
492
|
dispatcher (**no third-party CLI framework**).
|
|
493
|
+
|
|
362
494
|
- **`cosyte parse <file|->`**: reads a file argument or stdin (`-`); **autodetects the format by
|
|
363
495
|
content** (HL7 v2 `MSH` framing, FHIR JSON `resourceType`): conservative and fail-safe (a confident
|
|
364
496
|
single match parses; ambiguity/no-match is a data error asking for `--format`, never a guess); routes
|
|
365
497
|
to the wrapped parser (**lazy-loaded** per format); emits the parsed model as **typed JSON on
|
|
366
498
|
stdout**. Flags: `--format`, `--json`, `--quiet`, `--no-color`.
|
|
499
|
+
|
|
367
500
|
- **The exit-code contract** (`sysexits.h`-grounded, documented, tested): `0` success · `2` usage ·
|
|
368
501
|
`65` data/parse error (`EX_DATAERR`) · `66` no input (`EX_NOINPUT`) · `70` internal (`EX_SOFTWARE`).
|
|
369
502
|
The CLI never exits `0` on input it could not handle.
|
|
503
|
+
|
|
370
504
|
- **Value-free diagnostic channel** with stable `CLI_*` codes (`CLI_FORMAT_UNDETECTED`,
|
|
371
505
|
`CLI_FORMAT_AMBIGUOUS`, `CLI_FORMAT_UNSUPPORTED`, `CLI_NO_INPUT`, `CLI_EMPTY_INPUT`,
|
|
372
506
|
`CLI_PARSE_FAILED`, `CLI_USAGE`, `CLI_INTERNAL`). **stdout is the data channel; every stderr line is
|
|
373
507
|
value-free**: code + position only, never a field value. No temp files, no file logging.
|
|
508
|
+
|
|
374
509
|
- **Programmatic `core` API** (the `.` subpath): `detectFormat` / `classifyCandidates` /
|
|
375
510
|
`detectionError`, `EXIT`, `CLI_CODES` / `CliError`, `run`, `parseCommand`, `VERSION`.
|
|
511
|
+
|
|
376
512
|
- **Runtime dependencies (ADR 0021):** `@cosyte/hl7` (`46d50eb`, v0.0.1) and `@cosyte/fhir` (`7a099b2`,
|
|
377
513
|
v0.0.0) as **hard, first-party** deps (an `npx` bin cannot peer-depend) vendored as `pnpm pack`
|
|
378
514
|
tarballs under `vendor/` until PUB-FLIP (`pnpm vendor:refresh`; umbrella ADR 0008). Capped at **2**
|
|
379
515
|
by the umbrella `verify-policy.json`; third-party CLI-core runtime deps stay **zero**.
|
|
516
|
+
|
|
380
517
|
- **ADRs:** `0021` (developer-tooling tier is a `bin` that hard-depends on first-party siblings;
|
|
381
518
|
third-party runtime deps minimized) and `0022` (one repo, two bins: the CLI and the future
|
|
382
519
|
`cosyte-mcp` MCP server over one core; the web playground is out of scope).
|
|
@@ -439,6 +576,7 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
439
576
|
surrounding guarantees (value-free stderr, the never-a-fake `CLI_FORMAT_UNSUPPORTED`, the gated
|
|
440
577
|
`redact`, the exit-code contract) are worded exactly as strongly as before. Internal traceability
|
|
441
578
|
stays where the convention puts it: this file, the changesets, the commits and the roadmap.
|
|
579
|
+
|
|
442
580
|
- **A dependency-budget figure left `src/core/deid.ts` too.** The module said wiring `@cosyte/deid`
|
|
443
581
|
"would breach the CLI's runtime-dep cap (2)". Only the number was stale: the cap has been 4 since
|
|
444
582
|
`convert`/`map-codes` landed, and the constraint itself still holds, because the package declares
|
|
@@ -447,10 +585,12 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
447
585
|
constraint lapsed. The reasons that actually ground the refusal to ship a built-in redactor are
|
|
448
586
|
untouched: `@cosyte/deid` is unpublished, the wrapped parsers expose no de-identification API, and
|
|
449
587
|
a partial scrub would present a false-safety impression.
|
|
588
|
+
|
|
450
589
|
- **`CosyteFormat`'s documentation no longer understates autodetection.** It read as though content
|
|
451
590
|
detection recognised only HL7 v2 and FHIR, with the other six accepted by `--format` but "not yet
|
|
452
591
|
wired", which has not been true since all eight formats gained signatures. The stale sentence is
|
|
453
592
|
removed rather than restated.
|
|
593
|
+
|
|
454
594
|
- **A gate now enforces the public-surface rule, which is why the class stops regrowing.**
|
|
455
595
|
`scripts/check-no-internal-refs.sh` (`pnpm check:no-internal-refs`, on the `verify.sh cli` ladder)
|
|
456
596
|
plus `.github/workflows/no-internal-refs.yml` port the shape of `hl7`'s gate
|
|
@@ -469,6 +609,7 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
469
609
|
purpose, as it is in `hl7` and `ncpdp`: it ships inside the npm tarball, yet the convention names it
|
|
470
610
|
as one of the places identifiers belong. That contradiction is ecosystem-wide, and it is recorded
|
|
471
611
|
here rather than settled by one repo.
|
|
612
|
+
|
|
472
613
|
- **`redact`/`deid` no longer names an internal tracking identifier on any consumer surface.** The
|
|
473
614
|
`CLI_NOT_IMPLEMENTED` text printed when de-identification is unavailable carried an internal work
|
|
474
615
|
item that means nothing to anyone running the command, and the same identifier reached the
|
|
@@ -477,25 +618,24 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
477
618
|
`@cosyte/deid`, which is unpublished, and the CLI ships no built-in redactor because a partial
|
|
478
619
|
scrub would present a false-safety impression. The stable `CLI_NOT_IMPLEMENTED` code and the exit
|
|
479
620
|
`69` are unchanged.
|
|
621
|
+
|
|
480
622
|
- **`CLI_PARSER_UNAVAILABLE`'s message no longer cites an internal decision record.** The error
|
|
481
623
|
raised when an optional per-format parser is not installed pointed at an ADR number, which is
|
|
482
624
|
meaningless to a caller; it now just names the package to install. The stable
|
|
483
625
|
`CLI_PARSER_UNAVAILABLE` code and the exit `69` are unchanged. The same sweep removed the
|
|
484
626
|
remaining roadmap-phase language from `README.md` and `docs-content/troubleshooting.md`.
|
|
627
|
+
|
|
485
628
|
- **The CI checks are now binding on `main`.** `ci / verify (22, ubuntu-latest)`,
|
|
486
629
|
`ci / verify (24, ubuntu-latest)`, `ci / actionlint` and `codeql / analyze (javascript-typescript)`
|
|
487
630
|
are required status checks, each pinned to the `github-actions` app, alongside branch deletion and
|
|
488
631
|
force-push protection. They were advisory before: a red check could not stop a merge. Dependabot
|
|
489
632
|
now watches the npm and GitHub Actions dependency surfaces weekly, which nothing did previously.
|
|
633
|
+
|
|
490
634
|
- **Reshaped the package from the parser-library scaffold to a `bin` package.** Removed the archetype
|
|
491
635
|
stubs (`parseCli`, `WARNING_CODES`, `FATAL_CODES`); replaced the library `src/index.ts` and the
|
|
492
636
|
round-trip property test with the command tree, the programmatic `core` API, and command-contract /
|
|
493
637
|
autodetection / PHI-leak / equivalence tests. Rewrote `docs-content/` and `README.md` for the CLI.
|
|
494
638
|
|
|
495
|
-
### Deprecated
|
|
496
|
-
|
|
497
|
-
### Removed
|
|
498
|
-
|
|
499
639
|
### Fixed
|
|
500
640
|
|
|
501
641
|
- **README + guides now describe the shipped Phase-3 command surface.** The `README.md` and
|
|
@@ -504,10 +644,12 @@ parse` invocation never loads it; the core works with the SDK absent (`--omit=op
|
|
|
504
644
|
and the gated `redact`/`deid`) over the two wired parsers (HL7 v2 + FHIR R4). The pre-alpha,
|
|
505
645
|
not-yet-published-to-npm status is unchanged (accurate), and the `npx`/`npm install -g` examples now
|
|
506
646
|
carry a "not on npm yet" caveat (docs-only; README-ORG-SWEEP).
|
|
647
|
+
|
|
507
648
|
- **`phi-scan` now scans the real fixture directory.** The scanner's fixture root pointed at a
|
|
508
649
|
nonexistent `test/fixtures/`; it now walks `test/__fixtures__/` (and the same path in the staged
|
|
509
650
|
filter), so the PHI commit-gate actually covers the CLI's synthetic fixtures.
|
|
510
651
|
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
[
|
|
652
|
+
[Unreleased]: https://github.com/cosyte/cli/compare/v0.0.3...HEAD
|
|
653
|
+
[0.0.3]: https://github.com/cosyte/cli/compare/v0.0.2...v0.0.3
|
|
654
|
+
[0.0.2]: https://github.com/cosyte/cli/compare/v0.0.1...v0.0.2
|
|
655
|
+
[0.0.1]: https://github.com/cosyte/cli/releases/tag/v0.0.1
|