sheetom 0.1.0-rc.7 → 0.1.0-rc.8

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.
Files changed (51) hide show
  1. package/README.md +127 -234
  2. package/dist/index.cjs +78 -48
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +746 -27
  5. package/dist/index.d.ts +746 -27
  6. package/dist/index.js +78 -48
  7. package/dist/index.js.map +1 -1
  8. package/docs/api.md +6 -3
  9. package/engine-abi.json +2 -2
  10. package/package.json +82 -83
  11. package/compatibility/WPT-LICENSE.md +0 -15
  12. package/compatibility/baselines/0.1.0-rc.0.json +0 -70
  13. package/compatibility/baselines/0.1.0-rc.1.json +0 -108
  14. package/compatibility/baselines/0.1.0-rc.2.json +0 -142
  15. package/compatibility/baselines/0.1.0-rc.3.json +0 -2541
  16. package/compatibility/baselines/0.1.0-rc.4.json +0 -2541
  17. package/compatibility/baselines/0.1.0-rc.5.json +0 -3111
  18. package/compatibility/baselines/0.1.0-rc.6.json +0 -3211
  19. package/compatibility/baselines/0.1.0-rc.7.json +0 -3386
  20. package/compatibility/baselines/README.md +0 -3
  21. package/compatibility/browser-geometric-contracts.json +0 -93
  22. package/compatibility/native-grammar-inventory.json +0 -1810
  23. package/compatibility/number-result-math-capabilities.json +0 -11380
  24. package/compatibility/numeric-property-contracts.json +0 -23
  25. package/compatibility/schemas/browser-geometric-contracts.schema.json +0 -39
  26. package/compatibility/schemas/browser-longhand-composite-contracts.schema.json +0 -39
  27. package/compatibility/schemas/browser-longhand-keyword-contracts.schema.json +0 -51
  28. package/compatibility/schemas/compatibility-report.schema.json +0 -490
  29. package/compatibility/schemas/compatibility-resolutions.schema.json +0 -28
  30. package/compatibility/schemas/function-rule-cases.schema.json +0 -49
  31. package/compatibility/schemas/native-grammar-inventory.schema.json +0 -134
  32. package/compatibility/schemas/number-result-math-corpus.schema.json +0 -71
  33. package/compatibility/schemas/numeric-property-contracts.schema.json +0 -37
  34. package/compatibility/schemas/operation-fixture.schema.json +0 -87
  35. package/compatibility/schemas/property-grammar-extensions.schema.json +0 -51
  36. package/compatibility/schemas/property-value-observations.schema.json +0 -43
  37. package/compatibility/schemas/property-value-probes.schema.json +0 -26
  38. package/compatibility/schemas/relative-color-corpus.schema.json +0 -90
  39. package/compatibility/schemas/shorthand-capability-corpus.schema.json +0 -76
  40. package/compatibility/schemas/shorthand-grammar-contracts.schema.json +0 -53
  41. package/compatibility/schemas/shorthand-grammar-observations.schema.json +0 -43
  42. package/compatibility/schemas/value-capability-corpus.schema.json +0 -52
  43. package/compatibility/schemas/webref-branch-ratchet.schema.json +0 -48
  44. package/compatibility/schemas/webref-property-branches.schema.json +0 -158
  45. package/compatibility/schemas/webref-semantic-terminals.schema.json +0 -38
  46. package/compatibility/schemas/wpt-mappings.schema.json +0 -47
  47. package/compatibility/shorthand-capabilities.json +0 -5231
  48. package/compatibility/shorthand-grammar-contracts.json +0 -223
  49. package/compatibility/shorthand-grammar-observations.json +0 -4898
  50. package/compatibility/value-capabilities.json +0 -2649
  51. package/docs/releasing.md +0 -51
package/README.md CHANGED
@@ -1,73 +1,36 @@
1
1
  # SheetOM
2
2
 
3
- SheetOM is a mutable, browser-shaped CSS authoring object model for Node.js,
4
- Bun, and Deno. Its repository-owned Rust engine handles parsing,
5
- canonicalization, declaration state, and safe CSS serialization; JavaScript
6
- only owns the public WebIDL-shaped facade and live object identity.
3
+ **A browser-compatible, mutable CSSOM for JavaScript outside the browser.**
7
4
 
8
- It is intended for server-side stylesheet editing and serialization. It does
9
- not implement the DOM, cascade, selector matching, layout, or computed styles.
5
+ SheetOM lets build tools, publishers, and server applications parse, inspect,
6
+ mutate, and serialize stylesheets with familiar browser APIs. It preserves
7
+ browser recovery behavior for malformed-but-accepted CSS while still producing
8
+ deterministic, reparsable stylesheet output.
9
+
10
+ - Browser-shaped `CSSStyleSheet`, rules, and declarations
11
+ - Transactional `setProperty()` behavior and correct shorthand/longhand state
12
+ - Forgiving whole-sheet parsing without a DOM or global installation
13
+ - One repository-owned Rust engine for native and WebAssembly backends
14
+ - ESM, CommonJS, TypeScript, Node.js, Bun, Deno, browsers, and workers
15
+
16
+ SheetOM focuses on the **Authoring CSSOM**. It does not implement the cascade,
17
+ selector matching, layout, computed styles, fetching, or DOM attachment.
10
18
 
11
19
  ## Install
12
20
 
13
- Install the active release:
21
+ For Node.js, Bun, or Deno:
14
22
 
15
23
  ```sh
16
24
  npm install sheetom
17
25
  ```
18
26
 
19
- After the first stable release, use `npm install sheetom@next` to opt into an
20
- active prerelease. Until then, the `latest` and `next` dist-tags both identify
21
- the active release candidate.
22
-
23
- The root package has no JavaScript runtime or peer dependencies and contains no
24
- native addon. It pins one matching `@sheetom/native-*` implementation as an
25
- optional dependency, so npm installs only the binary for the current operating
26
- system, CPU, and Linux libc. Installing with `--omit=optional` is unsupported
27
- and produces an explicit missing-binding error rather than a behavioral
28
- fallback. The native engine includes a pinned, locally maintained Lightning CSS
29
- source snapshot; consumers do not install a second parser, provide globals, or
30
- select a fallback engine.
31
- SheetOM owns observable-value serialization and shorthand expansion rather
32
- than delegating CSSOM state to a browser-DOM emulation package.
33
-
34
- Node.js 22 executes the exact published package on macOS arm64/x64, Windows
35
- arm64/x64/x86, Linux glibc arm64/ARMv7/x64/ppc64le/s390x, and Linux musl
36
- arm64/ARMv7/x64. Node.js 24 is additionally tested on Linux x64, Windows x64,
37
- and macOS arm64. Bun 1.3.1 and Deno 2.9.5 are tested on Linux x64. Deno must use a local
38
- `node_modules` directory and grant SheetOM's native binding FFI and
39
- system-information permissions:
40
-
41
- ```sh
42
- deno run --node-modules-dir=manual --allow-ffi --allow-sys app.ts
43
- ```
44
-
45
- SheetOM exports browser-named classes but never modifies `globalThis`.
46
-
47
- Browser applications can install the separate, ESM-only WebAssembly backend:
27
+ For browsers and compatible JavaScript isolates:
48
28
 
49
29
  ```sh
50
30
  npm install @sheetom/wasm
51
31
  ```
52
32
 
53
- ```ts
54
- import { createSheetOM } from "@sheetom/wasm";
55
-
56
- const { CSSStyleSheet } = await createSheetOM();
57
- const sheet = new CSSStyleSheet();
58
- sheet.replaceSync(".card { color: red; }");
59
- ```
60
-
61
- `createSheetOM()` resolves the `.wasm` file relative to its own module and
62
- shares concurrent default initialization within one JavaScript realm. Passing
63
- an explicit `URL`, `Response`, `ArrayBuffer`, or `WebAssembly.Module` creates
64
- an independent facade with distinct class identity. The WASM backend uses the
65
- same Rust parser, Engine ABI Identity, Resource Budget, and CSSOM facade as the
66
- native package; it is never an automatic fallback for a missing native addon.
67
- See [`@sheetom/wasm` usage](./packages/wasm/README.md) for server and worker
68
- requirements.
69
-
70
- ## Use
33
+ ## Quick start
71
34
 
72
35
  ```ts
73
36
  import { CSSStyleRule, CSSStyleSheet, parseStyleSheet } from "sheetom";
@@ -77,41 +40,42 @@ sheet.replaceSync(".card { width: 12px; }");
77
40
 
78
41
  const rule = sheet.cssRules[0];
79
42
  if (rule instanceof CSSStyleRule) {
80
- rule.style.setProperty("padding", "8px 16px");
81
- rule.style.setProperty("background-color", "rebeccapurple");
43
+ rule.style.padding = "8px 16px";
44
+ rule.style.backgroundColor = "rebeccapurple";
45
+ rule.style.setProperty("--card-gap", "12px");
82
46
  }
83
47
 
84
48
  console.log(sheet.serialize());
85
49
 
86
- const existing = parseStyleSheet('@import "theme.css"; .card { color: red; }', {
87
- href: "https://example.com/assets/app.css",
88
- });
50
+ const existing = parseStyleSheet(
51
+ '@import "theme.css"; .card { color: red; }',
52
+ { href: "https://example.com/assets/app.css" },
53
+ );
54
+
89
55
  console.log(existing.cssRules.length); // 2
90
56
  ```
91
57
 
92
- `setProperty()` is the standard, fully typed way to set a declaration,
93
- especially when its name is dynamic. Browser-style camelCase assignments such
94
- as `rule.style.backgroundColor = "rebeccapurple"` work at runtime, but the
95
- current TypeScript declarations do not enumerate every named CSS property.
58
+ Named CSS properties are typed and assignable directly. Use `setProperty()`
59
+ when a property name is dynamic, custom, or hyphenated. `CSSStyleSheet` is the
60
+ only public CSSOM constructor; rules and declarations come from a sheet, just
61
+ as they do in browsers.
96
62
 
97
- Constructed sheets follow browser replacement behavior and strip `@import`.
98
- `parseStyleSheet` creates a regular authoring sheet and preserves valid imports
99
- without loading them.
63
+ Constructed sheets strip `@import` during replacement. `parseStyleSheet()` is a
64
+ SheetOM extension for existing regular stylesheets and preserves valid imports
65
+ without fetching them.
100
66
 
101
- ## Recovered values and reparsable serialization
67
+ ## Browser recovery, safe output
102
68
 
103
- SheetOM distinguishes browser-facing CSSOM text from reparsable stylesheet
104
- output. Chromium accepts some values using CSS Syntax end-of-input recovery
105
- while preserving the unclosed input in `getPropertyValue()` and `cssText`:
69
+ Browsers accept some CSS using end-of-input recovery and expose the incomplete
70
+ spelling through CSSOM. SheetOM keeps that observable behavior separate from
71
+ whole-sheet output:
106
72
 
107
73
  ```ts
108
74
  const sheet = new CSSStyleSheet();
109
75
  sheet.insertRule(".card {}");
110
76
 
111
77
  const rule = sheet.cssRules[0];
112
- if (!(rule instanceof CSSStyleRule)) {
113
- throw new TypeError("Expected a style rule");
114
- }
78
+ if (!(rule instanceof CSSStyleRule)) throw new TypeError("Expected a style rule");
115
79
 
116
80
  rule.style.setProperty("padding", "72px var(--space, var(--space,");
117
81
 
@@ -122,176 +86,105 @@ rule.style.cssText;
122
86
  // "padding: 72px var(--space, var(--space,;"
123
87
 
124
88
  sheet.serialize();
125
- // reparsable CSS with the missing syntax repaired
89
+ // reparsable CSS with the missing syntax safely confined and repaired
126
90
  ```
127
91
 
128
- The three text surfaces have distinct contracts:
129
-
130
- | Surface | Contract |
92
+ | Surface | Purpose |
131
93
  | --- | --- |
132
- | `rule.style.cssText` | Browser-compatible observable declaration text, including accepted recovery quirks. |
133
- | `rule.cssText` | Browser-compatible observable text for one rule and its current descendants. |
134
- | `sheet.serialize()` | Deterministic, reparsable stylesheet output with recoverable syntax confined to its declaration or rule. |
135
-
136
- Reparsable serialization means that the output can be parsed again without one
137
- declaration leaking into the next declaration or rule, while preserving the
138
- valid semantic state owned by SheetOM. It does not sanitize URLs, enforce CSP,
139
- block remote resources, or make valid hostile CSS safe to render.
140
-
141
- Invalid `setProperty` values and priorities are atomic no-ops, matching browser
142
- behavior. Opt into mutation diagnostics with `{ diagnostics: true }` and drain
143
- them using `takeDiagnostics()`. `SheetOMDiagnostic.code` is a stable string
144
- union. Diagnostics retain the complete rejected input until drained; when
145
- processing untrusted or very large input, callers should leave diagnostics off
146
- or drain them promptly to bound memory use.
147
-
148
- Static shorthands are owned as canonical longhand records. Updating or removing
149
- one longhand can therefore never reactivate an older shorthand value. Shorthand
150
- getters and `cssText` are synthesized only while the complete current longhand
151
- set has compatible values and priorities; genuinely deferred substitutions
152
- retain separate provenance until a longhand mutation breaks their group.
153
-
154
- The Chromium 151 compatibility baseline covers all 129 manifested
155
- multi-longhand shorthands. Grammar depth is a finite reviewed contract rather
156
- than a claim to implement every future CSS production: 24 codec profiles
157
- currently carry 96 positive and neighboring-negative branch cases, including
158
- cardinality, slash and comma lists, compound optional keywords, mutation
159
- atomicity, and reparsable round-trips. CI reprobes those cases against the
160
- pinned Chromium engine, and a release is blocked unless all 129 breadth seeds
161
- and all 96 reviewed branches pass exactly. The contracts and browser
162
- observations ship as audit evidence but are never imported as runtime value
163
- authority.
164
-
165
- Relative colors use the same typed engine rather than a text fallback. The
166
- pinned Chromium 151 and WPT corpus contains 1,146 accepted and 160 rejected
167
- branches across `rgb()`, `hsl()`, `hwb()`, Lab, LCH, predefined color spaces,
168
- channel calculations, missing components, and nested color functions. CI
169
- compares all 1,306 browser-facing getters in one batched browser session and
170
- also requires every accepted value to survive reparsable serialization.
171
-
172
- ## API scope
173
-
174
- - `CSSStyleSheet`, live `CSSRuleList`, `CSSRule`, and `MediaList`
175
- - nested `CSSStyleRule`, `CSSGroupingRule`, and `CSSConditionRule`
176
- - media, supports, container, layer, scope, and starting-style rules
177
- - import, font-face, page/margin, nested-declaration, and position-try rules
178
- - keyframes and mutable keyframe rules
179
- - counter-style descriptors and font-feature-value maps
180
- - custom `@function` parameters, return types, conditional groups, and live
181
- function descriptors
182
- - live indexed and named `CSSStyleDeclaration`
183
- - `insertRule`, `deleteRule`, `replace`, and `replaceSync`
184
- - `parseStyleSheet` for forgiving regular-sheet parsing
185
- - browser-facing `cssText` and reparsable `serialize()` output
186
- - generic retention of read-only metadata rules and experimental/future rules
187
-
188
- SheetOM targets standards and shared browser behavior first, with Chromium
189
- behavior used only as the final measured divergence fallback. Versioned JSON
190
- Operation Fixtures execute through SheetOM and native browser adapters;
191
- applicable WPT subtests retain their pinned source path, title, and blob SHA.
192
- Every release ships its machine-readable Compatibility Report. RC7-or-later
193
- reports distinguish native and WebAssembly backend evidence; the WASM dimension
194
- records direct HTTP, worker, bundler, memory-soak, and Publisher-shaped browser
195
- results instead of inferring them from the shared Rust engine.
196
-
197
- Modern or implementation-dependent value grammar is bounded by the checked-in
198
- [`Value Capability Corpus`](./compatibility/value-capabilities.json). Each
199
- measured family includes accepted and rejected neighboring cases; browser
200
- probing occurs only during conformance work and never at runtime.
201
- The corpus includes 94 CSS Math branches across number, integer, length,
202
- percentage, angle, and time contexts. It locks dimensional rejection,
203
- mixed-unit ordering, non-finite constants, function arity, CSSOM observable
204
- serialization, and atomic failure to Chromium 151.
205
-
206
- Computed-context number results are covered separately by the checked-in
207
- [`Number Result Math Corpus`](./compatibility/number-result-math-capabilities.json).
208
- It records 860 batched Chromium observations across all 70 accepting
209
- properties, including relative lengths, percentages, dynamic products and
210
- quotients, dimension-result neighbors, invalid dimensional multiplication,
211
- CSSOM expansion, declaration serialization, multi-item animations, slash
212
- sections, and contextual values in every position of `flex`, `grid`, columns,
213
- aspect ratios, and border-image families. Both direct and composite properties
214
- must pass mutation, `cssText`, safe round-trip, and atomic-rejection gates.
215
-
216
- Direct numeric and cross-dimension syntax is gated independently by the
217
- [`Numeric Property Contracts`](./compatibility/numeric-property-contracts.json).
218
- It crosses 57 number-, percentage-, length-, and legacy-number properties with
219
- 11 accepted and rejected neighboring branches. The public binding must match
220
- Chromium for acceptance, observable values, `cssText`, indexed names, and
221
- invalid-mutation atomicity; the browser observations remain test evidence and
222
- are never loaded by the runtime.
223
-
224
- The corresponding shorthand depth evidence is split between the reviewed
225
- [`Grammar Branch Contracts`](./compatibility/shorthand-grammar-contracts.json)
226
- and the generated
227
- [`Chromium observations`](./compatibility/shorthand-grammar-observations.json).
228
-
229
- See [the behavioral API reference](./docs/api.md) for return, exception,
230
- identity, and detachment contracts. Maintainers use the separately reviewed
231
- [release procedure](./docs/releasing.md); Changesets never publishes by itself.
232
-
233
- The checked-in ordinary-property manifest was generated against Chromium
234
- 151.0.7922.34. Run `npm run generate:properties` only when intentionally
235
- advancing the Compatibility Baseline.
236
-
237
- ## Security and resource boundaries
238
-
239
- SheetOM does not fetch `@import` targets or URLs and does not execute CSS. It is
240
- also not a sanitizer: valid authored URLs, imports, and browser features remain
241
- in serialized output. Callers must apply their own content and resource policy
242
- before attaching untrusted output to a document or another rendering
243
- environment.
244
-
245
- Every sheet has a high default Resource Budget that is checked before native
246
- parsing or CSSOM mutation: 64 MiB of stylesheet source, 1 MiB per declaration
247
- value, syntax depth 4,096, one million rules, and 100,000 declarations per
248
- block. Exceeding a budget throws `RangeError` without changing the previous
249
- sheet or declaration state. Limits are UTF-8 byte counts where applicable and
250
- can be changed per sheet without affecting other sheets:
251
-
252
- ```js
253
- const bounded = new CSSStyleSheet({
254
- resourceBudget: {
255
- maxStylesheetBytes: 8 * 1024 * 1024,
256
- maxRuleCount: 100_000,
257
- },
258
- });
259
- ```
94
+ | `style.cssText` | Browser-compatible declaration text, including measured recovery quirks. |
95
+ | `rule.cssText` | Browser-compatible text for the current rule. |
96
+ | `sheet.serialize()` | Deterministic, reparsable CSS for a complete stylesheet. |
97
+
98
+ Invalid property values and priorities are atomic no-ops: the previous state
99
+ survives unchanged. Static shorthands are stored as canonical longhands, so
100
+ editing and then removing one longhand cannot accidentally reactivate an old
101
+ shorthand value.
102
+
103
+ Reparsable output prevents malformed input from leaking into a following
104
+ declaration or rule. It is not a CSS sanitizer, URL policy, CSP, or rendering
105
+ sandbox.
106
+
107
+ ## Native and WebAssembly runtimes
108
+
109
+ The `sheetom` package contains the JavaScript facade and selects one exact
110
+ `@sheetom/native-*` optional package for the current platform. It installs no
111
+ JavaScript parser dependency, downloads no binary at install time, and never
112
+ falls back to a different engine. Omitting optional dependencies is unsupported
113
+ and fails explicitly.
260
114
 
261
- Resource Budgets protect the host process; they are not content policy,
262
- sanitization, or a rendering sandbox. See [the API contract](./docs/api.md) and
263
- [SECURITY.md](./SECURITY.md) for details.
115
+ | Runtime | Entry point | Notes |
116
+ | --- | --- | --- |
117
+ | Node.js 22+ | `sheetom` | ESM and CommonJS; prebuilt native packages for macOS, Windows, GNU Linux, and musl Linux targets. |
118
+ | Bun | `sheetom` | Tested through the npm package on Linux x64. |
119
+ | Deno | `sheetom` | Uses npm resolution and requires native FFI/system permissions. |
120
+ | Browsers and workers | `@sheetom/wasm` | ESM-only asynchronous factory; no WASI or global installation. |
264
121
 
265
- ## Development
122
+ Deno example:
266
123
 
267
124
  ```sh
268
- npm run check
269
- npm run test:browser:matrix
270
- npm run test:differential
271
- npm run conformance:drift
272
- npm run fuzz
273
- npm run benchmark
125
+ deno run --node-modules-dir=manual --allow-ffi --allow-sys app.ts
126
+ ```
127
+
128
+ WebAssembly example:
129
+
130
+ ```ts
131
+ import { createSheetOM } from "@sheetom/wasm";
132
+
133
+ const { CSSStyleSheet } = await createSheetOM();
134
+ const sheet = new CSSStyleSheet();
135
+ sheet.replaceSync(".card { color: red; }");
136
+ ```
137
+
138
+ The native and WebAssembly packages execute the same Rust engine and verify an
139
+ exact engine ABI identity before exposing CSSOM objects. `createSheetOM()`
140
+ shares default initialization within one JavaScript realm; passing an explicit
141
+ `URL`, `Response`, `ArrayBuffer`, or `WebAssembly.Module` creates an isolated
142
+ facade with its own class identity.
143
+
144
+ ## Compatibility contract
145
+
146
+ SheetOM tests complete observable state—not only whether serialized CSS looks
147
+ similar. Its versioned evidence covers getters, `cssText`, indexed property
148
+ order, priorities, invalid-mutation atomicity, live identity, shorthand
149
+ sequences, recovery, native-browser reparsing, subprocess crash safety,
150
+ grammar-oriented fuzzing, and Publisher-shaped performance workloads.
151
+
152
+ Standards and shared browser behavior take precedence. When browser engines
153
+ genuinely differ, SheetOM records the result and follows the pinned Chromium
154
+ baseline as its final fallback. Browser observations and WPT mappings remain
155
+ test evidence; they are never imported as runtime authority.
156
+
157
+ See [Compatibility](./docs/compatibility.md) for the exact promise, evidence,
158
+ and exclusions.
159
+
160
+ ## Resource limits and diagnostics
161
+
162
+ Each sheet has configurable limits for stylesheet bytes, declaration-value
163
+ bytes, syntax depth, rule count, and declarations per block. A limit violation
164
+ throws `RangeError` before mutation. These budgets protect the host process;
165
+ they are not content policy.
166
+
167
+ Mutation diagnostics are opt-in:
168
+
169
+ ```ts
170
+ const sheet = new CSSStyleSheet({ diagnostics: true });
171
+ // ...mutate the sheet...
172
+ const diagnostics = sheet.takeDiagnostics();
274
173
  ```
275
174
 
276
- `npm run check` covers types, public unit behavior, conformance documents, API
277
- documentation, build output, runtime artifacts, and the packed-package smoke
278
- test. Use `npm run test:browser:matrix` on a machine with all Playwright
279
- dependencies to run Chromium, Firefox, and WebKit. CI separately runs
280
- `npm run test:differential`, a deterministic, grammar-oriented declaration
281
- differential with native-browser reparsing witnesses. Any minimized mismatch
282
- must become an immutable Operation Fixture with an explicit Compatibility
283
- Resolution.
284
-
285
- `npm run docs:build` generates the TypeDoc reference under `site/api`. The
286
- benchmark gates both a 10,000-rule stress case and a publisher-shaped reference
287
- workload with one shared stylesheet, 20 page stylesheets, nested layers/media,
288
- distributed mutations, and two idempotent serialization passes.
289
-
290
- Only the latest published `0.x` minor and its active prereleases receive fixes
291
- before 1.0. During `0.x`, observable compatibility corrections and interface
292
- breaks require a new minor version and migration note; patches remain backward
293
- compatible.
175
+ Diagnostics retain rejected inputs until drained. Leave them disabled or drain
176
+ them promptly when handling untrusted or unusually large source.
177
+
178
+ ## Documentation
179
+
180
+ - [API behavior](./docs/api.md)
181
+ - [Architecture](https://github.com/leo91000/sheetom/blob/main/docs/architecture.md)
182
+ - [Compatibility](https://github.com/leo91000/sheetom/blob/main/docs/compatibility.md)
183
+ - [Contributing](https://github.com/leo91000/sheetom/blob/main/CONTRIBUTING.md)
184
+ - [Release process](https://github.com/leo91000/sheetom/blob/main/docs/releasing.md)
185
+ - [Architecture decisions](https://github.com/leo91000/sheetom/blob/main/docs/adr/README.md)
186
+ - [Security policy](./SECURITY.md)
294
187
 
295
188
  ## License
296
189
 
297
- MIT
190
+ MIT. Vendored parser sources retain their upstream licenses and provenance.