@texuli/spec 0.1.0-next.1 → 0.2.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 +157 -159
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,170 +1,168 @@
|
|
|
1
1
|
# @texuli/spec
|
|
2
2
|
|
|
3
|
-
The
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
##
|
|
22
|
-
|
|
23
|
-
| Path | What it holds |
|
|
24
|
-
| --- | --- |
|
|
25
|
-
| `schemas/` | The normative JSON schemas: `blueprint` (envelope v1 and the node tree), `catalog`, `diagnostics`, `manifest` |
|
|
26
|
-
| `catalog/components.json` | The closed vocabulary, projected from the built catalog: id, label, summary, group, placement (`app`/`content`), emit tiers, capability and props |
|
|
27
|
-
| `catalog/capabilities.json` | Reviewed capability claims. Empty: no id is audited portable yet, so every capability is `unknown` (ADR-003) |
|
|
28
|
-
| `fixtures/golden/` | Blueprints that must validate: a report, a dashboard, a proactive deck and a report with a named slot and a `when` condition (fictional data) |
|
|
29
|
-
| `fixtures/invalid/` | Blueprints that must fail with exact diagnostic codes, one or more per code, including slot and condition cases (an undeclared or root `slot`, an unknown condition `op`, an extra condition field) |
|
|
30
|
-
| `manifest.json` | The spec version, the dialect and a SHA-256 per normative file |
|
|
31
|
-
| `versions.json` | Every released spec version pinned to its spec digest (not normative: it pins the normative files) |
|
|
32
|
-
| `generated/typescript/`, `generated/kotlin/` | The projections. Never edit them |
|
|
33
|
-
| `generated-manifest.json` | A SHA-256 per generated file |
|
|
34
|
-
|
|
35
|
-
## The dialect
|
|
36
|
-
|
|
37
|
-
Schemas use a closed subset of JSON Schema 2020-12 (`DIALECT_KEYWORDS`):
|
|
38
|
-
`type`, `properties`, `required`, `additionalProperties`, `items`, `enum`,
|
|
39
|
-
`const`, string, number and array bounds, `pattern`, and local `$ref` /
|
|
40
|
-
`$defs`. Objects must be closed (`additionalProperties: false`) or explicit
|
|
41
|
-
maps. Anything else fails `checkSchemaDocument`, and generation refuses it.
|
|
42
|
-
|
|
43
|
-
## Exports
|
|
44
|
-
|
|
45
|
-
- `@texuli/spec`, the runtime half:
|
|
46
|
-
- the generated types (`BlueprintEnvelope`, `SpecCatalog`, `SpecValidation` …);
|
|
47
|
-
- `SPEC_COMPONENT_IDS` and `SpecComponentProps`;
|
|
48
|
-
- `validateInstance` (the dialect validator);
|
|
49
|
-
- `validateBlueprint` (the target-neutral blueprint check: envelope
|
|
50
|
-
schema, closed ids and props, prop kinds and enums, required props, no
|
|
51
|
-
platform-extension props from data, a node `slot` that names a slot prop
|
|
52
|
-
of its parent (`unknown-slot`), the portable profile failing closed,
|
|
53
|
-
and an optional catalog binding);
|
|
54
|
-
- `canonicalJson` and a synchronous `sha256`.
|
|
55
|
-
- `@texuli/spec/codegen`, build time: `buildSpec`, `projectCatalog`,
|
|
56
|
-
`checkConformance`, `formatJson`.
|
|
57
|
-
|
|
58
|
-
URL policy, tree limits, grammar and rendering stay in the runtime validator,
|
|
59
|
-
`@texuli/catalog/validate`.
|
|
60
|
-
|
|
61
|
-
## Projections
|
|
62
|
-
|
|
63
|
-
- **Web extensions.** Props of kind `slot`, `event` or `unknown`, and the
|
|
64
|
-
`class`, `className`, `style` and chart `renderer` props, are marked
|
|
65
|
-
`extension: "web"`. They are left out of `SpecComponentProps`, and data
|
|
66
|
-
that sets them is refused.
|
|
67
|
-
- **Kotlin** (`com.texuli.spec`, Kotlin 1.9+ for `entries` and
|
|
68
|
-
`data object`): data classes, closed enums and static decoders over a
|
|
69
|
-
generated `JsonValue` model, with no library dependency. Decoders check
|
|
70
|
-
JSON types, required and unknown fields, enums and constants. Patterns
|
|
71
|
-
and limits are the shared validator's job.
|
|
72
|
-
- **Stamp.** Every generated file carries the spec version and a digest of
|
|
73
|
-
the normative files. There are no timestamps, and output is
|
|
74
|
-
byte-identical for the same inputs in any order.
|
|
75
|
-
|
|
76
|
-
## Regenerate
|
|
3
|
+
The blueprint contract of [Texuli](https://texuli.com), an MIT-licensed
|
|
4
|
+
Svelte 5 component library by Dailybot, Inc. (*Small pieces. Infinite
|
|
5
|
+
possibilities.*). A **blueprint** is a JSON document, usually written by an
|
|
6
|
+
AI agent, that describes an interface as a tree of components from Texuli's
|
|
7
|
+
closed catalog. `@texuli/spec` is the platform-neutral source of truth for
|
|
8
|
+
that format: the generated TypeScript types, the closed component
|
|
9
|
+
vocabulary, a target-neutral blueprint validator and deterministic hashing.
|
|
10
|
+
|
|
11
|
+
Use it when you generate, store, diff or check blueprints, or build a
|
|
12
|
+
renderer for them. The same contract also generates the Kotlin models used
|
|
13
|
+
by Texuli's Kotlin Multiplatform twin. The package is framework-free: no
|
|
14
|
+
DOM, no Svelte, no Node APIs and no runtime dependencies.
|
|
15
|
+
|
|
16
|
+
> **Status: 0.x release.** Texuli is in development. The packages are
|
|
17
|
+
> published to npm as `0.2.0`, a pre-1.0 release (1.0.0 will be the first
|
|
18
|
+
> stable release). Under 0.x, a new minor (`0.3.0`) may contain breaking
|
|
19
|
+
> changes, so pin the exact version or use `^0.2.0`, which accepts only 0.2.x.
|
|
20
|
+
|
|
21
|
+
## Install
|
|
77
22
|
|
|
78
23
|
```bash
|
|
79
|
-
|
|
80
|
-
pnpm exec tsx packages/spec/scripts/generate.ts # write manifests and projections
|
|
81
|
-
pnpm exec tsx packages/spec/scripts/generate.ts --check # fail on drift
|
|
24
|
+
npm install @texuli/spec
|
|
82
25
|
```
|
|
83
26
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
- regenerating gives byte-identical files, none missing or extra;
|
|
90
|
-
- the golden fixtures validate and the invalid fixtures fail with exactly
|
|
91
|
-
their codes, covering every diagnostic code;
|
|
92
|
-
- `components.json` equals the projection of the live catalog, and the
|
|
93
|
-
blueprint schema matches the envelope `@texuli/catalog` reads;
|
|
94
|
-
- generation is deterministic and refuses schemas outside the dialect;
|
|
95
|
-
- the Kotlin text declares its package, balances its brackets, defines
|
|
96
|
-
every type it references and decodes closed;
|
|
97
|
-
- the spec version and digest match the newest release in `versions.json`.
|
|
98
|
-
|
|
99
|
-
When the catalog changes, refresh `components.json`, regenerate and review
|
|
100
|
-
the diff. Then classify the change, bump the version, and pin it (see
|
|
101
|
-
Versioning).
|
|
27
|
+
```bash
|
|
28
|
+
pnpm add @texuli/spec
|
|
29
|
+
# or
|
|
30
|
+
yarn add @texuli/spec
|
|
31
|
+
```
|
|
102
32
|
|
|
103
|
-
|
|
33
|
+
No peer dependencies and no CSS. The package is ESM-only and ships
|
|
34
|
+
TypeScript declarations. The normative JSON documents (the blueprint
|
|
35
|
+
schema, the component catalog and the fixtures) live in the
|
|
36
|
+
[repository](https://github.com/DailybotHQ/texuli/tree/main/packages/spec);
|
|
37
|
+
they are not part of the npm package.
|
|
38
|
+
|
|
39
|
+
## Quick start
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import {
|
|
43
|
+
canonicalJson,
|
|
44
|
+
type Schema,
|
|
45
|
+
SPEC_COMPONENT_IDS,
|
|
46
|
+
SPEC_VERSION,
|
|
47
|
+
sha256,
|
|
48
|
+
validateInstance,
|
|
49
|
+
} from '@texuli/spec';
|
|
50
|
+
|
|
51
|
+
SPEC_VERSION; // the spec version, e.g. '0.2.0'
|
|
52
|
+
SPEC_COMPONENT_IDS.includes('alert'); // true: the closed component vocabulary
|
|
53
|
+
|
|
54
|
+
// The dialect validator: a closed subset of JSON Schema 2020-12.
|
|
55
|
+
const schema: Schema = {
|
|
56
|
+
type: 'object',
|
|
57
|
+
properties: { title: { type: 'string', maxLength: 80 } },
|
|
58
|
+
required: ['title'],
|
|
59
|
+
additionalProperties: false,
|
|
60
|
+
};
|
|
61
|
+
validateInstance(schema, { title: 'Weekly report' }); // []
|
|
62
|
+
validateInstance(schema, { title: 42, extra: true });
|
|
63
|
+
// [{ code: 'type', path: '$.title', … }, { code: 'additional-property', path: '$.extra', … }]
|
|
64
|
+
|
|
65
|
+
// Deterministic serialization and hashing, identical in every runtime.
|
|
66
|
+
const digest = sha256(canonicalJson({ b: 1, a: [true, null] }));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
To check a whole blueprint, pass the blueprint schema and catalog documents
|
|
70
|
+
from the repository's `packages/spec/schemas/blueprint.schema.json` and
|
|
71
|
+
`packages/spec/catalog/components.json`:
|
|
104
72
|
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
73
|
+
```ts
|
|
74
|
+
import { type Schema, type SpecCatalog, validateBlueprint } from '@texuli/spec';
|
|
75
|
+
|
|
76
|
+
const result = validateBlueprint(blueprint, {
|
|
77
|
+
blueprintSchema: blueprintSchemaJson as Schema,
|
|
78
|
+
catalog: componentsJson as SpecCatalog,
|
|
79
|
+
});
|
|
80
|
+
if (!result.ok) {
|
|
81
|
+
for (const d of result.diagnostics) console.warn(d.code, d.path, d.message);
|
|
82
|
+
}
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
A node with an id outside the catalog fails with `unknown-id`; other codes
|
|
86
|
+
include `schema`, `unknown-prop`, `prop-type`, `enum-value`,
|
|
87
|
+
`missing-required`, `extension-prop`, `catalog-mismatch`,
|
|
88
|
+
`unsupported-profile` and `unknown-slot`.
|
|
89
|
+
|
|
90
|
+
## What's inside
|
|
91
|
+
|
|
92
|
+
| Subpath | Purpose | Headline exports |
|
|
93
|
+
| --- | --- | --- |
|
|
94
|
+
| `@texuli/spec` | Runtime: types, vocabulary, validation, hashing | `BlueprintEnvelope`, `SpecCatalog`, `SpecValidation` and the other generated types; `SPEC_COMPONENT_IDS`, `SpecComponentProps`, `SPEC_CATALOG_HASH`, `SPEC_VERSION`; `validateBlueprint`, `validateTree`, `validateInstance`, `checkSchemaDocument`; `canonicalJson`, `sha256` |
|
|
95
|
+
| `@texuli/spec/codegen` | Build time: generation and conformance | `buildSpec`, `projectCatalog`, `checkConformance`, `formatJson`, `nextSpecVersion`, `checkVersionHistory` |
|
|
96
|
+
|
|
97
|
+
## Key guarantees
|
|
98
|
+
|
|
99
|
+
- **Closed vocabulary.** Component ids, prop names, prop kinds and enum
|
|
100
|
+
values are closed; anything outside the catalog is refused.
|
|
101
|
+
- **No platform props from data.** Web-only props (slots, events, `class`,
|
|
102
|
+
`className`, `style` and the chart `renderer`) are marked as web
|
|
103
|
+
extensions, left out of `SpecComponentProps`, and refused when a
|
|
104
|
+
blueprint sets them.
|
|
105
|
+
- **Fails closed.** The portable profile is refused until a capability is
|
|
106
|
+
audited portable, and a blueprint bound to another catalog hash is
|
|
107
|
+
refused when you pass `catalogHash`.
|
|
108
|
+
- **Deterministic.** Canonical JSON sorts keys at every depth, and every
|
|
109
|
+
generated file carries the spec version and digest with no timestamps.
|
|
110
|
+
- **Structure only.** This validator checks structure. URL policy, tree
|
|
111
|
+
limits and rendering live in the runtime validator of
|
|
112
|
+
[`@texuli/catalog`](https://www.npmjs.com/package/@texuli/catalog).
|
|
113
|
+
|
|
114
|
+
## Versioning
|
|
110
115
|
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
and a one-line summary.
|
|
116
|
+
The spec has its own semantic version (`SPEC_VERSION`), separate from the
|
|
117
|
+
npm package version. The **spec digest** is the SHA-256 of the manifest
|
|
118
|
+
that pins every normative file (schemas, catalog and fixtures); any
|
|
119
|
+
normative change moves the digest and requires a new spec version.
|
|
116
120
|
|
|
117
|
-
|
|
|
121
|
+
| Change class | Examples | Before 1.0.0 | From 1.0.0 |
|
|
118
122
|
| --- | --- | --- | --- |
|
|
119
|
-
| patch |
|
|
120
|
-
| minor |
|
|
121
|
-
| major | Removing or renaming ids, props or fields; changing a prop type; making something required
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
`
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
- Compiling the Kotlin, and the native runtime (B2).
|
|
166
|
-
- A full type for `when`. The dialect has no unions, so `condition` and
|
|
167
|
-
`numberFormula` are closed records whose `op` is an enum and whose operands
|
|
168
|
-
are typed (except `value`, which is a number for `num` and a formula for
|
|
169
|
-
`round` and `clamp`). Which operands each `op` needs, and the formula
|
|
170
|
-
limits, are checked by the runtime parser in `@texuli/blocks/formula`.
|
|
123
|
+
| patch | Descriptions, diagnostic wording, a fixture for behavior that already holds | patch | patch |
|
|
124
|
+
| minor | Optional fields, new catalog ids, new optional props, new diagnostic codes for data that was already refused | minor | minor |
|
|
125
|
+
| major | Removing or renaming ids, props or fields; changing a prop type; making something required | minor | major |
|
|
126
|
+
|
|
127
|
+
For TypeScript consumers, a patch leaves the generated types and
|
|
128
|
+
`SPEC_COMPONENT_IDS` unchanged; code that compiled against a minor release
|
|
129
|
+
keeps compiling, though new optional fields and ids can appear in data it
|
|
130
|
+
reads. Native (Kotlin) builds compile the generated models from the same
|
|
131
|
+
spec, and their decoders are closed: a blueprint that uses a field from a
|
|
132
|
+
newer spec fails to decode on an older native build with a `schema`
|
|
133
|
+
diagnostic instead of passing silently. A blueprint binds to an exact
|
|
134
|
+
catalog hash today; an envelope field for a compatible spec range, and
|
|
135
|
+
migrations between versions, are planned and not built.
|
|
136
|
+
|
|
137
|
+
The full rules (the digest, `versions.json` pins, regeneration and the
|
|
138
|
+
conformance harness) are in
|
|
139
|
+
[contract.md](https://github.com/DailybotHQ/texuli/blob/main/packages/spec/docs/contract.md).
|
|
140
|
+
|
|
141
|
+
## Documentation
|
|
142
|
+
|
|
143
|
+
- Website: [texuli.com](https://texuli.com), the
|
|
144
|
+
[agents overview](https://texuli.com/agents-page/) and
|
|
145
|
+
[web and native](https://texuli.com/web-and-native/)
|
|
146
|
+
- Schemas, catalog and fixtures:
|
|
147
|
+
[packages/spec](https://github.com/DailybotHQ/texuli/tree/main/packages/spec)
|
|
148
|
+
- The contract in depth (the JSON Schema dialect, projections, conformance
|
|
149
|
+
and versioning): [contract.md](https://github.com/DailybotHQ/texuli/blob/main/packages/spec/docs/contract.md)
|
|
150
|
+
- The Kotlin Multiplatform twin that consumes the generated models:
|
|
151
|
+
[native/README.md](https://github.com/DailybotHQ/texuli/blob/main/native/README.md)
|
|
152
|
+
- Architecture: [ARCHITECTURE.md](https://github.com/DailybotHQ/texuli/blob/main/docs/ARCHITECTURE.md)
|
|
153
|
+
|
|
154
|
+
## Related packages
|
|
155
|
+
|
|
156
|
+
- [`@texuli/catalog`](https://www.npmjs.com/package/@texuli/catalog): the agent catalog and the renderer with no HTML sinks.
|
|
157
|
+
- [`@texuli/player`](https://www.npmjs.com/package/@texuli/player): the Svelte paint runtime for validated blueprints.
|
|
158
|
+
- [`texuli`](https://www.npmjs.com/package/texuli): the styled Svelte 5 components blueprints are built from.
|
|
159
|
+
|
|
160
|
+
## Contributing
|
|
161
|
+
|
|
162
|
+
Source, issues and contribution guidelines live at
|
|
163
|
+
[github.com/DailybotHQ/texuli](https://github.com/DailybotHQ/texuli). Report
|
|
164
|
+
bugs at [github.com/DailybotHQ/texuli/issues](https://github.com/DailybotHQ/texuli/issues).
|
|
165
|
+
|
|
166
|
+
## License
|
|
167
|
+
|
|
168
|
+
MIT © Dailybot, Inc.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@texuli/spec",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "The schema-first blueprint contract: JSON schemas, the catalog vocabulary, deterministic TypeScript and Kotlin projections, and the conformance harness.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"svelte",
|