Skip to main content
Version: v0.0.1

@cosyte/cli

Public programmatic entry point for @cosyte/cli (the . subpath export).

@cosyte/cli is a bin package: its primary artifact is the cosyte command on your PATH (npx @cosyte/cli parse …), not an import surface. This module is the small, honest programmatic API over the same core the CLI uses: the format autodetector, the exit-code contract, the value-free diagnostic types, and the dispatcher, so another adapter (the MCP server, or a web playground) can drive the same logic without shelling out.

The CLI is a thin, PHI-safe skin over the wrapped @cosyte/* parsers: it routes, reads, shapes output, and owns the exit-code + value-free-diagnostic disciplines; it re-implements no wire-format parsing.

Classes

CliError

A typed, PHI-safe CLI error. Its CliError.message | message is value-free by construction: callers must build it from codes, indices, offsets, format names, and file paths, never from an input value. It carries the ExitCode the invocation resolves to.

Example

import { CliError, CLI_CODES, EXIT } from "@cosyte/cli";

throw new CliError(CLI_CODES.CLI_NO_INPUT, EXIT.NOINPUT, "cannot read the named file");

Extends

  • Error

Constructors

Constructor

new CliError(code, exit, message): CliError

Parameters
code

CliCode

A stable CliCode.

exit

ExitCode

The ExitCode to resolve to.

message

string

A value-free explanation (positional/structural context only, never PHI).

Returns

CliError

Overrides

Error.constructor

Properties

code

readonly code: CliCode

The stable diagnostic code.

exit

readonly exit: ExitCode

The exit code this error resolves the invocation to.

Interfaces

DeidAvailability

Whether de-identification is available, and (while it is not) the value-free reason why. The one function the redact command consults before reading any input, so a redact invocation never touches the PHI it cannot yet safely strip.

Properties

available

readonly available: boolean

true once @cosyte/deid is wired; false today.

reason

readonly reason: string

A value-free explanation shown when DeidAvailability.available is false.


DetectResult

How confident autodetection is:

  • certain: exactly one signature matched (format names it);
  • ambiguous: more than one matched (format is null; candidates names them);
  • none: nothing matched (format is null; candidates is empty).

format is null unless confidence is certain, so a non-certain result can never be mistaken for a routable format.

Properties

candidates

readonly candidates: readonly CosyteFormat[]

The matching candidate formats (0 for none, 1 for certain, ≥2 for ambiguous). Value-free.

confidence

readonly confidence: "certain" | "ambiguous" | "none"

The detection confidence.

format

readonly format: CosyteFormat | null

The detected format, or null when confidence is not certain.


Finding

A single value-free finding: a stable code, a severity, and a positional locator. Every field is safe to print, log, or serialize. None carries a name, DOB, MRN, or field value.

Properties

code

readonly code: string

The stable diagnostic/warning code (the wrapped library's or the CLI's).

location

readonly location: string

A value-free positional locator: a FHIRPath expression, or an HL7 segment/field index path.

severity

readonly severity: string

The R4-style severity (fatal | error | warning | information), or warning for HL7.


FmtResult

The result of a canonical re-serialization (fmt): the spec-clean text + a value-free warning count.

Properties

output

readonly output: string

The wrapped serializer's output text.

warningCount

readonly warningCount: number

How many parse warnings the round-trip surfaced (value-free count only).


ParseResult

The result of wrapping a parser's parse: the library's parsed model + its value-free warnings.

Properties

model

readonly model: unknown

The wrapped library's parsed model: emitted verbatim as JSON on the data channel.

warnings

readonly warnings: readonly ParseWarning[]

The parser's value-free warnings (code + position).


PhiPosture

The resolved PHI display posture for one invocation. showValues is true only when the user passed --unsafe-show-values; every value-echoing decision reads this one flag.

Properties

showValues

readonly showValues: boolean

true iff --unsafe-show-values was given: a value may appear on a secondary surface.


ResolvedInput

A successfully-resolved input: the format (guaranteed to support the requested op) and the bytes.

Properties

bytes

readonly bytes: Uint8Array

The input bytes (a whole file or a drained stdin buffer); guaranteed non-empty.

format

readonly format: CosyteFormat

The resolved format: guaranteed to satisfy supportsOp(format, op) for the requested op.


RunDeps

The injectable input side-effects the dispatcher needs. Kept tiny and pure-ish so tests drive the CLI end to end with in-memory fakes and no real filesystem or stdin.

Properties

readFile

readonly readFile: (path) => Promise<Uint8Array<ArrayBufferLike>>

Read a file's bytes, or raise a CLI_NO_INPUT CliError if it cannot be read.

Parameters
path

string

Returns

Promise<Uint8Array<ArrayBufferLike>>

readStdin

readonly readStdin: () => Promise<Uint8Array<ArrayBufferLike>>

Read all of stdin's bytes.

Returns

Promise<Uint8Array<ArrayBufferLike>>


RunResult

A fully-resolved CLI invocation.

Example

import { EXIT, type RunResult } from "@cosyte/cli";

const r: RunResult = { stdout: "{}\n", stderr: "", exit: EXIT.OK };
r.exit; // => 0

Properties

exit

readonly exit: ExitCode

The exit code the invocation resolves to.

stderr

readonly stderr: string

The diagnostic channel is value-free: codes, positions, file paths, format names only.

stdout

readonly stdout: string

The data channel: the parsed model or requested output. May contain the user's data by design.


Verdict

The verdict of running a format's validation surface: value-free findings + the validity boolean.

Properties

findings

readonly findings: readonly Finding[]

The value-free findings (code + severity + positional locator).

valid

readonly valid: boolean

true iff the input is valid (no error/fatal-severity finding).

Type Aliases

CliCode

CliCode = typeof CLI_CODES[keyof typeof CLI_CODES]

A value from CLI_CODES: the stable code carried by a CliError.


CosyteFormat

CosyteFormat = "hl7" | "fhir" | "dicom" | "x12" | "ccda" | "ncpdp" | "astm" | "mllp"

The set of formats the cosyte command names.


ExitCode

ExitCode = typeof EXIT[keyof typeof EXIT]

A value from EXIT: the exit code a CLI invocation resolves to.


InputResolution

InputResolution = { input: ResolvedInput; ok: true; } | { ok: false; result: RunResult; }

The outcome of resolveInput: either the resolved input, or a ready-to-return value-free RunResult carrying the diagnostic + exit code for whatever went wrong. A discriminated union so a command reads if (!r.ok) return r.result; and then works with r.input.


InspectSummary

InspectSummary = Hl7Summary | FhirSummary | X12Summary | AstmSummary | CcdaSummary | DicomSummary | NcpdpSummary | MllpSummary

The discriminated value-free structural summary inspect renders.


Op

Op = "parse" | "inspect" | "fmt" | "validate"

The four wrapping operations a command can ask a format's adapter to perform.


ParseWarning

ParseWarning = object & Readonly<Record<string, unknown>>

A value-free parse warning: a stable code plus the parser's positional (index-only) context.

Type Declaration

code

readonly code: string

Variables

CLI_CODES

const CLI_CODES: object

Stable CLI diagnostic code registry: errors the CLI owns (routing, I/O, argument handling), distinct from the wrapped library's own warning/issue codes which are passed through unchanged. Each code is its own value (key === value) so the set survives Object.values(...); renaming or removing one is a breaking change because scripts branch on the stderr text.

Type Declaration

CLI_EMPTY_INPUT

readonly CLI_EMPTY_INPUT: "CLI_EMPTY_INPUT" = "CLI_EMPTY_INPUT"

The input was empty, no bytes to detect or parse. Exit 65.

CLI_FORMAT_AMBIGUOUS

readonly CLI_FORMAT_AMBIGUOUS: "CLI_FORMAT_AMBIGUOUS" = "CLI_FORMAT_AMBIGUOUS"

More than one format signature matched; the CLI will not guess. Names the candidates, never the bytes. Exit 65.

CLI_FORMAT_UNDETECTED

readonly CLI_FORMAT_UNDETECTED: "CLI_FORMAT_UNDETECTED" = "CLI_FORMAT_UNDETECTED"

No format signature matched; the CLI will not guess. Names the candidates, never the bytes. Exit 65.

CLI_FORMAT_UNSUPPORTED

readonly CLI_FORMAT_UNSUPPORTED: "CLI_FORMAT_UNSUPPORTED" = "CLI_FORMAT_UNSUPPORTED"

A recognised format whose parser does not support the requested operation (e.g. parse on a format wired only for inspect). Names the format + operation, never the bytes. Exit 65.

CLI_INTERNAL

readonly CLI_INTERNAL: "CLI_INTERNAL" = "CLI_INTERNAL"

An unexpected internal error (a bug). Exit 70.

CLI_MAP_INVALID

readonly CLI_MAP_INVALID: "CLI_MAP_INVALID" = "CLI_MAP_INVALID"

The BYO ConceptMap supplied to map-codes is not valid JSON or not a loadable FHIR ConceptMap. Names the stable terminology-loader code, never the map's bytes. Exit 65.

CLI_NO_INPUT

readonly CLI_NO_INPUT: "CLI_NO_INPUT" = "CLI_NO_INPUT"

The named file does not exist or could not be read. Exit 66.

CLI_NOT_IMPLEMENTED

readonly CLI_NOT_IMPLEMENTED: "CLI_NOT_IMPLEMENTED" = "CLI_NOT_IMPLEMENTED"

A command whose ground-layer library is not yet built (e.g. redact before @cosyte/deid ships). Never a fake success: a distinct, value-free "unavailable" signal. Exit 69.

CLI_PARSE_FAILED

readonly CLI_PARSE_FAILED: "CLI_PARSE_FAILED" = "CLI_PARSE_FAILED"

The wrapped parser rejected the input. Positional context only, never the offending bytes. Exit 65.

CLI_PARSER_UNAVAILABLE

readonly CLI_PARSER_UNAVAILABLE: "CLI_PARSER_UNAVAILABLE" = "CLI_PARSER_UNAVAILABLE"

The optional parser package for a recognised format is not installed. The six breadth parsers (dicom/x12/ccda/ncpdp/astm/mllp) are optionalDependencies: normally installed, but if one is absent the CLI degrades to this value-free signal rather than crashing. Exit 69.

CLI_USAGE

readonly CLI_USAGE: "CLI_USAGE" = "CLI_USAGE"

A required argument was missing or a flag was invalid. Exit 2.

Example

import { CLI_CODES } from "@cosyte/cli";

if (diagnostic.code === CLI_CODES.CLI_FORMAT_UNDETECTED) {
// ask the user for --format
}

DEID_UNAVAILABLE_REASON

const DEID_UNAVAILABLE_REASON: string

The value-free reason redact/deid reports while the ground-layer library is unavailable.


DETECTABLE_FORMATS

const DETECTABLE_FORMATS: readonly CosyteFormat[]

The formats content-autodetection can recognise (every format now carries a signature).


EXIT

const EXIT: object

The stable exit-code map. Adding a code is a documented, tested change to the CLI's contract; renaming or repurposing one is a breaking change.

Type Declaration

DATAERR

readonly DATAERR: 65 = 65

Data error: input could not be parsed or its format could not be detected (EX_DATAERR).

INVALID

readonly INVALID: 1 = 1

Operation-level failure: validate found the input invalid (parseable but non-conformant): a real, expected CI signal that the message is bad and the tool worked. Never emitted for unparseable input (that is DATAERR).

NOINPUT

readonly NOINPUT: 66 = 66

No input: the named file does not exist or is unreadable (EX_NOINPUT).

OK

readonly OK: 0 = 0

Success: the operation completed; validate found the input valid.

SOFTWARE

readonly SOFTWARE: 70 = 70

Internal error: an unexpected exception (a bug), distinct from a handled bad input (EX_SOFTWARE).

UNAVAILABLE

readonly UNAVAILABLE: 69 = 69

Unavailable: a required capability is not yet built (e.g. redact before @cosyte/deid), a distinct non-zero signal that is never a fake success (EX_UNAVAILABLE).

USAGE

readonly USAGE: 2 = 2

Usage error: unknown command, bad flag, missing argument (EX_USAGE).

Example

import { EXIT } from "@cosyte/cli";

process.exitCode = EXIT.OK; // => 0

KNOWN_FORMATS

const KNOWN_FORMATS: readonly CosyteFormat[]

The full set of format names --format accepts as syntactically valid (a bad value is a usage error).


OP_SUPPORT

const OP_SUPPORT: Readonly<Record<CosyteFormat, ReadonlySet<Op>>>

The honest per-format operation matrix. A (format, op) pair absent here is a value-free CLI_FORMAT_UNSUPPORTED, never a faked result. The unsupported cells and why:

  • dicom parse/fmt. The model is binary (no faithful JSON view; serializeDicom emits a Part-10 byte stream, not text). inspect/validate are supported.
  • ccda parse: the canonical form is XML; there is no library-blessed JSON model, so fmt (XML re-serialize) is the faithful surface. inspect/fmt/validate are supported.
  • mllp fmt/validate: MLLP is a transport container the CLI de-frames to HL7; parse yields the enclosed HL7 message(s) and inspect reports the frame count.

Example

import { OP_SUPPORT } from "@cosyte/cli";

OP_SUPPORT.dicom.has("parse"); // => false
OP_SUPPORT.hl7.has("validate"); // => true

SHOW_VALUES

const SHOW_VALUES: PhiPosture

The opted-in, PHI-exposing posture selected by --unsafe-show-values.


UNSAFE_EXCERPT_MAX

const UNSAFE_EXCERPT_MAX: 200 = 200

The maximum number of leading input bytes an --unsafe-show-values diagnostic may echo. Bounded so an unsafe excerpt stays a single, readable diagnostic line rather than dumping a whole message.


UNSAFE_SHOW_VALUES_FLAG

const UNSAFE_SHOW_VALUES_FLAG: "--unsafe-show-values" = "--unsafe-show-values"

The single global flag token that opts into showing values on secondary surfaces.


VALUE_FREE

const VALUE_FREE: PhiPosture

The default, safe posture: no value ever reaches a secondary surface.


VERSION

const VERSION: "0.0.0" = "0.0.0"

The @cosyte/cli version. On the uniform v0.0.x-until-first-alpha ladder.

Example

import { VERSION } from "@cosyte/cli";

typeof VERSION; // => "string"

Functions

asCosyteFormat()

asCosyteFormat(value): CosyteFormat | null

Narrow an arbitrary --format string to a CosyteFormat, or null if it is not a known format name (which the caller turns into a usage error, exit 2).

Parameters

value

string

The raw --format argument.

Returns

CosyteFormat | null

The narrowed format, or null.

Example

import { asCosyteFormat } from "@cosyte/cli";

asCosyteFormat("hl7"); // => "hl7"
asCosyteFormat("nope"); // => null

classifyCandidates()

classifyCandidates(candidates): DetectResult

Classify a list of matched candidate formats into a DetectResult: exactly one → certain, zero → none, two-or-more → ambiguous (all with format null unless certain). Split out and exported so the ambiguity contract is directly testable. It is otherwise unreachable while every signature is disjoint, and it must stay a detected ambiguity, never a mis-route.

Parameters

candidates

readonly CosyteFormat[]

The formats whose signatures matched the input.

Returns

DetectResult

The classified DetectResult.

Example

import { classifyCandidates } from "@cosyte/cli";

classifyCandidates(["hl7"]).confidence; // => "certain"
classifyCandidates([]).confidence; // => "none"
classifyCandidates(["hl7", "fhir"]).confidence; // => "ambiguous"

completionCommand()

completionCommand(args): RunResult

Run the completion command.

Parameters

args

string[]

The arguments after the completion subcommand token; the first is the shell name.

Returns

RunResult

A RunResult: the completion script on stdout (exit 0), or a value-free usage error (exit 2) when the shell is missing or unrecognised.

Example

import { completionCommand } from "@cosyte/cli";

completionCommand(["bash"]).exit; // => 0
completionCommand(["powershell"]).exit; // => 2

convertCommand()

convertCommand(args, deps, posture?): Promise<RunResult>

Run the convert command.

Parameters

args

string[]

The arguments after the convert subcommand token.

deps

RunDeps

Injected input readers (RunDeps).

posture?

PhiPosture = VALUE_FREE

The resolved PhiPosture (governs only the opt-in unsafe excerpt on an HL7 parse-failure diagnostic; the converted bundle and the value-free findings are unaffected).

Returns

Promise<RunResult>

A RunResult: the converted FHIR Bundle on stdout (the data channel), value-free findings on stderr (or JSON under --json), and an exit code that carries the outcome: 0 clean · 1 an error-severity conversion issue · 65 the HL7 input could not be parsed or is not an HL7 v2 source · 66 no input · 2 usage.

Throws

Never CliError; may propagate a truly unexpected error for the dispatcher to map to CLI_INTERNAL.

Example

import { convertCommand } from "@cosyte/cli";

const deps = {
readFile: async () => new TextEncoder().encode("MSH|^~\\&|A|B|C|D|20240101||ADT^A01|1|P|2.5\r"),
readStdin: async () => new Uint8Array(),
};
(await convertCommand(["adt.hl7", "--to", "fhir"], deps)).exit; // => 0

convertOutcome()

convertOutcome(findings): object

Decide the conversion outcome from the library's value-free findings: whether any is error-severity (which drives a non-zero exit: the load-bearing "a conversion error is never exit 0" rule) and the value-free human report. The severity classification is the library's: @cosyte/transform fixes each issue's severity; the CLI only reads it. Exported so the exit-verdict and report logic is unit-testable with synthetic findings, independent of which HL7 message happens to produce an error.

Parameters

findings

readonly Finding[]

The value-free Findings the conversion produced.

Returns

object

hasError (true iff any finding is error/fatal severity) and the rendered value-free report (one line per finding + a summary line).

hasError

readonly hasError: boolean

report

readonly report: string

Example

import { convertOutcome } from "@cosyte/cli";

convertOutcome([{ code: "TRANSFORM_RESOURCE_INVALID", severity: "error", location: "PID" }])
.hasError; // => true
convertOutcome([{ code: "TRANSFORM_ELEMENT_DROPPED", severity: "information", location: "PID.13" }])
.hasError; // => false

deframeMllp()

deframeMllp(bytes): Promise<{ payloads: Buffer<ArrayBufferLike>[]; warningCount: number; }>

De-frame an MLLP byte stream into its enclosed HL7 payloads via @cosyte/mllp's FrameReader. MLLP is a transport container, not a document format: each frame's payload is an HL7 v2 message the CLI then parses/inspects with the hl7 adapter. Multi-frame streams are the CLI's multi-message surface.

Parameters

bytes

Uint8Array

The MLLP-framed input.

Returns

Promise<{ payloads: Buffer<ArrayBufferLike>[]; warningCount: number; }>

The de-framed HL7 payloads (in stream order) + a value-free framing-warning count. Truncation is a data error, never a silent drop. The FrameReader is a streaming decoder: an unterminated trailing frame (a VT opened with no closing FS/CR) is left buffered and delivered by no callback, so feeding a whole file and reading only onFrame would silently lose the partial message with a green exit. We therefore detect an open trailing frame at the byte level (the last VT sits after the last FS: MLLP payloads are HL7 v2 text and never carry the 0x0B/0x1C framing bytes) and reject the whole stream as a value-free CLI_PARSE_FAILED data error.

Throws

CLI_PARSER_UNAVAILABLE if @cosyte/mllp is absent; CLI_PARSE_FAILED (exit 65) on a truncated stream; a hard framing error propagates for the caller's value-free boundary.

Example

import { deframeMllp } from "@cosyte/cli";

// a VT-framed "MSH|..." message → one payload
(await deframeMllp(new Uint8Array([0x0b, 0x4d, 0x53, 0x48, 0x1c, 0x0d]))).payloads.length; // => 1

deidStatus()

deidStatus(): DeidAvailability

Report the current de-identification availability. Today it is always unavailable (see the module docs); this is the single line that flips when @cosyte/deid is wired.

Returns

DeidAvailability

The DeidAvailability: { available: false, reason } until @cosyte/deid ships.

Example

import { deidStatus } from "@cosyte/cli";

deidStatus().available; // => false

detectFormat()

detectFormat(bytes): DetectResult

Detect the healthcare format of bytes by content, conservatively.

Parameters

bytes

Uint8Array

The input bytes (a whole file or a stdin buffer). Only the leading prefix is sniffed.

Returns

DetectResult

A DetectResult: certain + a format on a single match, else ambiguous/none with format: null and the value-free candidates list. Never guesses.

Example

import { detectFormat } from "@cosyte/cli";

const enc = new TextEncoder();
detectFormat(enc.encode("MSH|^~\\&|A|B\r")).format; // => "hl7"
detectFormat(enc.encode('{"resourceType":"Patient"}')).format; // => "fhir"
detectFormat(enc.encode("hello")).confidence; // => "none"

detectionError()

detectionError(detected): CliError

Build the value-free CliError for a non-certain detection: the data error the caller returns instead of guessing a parser. ambiguous names the matching candidates (a value-free code list); none asks for --format. Both map to the data-error exit (65). Never echoes input bytes.

Parameters

detected

DetectResult

A DetectResult whose format is null (i.e. not certain).

Returns

CliError

A value-free CLI_FORMAT_AMBIGUOUS or CLI_FORMAT_UNDETECTED error.

Example

import { classifyCandidates, detectionError } from "@cosyte/cli";

detectionError(classifyCandidates([])).code; // => "CLI_FORMAT_UNDETECTED"
detectionError(classifyCandidates(["hl7", "fhir"])).code; // => "CLI_FORMAT_AMBIGUOUS"

errorResult()

errorResult(err): RunResult

Resolve a CliError into a value-free RunResult: empty stdout (nothing reaches the data channel on an error), the rendered diagnostic on stderr, and the error's exit code. The single place the CLI turns an owned error into a result, so every command and the dispatcher render errors identically.

Parameters

err

CliError

The CLI error to resolve.

Returns

RunResult

The value-free RunResult.

Example

import { CliError, CLI_CODES, EXIT, errorResult } from "@cosyte/cli";

errorResult(new CliError(CLI_CODES.CLI_USAGE, EXIT.USAGE, "missing <file>")).exit; // => 2

extractPhiPosture()

extractPhiPosture(argv): object

Resolve the global --unsafe-show-values flag out of an argument vector, order-independently (it may appear before or after the subcommand), and return the posture plus the argv with every occurrence of the flag removed, so each command's own parseArgs never sees it and cannot reject it as unknown. This is the one place the flag is recognised.

Parameters

argv

readonly string[]

The raw arguments (after the program name).

Returns

object

The resolved PhiPosture and the flag-stripped argv.

argv

argv: string[]

posture

posture: PhiPosture

Example

import { extractPhiPosture } from "@cosyte/cli";

extractPhiPosture(["parse", "x.hl7"]).posture.showValues; // => false
extractPhiPosture(["--unsafe-show-values", "parse", "x.hl7"]).posture.showValues; // => true
extractPhiPosture(["parse", "x.hl7", "--unsafe-show-values"]).argv; // => ["parse", "x.hl7"]

extractStableCode()

extractStableCode(e): string | null

Pull a code off a thrown value only when it is a PHI-free constant token (^[A-Z][A-Z0-9_]*$: a letter-led UPPER_SNAKE code like MALFORMED_JSON), e.g. a wrapped parser's stable fatal code. Anything else (no code, a non-string, a non-token, or a pure-digit value that could be a raw identifier) yields null, so a parser exception that embedded input bytes in a code-shaped field can never reach a diagnostic.

Parameters

e

unknown

A caught value.

Returns

string | null

The stable code token, or null.

Example

import { extractStableCode } from "@cosyte/cli";

extractStableCode({ code: "MALFORMED_JSON" }); // => "MALFORMED_JSON"
extractStableCode(new Error("boom")); // => null

fmtCommand()

fmtCommand(args, deps, posture?): Promise<RunResult>

Run the fmt command.

Parameters

args

string[]

The arguments after the fmt subcommand token.

deps

RunDeps

Injected input readers (RunDeps).

posture?

PhiPosture = VALUE_FREE

The resolved PhiPosture (governs only the opt-in unsafe excerpt on a parse-failure diagnostic).

Returns

Promise<RunResult>

A RunResult: the canonical re-serialization on stdout (exit 0), a value-free warning-count note on stderr unless --quiet; an unparseable input is a data error (65) with no partial emit, an unreadable file 66, a bad flag 2.

Throws

Never CliError; may propagate a truly unexpected error for the dispatcher to map.

Example

import { fmtCommand } from "@cosyte/cli";

const deps = {
readFile: async () => new TextEncoder().encode('{ "resourceType":"Patient" , "id":"x" }'),
readStdin: async () => new Uint8Array(),
};
(await fmtCommand(["patient.json"], deps)).exit; // => 0

fmtFormat()

fmtFormat(format, bytes): Promise<FmtResult>

Canonically re-serialize one input of format via the wrapped library's spec-clean serializer. The CLI never re-canonicalizes on its own; the output is exactly the serializer's.

Parameters

format

CosyteFormat

A format for which supportsOp(format, "fmt") is true.

bytes

Uint8Array

The input bytes.

Returns

Promise<FmtResult>

The serialized text + a value-free warning count.

Throws

CLI_PARSER_UNAVAILABLE if the optional parser is absent; the wrapped parser's rejection propagates for the command's value-free failure boundary (no partial emit).

Example

import { fmtFormat } from "@cosyte/cli";

const bytes = new TextEncoder().encode('{ "resourceType":"Patient" , "id":"x" }');
(await fmtFormat("fhir", bytes)).output.startsWith("{"); // => true

formatDiagnostic()

formatDiagnostic(err): string

Render a CliError as a single value-free stderr line: cosyte: <CODE>: <message>. The message is already value-free by the CliError contract; this only prefixes the tool name and the code so scripts and humans can branch on a stable token.

Parameters

err

CliError

The CLI error to render.

Returns

string

The stderr line (no trailing newline).

Example

import { CliError, CLI_CODES, EXIT, formatDiagnostic } from "@cosyte/cli";

formatDiagnostic(new CliError(CLI_CODES.CLI_USAGE, EXIT.USAGE, "missing <file> argument"));
// => "cosyte: CLI_USAGE: missing <file> argument"

formatHl7Position()

formatHl7Position(pos): string

Render an HL7 warning position as a value-free locator string built only from its numeric indices: e.g. seg[3].field[5].comp[1]. No segment content, no field value, ever appears; only the structural coordinates the parser reported.

Parameters

pos

Hl7PositionLike

The HL7 position (segment/field/repetition/component/subcomponent indices).

Returns

string

A value-free locator, e.g. "seg[3].field[5]".

Example

import { formatHl7Position } from "@cosyte/cli";

formatHl7Position({ segmentIndex: 3, fieldIndex: 5 }); // => "seg[3].field[5]"
formatHl7Position({ segmentIndex: 0 }); // => "seg[0]"

formatsSupporting()

formatsSupporting(op): readonly CosyteFormat[]

The formats that support op, as a sorted, value-free list: used to build the "does not support" diagnostic so the user is told which formats do support the operation they asked for.

Parameters

op

Op

The wrapping operation.

Returns

readonly CosyteFormat[]

The supporting format names, sorted.

Example

import { formatsSupporting } from "@cosyte/cli";

formatsSupporting("fmt"); // => ["astm", "ccda", "fhir", "hl7", "ncpdp", "x12"]

inspectCommand()

inspectCommand(args, deps, posture?): Promise<RunResult>

Run the inspect command.

Parameters

args

string[]

The arguments after the inspect subcommand token.

deps

RunDeps

Injected input readers (RunDeps).

posture?

PhiPosture = VALUE_FREE

The resolved PhiPosture (governs only the opt-in unsafe excerpt on a parse-failure diagnostic; the summary itself is always value-free).

Returns

Promise<RunResult>

A RunResult: the value-free structural summary on stdout (human, or JSON under --json), exit 0; a parse failure is a data error (65), an unreadable file 66, a bad flag 2.

Throws

Never CliError; may propagate a truly unexpected error for the dispatcher to map.

Example

import { inspectCommand } from "@cosyte/cli";

const deps = {
readFile: async () => new TextEncoder().encode('{"resourceType":"Patient"}'),
readStdin: async () => new Uint8Array(),
};
(await inspectCommand(["patient.json", "--json"], deps)).exit; // => 0

inspectFormat()

inspectFormat(format, bytes): Promise<InspectSummary>

Build the value-free structural summary of one input of format: counts and structural type codes only, never a field value.

Parameters

format

CosyteFormat

A format for which supportsOp(format, "inspect") is true.

bytes

Uint8Array

The input bytes.

Returns

Promise<InspectSummary>

A InspectSummary variant for the format.

Throws

CLI_PARSER_UNAVAILABLE if the optional parser is absent; the wrapped parser's rejection propagates for the command's value-free failure boundary.

Example

import { inspectFormat } from "@cosyte/cli";

const bytes = new TextEncoder().encode('{"resourceType":"Patient"}');
(await inspectFormat("fhir", bytes)).format; // => "fhir"

loadOptional()

loadOptional<T>(format, load): Promise<T>

Lazy-import an optional parser package, mapping an absent package to a value-free CLI_PARSER_UNAVAILABLE (exit 69): the graceful-degradation path for the optionalDependencies breadth parsers. A genuine import that succeeds passes straight through; any error whose shape is "module not found" becomes the value-free CLI error. Other errors propagate unchanged.

Type Parameters

T

T

The imported module's type.

Parameters

format

CosyteFormat

The format whose optional parser is being loaded (named in the diagnostic).

load

() => Promise<T>

A thunk performing the dynamic import.

Returns

Promise<T>

The imported module.

Throws

CLI_PARSER_UNAVAILABLE (exit 69) when the package is absent; any other error propagates unchanged.

Example

import { loadOptional } from "@cosyte/cli";

// a present parser resolves; an absent one throws CLI_PARSER_UNAVAILABLE
await loadOptional("x12", () => import("@cosyte/x12"));

mapCodesCommand()

mapCodesCommand(args, deps): Promise<RunResult>

Run the map-codes command.

Parameters

args

string[]

The arguments after the map-codes subcommand token.

deps

RunDeps

Injected input readers (RunDeps); the positional argument (or -) is the BYO ConceptMap document.

Returns

Promise<RunResult>

A RunResult: the translation result on stdout (matched target coding(s) or the value-free unmapped signal), a value-free note on stderr (unless --quiet), and an exit code carrying the outcome: 0 mapped · 1 unmapped · 65 unloadable ConceptMap · 66 no input · 2 usage.

Throws

Never CliError; may propagate a truly unexpected error for the dispatcher to map to CLI_INTERNAL.

Example

import { mapCodesCommand } from "@cosyte/cli";

const cm = JSON.stringify({
resourceType: "ConceptMap",
group: [
{
source: "http://hl7.org/fhir/administrative-gender",
target: "http://terminology.hl7.org/CodeSystem/v2-0001",
element: [{ code: "male", target: [{ code: "M", equivalence: "equivalent" }] }],
},
],
});
const deps = {
readFile: async () => new TextEncoder().encode(cm),
readStdin: async () => new Uint8Array(),
};
const r = await mapCodesCommand(
["gender.json", "--system", "http://hl7.org/fhir/administrative-gender", "--code", "male"],
deps,
);
r.exit; // => 0

parseCommand()

parseCommand(args, deps, posture?): Promise<RunResult>

Run the parse command.

Parameters

args

string[]

The arguments after the parse subcommand token.

deps

RunDeps

Injected input readers (RunDeps).

posture?

PhiPosture = VALUE_FREE

The resolved PhiPosture. Defaults to VALUE_FREE; under --unsafe-show-values a bounded excerpt of the offending input is appended to a CLI_PARSE_FAILED diagnostic (the single, opt-in value-echoing surface): single-record mode only.

Returns

Promise<RunResult>

A RunResult: the typed-JSON model (or NDJSON records) on stdout, a value-free note (or nothing) on stderr, and the resolved exit code. Never throws a CliError: it resolves it to a result; unexpected exceptions are caught by the dispatcher and mapped to CLI_INTERNAL.

Throws

Never CliError; may propagate a truly unexpected error for the dispatcher to map.

Example

import { parseCommand } from "@cosyte/cli";

const enc = new TextEncoder();
const deps = {
readFile: async () => enc.encode('{"resourceType":"Patient","id":"x"}'),
readStdin: async () => new Uint8Array(),
};
(await parseCommand(["patient.json"], deps)).exit; // => 0

parseFailureResult()

parseFailureResult(format, bytes, posture, e): RunResult

Build the value-free RunResult for a wrapped-parser rejection: a CLI_PARSE_FAILED data error (exit 65). The stderr line names the format and, when the thrown value carried one, a stable code token in parentheses; it never echoes the parser's message or the input bytes. Under --unsafe-show-values (and only then) a bounded excerpt of the offending input is appended via the single unsafeInputSuffix chokepoint.

Parameters

format

CosyteFormat

The format whose parser rejected the input.

bytes

Uint8Array

The offending input (only consulted for the opt-in unsafe excerpt).

posture

PhiPosture

The resolved PhiPosture; the excerpt is appended only when it opts in.

e

unknown

The caught exception (its code, if a stable token, is surfaced: nothing else).

Returns

RunResult

A value-free CLI_PARSE_FAILED / exit-65 RunResult.

Example

import { parseFailureResult, VALUE_FREE } from "@cosyte/cli";

const bytes = new TextEncoder().encode("not hl7");
parseFailureResult("hl7", bytes, VALUE_FREE, { code: "MISSING_MSH" }).exit; // => 65

parseFormat()

parseFormat(format, bytes): Promise<ParseResult>

Parse one record of format into the wrapped library's model + its value-free warnings. The model is emitted verbatim on the data channel; the CLI adds no parsing of its own.

Parameters

format

CosyteFormat

A format for which supportsOp(format, "parse") is true.

bytes

Uint8Array

The single record's bytes (already de-framed for MLLP: callers pass "hl7" there).

Returns

Promise<ParseResult>

The parsed model + value-free warnings.

Throws

CLI_PARSER_UNAVAILABLE if the optional parser is absent; the wrapped parser's own rejection propagates for the command's value-free failure boundary to catch.

Example

import { parseFormat } from "@cosyte/cli";

const bytes = new TextEncoder().encode('{"resourceType":"Patient","id":"x"}');
(await parseFormat("fhir", bytes)).warnings.length; // => 0

readFileBytes()

readFileBytes(path): Promise<Uint8Array<ArrayBufferLike>>

Read a file into bytes, mapping any read failure to a value-free CLI_NO_INPUT / EXIT.NOINPUT error. The path is structural context (the user supplied it), so it may appear in the message; the file contents never do.

Parameters

path

string

The file path to read.

Returns

Promise<Uint8Array<ArrayBufferLike>>

The file bytes.

Throws

CLI_NO_INPUT (exit 66) when the file is missing, a directory, or unreadable.

Example

import { readFileBytes } from "@cosyte/cli";

await readFileBytes("/no/such/file"); // throws CliError CLI_NO_INPUT

readStreamBytes()

readStreamBytes(stream): Promise<Uint8Array<ArrayBufferLike>>

Drain a readable stream (e.g. process.stdin) into a single byte buffer.

Parameters

stream

Readable

The readable stream to drain.

Returns

Promise<Uint8Array<ArrayBufferLike>>

The concatenated bytes.

Example

import { Readable } from "node:stream";
import { readStreamBytes } from "@cosyte/cli";

const bytes = await readStreamBytes(Readable.from([Buffer.from("MSH|")]));
bytes.length; // => 4

redactCommand()

redactCommand(args): RunResult

Run the redact / deid command.

Parameters

args

string[]

The arguments after the redact/deid subcommand token.

Returns

RunResult

A RunResult. While @cosyte/deid is unavailable: empty stdout, a value-free CLI_NOT_IMPLEMENTED diagnostic on stderr, and exit EX_UNAVAILABLE (69). A malformed invocation (an unknown flag) is a usage error (exit 2). The input is never read.

Example

import { redactCommand } from "@cosyte/cli";

const r = redactCommand(["message.hl7"]);
r.exit; // => 69

resolveInput()

resolveInput(source, formatOverride, deps, op): Promise<InputResolution>

Resolve and read the input, and resolve its format, for a file-consuming command.

Parameters

source

string | undefined

The positional <file|-> argument (or undefined when it was omitted).

formatOverride

string | undefined

The raw --format value, or undefined to autodetect by content.

deps

RunDeps

Injected input readers (RunDeps).

op

Op

The wrapping operation the caller will run; the resolved format is confirmed to support it (else a value-free CLI_FORMAT_UNSUPPORTED naming the supporting formats).

Returns

Promise<InputResolution>

{ ok: true, input } when the bytes read and the format resolved to a parser supporting op; else { ok: false, result } with a value-free usage/no-input/data-error RunResult.

Throws

Propagates a non-CliError read failure unchanged, so the dispatcher maps it to CLI_INTERNAL (a CliError read failure, e.g. a missing file, is caught and returned).

Example

import { resolveInput } from "@cosyte/cli";

const deps = {
readFile: async () => new TextEncoder().encode('{"resourceType":"Patient"}'),
readStdin: async () => new Uint8Array(),
};
const r = await resolveInput("patient.json", undefined, deps, "parse");
if (r.ok) r.input.format; // => "fhir"

run()

run(argv, deps): Promise<RunResult>

Run a full cosyte invocation as data.

Parameters

argv

string[]

The arguments after the program name (i.e. process.argv.slice(2)).

deps

RunDeps

Injected input readers (RunDeps).

Returns

Promise<RunResult>

The RunResult to write to the process streams and exit with.

Example

import { run } from "@cosyte/cli";

const deps = { readFile: async () => new Uint8Array(), readStdin: async () => new Uint8Array() };
const { exit } = await run(["--version"], deps);
exit; // => 0

supportsOp()

supportsOp(format, op): boolean

True iff format's wrapped parser supports op in this build (see OP_SUPPORT).

Parameters

format

CosyteFormat

The resolved format.

op

Op

The wrapping operation.

Returns

boolean

Whether the (format, op) pair is wired.

Example

import { supportsOp } from "@cosyte/cli";

supportsOp("x12", "fmt"); // => true
supportsOp("dicom", "parse"); // => false

toCliError()

toCliError(err): CliError

Coerce an unknown thrown value into a CliError. A CliError passes through; anything else becomes a CLI_INTERNAL / EXIT.SOFTWARE error whose message is a fixed, value-free string: the original message is deliberately discarded so a parser exception that embedded input bytes can never reach stderr.

Parameters

err

unknown

The caught value.

Returns

CliError

A CliError safe to render to stderr.

Example

import { toCliError } from "@cosyte/cli";

toCliError(new Error("boom")).code; // => "CLI_INTERNAL"

unsafeInputSuffix()

unsafeInputSuffix(bytes, posture): string

Build the only value-bearing addition the CLI ever appends to a secondary (stderr) surface: a bounded, single-line excerpt of the offending input, shown iff --unsafe-show-values is set. Under the default value-free posture it returns the empty string, so a diagnostic stays value-free unless the user explicitly opted in. This is the single chokepoint the PHI-leak matrix pins.

Parameters

bytes

Uint8Array

The input the CLI is operating on (only the leading UNSAFE_EXCERPT_MAX bytes are considered).

posture

PhiPosture

The resolved PhiPosture.

Returns

string

"" under the value-free default; otherwise a [unsafe-show-values] … suffix carrying a bounded, newline-flattened prefix of bytes.

Example

import { unsafeInputSuffix, VALUE_FREE, SHOW_VALUES } from "@cosyte/cli";

const bytes = new TextEncoder().encode("bad message");
unsafeInputSuffix(bytes, VALUE_FREE); // => ""
unsafeInputSuffix(bytes, SHOW_VALUES); // => " [unsafe-show-values] offending input …: bad message"

validateCommand()

validateCommand(args, deps, posture?): Promise<RunResult>

Run the validate command.

Parameters

args

string[]

The arguments after the validate subcommand token.

deps

RunDeps

Injected input readers (RunDeps).

posture?

PhiPosture = VALUE_FREE

The resolved PhiPosture (governs only the opt-in unsafe excerpt on a parse-failure diagnostic; a validation verdict is always value-free).

Returns

Promise<RunResult>

A RunResult whose exit code carries the verdict (0 valid / 1 invalid / 65 unparseable / 66 no input / 2 usage). Value-free findings on stderr, or value-free JSON on stdout under --json.

Throws

Never CliError; may propagate a truly unexpected error for the dispatcher to map.

Example

import { validateCommand } from "@cosyte/cli";

const deps = {
readFile: async () => new TextEncoder().encode('{"resourceType":"Patient","gender":"male"}'),
readStdin: async () => new Uint8Array(),
};
(await validateCommand(["patient.json"], deps)).exit; // => 0

validateFormat()

validateFormat(format, bytes): Promise<Verdict>

Run the format's validation surface and return a value-free Verdict. For the Postel's-Law lenient parsers, a parseable input is valid: recovered deviations are non-fatal warnings the library surfaces, never a stricter verdict the CLI invents. FHIR additionally runs validateResource and is invalid on any error/fatal-severity issue.

Parameters

format

CosyteFormat

A format for which supportsOp(format, "validate") is true.

bytes

Uint8Array

The input bytes.

Returns

Promise<Verdict>

The value-free verdict (findings + validity).

Throws

CLI_PARSER_UNAVAILABLE if the optional parser is absent; an unparseable input propagates as the wrapped parser's throw for the command to map to a data error (65).

Example

import { validateFormat } from "@cosyte/cli";

const bytes = new TextEncoder().encode('{"resourceType":"Patient","gender":"male"}');
(await validateFormat("fhir", bytes)).valid; // => true

valueFreeLocator()

valueFreeLocator(pos): string

Render an arbitrary parser position object as a value-free locator string, keeping only number-valued own properties (the parsers' positions are index-only): e.g. { segmentIndex: 3, elementIndex: 2 }segmentIndex[3].elementIndex[2]. A non-number field (which a position should never carry) is dropped, so a stray value can never reach a diagnostic. Falls back to "?" when no numeric index is present.

Parameters

pos

unknown

A parser position object (index-only by the parser's contract).

Returns

string

A value-free locator built solely from numeric indices.

Example

import { valueFreeLocator } from "@cosyte/cli";

valueFreeLocator({ segmentIndex: 3, elementIndex: 2 }); // => "segmentIndex[3].elementIndex[2]"
valueFreeLocator({}); // => "?"