diff --git a/.changeset/cli-1-parse-foundation.md b/.changeset/cli-1-parse-foundation.md deleted file mode 100644 index e65fcb1..0000000 --- a/.changeset/cli-1-parse-foundation.md +++ /dev/null @@ -1,9 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -`cosyte parse ` reads HL7 v2 and FHIR R4 with format autodetection that fails safe on -ambiguity, writes typed JSON to stdout, and keeps PHI off stderr under a documented exit-code -contract. Lazy-loaded parsers; exit codes 0/2/65/66/70; a value-free `CLI_*` diagnostic channel. Adds `@cosyte/hl7` + `@cosyte/fhir` as -hard, first-party, vendored runtime dependencies (ADR 0021) and the one-repo-two-bins decision -(ADR 0022). diff --git a/.changeset/cli-2-phi-hardening.md b/.changeset/cli-2-phi-hardening.md deleted file mode 100644 index 9469362..0000000 --- a/.changeset/cli-2-phi-hardening.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Phase 2 (CLI-2): harden the PHI posture and add the `redact`/`deid` command as an honest, gated stub. -Adds the global, opt-in `--unsafe-show-values` flag: resolved once and funnelled through a single -chokepoint (`core/phi.ts`) so a value reaches a secondary surface **iff** the flag is set; by default -every diagnostic stays value-free and a successful parse puts values only on stdout. Adds `redact` / -`deid` (``, `--format`) as a typed `CLI_NOT_IMPLEMENTED` (exit `69`, `EX_UNAVAILABLE`): it is -gated on `@cosyte/deid` (unpublished), **never reads the input**, and never emits a partial Safe-Harbor -scrub dressed up as de-identified: a built-in redactor is deliberately withheld to avoid a -false-safety impression, delegating to `@cosyte/deid` via a documented seam (`core/deid.ts`) when it -ships. Also fixes the `phi-scan` fixture root (it now scans the real `test/__fixtures__/`). No new -runtime dependencies: stays within the cap of 2. diff --git a/.changeset/cli-3-validate-inspect-fmt.md b/.changeset/cli-3-validate-inspect-fmt.md deleted file mode 100644 index 9946116..0000000 --- a/.changeset/cli-3-validate-inspect-fmt.md +++ /dev/null @@ -1,29 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Phase 3 (CLI-3): add `validate`, `inspect`, and `fmt` over the two wired parsers (HL7 v2 + FHIR R4), -each a thin, PHI-safe wrapper that re-implements no library logic. - -- **`validate [--profile] [--json] [--quiet]`**: parse + run the wrapped parser's own - validation surface, with the **verdict in the exit code**: `0` valid, `1` invalid (parseable but - non-conformant), `65` unparseable, `66` no input, `2` usage. The load-bearing rule holds: a - validation failure is **never** exit `0`, and "unparseable" (`65`) is a distinct signal from - "parsed but invalid" (`1`). The CLI invents no verdict: FHIR validity is `@cosyte/fhir`'s - `validateResource().valid` (plus any error-severity read issue); HL7 validity is "parseable" (its - warnings are non-fatal by the library's design: surfaced, never failing). `--profile` is gated to - an honest `CLI_NOT_IMPLEMENTED` (exit `69`): the CLI bundles no profiles yet, so it never fakes or - silently drops a profile verdict. -- **`inspect [--json]`**: a value-free structural summary: HL7 message type + version + - per-segment-type counts + warning count; FHIR `resourceType`, Bundle entry counts by type, and - issue count. Counts and structural type codes only, never a field value. -- **`fmt `**: canonical re-serialization via the wrapped library's spec-clean serializer - (`Hl7Message.toString()` / `serializeResource`). Its stdout **is** the data channel; an unparseable - input is a data error (`65`) with **no partial emit**. - -New `EXIT.INVALID` (`1`): the `validate` verdict code. All four commands share one input + format -front door (`core/resolveInput`) and one value-free parser-failure boundary (`core/wrap`), so the -value-free-by-default posture and `--unsafe-show-values` chokepoint apply uniformly (`parse` was -refactored onto the shared helpers, behavior-preserving). New programmatic exports: `validateCommand`, -`inspectCommand`, `fmtCommand`, `resolveInput`, `parseFailureResult`, `formatHl7Position`, -`errorResult`. No new runtime dependencies: stays within the cap of 2. diff --git a/.changeset/cli-4-convert-map-codes.md b/.changeset/cli-4-convert-map-codes.md deleted file mode 100644 index c18f1d7..0000000 --- a/.changeset/cli-4-convert-map-codes.md +++ /dev/null @@ -1,14 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -`cosyte convert` turns HL7 v2 into FHIR R4 and `cosyte map-codes` translates a code through a -ConceptMap you supply, with no mapping or terminology logic of the CLI's own. `convert` runs via -`@cosyte/transform`; `map-codes` runs `$translate` via `@cosyte/terminology`. `convert --to fhir` parses with `@cosyte/hl7`, converts via `transform.toFhir`, and -emits the serialized FHIR message `Bundle` on stdout; the library's value-free issues go to stderr and -an error-severity issue drives a non-zero exit (`1`), never exit `0`. `map-codes --code … -[--system …]` loads the user's FHIR ConceptMap and forwards `terminology.translate` faithfully: -mapped → the target coding(s) + exit `0`, unmapped → the value-free `TERM_TRANSLATE_UNMAPPED` signal + -exit `1`, an unloadable map → the new `CLI_MAP_INVALID` data error (`65`). The CLI adds no mapping or -terminology logic of its own. Adds `@cosyte/transform` + `@cosyte/terminology` as hard, lazy-loaded, -first-party runtime deps (vendored tarballs; umbrella dep cap raised 2 → 4: ADR 0023). diff --git a/.changeset/cli-5-mcp-server.md b/.changeset/cli-5-mcp-server.md deleted file mode 100644 index ebd60f3..0000000 --- a/.changeset/cli-5-mcp-server.md +++ /dev/null @@ -1,16 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Phase 5 (CLI-5): the `cosyte-mcp` **MCP server**, the agent front door (ADR 0022, 0024). A stdio Model -Context Protocol server exposing the shared command core to an LLM/agent as callable tools (`parse`, -`validate`, `inspect`, `convert`), reachable as the new `cosyte-mcp` bin, the `cosyte mcp` subcommand, -and the `@cosyte/cli/mcp` subpath export. Each tool calls the same command handler the terminal uses -(with `--json`), so `cosyte parse` and the MCP `parse` tool agree; the CLI re-implements nothing. Every -tool runs value-free. There is no `--unsafe-show-values` door on the agent surface; a tool result -carries the requested data, a tool error carries only value-free diagnostics, and a parsed-but-invalid -`validate` verdict is a successful call reporting the verdict (not a tool error). The -`@modelcontextprotocol/sdk` (the CLI's first and only third-party runtime dependency) is declared in -`optionalDependencies` (pinned `1.29.0`), imported only in `src/mcp/server.ts`, and reachable solely via -the `./mcp` boundary, so a `cosyte parse` invocation never loads it and the core works with the SDK -absent. Because the SDK is not part of the hard runtime closure, the umbrella runtime-dep cap stays 4. diff --git a/.changeset/cli-6-formats-streaming.md b/.changeset/cli-6-formats-streaming.md deleted file mode 100644 index 5fc4b9a..0000000 --- a/.changeset/cli-6-formats-streaming.md +++ /dev/null @@ -1,30 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Phase 6 (CLI-6): **six more formats + streaming + shell completion** (ADR 0025). The `cosyte` CLI now -wraps all eight cosyte formats, wired through a single lazy **per-format adapter registry** -(`core/parsers.ts`) that replaces the old `hl7 ? : fhir` command branches and makes support **per -(format, operation)**: an unsupported (format, op) is a value-free `CLI_FORMAT_UNSUPPORTED`, never a -fake. - -- **New formats & their honest capabilities:** `x12`, `astm`, `ncpdp` (SCRIPT) → `parse` + `inspect` + - `fmt` + `validate`; `ccda` → `inspect` + `fmt` (XML) + `validate` (no library-blessed JSON model, so - `parse` is deferred); `dicom` → `inspect` + `validate` (binary model, so `parse`/`fmt` are deferred); - `mllp` → `parse` + `inspect` (a transport container de-framed to its enclosed HL7 message(s)). - Content autodetection now covers all eight; `--format` accepts `mllp`. -- **Streaming / multi-message:** `parse` emits **NDJSON** with per-record isolation for inherently - multi-record inputs: an **MLLP** stream (one record per frame) and any input under the new - **`--ndjson`** flag (one record per non-empty line; the FHIR bulk-data convention). A failed record - becomes a value-free `{ record, error }` line and the stream continues; the overall exit is a data - error (`65`) if any record failed. A single message is unchanged (one pretty/`--json` envelope). -- **Shell completion:** `cosyte completion ` prints a static, value-free completion - script generated from the command tree. -- **Dependencies:** the six breadth parsers are **`optionalDependencies`** (vendored tarballs), - lazy-loaded per format and outside the hard-runtime-dep closure, so the umbrella `verify-policy` - `cli` cap stays **4** (ADR 0025, mirroring the MCP SDK isolation of ADR 0024). An absent optional - parser degrades to a value-free `CLI_PARSER_UNAVAILABLE` (exit `69`), never a crash. -- **New diagnostic:** `CLI_PARSER_UNAVAILABLE` (exit `69`). Exit-code contract unchanged - (`0/1/2/65/66/69/70`). -- Pinned sibling commits: dicom `d1ed590`, x12 `0c60606`, ccda `3753216`, ncpdp `184eecc`, mllp - `aecff75`, astm `92ac210`. diff --git a/.changeset/cli-7-release-hardening.md b/.changeset/cli-7-release-hardening.md deleted file mode 100644 index 8c41eac..0000000 --- a/.changeset/cli-7-release-hardening.md +++ /dev/null @@ -1,23 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Release hardening: no new command surface, with a fuzz gate over both input boundaries and a golden -matrix pinning every documented exit code. The CLI is feature-complete and its contracts are locked. - -- **Fuzz gate over the two input boundaries.** `test/fuzz.property.test.ts` fuzzes the terminal (`run`, - over arbitrary argv vectors + stdin bytes) and the agent surface (`dispatchTool`, over an arbitrary - tool name + arguments): neither ever throws an unhandled exception, both always resolve to a - documented exit code, and no raw stack frame ever reaches a secondary channel. Scaled by - `CLI_FUZZ_RUNS`; run nightly by `.github/workflows/fuzz.yml` and on demand via `pnpm test:fuzz`. -- **Exit-code golden matrix.** `test/exit-code-matrix.test.ts` pins one representative invocation for - every code in the `0/1/2/65/66/69/70` contract, driven end-to-end through `run`, so a regression that - turns an invalid-input exit `1` into a `0` (or renumbers a code) fails CI. The exit-code map and the - stable `CLI_*` diagnostic codes are a stability surface: renaming one is a breaking change. -- **Publish dry-run proven.** A new `smoke` gate (`scripts/smoke.mjs`, wired into `verify.sh`) exercises - the built dual ESM/CJS `.` and `./mcp` subpaths and **both** `cosyte` / `cosyte-mcp` bins under - `node`; `npm publish --dry-run` assembles a clean tarball; `attw` stays a publish gate. -- **Honesty + release docs.** `docs-content/limitations.md`, a man-page-style - `docs-content/reference-commands.md`, and `RELEASING.md` (the one-package-two-bins publish, - provenance/OIDC, the vendored-`file:`→npm dep swap, and the two standing founder stops: public-flip - and `npm publish`). diff --git a/.changeset/cli-required-checks-and-dependabot.md b/.changeset/cli-required-checks-and-dependabot.md deleted file mode 100644 index a75e378..0000000 --- a/.changeset/cli-required-checks-and-dependabot.md +++ /dev/null @@ -1,18 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Two error messages no longer quote internal tracking identifiers that mean nothing outside this -project. - -- **`redact`/`deid`'s unavailable message.** The `CLI_NOT_IMPLEMENTED` text printed when - de-identification is unavailable named an internal work item, and the same identifier reached the - published type declarations, where it showed up in editor tooltips. Both now state only what a - caller can act on: the command delegates to `@cosyte/deid`, which is unpublished, and the CLI - ships no built-in redactor because a partial scrub would present a false-safety impression. -- **`CLI_PARSER_UNAVAILABLE`'s message.** Telling you an optional parser is not installed, it also - cited an internal decision record. It now just names the package to install. - -The stable `CLI_NOT_IMPLEMENTED` and `CLI_PARSER_UNAVAILABLE` codes and their exit `69` are -unchanged, so nothing branching on them moves. Everything else in this release is internal: branch -protection, Dependabot, and caller workflows. diff --git a/.changeset/no-em-dashes-on-any-surface.md b/.changeset/no-em-dashes-on-any-surface.md deleted file mode 100644 index 2d79ac7..0000000 --- a/.changeset/no-em-dashes-on-any-surface.md +++ /dev/null @@ -1,19 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -Correct the documented support matrix, where three cells said nothing instead of saying "not -supported", and rewrite every user-visible text surface so none of them uses an em dash. - -- **The published support matrix now states its negatives in words.** In "What it does and does not - do", the per-(format, operation) table used a bare dash as the value meaning **not supported**. Three - cells (`dicom` `fmt`, `mllp` `fmt`, `mllp` `validate`) are now spelled `not supported`, so an absent - capability reads as an explicit claim rather than as punctuation a reader could mistake for a - rendering artifact. The support facts are unchanged; what changed is that the page now says them. -- **The npm package description, the README, and the published documentation** are rewritten with a - period, a colon, a comma, or parentheses. The description is what renders on the package page, so - this is visible before anything is installed. -- **Terminal output changes wording only.** `cosyte --help`, the generated `bash`/`zsh`/`fish` - completion scripts, and the messages for `redact`/`deid` and the reserved `--profile` flag are - rephrased. Every stable code, exit code, flag name, and JSON field is untouched, so anything - branching on the exit code or parsing `--json` is unaffected. diff --git a/.changeset/no-internal-refs-in-type-declarations.md b/.changeset/no-internal-refs-in-type-declarations.md deleted file mode 100644 index c0c0d12..0000000 --- a/.changeset/no-internal-refs-in-type-declarations.md +++ /dev/null @@ -1,20 +0,0 @@ ---- -"@cosyte/cli": patch ---- - -The published type declarations no longer carry internal project references, so editor tooltips -describe only what the software does. - -`dist/index.d.ts` and `dist/mcp.d.ts` (and their `.d.cts` twins) are compiled from the JSDoc on -every exported symbol, and that JSDoc was citing internal tracking identifiers, internal decision -records, an internal planning document and its section numbers, and internal sequencing language. -None of it meant anything outside this project, and all of it was rendering on hover for anyone who -installed the package. Every one of those citations is gone; the surrounding statements about what -the CLI guarantees are unchanged. - -One factual correction came with the sweep: the `CosyteFormat` type was documented as though content -autodetection recognised only HL7 v2 and FHIR, with the other six formats accepted by `--format` but -not wired. That has not been true since all eight formats gained signatures, and the stale sentence -is removed rather than restated. - -No command, flag, exit code or `CLI_*` diagnostic changed. diff --git a/package.json b/package.json index 478e767..e4b5ee8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@cosyte/cli", - "version": "0.0.0", + "version": "0.0.1", "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.", "keywords": [ "cli",