@dtmd/temper 0.0.18 → 0.0.19
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/dist/src/assembly.d.ts +40 -0
- package/dist/src/assembly.js +43 -0
- package/dist/src/builtins.d.ts +110 -4
- package/dist/src/builtins.js +64 -3
- package/dist/src/claude-code.d.ts +2 -2
- package/dist/src/claude-code.js +1 -1
- package/dist/src/contract.d.ts +96 -3
- package/dist/src/contract.js +89 -2
- package/dist/src/declarations.js +104 -17
- package/dist/src/generated/ClauseRow.d.ts +21 -6
- package/dist/src/generated/Declarations.d.ts +8 -0
- package/dist/src/generated/InputRow.d.ts +21 -0
- package/dist/src/generated/InputRow.js +2 -0
- package/dist/src/generated/KindFactRow.d.ts +12 -0
- package/dist/src/generated/index.d.ts +1 -0
- package/dist/src/index.d.ts +6 -5
- package/dist/src/index.js +8 -4
- package/dist/src/kind.d.ts +102 -7
- package/dist/src/kind.js +108 -3
- package/dist/src/prose.d.ts +22 -5
- package/dist/src/prose.js +39 -7
- package/package.json +3 -3
package/dist/src/declarations.js
CHANGED
|
@@ -69,13 +69,24 @@ function clauseRow(clause, kind) {
|
|
|
69
69
|
count: predicate.key === "count"
|
|
70
70
|
? { min: predicate.args?.min ?? 0, max: predicate.args?.max ?? Number.MAX_SAFE_INTEGER }
|
|
71
71
|
: undefined,
|
|
72
|
-
|
|
72
|
+
// The requirement-name column `membership`'s allowed-value target and
|
|
73
|
+
// `reached-from`'s closure roots share — one naming scheme for "the requirement
|
|
74
|
+
// whose satisfiers this clause reads" (`src/contract.rs` `predicate_from_row`).
|
|
75
|
+
target: predicate.key === "membership" || predicate.key === "reached-from"
|
|
76
|
+
? predicate.target
|
|
77
|
+
: undefined,
|
|
73
78
|
degree: predicate.key === "degree"
|
|
74
79
|
? {
|
|
75
80
|
incoming: edgeBoundArgs(predicate.args, "incoming"),
|
|
76
81
|
outgoing: edgeBoundArgs(predicate.args, "outgoing"),
|
|
77
82
|
}
|
|
78
83
|
: undefined,
|
|
84
|
+
// The by-incidence field set rides its own shared column, not the direction-only
|
|
85
|
+
// `degree` bound — the slot `reached-from`'s via set joins it. Copied into a
|
|
86
|
+
// fresh array: the predicate's set is read-only, the row's column is not.
|
|
87
|
+
fields: (predicate.key === "degree" || predicate.key === "reached-from") && predicate.fields
|
|
88
|
+
? [...predicate.fields]
|
|
89
|
+
: undefined,
|
|
79
90
|
gate: predicate.key === "mention-reachable" ? predicate.gate : undefined,
|
|
80
91
|
value_type: predicate.key === "type" && predicate.value_type ? [...predicate.value_type] : undefined,
|
|
81
92
|
shape: predicate.key === "shape" ? predicate.shape : undefined,
|
|
@@ -106,17 +117,18 @@ function clauseRow(clause, kind) {
|
|
|
106
117
|
};
|
|
107
118
|
}
|
|
108
119
|
/**
|
|
109
|
-
* The `field` column for one predicate: the field it names, or — for the
|
|
110
|
-
* predicates that name a *section*
|
|
111
|
-
* from the arguments the row already carries.
|
|
120
|
+
* The `field` column for one predicate: the field it names, or — for the four
|
|
121
|
+
* predicates that name a *section*, a field *set*, or a *requirement* rather than a
|
|
122
|
+
* field — an identity synthesized from the arguments the row already carries.
|
|
112
123
|
*
|
|
113
|
-
* `section_contains` and `
|
|
114
|
-
* emit stamps a clause's label from (`stamp_clause_label`,
|
|
115
|
-
* reading `Predicate.field` folds every clause of
|
|
116
|
-
* into one label — two rows wearing one label, which
|
|
117
|
-
* malformed lock. Synthesizing here keeps the whole fix at
|
|
118
|
-
* reader reconstructs
|
|
119
|
-
* never from this one, so nothing
|
|
124
|
+
* `section_contains`, `require_sections`, `degree` and `reached-from` set no `field`,
|
|
125
|
+
* and the column is what emit stamps a clause's label from (`stamp_clause_label`,
|
|
126
|
+
* `src/drift.rs`), so reading `Predicate.field` folds every clause of one of those
|
|
127
|
+
* predicates on one kind into one label — two rows wearing one label, which
|
|
128
|
+
* admissibility refuses as a malformed lock. Synthesizing here keeps the whole fix at
|
|
129
|
+
* the lowering: the Rust reader reconstructs all four predicates from the
|
|
130
|
+
* `section`/`sections`/`fields`/`target` columns and never from this one, so nothing
|
|
131
|
+
* round-trips through the synthesized text.
|
|
120
132
|
*/
|
|
121
133
|
function clauseField(predicate) {
|
|
122
134
|
if (predicate.key === "section_contains") {
|
|
@@ -128,6 +140,31 @@ function clauseField(predicate) {
|
|
|
128
140
|
// set it is and two different heading lists cannot fold to one label.
|
|
129
141
|
return predicate.sections?.join("+");
|
|
130
142
|
}
|
|
143
|
+
if (predicate.key === "degree") {
|
|
144
|
+
// A `degree` clause names no field of its own: its by-incidence filter is what
|
|
145
|
+
// distinguishes two bounds on one kind, so the filter is the segment — sorted and
|
|
146
|
+
// `+`-joined by the rule directly above, so two field lists spelling one set land
|
|
147
|
+
// one address and two different sets never fold to one. An unfiltered bound adds
|
|
148
|
+
// no segment: it ranges over every edge at the member, so two of them on one kind
|
|
149
|
+
// are a redundancy the author collapses, never a distinction an address must hold.
|
|
150
|
+
return predicate.fields === undefined ? undefined : [...predicate.fields].sort().join("+");
|
|
151
|
+
}
|
|
152
|
+
if (predicate.key === "reached-from") {
|
|
153
|
+
// A `reached-from` clause names no field either: its identity is the pair it walks.
|
|
154
|
+
// The roots requirement leads, and a declared via set follows after a `.` — the
|
|
155
|
+
// two-argument `section_contains` precedent — sorted and `+`-joined by `degree`'s
|
|
156
|
+
// rule directly above. So two closures rooted at one requirement over different
|
|
157
|
+
// arcs land two addresses instead of folding into one, and two spellings of one via
|
|
158
|
+
// set land one. An unfiltered closure adds no second segment: the roots are its
|
|
159
|
+
// whole identity, and two of them on one kind are a redundancy the author
|
|
160
|
+
// collapses.
|
|
161
|
+
const { target } = predicate;
|
|
162
|
+
if (target === undefined)
|
|
163
|
+
return undefined;
|
|
164
|
+
return predicate.fields === undefined
|
|
165
|
+
? target
|
|
166
|
+
: `${target}.${[...predicate.fields].sort().join("+")}`;
|
|
167
|
+
}
|
|
131
168
|
return predicate.field;
|
|
132
169
|
}
|
|
133
170
|
/** `min_len`/`max_len`/`extent`'s scalar bound off their shared `min`/`max`
|
|
@@ -267,6 +304,16 @@ function collectionAddressRow(facts) {
|
|
|
267
304
|
entry_shape: facts.collectionAddress.entryShape,
|
|
268
305
|
};
|
|
269
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* Lower a kind's exhaustive leaf-set witness into the row's `leaves` column: the
|
|
309
|
+
* witness's own keys, in the order its author declared them (`kind.ts`'s `LeafSet`,
|
|
310
|
+
* decision 0053 — the type is the declaration, and TypeScript erases it, so the record is
|
|
311
|
+
* how the corpus hands the key set over). `undefined` for a kind declaring no witness, so
|
|
312
|
+
* its row omits the column.
|
|
313
|
+
*/
|
|
314
|
+
function leafSetRow(leaves) {
|
|
315
|
+
return leaves === undefined ? undefined : Object.keys(leaves);
|
|
316
|
+
}
|
|
270
317
|
/**
|
|
271
318
|
* One kind's fact row — an `at` locus supplies `governs_root`/`governs_glob` and any
|
|
272
319
|
* other locus neither (a nested-file kind's path composes from its host's unit and the
|
|
@@ -274,7 +321,8 @@ function collectionAddressRow(facts) {
|
|
|
274
321
|
* A file locus's `commitment` class rides the same spelling, absent for the committed
|
|
275
322
|
* default. `templates` names the embedded kinds the corpus admits over it, and `content`
|
|
276
323
|
* lowers a declared layout (absent for a `file`-content kind). A registration kind
|
|
277
|
-
* extends the row with its `shape` marker and `collection_address`.
|
|
324
|
+
* extends the row with its `shape` marker and `collection_address`. A declared leaf-set
|
|
325
|
+
* witness lowers to `leaves` ([`leafSetRow`]), absent for a kind declaring none. Advisory
|
|
278
326
|
* `guidance`/`cite` pair rides alongside, locus-optional so an embedded kind's own
|
|
279
327
|
* counsel reaches the lock the same way a nested-file kind's already does (decision
|
|
280
328
|
* 0045) — callable for any locus; [`kindFactKindsInPlay`] decides which embedded kinds
|
|
@@ -294,6 +342,7 @@ function kindFactRow(facts, admissions) {
|
|
|
294
342
|
templates: templatesFor(facts, admissions),
|
|
295
343
|
content: contentRow(facts.content),
|
|
296
344
|
shape: facts.shape,
|
|
345
|
+
leaves: leafSetRow(facts.leaves),
|
|
297
346
|
collection_address: collectionAddressRow(facts),
|
|
298
347
|
guidance: facts.guidance,
|
|
299
348
|
cite: facts.cite,
|
|
@@ -436,13 +485,20 @@ function atLocusKindsInPlay(allKinds) {
|
|
|
436
485
|
/**
|
|
437
486
|
* The distinct kinds in play that take a kind-fact row: every non-embedded locus
|
|
438
487
|
* unconditionally (a nested-file kind owns a file the engine must place, and places it
|
|
439
|
-
* off its row, though it governs no glob to be discovered at), plus an embedded kind
|
|
440
|
-
*
|
|
441
|
-
*
|
|
442
|
-
*
|
|
488
|
+
* off its row, though it governs no glob to be discovered at), plus an embedded kind that
|
|
489
|
+
* has something of its own for a row to carry: `guidance` or `cite` (decision 0045), or a
|
|
490
|
+
* declared leaf set (decision 0053). The leaf set is on this list for the reason the
|
|
491
|
+
* column exists — it teaches what a child carries *before* the surface holds a member of
|
|
492
|
+
* it, and an embedded kind taking no row never reaches the lock to teach it. An embedded
|
|
493
|
+
* kind declaring none of the three has nothing for the row to carry, and its members
|
|
494
|
+
* already reach the corpus through their host's `templates` column alone (`kindsInPlay`),
|
|
495
|
+
* never the row.
|
|
443
496
|
*/
|
|
444
497
|
function kindFactKindsInPlay(allKinds) {
|
|
445
|
-
return allKinds.filter((facts) => facts.locus.kind !== "embedded" ||
|
|
498
|
+
return allKinds.filter((facts) => facts.locus.kind !== "embedded" ||
|
|
499
|
+
facts.guidance !== undefined ||
|
|
500
|
+
facts.cite !== undefined ||
|
|
501
|
+
facts.leaves !== undefined);
|
|
446
502
|
}
|
|
447
503
|
/** The requirement rows — assembly `require` and every member's `requires`, one namespace. */
|
|
448
504
|
function requirementRows(harness) {
|
|
@@ -611,6 +667,27 @@ function includeRows(harness) {
|
|
|
611
667
|
}
|
|
612
668
|
return rows;
|
|
613
669
|
}
|
|
670
|
+
/**
|
|
671
|
+
* The `input` rows — every member's declared inputs, in member-then-authored order.
|
|
672
|
+
* Each carries the declaring member's `kind:name` address and the input's path resolved
|
|
673
|
+
* against the stating module ({@link fileURLToPath} over the input's own `moduleUrl`),
|
|
674
|
+
* never the workspace — exactly as an include's is; the engine reads and fingerprints
|
|
675
|
+
* it, and splices nothing.
|
|
676
|
+
*
|
|
677
|
+
* Unlike an include, an input pairs with no body slot, so nothing downstream depends on
|
|
678
|
+
* this order — the authored one is kept anyway, so a re-emit is byte-stable and the
|
|
679
|
+
* author reads their own declarations back.
|
|
680
|
+
*/
|
|
681
|
+
function inputRows(harness) {
|
|
682
|
+
const rows = [];
|
|
683
|
+
for (const member of harness.members) {
|
|
684
|
+
const address = hostAddress(member.kind, member.name);
|
|
685
|
+
for (const declared of member.inputs) {
|
|
686
|
+
rows.push({ member: address, source_path: fileURLToPath(new URL(declared.path, declared.moduleUrl)) });
|
|
687
|
+
}
|
|
688
|
+
}
|
|
689
|
+
return rows;
|
|
690
|
+
}
|
|
614
691
|
/**
|
|
615
692
|
* One composed embedded value's key in an {@link EdgePlacements} table — its host's
|
|
616
693
|
* `kind:name` address plus the value's own kind and key, the same triple the
|
|
@@ -891,6 +968,15 @@ export function compileDeclarations(harness, placements, extents) {
|
|
|
891
968
|
clauses.push(clauseRow(clause, binding.kind.key));
|
|
892
969
|
}
|
|
893
970
|
}
|
|
971
|
+
// The root member's own clauses — the third source of a clause row, beside `expect`'s
|
|
972
|
+
// kind-keyed rows and a requirement's nested ones. They lower with **no** `kind`
|
|
973
|
+
// column: that absence at the top level is the discriminator
|
|
974
|
+
// `compose::root_contract_from_rows` reads, and `drift::stamp_clause_labels` addresses
|
|
975
|
+
// them under the `root` owner segment. Declaration order within the array, appended
|
|
976
|
+
// past the kind-sorted `expect` rows — a fixed position, so double emit is byte-stable.
|
|
977
|
+
for (const clause of harness.contract) {
|
|
978
|
+
clauses.push(clauseRow(clause, undefined));
|
|
979
|
+
}
|
|
894
980
|
return {
|
|
895
981
|
kinds: kindFactKindsInPlay(allKinds).map((facts) => kindFactRow(facts, admissions)),
|
|
896
982
|
clauses,
|
|
@@ -899,6 +985,7 @@ export function compileDeclarations(harness, placements, extents) {
|
|
|
899
985
|
satisfies: satisfiesRows(harness),
|
|
900
986
|
mentions: mentionRows(harness),
|
|
901
987
|
includes: includeRows(harness),
|
|
988
|
+
inputs: inputRows(harness),
|
|
902
989
|
nested_members: nestedMemberRows(harness, admissions, mentionScope(harness), placements, extents),
|
|
903
990
|
registrations: [...registrationRows(harness), ...tapHookRows(harness)],
|
|
904
991
|
settings: settingsRows(harness),
|
|
@@ -38,10 +38,11 @@ export type ClauseRow = {
|
|
|
38
38
|
*/
|
|
39
39
|
label?: string;
|
|
40
40
|
/**
|
|
41
|
-
* The kind whose contract carries the clause. `None`
|
|
42
|
-
* inside a [`RequirementRow`]'s own
|
|
43
|
-
* requirement's set-scope demand
|
|
44
|
-
* whatever kind the requirement's own row already carries
|
|
41
|
+
* The kind whose contract carries the clause. `None` has two homes, distinguished
|
|
42
|
+
* by nesting rather than by a second column: inside a [`RequirementRow`]'s own
|
|
43
|
+
* [`clauses`](RequirementRow::clauses) it is the requirement's set-scope demand,
|
|
44
|
+
* ranging over whatever kind the requirement's own row already carries; at the top
|
|
45
|
+
* level it is the **root member's** clause, ranging over the whole governed forest.
|
|
45
46
|
*/
|
|
46
47
|
kind?: string;
|
|
47
48
|
/**
|
|
@@ -78,14 +79,28 @@ export type ClauseRow = {
|
|
|
78
79
|
*/
|
|
79
80
|
count?: CountBoundRow;
|
|
80
81
|
/**
|
|
81
|
-
* The
|
|
82
|
-
* `membership
|
|
82
|
+
* The **requirement name** whose satisfiers a clause reads its second selection
|
|
83
|
+
* from — two owners, one naming scheme: `membership`'s allowed-set source and
|
|
84
|
+
* `reached-from`'s closure roots. Both ask the same question of the same column
|
|
85
|
+
* ("which requirement's satisfiers?"), so a second column would be the residue
|
|
86
|
+
* class ([`crate::contract::predicate_from_row`] decodes either from here).
|
|
83
87
|
*/
|
|
84
88
|
target?: string;
|
|
85
89
|
/**
|
|
86
90
|
* The `degree` clause's in/out edge-count bound, when the predicate is `degree`.
|
|
87
91
|
*/
|
|
88
92
|
degree?: DegreeBoundRow;
|
|
93
|
+
/**
|
|
94
|
+
* The **field set** a by-incidence clause filters its selection to — `degree`'s
|
|
95
|
+
* bound and `reached-from`'s via set (`specs/decisions/0056-…`). Shared rather
|
|
96
|
+
* than nested inside [`DegreeBoundRow`] because the filter is the *clause's*, not
|
|
97
|
+
* either direction's, and the two consumers name one concept: a lock spelling it
|
|
98
|
+
* twice would be the residue class.
|
|
99
|
+
*
|
|
100
|
+
* Absent ⇒ unfiltered, so no committed lock row moves when a clause declares no
|
|
101
|
+
* filter.
|
|
102
|
+
*/
|
|
103
|
+
fields?: Array<string>;
|
|
89
104
|
/**
|
|
90
105
|
* The `mention-reachable` clause's **target-side gate field**, when the predicate
|
|
91
106
|
* is `mention-reachable`. The one predicate taking two field arguments: its
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import type { AssemblyFactRow } from "./AssemblyFactRow.js";
|
|
2
2
|
import type { ClauseRow } from "./ClauseRow.js";
|
|
3
3
|
import type { IncludeRow } from "./IncludeRow.js";
|
|
4
|
+
import type { InputRow } from "./InputRow.js";
|
|
4
5
|
import type { KindFactRow } from "./KindFactRow.js";
|
|
5
6
|
import type { MentionRow } from "./MentionRow.js";
|
|
6
7
|
import type { NestedMemberRow } from "./NestedMemberRow.js";
|
|
@@ -65,6 +66,13 @@ export type Declarations = {
|
|
|
65
66
|
* declaration table, so a lock round-trip reads it empty).
|
|
66
67
|
*/
|
|
67
68
|
includes: Array<IncludeRow>;
|
|
69
|
+
/**
|
|
70
|
+
* The members' declared inputs — the files their claims rest on. Seam-inbound
|
|
71
|
+
* like `includes`: `emit` resolves and fingerprints each as an `input` source
|
|
72
|
+
* dependency without moving a byte into any projection, so a lock round-trip reads
|
|
73
|
+
* this family empty.
|
|
74
|
+
*/
|
|
75
|
+
inputs: Array<InputRow>;
|
|
68
76
|
/**
|
|
69
77
|
* The host members' declared embedded-member facts — captured as declaration
|
|
70
78
|
* rows rather than a second copy the engine reads back off the rendered fence
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* One **declared input** the SDK declares — a file the member's claims rest on, and the
|
|
3
|
+
* member that rests on it. Its own type, not a reuse of [`IncludeRow`]: an include's
|
|
4
|
+
* path pairs positionally with a body slot, an input's moves nothing, and two concepts
|
|
5
|
+
* sharing two columns are still two concepts.
|
|
6
|
+
*
|
|
7
|
+
* A seam-inbound row only, the same posture an include takes: `emit` resolves it against
|
|
8
|
+
* disk ([`resolve_source_dependency`]) and lowers it to a fingerprinted `input` source
|
|
9
|
+
* dependency — this row itself never reaches the lock. Nothing is spliced and no byte
|
|
10
|
+
* moves, so the target is never decoded and a binary input is legal.
|
|
11
|
+
*/
|
|
12
|
+
export type InputRow = {
|
|
13
|
+
/**
|
|
14
|
+
* The declaring member's own `kind:name` address.
|
|
15
|
+
*/
|
|
16
|
+
member: string;
|
|
17
|
+
/**
|
|
18
|
+
* The input's SDK-resolved absolute path.
|
|
19
|
+
*/
|
|
20
|
+
source_path: string;
|
|
21
|
+
};
|
|
@@ -73,6 +73,18 @@ export type KindFactRow = {
|
|
|
73
73
|
* take, so a body-bearing kind's row stays byte-identical.
|
|
74
74
|
*/
|
|
75
75
|
shape?: string;
|
|
76
|
+
/**
|
|
77
|
+
* The kind's **leaf set** — the leaf names a member of it carries, derived at emit
|
|
78
|
+
* from the member value type the SDK knows, never authored twice (decision 0053).
|
|
79
|
+
* Empty for a kind whose declaration carries none, the same tolerant round-trip
|
|
80
|
+
* [`registration`](KindFactRow::registration) takes, so a committed lock written
|
|
81
|
+
* before the column existed re-reads byte-identically.
|
|
82
|
+
*
|
|
83
|
+
* The declaration a read verb renders where the surface holds no member yet: the
|
|
84
|
+
* type is the declaration, so a present set outranks the union of what members
|
|
85
|
+
* carry today.
|
|
86
|
+
*/
|
|
87
|
+
leaves?: Array<string>;
|
|
76
88
|
/**
|
|
77
89
|
* The declared **collection address** — for a registration member surfacing inside a
|
|
78
90
|
* host manifest, which manifest and which key path it keys at. Absent for a
|
|
@@ -15,6 +15,7 @@ export type { FeatureValue } from "./FeatureValue.js";
|
|
|
15
15
|
export type { Features } from "./Features.js";
|
|
16
16
|
export type { FencedBlock } from "./FencedBlock.js";
|
|
17
17
|
export type { IncludeRow } from "./IncludeRow.js";
|
|
18
|
+
export type { InputRow } from "./InputRow.js";
|
|
18
19
|
export type { KindFactRow } from "./KindFactRow.js";
|
|
19
20
|
export type { LayoutRegionRow } from "./LayoutRegionRow.js";
|
|
20
21
|
export type { LayoutRow } from "./LayoutRow.js";
|
package/dist/src/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* temper's authoring face — the six-noun core as a typed module library.
|
|
3
3
|
* A harness author imports plain nouns — `harness()`, the generic `kind`
|
|
4
|
-
* constructor, the clause and requirement constructors, `needs`, and the
|
|
4
|
+
* constructor, the clause and requirement constructors, `needs`, and the four
|
|
5
5
|
* prose constructors — and composes members as typed values. `emit` compiles the
|
|
6
6
|
* whole into the declaration rows and the projected members' erased payload —
|
|
7
7
|
* the JSON pipe printed to stdout; the engine is the sole compiler of every
|
|
@@ -13,15 +13,16 @@
|
|
|
13
13
|
* the `./claude-code` subpath, never here.
|
|
14
14
|
*/
|
|
15
15
|
export type { Blocks, File, Include, Mention, Mentionable, Prose, Reference, Text } from "./prose.js";
|
|
16
|
-
export { blocks, file, include, mentionOf, renderText, text } from "./prose.js";
|
|
16
|
+
export { blocks, file, include, mentionOf, renderText, span, text } from "./prose.js";
|
|
17
17
|
export type { Capability } from "./needs.js";
|
|
18
18
|
export { bash, capability, permissionUnion } from "./needs.js";
|
|
19
19
|
export type { Charset, Clause, ExtentUnit, Predicate, Requirement, Severity, Verifier } from "./contract.js";
|
|
20
|
-
export { allowedChars, clause, closedKeys, count, degree, deny, enumOf, extent, forbiddenKeys, formatPlacesEdges, globValid, maxLen, membership, mentionReachable, minLen, mustDefine, nameMatchesDir, optional, range, required, requireSections, requirement, script, sectionContains, shape, telemetry, type, unique, uniqueName, when, } from "./contract.js";
|
|
21
|
-
export type { CollectionAddress, EdgeField, EdgeTargetFacts, EmbeddedMemberCollectionEntry, EmbeddedMemberValue, Format, KindDefinition, KindFacts, KindOptions, KindRelocation, Layout, LayoutRegion, Locus, Member, MemberInit, Registration, ResolvedEmbeddedMemberCollectionEntry, ResolvedEmbeddedMemberValue, Shape, Template, UnitShape, } from "./kind.js";
|
|
20
|
+
export { allowedChars, clause, closedKeys, count, degree, deny, enumOf, extent, forbiddenKeys, formatPlacesEdges, fresh, globValid, locusDeclared, maxLen, membership, mentionReachable, minLen, mustDefine, nameMatchesDir, optional, range, reachable, reachedFrom, required, requireSections, requirement, script, sectionContains, shape, telemetry, type, unique, uniqueName, when, } from "./contract.js";
|
|
21
|
+
export type { CollectionAddress, EdgeField, EdgeTargetFacts, EmbeddedMemberCollectionEntry, EmbeddedMemberValue, Format, Input, KindDefinition, KindFacts, KindOptions, KindRelocation, Layout, LayoutRegion, LeafSet, Locus, Member, MemberInit, Registration, Residue, ResolvedEmbeddedMemberCollectionEntry, ResolvedEmbeddedMemberValue, Shape, Template, UnitShape, } from "./kind.js";
|
|
22
22
|
export { embeddedMemberValue, kind, relocate } from "./kind.js";
|
|
23
|
+
export { input } from "./kind.js";
|
|
23
24
|
export type { Admission, EnforcementMode, ExpectBinding, Harness } from "./assembly.js";
|
|
24
|
-
export { harness } from "./assembly.js";
|
|
25
|
+
export { harness, rootDefaultContract } from "./assembly.js";
|
|
25
26
|
export type { EdgeTarget, EmbeddedTarget, EmitResult, RegistrationFact, ResolveOptions, SettingsResidue, } from "./emit.js";
|
|
26
27
|
export { emit } from "./emit.js";
|
|
27
28
|
export type { Dial, DialEntry } from "./dial.js";
|
package/dist/src/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* temper's authoring face — the six-noun core as a typed module library.
|
|
3
3
|
* A harness author imports plain nouns — `harness()`, the generic `kind`
|
|
4
|
-
* constructor, the clause and requirement constructors, `needs`, and the
|
|
4
|
+
* constructor, the clause and requirement constructors, `needs`, and the four
|
|
5
5
|
* prose constructors — and composes members as typed values. `emit` compiles the
|
|
6
6
|
* whole into the declaration rows and the projected members' erased payload —
|
|
7
7
|
* the JSON pipe printed to stdout; the engine is the sole compiler of every
|
|
@@ -12,10 +12,14 @@
|
|
|
12
12
|
* The first-party Claude Code provider face — the built-in kinds — lives at
|
|
13
13
|
* the `./claude-code` subpath, never here.
|
|
14
14
|
*/
|
|
15
|
-
export { blocks, file, include, mentionOf, renderText, text } from "./prose.js";
|
|
15
|
+
export { blocks, file, include, mentionOf, renderText, span, text } from "./prose.js";
|
|
16
16
|
export { bash, capability, permissionUnion } from "./needs.js";
|
|
17
|
-
export { allowedChars, clause, closedKeys, count, degree, deny, enumOf, extent, forbiddenKeys, formatPlacesEdges, globValid, maxLen, membership, mentionReachable, minLen, mustDefine, nameMatchesDir, optional, range, required, requireSections, requirement, script, sectionContains, shape, telemetry, type, unique, uniqueName, when, } from "./contract.js";
|
|
17
|
+
export { allowedChars, clause, closedKeys, count, degree, deny, enumOf, extent, forbiddenKeys, formatPlacesEdges, fresh, globValid, locusDeclared, maxLen, membership, mentionReachable, minLen, mustDefine, nameMatchesDir, optional, range, reachable, reachedFrom, required, requireSections, requirement, script, sectionContains, shape, telemetry, type, unique, uniqueName, when, } from "./contract.js";
|
|
18
18
|
export { embeddedMemberValue, kind, relocate } from "./kind.js";
|
|
19
|
-
|
|
19
|
+
// Inputs — the files a member's claims rest on, fingerprinted by the lock and moved
|
|
20
|
+
// nowhere. A member-grain declaration, not a word in a body, so it rides here rather
|
|
21
|
+
// than on the prose line.
|
|
22
|
+
export { input } from "./kind.js";
|
|
23
|
+
export { harness, rootDefaultContract } from "./assembly.js";
|
|
20
24
|
export { emit } from "./emit.js";
|
|
21
25
|
export { dial, dialDefaultContract } from "./dial.js";
|
package/dist/src/kind.d.ts
CHANGED
|
@@ -137,6 +137,24 @@ export interface Layout {
|
|
|
137
137
|
* {@link Layout}.
|
|
138
138
|
*/
|
|
139
139
|
export type Shape = "fields";
|
|
140
|
+
/**
|
|
141
|
+
* A kind's **leaf-set witness** — the leaf names a member of the kind carries, handed
|
|
142
|
+
* over by the kind's own typed surface `T` (decision 0053). The type is the declaration:
|
|
143
|
+
* nothing here is a second schema to keep in step with `T`, because the record's keys
|
|
144
|
+
* *are* `keyof T`. It exists at all because TypeScript erases `T` at the seam, so the
|
|
145
|
+
* set the compiler knows has to reach emit as a runtime value.
|
|
146
|
+
*
|
|
147
|
+
* The record is **exhaustive** — `-?` strips optionality, so omitting one key of `T` is a
|
|
148
|
+
* compile error and a key that is not `T`'s own is one too. That binding is what keeps
|
|
149
|
+
* the witness from degrading into the free-hand leaf schema the decision rejected: a
|
|
150
|
+
* partial set is unwritable rather than merely discouraged.
|
|
151
|
+
*
|
|
152
|
+
* Key order is the order the lowered row carries (`declarations.ts`), so a kind's leaves
|
|
153
|
+
* read in the order its author declared them.
|
|
154
|
+
*/
|
|
155
|
+
export type LeafSet<T extends object> = {
|
|
156
|
+
readonly [K in keyof T]-?: true;
|
|
157
|
+
};
|
|
140
158
|
/**
|
|
141
159
|
* A registration member's **collection address** — where inside a host manifest its
|
|
142
160
|
* registration surfaces: which `manifest` (`settings.json`, `.mcp.json`) and which
|
|
@@ -168,8 +186,15 @@ export interface Template {
|
|
|
168
186
|
/** Where a file child's unit sits, relative to the parent's unit; absent for an embedded layer. */
|
|
169
187
|
readonly path?: string;
|
|
170
188
|
}
|
|
171
|
-
/**
|
|
172
|
-
|
|
189
|
+
/**
|
|
190
|
+
* The seven facts of a kind's runtime residue, plus the derived {@link LeafSet} witness
|
|
191
|
+
* its typed surface hands over. `T` is that surface — the interface the kind's
|
|
192
|
+
* constructor is generic over. It defaults to an erased `Record<string, unknown>`, so
|
|
193
|
+
* every signature that only ever *reads* a facts value (`declarations.ts`'s lowering,
|
|
194
|
+
* {@link Member}, {@link KindDefinition}) names `KindFacts` bare and no call site
|
|
195
|
+
* re-spells a type argument.
|
|
196
|
+
*/
|
|
197
|
+
export type KindFacts<T extends object = Record<string, unknown>> = {
|
|
173
198
|
/** Fact 1, label — the compiled debug label findings speak; the kind's name. */
|
|
174
199
|
readonly name: string;
|
|
175
200
|
/** The declared provider authority, when the kind qualifies by one. */
|
|
@@ -225,6 +250,11 @@ export type KindFacts = {
|
|
|
225
250
|
/** Fact 7, template — one {@link Template} per inner layer of nested members the kind
|
|
226
251
|
* hosts; absent for a kind that nests nothing. */
|
|
227
252
|
readonly templates?: readonly Template[];
|
|
253
|
+
/** The kind's **leaf set**, witnessed exhaustively over its own typed surface and
|
|
254
|
+
* lowered to the row's `leaves` column at emit ({@link LeafSet}, decision 0053) —
|
|
255
|
+
* what a read verb renders where the surface holds no member of the kind yet.
|
|
256
|
+
* Absent for a kind whose constructor declares no witness. */
|
|
257
|
+
readonly leaves?: LeafSet<T>;
|
|
228
258
|
/** Advisory authoring counsel for the kind as a whole — teaching at authoring time via
|
|
229
259
|
* `schema` hover or `explain`, carrying no predicate or severity (decision 0045). */
|
|
230
260
|
readonly guidance?: string;
|
|
@@ -283,6 +313,11 @@ export type KindFacts = {
|
|
|
283
313
|
/** Fact 7, template — one {@link Template} per inner layer of nested members the kind
|
|
284
314
|
* hosts; absent for a kind that nests nothing. */
|
|
285
315
|
readonly templates?: readonly Template[];
|
|
316
|
+
/** The kind's **leaf set**, witnessed exhaustively over its own typed surface and
|
|
317
|
+
* lowered to the row's `leaves` column at emit ({@link LeafSet}, decision 0053) —
|
|
318
|
+
* what a read verb renders where the surface holds no member of the kind yet.
|
|
319
|
+
* Absent for a kind whose constructor declares no witness. */
|
|
320
|
+
readonly leaves?: LeafSet<T>;
|
|
286
321
|
/** Advisory authoring counsel for the kind as a whole — teaching at authoring time via
|
|
287
322
|
* `schema` hover or `explain`, carrying no predicate or severity (decision 0045). */
|
|
288
323
|
readonly guidance?: string;
|
|
@@ -341,6 +376,11 @@ export type KindFacts = {
|
|
|
341
376
|
/** Fact 7, template — one {@link Template} per inner layer of nested members the kind
|
|
342
377
|
* hosts; absent for a kind that nests nothing. */
|
|
343
378
|
readonly templates?: readonly Template[];
|
|
379
|
+
/** The kind's **leaf set**, witnessed exhaustively over its own typed surface and
|
|
380
|
+
* lowered to the row's `leaves` column at emit ({@link LeafSet}, decision 0053) —
|
|
381
|
+
* what a read verb renders where the surface holds no member of the kind yet.
|
|
382
|
+
* Absent for a kind whose constructor declares no witness. */
|
|
383
|
+
readonly leaves?: LeafSet<T>;
|
|
344
384
|
/** Advisory authoring counsel for the kind as a whole — teaching at authoring time via
|
|
345
385
|
* `schema` hover or `explain`, carrying no predicate or severity (decision 0045). */
|
|
346
386
|
readonly guidance?: string;
|
|
@@ -348,6 +388,31 @@ export type KindFacts = {
|
|
|
348
388
|
* carried as data. */
|
|
349
389
|
readonly cite?: string;
|
|
350
390
|
};
|
|
391
|
+
/**
|
|
392
|
+
* A **declared input** — a file the member's claims rest on, fingerprinted by the lock
|
|
393
|
+
* and moved nowhere (`specs/model/authoring.md`, "The SDK"). The path resolves against
|
|
394
|
+
* the stating module ({@link moduleUrl}), never the workspace — the same anchor
|
|
395
|
+
* `include()` and a `file()` body take.
|
|
396
|
+
*
|
|
397
|
+
* It lives here rather than beside the prose references it rhymes with: an input rides
|
|
398
|
+
* no text span and pairs with no body slot, so it is a member-grain framework key, not a
|
|
399
|
+
* word in a body. When the input's bytes move, the member's own freshness finding routes
|
|
400
|
+
* the author to re-verify the claims *before* re-emitting — temper never judges whether
|
|
401
|
+
* the claim still holds, only names the place to look.
|
|
402
|
+
*/
|
|
403
|
+
export interface Input {
|
|
404
|
+
readonly kind: "input";
|
|
405
|
+
/** Path to the input, resolved against {@link moduleUrl}. */
|
|
406
|
+
readonly path: string;
|
|
407
|
+
/** The declaring module's own `import.meta.url` — what {@link path} resolves against. */
|
|
408
|
+
readonly moduleUrl: string;
|
|
409
|
+
}
|
|
410
|
+
/**
|
|
411
|
+
* Declare a file a member's claims rest on — the lock fingerprints it and no byte
|
|
412
|
+
* reaches the projection. The path resolves against the stating module, so the call is
|
|
413
|
+
* `input(import.meta.url, "./schema.json")`.
|
|
414
|
+
*/
|
|
415
|
+
export declare function input(moduleUrl: string, path: string): Input;
|
|
351
416
|
/**
|
|
352
417
|
* One authored member — a typed value in the library. Kind identity travels by
|
|
353
418
|
* import (`facts`), never by string; the
|
|
@@ -373,8 +438,27 @@ export interface Member {
|
|
|
373
438
|
readonly requires: Readonly<Record<string, Requirement>>;
|
|
374
439
|
/** The capabilities the member's behavior uses — the permission union's source. */
|
|
375
440
|
readonly needs: readonly Capability[];
|
|
441
|
+
/** The files this member's claims rest on — fingerprinted, never moved. */
|
|
442
|
+
readonly inputs: readonly Input[];
|
|
376
443
|
}
|
|
377
|
-
/**
|
|
444
|
+
/**
|
|
445
|
+
* The bag a surface `T` declares its {@link RESIDUE_KEY} channel as — the keys `T` does
|
|
446
|
+
* *not* type, and only those. The two halves partition the format's key space, so a key
|
|
447
|
+
* in both is a mis-spelling rather than an override: open by key, then narrowed against
|
|
448
|
+
* `keyof T`, which leaves a typed key's slot here holding nothing a value can fill.
|
|
449
|
+
*
|
|
450
|
+
* The narrowing is the front door, never the whole gate — a bag the program computed
|
|
451
|
+
* arrives as a bare `Record<string, unknown>` and types fine, so the constructor refuses
|
|
452
|
+
* the collision again over the keys it actually holds ({@link orderedFields}).
|
|
453
|
+
*/
|
|
454
|
+
export type Residue<T> = Readonly<Record<string, unknown>> & {
|
|
455
|
+
readonly [K in keyof T]?: never;
|
|
456
|
+
};
|
|
457
|
+
/**
|
|
458
|
+
* The init a kind constructor takes — the framework keys plus the kind's typed fields `T`.
|
|
459
|
+
* {@link RESIDUE_KEY} is a framework key too, deliberately not spelled below: a kind opts
|
|
460
|
+
* into that channel through its own surface `T`.
|
|
461
|
+
*/
|
|
378
462
|
export type MemberInit<T> = {
|
|
379
463
|
readonly name: string;
|
|
380
464
|
/** The host member this member's unit composes under — a nested-file child's, and only its. */
|
|
@@ -383,6 +467,12 @@ export type MemberInit<T> = {
|
|
|
383
467
|
readonly satisfies?: readonly string[];
|
|
384
468
|
readonly requires?: Readonly<Record<string, Requirement>>;
|
|
385
469
|
readonly needs?: readonly Capability[];
|
|
470
|
+
/**
|
|
471
|
+
* The files this member's claims rest on ({@link input}) — fingerprinted by the lock,
|
|
472
|
+
* with no byte reaching the projection. The surface binds a *member*: an embedded
|
|
473
|
+
* value takes no `MemberInit`, and its claims are its host's.
|
|
474
|
+
*/
|
|
475
|
+
readonly inputs?: readonly Input[];
|
|
386
476
|
} & T;
|
|
387
477
|
/**
|
|
388
478
|
* A kind — a callable constructor carrying its seven facts. Calling it builds a
|
|
@@ -414,8 +504,13 @@ export interface KindOptions {
|
|
|
414
504
|
* into emit is the seven facts plus flat field data. `options.render`, when given,
|
|
415
505
|
* rides alongside `facts`/`key` on the returned constructor — never on the member
|
|
416
506
|
* it builds, since it is erased before a member reaches emit.
|
|
507
|
+
*
|
|
508
|
+
* The facts are typed over the same `T` the constructor is, which is what binds a
|
|
509
|
+
* declared {@link LeafSet} witness to `keyof T`: the leaf set is the kind's own surface,
|
|
510
|
+
* checked here at the keystroke, and its lowering to the row is the one place it is
|
|
511
|
+
* spelled again (`declarations.ts`).
|
|
417
512
|
*/
|
|
418
|
-
export declare function kind<T extends object>(facts: KindFacts
|
|
513
|
+
export declare function kind<T extends object>(facts: KindFacts<T>, options?: KindOptions): KindDefinition<T>;
|
|
419
514
|
/**
|
|
420
515
|
* A **relocation delta** — the facts a relocated built-in kind diverges from its base
|
|
421
516
|
* on. Two faces, either or both:
|
|
@@ -428,9 +523,9 @@ export declare function kind<T extends object>(facts: KindFacts, options?: KindO
|
|
|
428
523
|
* members are found, the one fact the engine's own overlay exists to apply
|
|
429
524
|
* (`src/compose.rs`'s `overlay_builtin_kind`).
|
|
430
525
|
*
|
|
431
|
-
* Every other fact — format, unit shape, registration, content, templates
|
|
432
|
-
* through unchanged, which is exactly what makes the emitted row still
|
|
433
|
-
* relocation rather than a name collision on the reading side.
|
|
526
|
+
* Every other fact — format, unit shape, registration, content, templates, the declared
|
|
527
|
+
* leaf set — rides through unchanged, which is exactly what makes the emitted row still
|
|
528
|
+
* read as a relocation rather than a name collision on the reading side.
|
|
434
529
|
*/
|
|
435
530
|
export interface KindRelocation<T> {
|
|
436
531
|
/** The edge fields this relocation adds, each over a field of the kind's own surface. */
|