@dtmd/temper 0.0.6 → 0.0.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.
- package/README.md +84 -53
- package/bin/temper.js +52 -0
- package/dist/src/assembly.d.ts +15 -1
- package/dist/src/assembly.js +2 -1
- package/dist/src/builtins.d.ts +765 -48
- package/dist/src/builtins.js +767 -68
- package/dist/src/claude-code.d.ts +2 -2
- package/dist/src/claude-code.js +1 -1
- package/dist/src/contract.d.ts +180 -29
- package/dist/src/contract.js +128 -15
- package/dist/src/declarations.d.ts +92 -6
- package/dist/src/declarations.js +448 -102
- package/dist/src/dial.d.ts +75 -0
- package/dist/src/dial.js +82 -0
- package/dist/src/emit.d.ts +82 -1
- package/dist/src/emit.js +402 -56
- package/dist/src/generated/AssemblyFactRow.d.ts +2 -2
- package/dist/src/generated/BoundRow.d.ts +2 -2
- package/dist/src/generated/ClauseRow.d.ts +73 -3
- package/dist/src/generated/CollectionAddressRow.d.ts +21 -0
- package/dist/src/generated/CollectionAddressRow.js +2 -0
- package/dist/src/generated/Declarations.d.ts +17 -0
- package/dist/src/generated/EmbeddedMember.d.ts +3 -3
- package/dist/src/generated/FeatureValue.d.ts +2 -2
- package/dist/src/generated/Features.d.ts +52 -3
- package/dist/src/generated/KindFactRow.d.ts +38 -7
- package/dist/src/generated/MentionRow.d.ts +5 -3
- package/dist/src/generated/NestedMemberRow.d.ts +32 -0
- package/dist/src/generated/PayloadMember.d.ts +6 -0
- package/dist/src/generated/RegistrationRow.d.ts +35 -0
- package/dist/src/generated/RegistrationRow.js +2 -0
- package/dist/src/generated/RequirementRow.d.ts +4 -2
- package/dist/src/generated/SatisfiesRow.d.ts +2 -1
- package/dist/src/generated/SettingsRow.d.ts +25 -0
- package/dist/src/generated/SettingsRow.js +2 -0
- package/dist/src/generated/Shape.d.ts +15 -0
- package/dist/src/generated/Shape.js +2 -0
- package/dist/src/generated/TemplateRow.d.ts +24 -0
- package/dist/src/generated/TemplateRow.js +2 -0
- package/dist/src/generated/ValueType.d.ts +11 -2
- package/dist/src/generated/Verifier.d.ts +20 -0
- package/dist/src/generated/Verifier.js +2 -0
- package/dist/src/generated/index.d.ts +6 -0
- package/dist/src/index.d.ts +8 -8
- package/dist/src/index.js +3 -3
- package/dist/src/kind.d.ts +160 -29
- package/dist/src/kind.js +47 -16
- package/dist/src/prose.d.ts +81 -25
- package/dist/src/prose.js +91 -21
- package/package.json +10 -2
|
@@ -12,8 +12,9 @@ import type { SectionContainsRow } from "./SectionContainsRow.js";
|
|
|
12
12
|
* and, per predicate, its own argument: the node-set/edge-scope predicates
|
|
13
13
|
* carry
|
|
14
14
|
* their bounds/target, and the node-scope predicates that need more than
|
|
15
|
-
* `field`/`severity` (`min_len`/`max_len`/`
|
|
16
|
-
* charset, `forbidden_keys`'s keys, `deny`'s values
|
|
15
|
+
* `field`/`severity` (`min_len`/`max_len`/`extent`'s bound, `extent`'s unit,
|
|
16
|
+
* `allowed_chars`'s charset, `forbidden_keys`'s keys, `deny`'s values, `type`'s declared
|
|
17
|
+
* kind) carry theirs too — so a kind's
|
|
17
18
|
* own floor clause round-trips losslessly, not identity+severity alone.
|
|
18
19
|
* `unique`'s field rides the shared `field`
|
|
19
20
|
* column (the same slot `required`/`min_len`/… target); the rest carry their own
|
|
@@ -24,6 +25,18 @@ import type { SectionContainsRow } from "./SectionContainsRow.js";
|
|
|
24
25
|
* [`crate::contract::Predicate`] already makes for its own `Range` bounds.
|
|
25
26
|
*/
|
|
26
27
|
export type ClauseRow = {
|
|
28
|
+
/**
|
|
29
|
+
* The clause's **address** — the deterministic, human-legible label
|
|
30
|
+
* [`crate::contract::clause_label`] derives from the row's identity columns, and
|
|
31
|
+
* the row's identity in the lock: every finding this clause produces prints it as
|
|
32
|
+
* the diagnostic `rule` id, `explain` narrates it, and the dial names a clause by
|
|
33
|
+
* it.
|
|
34
|
+
*
|
|
35
|
+
* `None` on a payload row and `Some` on a lock row: emit is the one writer
|
|
36
|
+
* ([`emit`]), stamping every row as it composes the lock, so the seam has no label
|
|
37
|
+
* to author and no way to author a wrong one.
|
|
38
|
+
*/
|
|
39
|
+
label?: string;
|
|
27
40
|
/**
|
|
28
41
|
* The kind whose contract carries the clause. `None` when this row is nested
|
|
29
42
|
* inside a [`RequirementRow`]'s own [`clauses`](RequirementRow::clauses) — a
|
|
@@ -67,10 +80,51 @@ export type ClauseRow = {
|
|
|
67
80
|
*/
|
|
68
81
|
degree?: DegreeBoundRow;
|
|
69
82
|
/**
|
|
70
|
-
* The `
|
|
83
|
+
* The `mention-reachable` clause's **target-side gate field**, when the predicate
|
|
84
|
+
* is `mention-reachable`. The one predicate taking two field arguments: its
|
|
85
|
+
* source-side scope field rides the shared [`field`](ClauseRow::field) column, and
|
|
86
|
+
* this column carries the other end — the field read off the *mentioned* member,
|
|
87
|
+
* which `field` alone cannot express.
|
|
88
|
+
*/
|
|
89
|
+
gate?: string;
|
|
90
|
+
/**
|
|
91
|
+
* The `type` clause's declared source kinds, when the predicate is `type` — the
|
|
92
|
+
* lattice names (`string`/`integer`/`number`/`boolean`/`null`/`list`/`map`) that
|
|
93
|
+
* [`crate::extract::ValueType::from_name`] decodes. Carried as names rather than
|
|
94
|
+
* as [`crate::extract::ValueType`]s: the lattice is a feature-side type, and the
|
|
95
|
+
* row family decodes its arguments at the boundary.
|
|
96
|
+
*
|
|
97
|
+
* A **set**, since a `type` clause declares one: the column is an array of names
|
|
98
|
+
* in lattice order, and a one-element array is the single-kind clause. A lock
|
|
99
|
+
* written by an older engine spells that case as a bare string, which
|
|
100
|
+
* [`ClauseRow::from_table`] reads as the one-element set it means; the next `emit`
|
|
101
|
+
* rewrites the file whole in the array form, which is the upgrade — a committed
|
|
102
|
+
* lock is re-emitted from its source, never patched in place.
|
|
103
|
+
*/
|
|
104
|
+
value_type?: Array<string>;
|
|
105
|
+
/**
|
|
106
|
+
* The `shape` clause's declared shape, when the predicate is `shape` — the closed
|
|
107
|
+
* set's own spelling (`hyphen-placement`/`no-xml-tags`) that
|
|
108
|
+
* [`crate::contract::Shape::from_name`] decodes. Carried as a name rather than as a
|
|
109
|
+
* [`crate::contract::Shape`], the trade `value_type` already makes: the row family
|
|
110
|
+
* carries its arguments as names and decodes them at the boundary.
|
|
111
|
+
*
|
|
112
|
+
* One name, never a set — a clause names exactly one shape — so this is a plain
|
|
113
|
+
* string column, and no read-side skew tolerance answers it.
|
|
114
|
+
*/
|
|
115
|
+
shape?: string;
|
|
116
|
+
/**
|
|
117
|
+
* The `min_len`/`max_len`/`extent` clause's scalar bound, when the predicate
|
|
71
118
|
* is one of those three.
|
|
72
119
|
*/
|
|
73
120
|
bound?: BoundRow;
|
|
121
|
+
/**
|
|
122
|
+
* The `extent` clause's declared unit (`lines`/`characters`), when the predicate is
|
|
123
|
+
* `extent` — the closed set [`crate::contract::ExtentUnit::from_name`] decodes, an
|
|
124
|
+
* unknown value refused at load. Carried as a name, the trade the whole row family
|
|
125
|
+
* makes for its closed-vocabulary arguments.
|
|
126
|
+
*/
|
|
127
|
+
unit?: string;
|
|
74
128
|
/**
|
|
75
129
|
* The `allowed_chars` clause's declared character class, when the predicate is
|
|
76
130
|
* `allowed_chars`.
|
|
@@ -94,4 +148,20 @@ export type ClauseRow = {
|
|
|
94
148
|
* predicate is `section_contains`.
|
|
95
149
|
*/
|
|
96
150
|
section?: SectionContainsRow;
|
|
151
|
+
/**
|
|
152
|
+
* The `require_sections` clause's required heading list, when the predicate is
|
|
153
|
+
* `require_sections`.
|
|
154
|
+
*/
|
|
155
|
+
sections?: Array<string>;
|
|
156
|
+
/**
|
|
157
|
+
* The `when` clause's guard predicate key (`enum` or `type`), when the predicate
|
|
158
|
+
* is `when`. The guard predicate's own arguments (field, values, etc.) ride the
|
|
159
|
+
* shared columns as if it were a bare guard row.
|
|
160
|
+
*/
|
|
161
|
+
guard_predicate?: string;
|
|
162
|
+
/**
|
|
163
|
+
* The `when` clause's nested body rows, when the predicate is `when` — the
|
|
164
|
+
* clauses evaluated where the guard holds.
|
|
165
|
+
*/
|
|
166
|
+
body?: Array<ClauseRow>;
|
|
97
167
|
};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A kind's declared **collection address** row — the manifest a registration member
|
|
3
|
+
* surfaces in and the key path it keys at, the presence-coupled pair
|
|
4
|
+
* [`KindFactRow::collection_address`] carries. Absent from a [`KindFactRow`] means the
|
|
5
|
+
* kind owns its own file locus.
|
|
6
|
+
*/
|
|
7
|
+
export type CollectionAddressRow = {
|
|
8
|
+
/**
|
|
9
|
+
* The host manifest the registration surfaces in (`settings.json`, `.mcp.json`).
|
|
10
|
+
*/
|
|
11
|
+
manifest: string;
|
|
12
|
+
/**
|
|
13
|
+
* The manifest key path the registration keys at (`hooks.<Event>`, `mcpServers.*`), a
|
|
14
|
+
* closed vocabulary the engine's kind lift rejects an unknown value from.
|
|
15
|
+
*/
|
|
16
|
+
key_path: string;
|
|
17
|
+
/**
|
|
18
|
+
* The entry's declared shape — whether it's an object, scalar, or group-array.
|
|
19
|
+
*/
|
|
20
|
+
entry_shape: string | null;
|
|
21
|
+
};
|
|
@@ -4,8 +4,10 @@ import type { IncludeRow } from "./IncludeRow.js";
|
|
|
4
4
|
import type { KindFactRow } from "./KindFactRow.js";
|
|
5
5
|
import type { MentionRow } from "./MentionRow.js";
|
|
6
6
|
import type { NestedMemberRow } from "./NestedMemberRow.js";
|
|
7
|
+
import type { RegistrationRow } from "./RegistrationRow.js";
|
|
7
8
|
import type { RequirementRow } from "./RequirementRow.js";
|
|
8
9
|
import type { SatisfiesRow } from "./SatisfiesRow.js";
|
|
10
|
+
import type { SettingsRow } from "./SettingsRow.js";
|
|
9
11
|
/**
|
|
10
12
|
* The lock's **declaration-row family** — the composed program's erased declarations,
|
|
11
13
|
* beside the
|
|
@@ -69,4 +71,19 @@ export type Declarations = {
|
|
|
69
71
|
* (0018, "the projection is not the database").
|
|
70
72
|
*/
|
|
71
73
|
nested_members: Array<NestedMemberRow>;
|
|
74
|
+
/**
|
|
75
|
+
* The fields-only registration members the SDK erased for the manifest write face —
|
|
76
|
+
* seam-inbound carrying their folded fields, so `emit` routes each host manifest whole
|
|
77
|
+
* through the canonical write face. The lock's `registration` family records only each
|
|
78
|
+
* member's identity and collection address; the fields live in the projected manifest
|
|
79
|
+
* artifact, never a second copy read back (0018), so a lock round-trip reads them
|
|
80
|
+
* fieldless.
|
|
81
|
+
*/
|
|
82
|
+
registrations: Array<RegistrationRow>;
|
|
83
|
+
/**
|
|
84
|
+
* The harness-level settings residue — seam-inbound opaque `settings.json` keys with
|
|
85
|
+
* no member home, folded into their manifest's residue at emit. Like `includes`, never
|
|
86
|
+
* written into this declaration table, so a lock round-trip reads none.
|
|
87
|
+
*/
|
|
88
|
+
settings: Array<SettingsRow>;
|
|
72
89
|
};
|
|
@@ -10,9 +10,9 @@ import type { EmbeddedMemberCollectionEntry } from "./EmbeddedMemberCollectionEn
|
|
|
10
10
|
* addressed structurally (member + kind + key + child path) so drift, `impact`, and
|
|
11
11
|
* citations survive rewording ([`EmbeddedMember::addressed_leaves`]).
|
|
12
12
|
*
|
|
13
|
-
* Floor leaves carry no mentions
|
|
14
|
-
* mention syntax
|
|
15
|
-
*
|
|
13
|
+
* Floor leaves carry no mentions: an edge is declared at a position, never matched as
|
|
14
|
+
* a pattern within prose, so no floor mention syntax can exist and a leaf is
|
|
15
|
+
* permanently a plain [`String`], never a mention-bearing span.
|
|
16
16
|
*/
|
|
17
17
|
export type EmbeddedMember = {
|
|
18
18
|
/**
|
|
@@ -4,8 +4,8 @@ import type { ValueType } from "./ValueType.js";
|
|
|
4
4
|
* [`ValueType`] alongside its comparison text), a list field (e.g. a YAML sequence
|
|
5
5
|
* like `allowed-tools`), or a map field. Scalar predicates (`min_len`, `enum`,
|
|
6
6
|
* `deny`, `allowed_chars`) read the scalar text; presence predicates
|
|
7
|
-
* (`required`, `forbidden_keys`) need only the key; the `type` primitive
|
|
8
|
-
*
|
|
7
|
+
* (`required`, `forbidden_keys`) need only the key; the `type` primitive reads
|
|
8
|
+
* [`FeatureValue::kind`].
|
|
9
9
|
*/
|
|
10
10
|
export type FeatureValue = {
|
|
11
11
|
"Scalar": {
|
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
import type { EmbeddedMember } from "./EmbeddedMember.js";
|
|
2
|
-
import type { FeatureValue } from "./FeatureValue.js";
|
|
3
2
|
import type { FencedBlock } from "./FencedBlock.js";
|
|
4
3
|
import type { Section } from "./Section.js";
|
|
5
4
|
/**
|
|
@@ -15,14 +14,46 @@ export type Features = {
|
|
|
15
14
|
* Frontmatter fields by name — the typed fields *and* the `extra` keys, so
|
|
16
15
|
* a clause resolves `name`/`description`/`version` or any unknown key
|
|
17
16
|
* (e.g. for `forbidden_keys`) through one generic lookup.
|
|
17
|
+
*
|
|
18
|
+
* Each value is retained **as parsed**, never flattened: a clause addresses a field
|
|
19
|
+
* by a path that may step into an object or grain over an array's elements
|
|
20
|
+
* ([`Features::locate`]), so the nesting has to survive extraction. Projection to
|
|
21
|
+
* the [`FeatureValue`] the predicates read happens at the read edge
|
|
22
|
+
* ([`json_to_feature`]), on the node the path located rather than on the top-level
|
|
23
|
+
* value alone.
|
|
24
|
+
*
|
|
25
|
+
* A retained value is arbitrary parsed JSON, and the binding says exactly that: the
|
|
26
|
+
* TS face narrows before it reads, because typing the value is the *contract*'s job
|
|
27
|
+
* and no consumer of this map knows the kind yet.
|
|
18
28
|
*/
|
|
19
29
|
fields: {
|
|
20
|
-
[key in string]:
|
|
30
|
+
[key in string]: unknown;
|
|
21
31
|
};
|
|
22
32
|
/**
|
|
23
|
-
* The artifact body's line count
|
|
33
|
+
* The artifact body's line count — the `line_count` primitive's feature, populated
|
|
34
|
+
* only when a kind composes it.
|
|
24
35
|
*/
|
|
25
36
|
body_lines: number;
|
|
37
|
+
/**
|
|
38
|
+
* The member's **rendered extent** in lines — the projection's line count, measured
|
|
39
|
+
* intrinsically off every unit rather than gated behind a composed primitive, since
|
|
40
|
+
* `extent` is node-scope and must decide over any kind's members. Distinct from
|
|
41
|
+
* [`body_lines`](Features::body_lines): that reads only where `line_count` is
|
|
42
|
+
* composed; this carries the projected body's size.
|
|
43
|
+
*
|
|
44
|
+
* `None` where nothing rendered a projection to measure — an embedded member read off
|
|
45
|
+
* a layout host's source, never a format's output. A file member always carries
|
|
46
|
+
* `Some` (its committed body is the projection), so an `extent` clause over it stays
|
|
47
|
+
* decidable; a `None` member's `extent` is undecidable rather than a zero read as a
|
|
48
|
+
* pass.
|
|
49
|
+
*/
|
|
50
|
+
rendered_lines: number | null;
|
|
51
|
+
/**
|
|
52
|
+
* The member's **rendered extent** in characters — the projection's character count,
|
|
53
|
+
* the second unit an `extent` clause measures in. `None` on the same terms as
|
|
54
|
+
* [`rendered_lines`](Features::rendered_lines).
|
|
55
|
+
*/
|
|
56
|
+
rendered_chars: number | null;
|
|
26
57
|
/**
|
|
27
58
|
* The ATX headings (`#`..`######`) in the body, in document order, with the
|
|
28
59
|
* `#` run and any closing `#` run trimmed (for `require_sections`). A `#`
|
|
@@ -79,4 +110,22 @@ export type Features = {
|
|
|
79
110
|
* decidable feature.
|
|
80
111
|
*/
|
|
81
112
|
satisfies: Array<string>;
|
|
113
|
+
/**
|
|
114
|
+
* Each edge this member *carries*, paired with whether the format that renders the
|
|
115
|
+
* member placed it — the feature a `format-places-edges` clause decides over. The
|
|
116
|
+
* carried set is the lock's `assembly` `edge` facts for this member's kind, narrowed
|
|
117
|
+
* to the fields its own row fills; the placed set is its
|
|
118
|
+
* [`NestedMemberRow::placed_edges`](crate::drift::NestedMemberRow::placed_edges),
|
|
119
|
+
* which `emit` captured while rendering. It arrives as a declaration row because
|
|
120
|
+
* the engine never sees the `render` hook and never reads a projection back.
|
|
121
|
+
*
|
|
122
|
+
* The two ways a member offers nothing to indict stay apart, because an empty map
|
|
123
|
+
* standing for both is what would leave the clause undecidable: `None` is no format
|
|
124
|
+
* at all (a layout host's document is source, so no rendering happened, and a kind
|
|
125
|
+
* declaring no edge places nothing either way), `Some` over an empty map is a format
|
|
126
|
+
* that ran with no carried edge to place. Both hold; neither is a fabricated pass.
|
|
127
|
+
*/
|
|
128
|
+
edge_placements: {
|
|
129
|
+
[key in string]: boolean;
|
|
130
|
+
} | null;
|
|
82
131
|
};
|
|
@@ -1,4 +1,6 @@
|
|
|
1
|
+
import type { CollectionAddressRow } from "./CollectionAddressRow.js";
|
|
1
2
|
import type { LayoutRow } from "./LayoutRow.js";
|
|
3
|
+
import type { TemplateRow } from "./TemplateRow.js";
|
|
2
4
|
/**
|
|
3
5
|
* One kind's declaration row — its identity and declared runtime facts.
|
|
4
6
|
* The optional facts are omitted from the lock when the kind declares none, so the row
|
|
@@ -14,13 +16,29 @@ export type KindFactRow = {
|
|
|
14
16
|
*/
|
|
15
17
|
provider?: string;
|
|
16
18
|
/**
|
|
17
|
-
* The `governs` locus root directory.
|
|
19
|
+
* The `governs` locus root directory. Absent together with
|
|
20
|
+
* [`governs_glob`](KindFactRow::governs_glob) for a **nested file** kind: its members'
|
|
21
|
+
* paths compose from their host's unit and the host template's pattern, so it governs
|
|
22
|
+
* no glob of its own and two kinds still never share one.
|
|
18
23
|
*/
|
|
19
|
-
governs_root
|
|
24
|
+
governs_root?: string;
|
|
20
25
|
/**
|
|
21
|
-
* The `governs` locus filename glob
|
|
26
|
+
* The `governs` locus filename glob, absent for a nested file kind (see
|
|
27
|
+
* [`governs_root`](KindFactRow::governs_root)).
|
|
22
28
|
*/
|
|
23
|
-
governs_glob
|
|
29
|
+
governs_glob?: string;
|
|
30
|
+
/**
|
|
31
|
+
* The file locus's declared **commitment class** label — `local` for a per-machine,
|
|
32
|
+
* uncommitted locus: the kind is declared and reviewed, its members' documents are
|
|
33
|
+
* not. Absent for the committed class every
|
|
34
|
+
* shipped kind takes, so an ordinary row stays byte-identical — the same tolerant
|
|
35
|
+
* round-trip the rest of the optional facts take.
|
|
36
|
+
*
|
|
37
|
+
* A local member's rows never enter the lock, so this column is the *whole* of a
|
|
38
|
+
* local kind's residue here: the row declares the kind, and the documents it governs
|
|
39
|
+
* derive at read time under it.
|
|
40
|
+
*/
|
|
41
|
+
commitment?: string;
|
|
24
42
|
/**
|
|
25
43
|
* The declared projection format label, when declared.
|
|
26
44
|
*/
|
|
@@ -36,16 +54,29 @@ export type KindFactRow = {
|
|
|
36
54
|
*/
|
|
37
55
|
registration?: Array<string>;
|
|
38
56
|
/**
|
|
39
|
-
* The
|
|
40
|
-
*
|
|
57
|
+
* The kind's declared nesting templates — one [`TemplateRow`] per inner layer of
|
|
58
|
+
* nested members it hosts. Empty for
|
|
41
59
|
* a kind that nests nothing, the tolerant round-trip a lockless/template-less
|
|
42
60
|
* kind takes.
|
|
43
61
|
*/
|
|
44
|
-
templates?: Array<
|
|
62
|
+
templates?: Array<TemplateRow>;
|
|
45
63
|
/**
|
|
46
64
|
* The declared content: absent for a `file`-content kind (the default the whole
|
|
47
65
|
* built-in set takes, so those rows stay byte-identical), a [`LayoutRow`] for a
|
|
48
66
|
* kind whose body is a declared layout over its heading tree.
|
|
49
67
|
*/
|
|
50
68
|
content?: LayoutRow;
|
|
69
|
+
/**
|
|
70
|
+
* The **fields-only** body-shape marker — `fields` for a no-body-slot kind (a hook,
|
|
71
|
+
* an MCP server); absent for a body-bearing kind, whose body is `file` or a `content`
|
|
72
|
+
* layout. The tolerant `#[serde(default)]` round-trip the rest of the optional facts
|
|
73
|
+
* take, so a body-bearing kind's row stays byte-identical.
|
|
74
|
+
*/
|
|
75
|
+
shape?: string;
|
|
76
|
+
/**
|
|
77
|
+
* The declared **collection address** — for a registration member surfacing inside a
|
|
78
|
+
* host manifest, which manifest and which key path it keys at. Absent for a
|
|
79
|
+
* file-locus kind, so an ordinary row stays byte-identical.
|
|
80
|
+
*/
|
|
81
|
+
collection_address?: CollectionAddressRow;
|
|
51
82
|
};
|
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* One authored `n` mention edge's declaration row — the citing member's own
|
|
3
3
|
* `kind:name` address and the address its mention names (another member's
|
|
4
|
-
* `kind:name`, or a bare requirement name)
|
|
5
|
-
*
|
|
6
|
-
*
|
|
4
|
+
* `kind:name`, or a bare requirement name). Recorded unconditionally, carrying no
|
|
5
|
+
* resolution state of its own: `emit` refuses a mention naming no declared kind
|
|
6
|
+
* before a byte is written, while a mention naming a declared kind with no composed
|
|
7
|
+
* member defers — its row rides the lock for `check` to resolve against the
|
|
8
|
+
* discovered corpus.
|
|
7
9
|
*/
|
|
8
10
|
export type MentionRow = {
|
|
9
11
|
/**
|
|
@@ -36,4 +36,36 @@ export type NestedMemberRow = {
|
|
|
36
36
|
collections: {
|
|
37
37
|
[key in string]: Array<CollectionEntryWire>;
|
|
38
38
|
};
|
|
39
|
+
/**
|
|
40
|
+
* The declared edge fields this value's **format placed** — which of them the
|
|
41
|
+
* format selected while `emit` rendered the value, sorted. The engine never sees
|
|
42
|
+
* a format and never reads a rendering back, so an edge's placement reaches it
|
|
43
|
+
* here or not at all; the declared set it is measured against is the `assembly`
|
|
44
|
+
* family's `edge` facts for [`kind`](Self::kind).
|
|
45
|
+
*
|
|
46
|
+
* `None` and `Some(vec![])` are distinct, and the distinction is the whole point:
|
|
47
|
+
* `Some(vec![])` is a format that placed no edge (a `format-places-edges` finding
|
|
48
|
+
* per declared edge), while `None` is a value **no format rendered** — a member
|
|
49
|
+
* embedded in a layout document is read off its host's declared layout, so it has
|
|
50
|
+
* no format to omit anything and the clause has nothing to decide. Absent from a
|
|
51
|
+
* row whose value no format rendered, so an ordinary row stays byte-identical.
|
|
52
|
+
*/
|
|
53
|
+
placed_edges?: Array<string>;
|
|
54
|
+
/**
|
|
55
|
+
* The value's **rendered extent** in lines — the line count of the block `emit`
|
|
56
|
+
* projected for this member, captured off the same render, so an `extent` clause bound
|
|
57
|
+
* to the embedded kind budgets real data instead of a hardcoded zero.
|
|
58
|
+
*
|
|
59
|
+
* `None` is a member **no format rendered** — one embedded in a layout document, read
|
|
60
|
+
* off its host's declared layout rather than projected — which has no rendered span to
|
|
61
|
+
* measure, so its `extent` stays undecidable. Absent from such a row, so an ordinary
|
|
62
|
+
* row stays byte-identical (the [`placed_edges`](Self::placed_edges) precedent).
|
|
63
|
+
*/
|
|
64
|
+
rendered_lines?: number;
|
|
65
|
+
/**
|
|
66
|
+
* The value's **rendered extent** in characters — the second unit an `extent` clause
|
|
67
|
+
* measures in, captured off the same render. `None` on the same terms as
|
|
68
|
+
* [`rendered_lines`](Self::rendered_lines).
|
|
69
|
+
*/
|
|
70
|
+
rendered_chars?: number;
|
|
39
71
|
};
|
|
@@ -13,6 +13,12 @@ export type PayloadMember = {
|
|
|
13
13
|
* Identity within the kind.
|
|
14
14
|
*/
|
|
15
15
|
name: string;
|
|
16
|
+
/**
|
|
17
|
+
* The `kind:name` address of the host member this member's unit composes under —
|
|
18
|
+
* carried by a **nested file** child, whose path is its host's unit joined with the
|
|
19
|
+
* host template's pattern; absent at every other locus.
|
|
20
|
+
*/
|
|
21
|
+
host?: string;
|
|
16
22
|
/**
|
|
17
23
|
* The kind's typed fields, flat and ordered — the projected frontmatter. The
|
|
18
24
|
* value is arbitrary JSON, so the seam type is `unknown`, never a serde_json
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One fields-only registration member the SDK erased for the manifest write face — a
|
|
3
|
+
* hook, an MCP server — carried across the seam so `emit` routes its host manifest whole
|
|
4
|
+
* through the canonical write face ([`crate::json_manifest::write_manifest`]) rather than
|
|
5
|
+
* the unrepresented in-place splice. `kind`/`key` are the member's identity; `manifest`/
|
|
6
|
+
* `key_path` name the collection address it surfaces at; `fields` are its folded typed
|
|
7
|
+
* fields — the entry value the write face places under `key`.
|
|
8
|
+
*
|
|
9
|
+
* **Seam-inbound with `fields`.** The lock's `registration` declaration family records
|
|
10
|
+
* only the identity and address: the fields live in the projected manifest artifact, never
|
|
11
|
+
* a second copy the engine reads back (0018, "the projection is not the database"), so a
|
|
12
|
+
* row read back off the lock carries an empty `fields`.
|
|
13
|
+
*/
|
|
14
|
+
export type RegistrationRow = {
|
|
15
|
+
/**
|
|
16
|
+
* The registration kind's bare name — `hook`, `mcp-server` — joining `declarations.kinds`.
|
|
17
|
+
*/
|
|
18
|
+
kind: string;
|
|
19
|
+
/**
|
|
20
|
+
* The member's key among its collection's entries — a hook's event, a server's name.
|
|
21
|
+
*/
|
|
22
|
+
key: string;
|
|
23
|
+
/**
|
|
24
|
+
* The host manifest the registration surfaces in (`settings.json`, `.mcp.json`).
|
|
25
|
+
*/
|
|
26
|
+
manifest: string;
|
|
27
|
+
/**
|
|
28
|
+
* The manifest key-path label the registration keys at (`hooks.<Event>`, `mcpServers.*`).
|
|
29
|
+
*/
|
|
30
|
+
key_path: string;
|
|
31
|
+
/**
|
|
32
|
+
* The member's folded typed fields — seam-inbound only, dropped from the lock row.
|
|
33
|
+
*/
|
|
34
|
+
fields: Array<[string, unknown]>;
|
|
35
|
+
};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { ClauseRow } from "./ClauseRow.js";
|
|
2
|
+
import type { Verifier } from "./Verifier.js";
|
|
2
3
|
/**
|
|
3
4
|
* One named requirement's declaration row,
|
|
4
5
|
* carrying the scalar facets plus the requirement's own **clause rows** — the
|
|
@@ -29,9 +30,10 @@ export type RequirementRow = {
|
|
|
29
30
|
*/
|
|
30
31
|
clauses: Array<ClauseRow>;
|
|
31
32
|
/**
|
|
32
|
-
* The
|
|
33
|
+
* The typed verifier for the behavioral remainder, when declared — a
|
|
34
|
+
* species-tagged [`Verifier`], resolved at admissibility, never run.
|
|
33
35
|
*/
|
|
34
|
-
|
|
36
|
+
verifier?: Verifier;
|
|
35
37
|
/**
|
|
36
38
|
* The authored intent the requirement exists to carry, when declared —
|
|
37
39
|
* carried verbatim, never interpreted.
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One harness-level settings-residue key the SDK erased for the manifest write face — an
|
|
3
|
+
* opaque top-level key of the manifest it names (Claude Code's `settings.json`) with no
|
|
4
|
+
* typed member kind of its own yet. Carried across the seam so `emit` folds it into that
|
|
5
|
+
* manifest's opaque residue beside the collection segments its registration members build.
|
|
6
|
+
*
|
|
7
|
+
* **Seam-inbound with `value`.** Like a composed-prose include, this row is consumed at
|
|
8
|
+
* emit and never written into the lock's declaration table: the value lives in the
|
|
9
|
+
* projected manifest artifact, never a second copy the engine reads back (0018), so a lock
|
|
10
|
+
* round-trip carries none.
|
|
11
|
+
*/
|
|
12
|
+
export type SettingsRow = {
|
|
13
|
+
/**
|
|
14
|
+
* The host manifest the residue key surfaces in (`settings.json`).
|
|
15
|
+
*/
|
|
16
|
+
manifest: string;
|
|
17
|
+
/**
|
|
18
|
+
* The residue key — an opaque top-level manifest key with no member home.
|
|
19
|
+
*/
|
|
20
|
+
key: string;
|
|
21
|
+
/**
|
|
22
|
+
* The key's opaque JSON value, placed verbatim into the manifest's residue.
|
|
23
|
+
*/
|
|
24
|
+
value: unknown;
|
|
25
|
+
};
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The closed set of value forms a [`Predicate::Shape`] clause may name.
|
|
3
|
+
*
|
|
4
|
+
* A member exists only where an external document states the rule and this engine
|
|
5
|
+
* implements it, so the set is closed by construction and an author extends it with
|
|
6
|
+
* nothing: the enum *is* the vocabulary, and [`from_name`](Shape::from_name) rejects
|
|
7
|
+
* anything outside it at load. That closure is the whole safety property — it is what
|
|
8
|
+
* separates a shape from an open lint, which no clause may become.
|
|
9
|
+
*
|
|
10
|
+
* Each member's mechanics are one regex plus a polarity: [`pattern`](Shape::pattern) is
|
|
11
|
+
* the expression, [`match_holds`](Shape::match_holds) says whether matching it means the
|
|
12
|
+
* shape holds or is violated. One definition serves both the gate and the emitted
|
|
13
|
+
* schema, so the two channels cannot decide the same shape differently.
|
|
14
|
+
*/
|
|
15
|
+
export type Shape = "hyphen-placement" | "no-xml-tags" | "leading-dot-slash";
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A kind's declared **nesting template** row — one inner layer of nested members the
|
|
3
|
+
* kind hosts: the child kind, plus the `path` pattern (relative to the parent's unit)
|
|
4
|
+
* when that layer's children are files (`model/representation.md`, "kind"). The child
|
|
5
|
+
* kind alone means an embedded layer: the children live in the host's own body, so no
|
|
6
|
+
* path addresses them.
|
|
7
|
+
*
|
|
8
|
+
* A declared template is the kind's own nesting *fact*, never a resolution rule: a
|
|
9
|
+
* host's actual embedded members are resolved off [`Declarations::nested_members`] by
|
|
10
|
+
* address, and nothing discovers a file child off its `path` pattern.
|
|
11
|
+
*/
|
|
12
|
+
export type TemplateRow = {
|
|
13
|
+
/**
|
|
14
|
+
* The child kind this layer templates — the `member.<kind>` an embedded child's
|
|
15
|
+
* fence info string carries, or the kind a file child's unit is read as.
|
|
16
|
+
*/
|
|
17
|
+
kind: string;
|
|
18
|
+
/**
|
|
19
|
+
* The path pattern a file child's unit sits at, relative to the parent's unit
|
|
20
|
+
* (a skill's `*.md`). Absent for an embedded layer, whose children have no unit of
|
|
21
|
+
* their own.
|
|
22
|
+
*/
|
|
23
|
+
path?: string;
|
|
24
|
+
};
|
|
@@ -3,7 +3,16 @@
|
|
|
3
3
|
* field schema ranges over. Taken from the *parsed*
|
|
4
4
|
* YAML/JSON value, not its stringified form: a sound `type` check needs the
|
|
5
5
|
* extractor to preserve the source kind rather than collapse every scalar to a
|
|
6
|
-
* bare string
|
|
6
|
+
* bare string. The five scalar kinds
|
|
7
7
|
* answer [`FeatureValue::as_scalar`]; the two container kinds do not.
|
|
8
|
+
*
|
|
9
|
+
* The binding renames to lowercase so the TS spelling is the one
|
|
10
|
+
* [`ValueType::from_name`] decodes — the lattice has one name across the seam,
|
|
11
|
+
* and a `type` clause's declared kind crosses the lock in that spelling.
|
|
12
|
+
*
|
|
13
|
+
* `Ord` is the declaration order above, and it is what gives a declared *set* of
|
|
14
|
+
* kinds one canonical spelling: a `type` clause holds its kinds in a `BTreeSet`, so
|
|
15
|
+
* the order an author wrote them in never reaches the lock, the diagnostic, or the
|
|
16
|
+
* emitted schema.
|
|
8
17
|
*/
|
|
9
|
-
export type ValueType = "
|
|
18
|
+
export type ValueType = "string" | "integer" | "number" | "boolean" | "null" | "list" | "map";
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* A requirement's **typed verifier** — the declared delegate that judges the
|
|
3
|
+
* behavioral remainder, resolved at admissibility and never run. Two species this
|
|
4
|
+
* slice; a probe stays a documented pattern until a consumer types its transcript
|
|
5
|
+
* surface. One shared shape: [`crate::drift::RequirementRow`] carries it on the
|
|
6
|
+
* wire and [`crate::roster`] resolves over it.
|
|
7
|
+
*/
|
|
8
|
+
export type Verifier = {
|
|
9
|
+
"species": "script";
|
|
10
|
+
/**
|
|
11
|
+
* The test/CI path, relative to the harness root.
|
|
12
|
+
*/
|
|
13
|
+
path: string;
|
|
14
|
+
} | {
|
|
15
|
+
"species": "telemetry";
|
|
16
|
+
/**
|
|
17
|
+
* The harness lifecycle event names this verifier reads the tap for.
|
|
18
|
+
*/
|
|
19
|
+
events: Array<string>;
|
|
20
|
+
};
|
|
@@ -2,6 +2,7 @@ export type { AssemblyFactRow } from "./AssemblyFactRow.js";
|
|
|
2
2
|
export type { BoundRow } from "./BoundRow.js";
|
|
3
3
|
export type { CharsetRow } from "./CharsetRow.js";
|
|
4
4
|
export type { ClauseRow } from "./ClauseRow.js";
|
|
5
|
+
export type { CollectionAddressRow } from "./CollectionAddressRow.js";
|
|
5
6
|
export type { CollectionEntryRow } from "./CollectionEntryRow.js";
|
|
6
7
|
export type { CollectionEntryWire } from "./CollectionEntryWire.js";
|
|
7
8
|
export type { CountBoundRow } from "./CountBoundRow.js";
|
|
@@ -22,8 +23,13 @@ export type { NestedMemberRow } from "./NestedMemberRow.js";
|
|
|
22
23
|
export type { Payload } from "./Payload.js";
|
|
23
24
|
export type { PayloadMember } from "./PayloadMember.js";
|
|
24
25
|
export type { RangeBoundRow } from "./RangeBoundRow.js";
|
|
26
|
+
export type { RegistrationRow } from "./RegistrationRow.js";
|
|
25
27
|
export type { RequirementRow } from "./RequirementRow.js";
|
|
26
28
|
export type { SatisfiesRow } from "./SatisfiesRow.js";
|
|
27
29
|
export type { Section } from "./Section.js";
|
|
28
30
|
export type { SectionContainsRow } from "./SectionContainsRow.js";
|
|
31
|
+
export type { SettingsRow } from "./SettingsRow.js";
|
|
32
|
+
export type { Shape } from "./Shape.js";
|
|
33
|
+
export type { TemplateRow } from "./TemplateRow.js";
|
|
29
34
|
export type { ValueType } from "./ValueType.js";
|
|
35
|
+
export type { Verifier } from "./Verifier.js";
|