@smile-digital-health/crl 5.0.0 → 5.1.0

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/README.md CHANGED
@@ -6,31 +6,31 @@ Clinical Reasoning Language (CRL) provides a structured way to model clinical de
6
6
 
7
7
  ## Overview
8
8
 
9
- See the [User Guide](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl/USER_GUIDE.md) for a comprehensive introduction to the CRL language, syntax, and authoring best practices. For the **CLI and MCP tool reference** (emit, validate, the MCP tools — for both CRL and CEL), see [TOOLING.md](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl/TOOLING.md).
9
+ See the [User Guide](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl/USER_GUIDE.md) for a comprehensive introduction to the CRL language, syntax, and authoring best practices. For the **CLI and MCP tool reference** (emit, validate, the MCP tools — for both CRL and CEL), see [TOOLING.md](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl/TOOLING.md).
10
10
 
11
11
  CRL is a domain-specific language designed for expressing clinical practice guidelines in a structured and machine-readable format. The language is implemented in TypeScript and provides a comprehensive set of tools for processing CRL documents.
12
12
 
13
13
  ## Metadata annotations
14
14
 
15
- CRL concepts can carry typed metadata via an `@tag` convention on `meta` lines (e.g. `@description`, `@ke-feedback`, `@kg-concept`) — for descriptions, knowledge-engineer feedback, plain-language logic, external-store hints, and extraction provenance. See the [metadata model](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl/spec/metadata-model.md) and the canonical [tag registry](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl/spec/metadata-registry.json). *(Draft: the convention parses today; Validator enforcement is forthcoming.)*
15
+ CRL concepts can carry typed metadata via an `@tag` convention on `meta` lines (e.g. `@description`, `@ke-feedback`, `@kg-concept`) — for descriptions, knowledge-engineer feedback, plain-language logic, external-store hints, and extraction provenance. See the [metadata model](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl/spec/metadata-model.md) and the canonical [tag registry](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl/spec/metadata-registry.json). *(Draft: the convention parses today; Validator enforcement is forthcoming.)*
16
16
 
17
17
  ## Installation
18
18
 
19
19
  The package is publicly available from npm; installation does not require an npm account or token.
20
20
 
21
21
  ```bash
22
- npm install @smile-digital-health/crl@5.0.0
22
+ npm install @smile-digital-health/crl@5.1.0
23
23
  ```
24
24
 
25
25
  For a dependency that accepts compatible CRL5 updates:
26
26
 
27
27
  ```json
28
28
  "dependencies": {
29
- "@smile-digital-health/crl": "^5.0.0"
29
+ "@smile-digital-health/crl": "^5.1.0"
30
30
  }
31
31
  ```
32
32
 
33
- CRL5 is a breaking language transition. Migrate existing content using the current authoring kit before upgrading; a `^4` dependency does not select5.x. The release notes describe the migration and distinguish changes already shipped in4.123.0.
33
+ CRL5.1 changes the public authoring-kit npm and MCP APIs. When upgrading from 5.0.0, update kit calls as described in the [5.1.0 release notes](https://github.com/alphora/clinical-reasoning-language/releases/tag/v5.1.0); the CRL/CEL language and emitted CQL/FHIR are unchanged from 5.0.0. A `^5` dependency permits 5.1.0. Content from before the CRL5 language transition may also need language migration using the current authoring kit.
34
34
 
35
35
  ### For Package Maintainers
36
36
 
@@ -160,7 +160,7 @@ The FSH-to-CRL transformer converts FHIR Shorthand (FSH) files into Clinical Rea
160
160
  - **Deduplication and Suffixing**: Terminology blocks are unique by identifier and body. If a duplicate identifier is encountered with a different body, a numeric suffix (e.g., `_2`) is added to the identifier. If both identifier and body are the same, the block is not duplicated.
161
161
  - **Extraction Logic**: For `medicationCodeableConcept`, the transformer uses `system`, `code`, and `identifier` from the FSH object. For `dynamicValue.expression.expression` (where `path = "code.coding"`), the transformer uses `system` and `code` from the CQL code expression string and `identifier` from the corresponding description.
162
162
 
163
- For more details, see the [User Guide](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl/USER_GUIDE.md) and the technical mapping documentation.
163
+ For more details, see the [User Guide](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl/USER_GUIDE.md) and the technical mapping documentation.
164
164
 
165
165
  ## CLI Tool Usage
166
166
 
@@ -188,7 +188,7 @@ crl-emit --path <root.crl> --out-dir <project-root> --target fhir-def
188
188
 
189
189
  Output lands at `<project-root>/src/fhir/<ResourceType>/<id>.json`. CQL emit (the existing `--target cql` / default behavior) lands at `<project-root>/src/cql/<library-name>.cql`. Library content references the CQL file via the relative path `../../cql/<library-name>.cql`.
190
190
 
191
- For semantic rules, layout details, deliberate spec deviations, and the MCP `emit_crl` tool, see [`USER_GUIDE.md` §"Emitting FHIR Definition resources"](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl/USER_GUIDE.md#emitting-fhir-definition-resources).
191
+ For semantic rules, layout details, deliberate spec deviations, and the MCP `emit_crl` tool, see [`USER_GUIDE.md` §"Emitting FHIR Definition resources"](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl/USER_GUIDE.md#emitting-fhir-definition-resources).
192
192
 
193
193
  ## API Usage & Reference
194
194
 
@@ -490,7 +490,7 @@ Note: This project uses a custom AST implementation that uses ANTLR's visitor pa
490
490
  >
491
491
  > The authoritative release checklist and instructions are maintained in a single location:
492
492
  >
493
- > **[.github/PULL_REQUEST_TEMPLATE/release.md](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/.github/PULL_REQUEST_TEMPLATE/release.md)**
493
+ > **[.github/PULL_REQUEST_TEMPLATE/release.md](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/.github/PULL_REQUEST_TEMPLATE/release.md)**
494
494
  >
495
495
  > Always follow the steps in this file when preparing a new release. This ensures consistency and reduces maintenance overhead. If you need to update the release process, update the PR template only.
496
496
 
@@ -504,7 +504,7 @@ Note: This project uses a custom AST implementation that uses ANTLR's visitor pa
504
504
  - **Generated Files:** Auto-generated files (e.g., ANTLR outputs, grammar-driven types) are ignored by git and should never be edited manually. Always use the provided scripts to regenerate them.
505
505
  - **Documentation:** Keep all documentation referencing the release checklist up-to-date by linking to the PR template.
506
506
 
507
- For more details, see the [release PR template](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/.github/PULL_REQUEST_TEMPLATE/release.md) and the automation scripts in `.github/scripts/`.
507
+ For more details, see the [release PR template](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/.github/PULL_REQUEST_TEMPLATE/release.md) and the automation scripts in `.github/scripts/`.
508
508
 
509
509
  ### Error Handling Strategy
510
510
 
@@ -547,7 +547,7 @@ We provide a Visual Studio Code extension for CRL files:
547
547
  - Comment support
548
548
  - Language basics for a better editing experience
549
549
 
550
- For installation instructions and full details, see [crl-vscode/README.md](https://github.com/alphora/clinical-reasoning-language/blob/v5.0.0/packages/crl-vscode/README.md)
550
+ For installation instructions and full details, see [crl-vscode/README.md](https://github.com/alphora/clinical-reasoning-language/blob/v5.1.0/packages/crl-vscode/README.md)
551
551
 
552
552
  ## License
553
553
 
@@ -0,0 +1,7 @@
1
+ {
2
+ "auditedRevision": "451be38f1fc33723cfe44eec12c1add689c5c52b",
3
+ "auditedSchemaVersion": "2.0",
4
+ "auditedContentHash": "e9870c0042e7cb2e76a66d10b0edc72056786e0a53ccb73dc417544c8753c8b2",
5
+ "scope": "Unified kit schema 2.0: all 32 rules, 15 examples, 13 artifacts and retrieval/export; incremental maintenance from 345af5782c61188b11de87b788aecf0276421f1a. Existing 301-file survey retained with explicit limitations; changed guidance/test/tooling scope reviewed in the evidence ledger. No new native-engine or clinical-fidelity certification.",
6
+ "evidence": "packages/crl/src/authoring-kit/tests/coverage.md"
7
+ }
@@ -0,0 +1,6 @@
1
+ import type { AuthoringKit } from "./types";
2
+ export declare function assertAuditedKit(kit: AuthoringKit): void;
3
+ export declare function exportAuthoringKit(kit: AuthoringKit): {
4
+ json: string;
5
+ markdown: string;
6
+ };
@@ -0,0 +1,49 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.assertAuditedKit = assertAuditedKit;
4
+ exports.exportAuthoringKit = exportAuthoringKit;
5
+ const node_crypto_1 = require("node:crypto");
6
+ function assertAuditedKit(kit) {
7
+ const { contentHash, audit, ...content } = kit;
8
+ const actual = (0, node_crypto_1.createHash)("sha256").update(JSON.stringify(content)).digest("hex");
9
+ const scopeSchema = new RegExp("\\bschema\\s+" + kit.schemaVersion.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") + "(?![\\d.])", "i");
10
+ if (actual !== contentHash || audit.auditedContentHash !== actual ||
11
+ audit.auditedSchemaVersion !== kit.schemaVersion || !audit.contentMatchesAudit ||
12
+ !/^[0-9a-f]{40}$/.test(audit.auditedRevision) || !scopeSchema.test(audit.scope) || !audit.evidence.trim()) {
13
+ throw new Error("Kit export requires a completed audit matching this schema and content. Follow crl-kit-update; a build must not advance the stamp.");
14
+ }
15
+ }
16
+ const title = (key) => key.replace(/([a-z])([A-Z])/g, "$1 $2").replace(/^./, c => c.toUpperCase());
17
+ const prose = (value) => String(value).replace(/(`+)([\s\S]*?)\1|<[^>\n]+>/g, (match, ticks) => ticks ? match : match.replace(/</g, "\\<").replace(/>/g, "\\>"));
18
+ function render(value, depth, language = "text") {
19
+ if (value === null || typeof value !== "object")
20
+ return `${prose(value)}\n\n`;
21
+ if (Array.isArray(value))
22
+ return value.map((item, i) => {
23
+ if (item === null || typeof item !== "object")
24
+ return `- ${prose(item)}\n`;
25
+ const record = item;
26
+ const name = record.title ?? record.name ?? record.id ?? record.check ?? record.tier ?? `Item ${i + 1}`;
27
+ return `${"#".repeat(Math.min(depth, 6))} ${prose(name)}\n\n${render(item, depth + 1, language)}`;
28
+ }).join("\n") + "\n";
29
+ const record = value;
30
+ const sourceLanguage = typeof record.language === "string" ? record.language : language;
31
+ return Object.entries(record).filter(([, item]) => item !== undefined).map(([key, item]) => {
32
+ const heading = `${"#".repeat(Math.min(depth, 6))} ${title(key)}\n\n`;
33
+ if ((key === "source" || key === "snippet") && typeof item === "string") {
34
+ const longest = Math.max(2, ...(item.match(/`+/g) ?? []).map(run => run.length));
35
+ const fence = "`".repeat(longest + 1);
36
+ return `${heading}${fence}${sourceLanguage}\n${item}\n${fence}\n\n`;
37
+ }
38
+ return heading + render(item, depth + 1, sourceLanguage);
39
+ }).join("");
40
+ }
41
+ function exportAuthoringKit(kit) {
42
+ assertAuditedKit(kit);
43
+ return {
44
+ json: JSON.stringify(kit, null, 2) + "\n",
45
+ markdown: "# CRL authoring kit\n\nGenerated from the canonical kit. The JSON companion preserves its machine-readable structure. " +
46
+ "The audit identifies reviewed content; it does not certify later implementation changes or clinical fidelity.\n\n" + render(kit, 2),
47
+ };
48
+ }
49
+ //# sourceMappingURL=export.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"export.js","sourceRoot":"","sources":["../../src/authoring-kit/export.ts"],"names":[],"mappings":"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"}
@@ -1,11 +1,3 @@
1
- import type { AuthoringEdge, AuthoringKit, AuthoringStage, AuthoringUseCase } from "./types";
2
- export type { AuthoringEdge, AuthoringKit, AuthoringStage, AuthoringUseCase, KitFacet, } from "./types";
3
- export declare const DEFAULT_STAGE: AuthoringStage;
4
- export declare const STAGES: readonly AuthoringStage[];
5
- export declare const DEFAULT_USE_CASE: AuthoringUseCase;
6
- export declare const USE_CASES: Record<AuthoringUseCase, {
7
- label: string;
8
- chain: readonly AuthoringEdge[];
9
- }>;
10
- export declare const USE_CASE_NAMES: readonly AuthoringUseCase[];
11
- export declare function getAuthoringKit(stage?: string, useCase?: string): AuthoringKit;
1
+ import type { AuthoringKit } from "./types";
2
+ export type { AuthoringKit, } from "./types";
3
+ export declare function getAuthoringKit(): AuthoringKit;