Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
57 commits
Select commit Hold shift + click to select a range
f3e5474
Add version scope model
GinoCanessa Aug 31, 2026
988732c
Add scoped candidate ranking to FHIRDefinitions
GinoCanessa Aug 31, 2026
dc3341f
Install version scopes during dependency loading
GinoCanessa Sep 1, 2026
6c6cd17
Resolve exported artifacts in their own version scope
GinoCanessa Sep 1, 2026
617f2db
Format version scope model to repository style
GinoCanessa Sep 1, 2026
b6130c9
Rank unlisted resource types last in scoped fishing
GinoCanessa Sep 1, 2026
aedd5fc
Discriminate package versions in version-scoped dependency bands
GinoCanessa Sep 1, 2026
0b0e0ca
Match Type/id inclusion entries for instance scope keys
GinoCanessa Sep 1, 2026
5e33eee
Agents guide file updates
GinoCanessa Sep 2, 2026
261e7ab
Delete the unused packageOrderForVersions accessor
GinoCanessa Sep 14, 2026
ece52d8
Accept the Publisher's two-part version family tokens
GinoCanessa Sep 14, 2026
3f1de8a
Read version scope parameters from R5 Coding codes
GinoCanessa Sep 14, 2026
f32b124
Report discarded version scope configuration
GinoCanessa Sep 14, 2026
b0d0846
Load the packages named by per-version dependency overrides
GinoCanessa Sep 14, 2026
e6a99b4
Derive scope key urls from the FSH definition
GinoCanessa Sep 14, 2026
c50b2ff
Enforce a synchronous-only contract on inVersionScopeOf
GinoCanessa Sep 14, 2026
00f5c25
Unify the scoped lookup path across the fishing methods
GinoCanessa Sep 14, 2026
dd8db92
Demote the authored coordinate replaced by a version override
GinoCanessa Sep 14, 2026
eb3beb9
Don't strip invalid characters from ImplementationGuide name (#1639)
cpruijsen Sep 17, 2026
d623e96
Fix missing null-padded value arrays on repeating primitives (#1638)
cpruijsen Sep 18, 2026
2a6ef3d
Improve performance with large CodeSystems (#1637)
vadi2 Sep 30, 2026
4140f8d
Fix misleading error when a flag is used on an only rule (#1643)
drlalithapranathi Oct 10, 2026
5af148f
Add more tests for the fshToFhir API (#1642)
drlalithapranathi Oct 10, 2026
4f59135
Record the profile when its id is the same as the type it profiles (#…
AltangerelG Oct 10, 2026
648ef14
Restore logger state after each fshToFhir call (#1646)
cpruijsen Oct 15, 2026
6cd9a32
Allow ig.ini to have other sections in addition to [IG] (#1650)
cmoesel Oct 15, 2026
9ed4147
Dependency Updates: October 2026 (#1651)
cmoesel Oct 15, 2026
9659060
v3.21.0
cmoesel Oct 15, 2026
fe04d75
Share effective version dependency selection
GinoCanessa Oct 15, 2026
84323d2
Preserve automatic dependency priority across version scopes
GinoCanessa Oct 15, 2026
55b0c8c
Add identity-safe version scope primitives
GinoCanessa Oct 15, 2026
f2461d1
Resolve instance version membership before materialization
GinoCanessa Oct 15, 2026
333b243
Clarify artifact scope keys and exported identifier reporting
GinoCanessa Oct 15, 2026
6b3f5b2
Add version scope model
GinoCanessa Aug 31, 2026
8c0bd28
Add scoped candidate ranking to FHIRDefinitions
GinoCanessa Aug 31, 2026
c86115f
Install version scopes during dependency loading
GinoCanessa Sep 1, 2026
0446b98
Resolve exported artifacts in their own version scope
GinoCanessa Sep 1, 2026
f0164f9
Format version scope model to repository style
GinoCanessa Sep 1, 2026
115e89f
Rank unlisted resource types last in scoped fishing
GinoCanessa Sep 1, 2026
3834975
Discriminate package versions in version-scoped dependency bands
GinoCanessa Sep 1, 2026
e101650
Match Type/id inclusion entries for instance scope keys
GinoCanessa Sep 1, 2026
8e61b3e
Agents guide file updates
GinoCanessa Sep 2, 2026
1d4df54
Delete the unused packageOrderForVersions accessor
GinoCanessa Sep 14, 2026
dc3825f
Accept the Publisher's two-part version family tokens
GinoCanessa Sep 14, 2026
c0ddded
Read version scope parameters from R5 Coding codes
GinoCanessa Sep 14, 2026
81f82b6
Report discarded version scope configuration
GinoCanessa Sep 14, 2026
f086dd5
Load the packages named by per-version dependency overrides
GinoCanessa Sep 14, 2026
51041c4
Derive scope key urls from the FSH definition
GinoCanessa Sep 14, 2026
e1fd9c2
Enforce a synchronous-only contract on inVersionScopeOf
GinoCanessa Sep 14, 2026
ae6b345
Unify the scoped lookup path across the fishing methods
GinoCanessa Sep 14, 2026
190de4c
Demote the authored coordinate replaced by a version override
GinoCanessa Sep 14, 2026
9659e5b
Share effective version dependency selection
GinoCanessa Oct 15, 2026
63d993a
Preserve automatic dependency priority across version scopes
GinoCanessa Oct 15, 2026
317ecc0
Add identity-safe version scope primitives
GinoCanessa Oct 15, 2026
b93c009
Resolve instance version membership before materialization
GinoCanessa Oct 15, 2026
83139c3
Clarify artifact scope keys and exported identifier reporting
GinoCanessa Oct 15, 2026
53a0e9c
Merge branch 'multi-version' of github.com:FHIR/sushi into multi-version
GinoCanessa Oct 16, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
73 changes: 73 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# AGENTS.md — SUSHI Codebase Guide

Canonical, machine-readable conventions for automated agents working in **SUSHI**.

**Precedence.** This file is authoritative for commands, conventions, and invariants an agent must follow. [`CONTRIBUTING.md`](CONTRIBUTING.md) and [`BEST-PRACTICES.md`](BEST-PRACTICES.md) are authoritative for contribution process and coding rationale; [`README.md`](README.md) is authoritative for user-facing behavior and configuration reference. Look there for the "why". If this file contradicts the repository itself, the repository wins — fix this file.

## What this project is

SUSHI ("SUSHI Unshortens Short Hand Inputs") is a TypeScript CLI compiler and library that converts FHIR Shorthand (FSH) source files into FHIR R4/R4B/R5 JSON artifacts (StructureDefinitions, CodeSystems, ValueSets, Instances, etc.) for use in FHIR Implementation Guides (IGs).
Expand Down Expand Up @@ -43,6 +47,42 @@ dist/ Compiled output (do not edit)

Always run `npm run check` before submitting a PR.

Note that `npm run lint` runs a full emitting `tsc` before ESLint, so it writes `dist/`. `npm run lint:fix` uses `tsc --noEmit` and does not.

### Running a subset of tests

The runner is **Jest** (`jest.config.js`, `testMatch: **/test/**/*.test.(ts|js)`). Prefer the smallest command that covers the change; escalate to the full suite only when the focused run indicates you need to.

```
npm test # full suite
npm test -- test/fshtypes/rules/CardRule.test.ts # scoped: one file or path
npm test -- <path> -t "<test name substring>" # focused: one describe/it
```

Everything after `--` is passed through to Jest, so `-t`, `--testPathPattern`, and `--watch` all work. Coverage is collected on every run unless `CI=true` is set in the environment; set it to speed up focused runs.

## Toolchain pins

- **Node 22** — pinned in `.nvmrc` (`22`) and `.tool-versions` (`nodejs 22.21.1`). That is the development version; several dependencies are deliberately held back so SUSHI still runs on **Node 18** (see "Dependency constraints").
- **TypeScript**, configured in `tsconfig.json`: `target` ES2018, `module` **commonjs**, `lib` ES2020 + DOM, `outDir` `dist`, `declaration` and `sourceMap` on, `esModuleInterop` on, `resolveJsonModule` on. Only `src/**/*` is included.
- **Strictness is partial and deliberate**: `noImplicitAny` is on; `strict` and `strictNullChecks` are **off**. Do not turn them on as a drive-by change. `test/tsconfig.json` extends the root config and adds `strictNullChecks: false`, `noEmit: true`, `types: ["jest", "node"]`.
- Warnings are **not** errors, but `npm run lint` runs `tsc` first, so any type error fails lint.

## Run

SUSHI is a CLI whose entry point is `dist/app.js` (`bin.sushi`); the library entry is `dist/index.js`. Build first, then run:

```
npm run build
node dist/app.js <path-to-fsh-project> -o <output-dir>
```

To run without building:

```
npx ts-node src/app.ts <path-to-fsh-project> -o <output-dir>
```

## Architecture: the compile pipeline

FSH source → **import** → **tank** → **export** → FHIR JSON
Expand Down Expand Up @@ -115,10 +155,43 @@ Do **not** bump these without reading `DEPENDENCY-NOTES.md` and understanding th
- ESLint + Prettier enforce formatting. Run `npm run lint:fix && npm run prettier:fix` after changes.
- Prefer self-explanatory code; add comments only for non-obvious constraints or workarounds.
- Do not use ESM-only packages (the build target is CommonJS).
- Formatting is defined by `.prettierrc`: single quotes, no trailing commas, `printWidth` 100, `tabWidth` 2, `arrowParens: "avoid"`, `endOfLine: "auto"`. It is enforced by `npm run prettier`, not by the build.
- Match the surrounding file. Consistency with neighbouring code beats any general preference.

### Architectural invariants

These are decisions, not preferences. Violating one is a review Blocker.

- **CommonJS only.** `tsconfig.json` sets `"module": "commonjs"`, so an ESM-only dependency breaks the build and the published package. This is why the packages in "Dependency constraints" are pinned; read `DEPENDENCY-NOTES.md` before touching any of them.
- **Node 18 must keep working at runtime**, even though development is on Node 22. Do not adopt APIs or dependencies that require a newer runtime floor.
- **Generated parser code is not hand-edited.** `src/import/generated/` comes from the ANTLR grammar in `antlr/src/main/antlr4/FSH.g4` via `npm run build:grammar` (requires Java/Gradle). Change the grammar, regenerate — never patch the output. It is excluded from coverage for the same reason.
- **`dist/` is build output.** Never edit it; it is regenerated by `npm run build` and deleted by `del-cli` at the start of every build.
- **Fishing is the lookup mechanism.** Resolve artifacts through the `Fishable` interface / `MasterFisher` rather than reaching into `FSHTank` or `FHIRDefinitions` directly.

## FHIR/FSH domain knowledge

- FSH supports FHIR R4, R4B, and R5. Version-specific handling lives in `src/utils/FHIRVersionUtils.ts` and `src/fhirdefs/R5DefsForR4/`.
- FHIR canonical URLs uniquely identify artifacts; `valid-url` is used to validate them.
- "Slicing" is a core FHIR concept for constraining arrays of elements; its complexity is concentrated in `ElementDefinition.ts` and `StructureDefinitionExporter.ts`.
- The `Fishable` interface (`src/utils/Fishable.ts`) and its `Type` enum are the primary lookup mechanism throughout the codebase.

## Commit conventions

**SUSHI does not use conventional commits.** Do not write `feat(scope): …` or `fix(scope): …` here — it does not match the history and will look out of place.

- **Subject**: imperative, sentence case, no type prefix, target ≤ 72 characters. Real examples from `master`: `Fix processing of slices on choice elements`, `Replace extract zip`, `Make copyrightYear and releaseLabel optional`.
- **Do not hand-append `(#NNNN)`.** PRs are squash-merged and GitHub appends the PR number to the subject automatically. Local phase commits carry a bare subject.
- **Trailers**: `Co-authored-by: Name <email>` is used in this repository and should be included when applicable, after a blank line at the end of the message.
- One logical change per commit.
- Agents **do not push** and **do not open pull requests** unless the user explicitly asks. See "Agent guardrails".

## Agent guardrails

- Read this file before proposing any build, test, or lint command. **Never invent a command.** If something you need is not documented here, say so rather than guessing.
- Prefer the smallest targeted verification that covers the change; escalate to the full suite only when the targeted run indicates it is needed. The full suite is large — use the scoped and focused forms above.
- Do not add new linting, building, or testing tooling without being asked.
- **Do not hand-edit generated or build output**: `src/import/generated/` (regenerate via `npm run build:grammar`) and `dist/` (regenerate via `npm run build`).
- **Do not bump a pinned dependency** listed under "Dependency constraints" without reading `DEPENDENCY-NOTES.md` and stating why the constraint no longer applies.
- Do not enable `strict` or `strictNullChecks` as a side effect of another change; that is a project-wide decision with a large blast radius.
- Regression tests (`npm run regression`) hit real-world IG repositories over the network and are slow. Run them only when asked or when the change plausibly affects IG output.

Loading
Loading