@dtmd/temper 0.0.7 → 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 +0 -0
- package/dist/src/assembly.d.ts +15 -1
- package/dist/src/assembly.js +2 -1
- package/dist/src/builtins.d.ts +682 -66
- package/dist/src/builtins.js +664 -92
- 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 +72 -5
- package/dist/src/declarations.js +389 -107
- package/dist/src/dial.d.ts +75 -0
- package/dist/src/dial.js +82 -0
- package/dist/src/emit.d.ts +35 -1
- package/dist/src/emit.js +369 -63
- 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 +4 -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 +24 -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/RequirementRow.d.ts +4 -2
- package/dist/src/generated/SatisfiesRow.d.ts +2 -1
- 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 +3 -0
- package/dist/src/index.d.ts +8 -8
- package/dist/src/index.js +3 -3
- package/dist/src/kind.d.ts +135 -29
- package/dist/src/kind.js +35 -8
- package/dist/src/prose.d.ts +81 -25
- package/dist/src/prose.js +91 -21
- package/package.json +2 -2
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shipped **dial** kind — temper's own, not a provider's.
|
|
3
|
+
*
|
|
4
|
+
* A local-locus TOML document at `.temper/dial.toml` whose entries name a clause by
|
|
5
|
+
* its compiled address (`contract.md`, "clause") and declare the severity this machine
|
|
6
|
+
* reads it at: see the annoying finding, read its label, dial it — locally,
|
|
7
|
+
* uncommitted, and without ever softening the shared gate.
|
|
8
|
+
*
|
|
9
|
+
* This module is **root-exported** (`@dtmd/temper`), never the `./claude-code`
|
|
10
|
+
* subpath: the subpath is the Claude Code provider face, and the dial is a claim about
|
|
11
|
+
* temper's own gate rather than about any harness Claude Code reads. Its facts are
|
|
12
|
+
* therefore not external facts and carry no `cite` — the citation is the corpus
|
|
13
|
+
* (decisions 0030, 0032).
|
|
14
|
+
*
|
|
15
|
+
* **The schema is the envelope** (decision 0030, re-spelled by 0032). Severity is the
|
|
16
|
+
* only verb an entry has: there is no `off`, no `skip`, no `delete`, and the severity
|
|
17
|
+
* vocabulary is the same closed two the authored clause declares under. A dialed clause
|
|
18
|
+
* therefore still reports, and the bound 0030 stated as an admissibility condition over
|
|
19
|
+
* a layer's *effect* is held structurally — by the shape of a kind, which an author
|
|
20
|
+
* cannot spell their way past. The other half of the bound is the engine's:
|
|
21
|
+
* dialed softening is inert in block mode, so a block-mode pass on any machine implies
|
|
22
|
+
* the shared gate's pass (`pipeline.md`, "Layers").
|
|
23
|
+
*/
|
|
24
|
+
import type { Clause, Severity } from "./contract.js";
|
|
25
|
+
import type { KindDefinition } from "./kind.js";
|
|
26
|
+
/**
|
|
27
|
+
* One dial entry: a clause's compiled address, and the severity this machine reads it
|
|
28
|
+
* at. The two fields are the whole verb — the interface is where the envelope is
|
|
29
|
+
* spelled, and there is nothing here to widen it with.
|
|
30
|
+
*/
|
|
31
|
+
export interface DialEntry {
|
|
32
|
+
/**
|
|
33
|
+
* The clause's compiled address — the label every finding prints as its `rule` id
|
|
34
|
+
* and `explain` narrates (decision 0032). Spelled straight back out of the finding:
|
|
35
|
+
* that round trip is what the label's legibility exists for.
|
|
36
|
+
*/
|
|
37
|
+
readonly label: string;
|
|
38
|
+
/** The severity this machine reads that clause at. */
|
|
39
|
+
readonly severity: Severity;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The dial document's fields — the whole top-level table of `.temper/dial.toml`.
|
|
43
|
+
*
|
|
44
|
+
* `name` is the machine's own label, and it is the member's identity: the file's stem is
|
|
45
|
+
* `dial` on every machine that has one, so identity comes from a declared field.
|
|
46
|
+
*/
|
|
47
|
+
export interface Dial {
|
|
48
|
+
/** This machine's name — the dial's identity, and what its findings speak. */
|
|
49
|
+
readonly name: string;
|
|
50
|
+
/** The dialed clauses. Absent or empty is a dial that changes nothing. */
|
|
51
|
+
readonly clause?: readonly DialEntry[];
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* The `dial` kind: `.temper/dial.toml`, a **local** file locus — the kind is declared,
|
|
55
|
+
* committed and reviewed here; a machine's own dial document is not.
|
|
56
|
+
*
|
|
57
|
+
* Read-side only by construction (decision 0034): `toml-document` is a read face with no
|
|
58
|
+
* write twin, emit's codomain is the committed tree, and a local member's rows never
|
|
59
|
+
* enter the lock. Channel-less: a dial is read by temper's own gate, never surfaced to a
|
|
60
|
+
* model or an installer, so it declares no registration.
|
|
61
|
+
*/
|
|
62
|
+
export declare const dial: KindDefinition<Dial>;
|
|
63
|
+
/**
|
|
64
|
+
* The default contract for `dial` — the envelope, stated as clauses.
|
|
65
|
+
*
|
|
66
|
+
* Every clause here is `required`: this contract is the one thing on the machine a dial
|
|
67
|
+
* must not be able to soften, since softening it is how a dial would talk its way out of
|
|
68
|
+
* its own shape. The engine refuses a dial entry naming a `dial.*` label for that reason
|
|
69
|
+
* — the clauses below are what an entry is *checked against*, never what it ranges over.
|
|
70
|
+
*
|
|
71
|
+
* `closed-keys` is the load-bearing one: it is what makes a misspelt verb a finding
|
|
72
|
+
* instead of a silently ignored key. A dial that wrote `off = true` beside its entries
|
|
73
|
+
* would otherwise read as an honest dial that happened to do nothing.
|
|
74
|
+
*/
|
|
75
|
+
export declare const dialDefaultContract: readonly Clause[];
|
package/dist/src/dial.js
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shipped **dial** kind — temper's own, not a provider's.
|
|
3
|
+
*
|
|
4
|
+
* A local-locus TOML document at `.temper/dial.toml` whose entries name a clause by
|
|
5
|
+
* its compiled address (`contract.md`, "clause") and declare the severity this machine
|
|
6
|
+
* reads it at: see the annoying finding, read its label, dial it — locally,
|
|
7
|
+
* uncommitted, and without ever softening the shared gate.
|
|
8
|
+
*
|
|
9
|
+
* This module is **root-exported** (`@dtmd/temper`), never the `./claude-code`
|
|
10
|
+
* subpath: the subpath is the Claude Code provider face, and the dial is a claim about
|
|
11
|
+
* temper's own gate rather than about any harness Claude Code reads. Its facts are
|
|
12
|
+
* therefore not external facts and carry no `cite` — the citation is the corpus
|
|
13
|
+
* (decisions 0030, 0032).
|
|
14
|
+
*
|
|
15
|
+
* **The schema is the envelope** (decision 0030, re-spelled by 0032). Severity is the
|
|
16
|
+
* only verb an entry has: there is no `off`, no `skip`, no `delete`, and the severity
|
|
17
|
+
* vocabulary is the same closed two the authored clause declares under. A dialed clause
|
|
18
|
+
* therefore still reports, and the bound 0030 stated as an admissibility condition over
|
|
19
|
+
* a layer's *effect* is held structurally — by the shape of a kind, which an author
|
|
20
|
+
* cannot spell their way past. The other half of the bound is the engine's:
|
|
21
|
+
* dialed softening is inert in block mode, so a block-mode pass on any machine implies
|
|
22
|
+
* the shared gate's pass (`pipeline.md`, "Layers").
|
|
23
|
+
*/
|
|
24
|
+
import { clause, closedKeys, enumOf, required, type } from "./contract.js";
|
|
25
|
+
import { kind } from "./kind.js";
|
|
26
|
+
/**
|
|
27
|
+
* The `dial` kind: `.temper/dial.toml`, a **local** file locus — the kind is declared,
|
|
28
|
+
* committed and reviewed here; a machine's own dial document is not.
|
|
29
|
+
*
|
|
30
|
+
* Read-side only by construction (decision 0034): `toml-document` is a read face with no
|
|
31
|
+
* write twin, emit's codomain is the committed tree, and a local member's rows never
|
|
32
|
+
* enter the lock. Channel-less: a dial is read by temper's own gate, never surfaced to a
|
|
33
|
+
* model or an installer, so it declares no registration.
|
|
34
|
+
*/
|
|
35
|
+
export const dial = kind({
|
|
36
|
+
name: "dial",
|
|
37
|
+
locus: { kind: "at", root: ".temper", glob: "dial.toml", commitment: "local" },
|
|
38
|
+
format: "toml-document",
|
|
39
|
+
unitShape: "named-field",
|
|
40
|
+
registration: [],
|
|
41
|
+
identityField: "name",
|
|
42
|
+
});
|
|
43
|
+
/**
|
|
44
|
+
* The default contract for `dial` — the envelope, stated as clauses.
|
|
45
|
+
*
|
|
46
|
+
* Every clause here is `required`: this contract is the one thing on the machine a dial
|
|
47
|
+
* must not be able to soften, since softening it is how a dial would talk its way out of
|
|
48
|
+
* its own shape. The engine refuses a dial entry naming a `dial.*` label for that reason
|
|
49
|
+
* — the clauses below are what an entry is *checked against*, never what it ranges over.
|
|
50
|
+
*
|
|
51
|
+
* `closed-keys` is the load-bearing one: it is what makes a misspelt verb a finding
|
|
52
|
+
* instead of a silently ignored key. A dial that wrote `off = true` beside its entries
|
|
53
|
+
* would otherwise read as an honest dial that happened to do nothing.
|
|
54
|
+
*/
|
|
55
|
+
export const dialDefaultContract = [
|
|
56
|
+
clause(required("name"), {
|
|
57
|
+
severity: "required",
|
|
58
|
+
guidance: "A dial names the machine it speaks for — its identity, and what its findings are reported under. There is no filename fallback: every machine's dial is `dial.toml`.",
|
|
59
|
+
}),
|
|
60
|
+
clause(type("name", ["string"]), { severity: "required" }),
|
|
61
|
+
clause(type("clause", ["list"]), {
|
|
62
|
+
severity: "required",
|
|
63
|
+
guidance: "The dialed clauses are an array of tables — `[[clause]]` per entry, each naming one `label` and one `severity`.",
|
|
64
|
+
}),
|
|
65
|
+
clause(required("clause[*].label"), {
|
|
66
|
+
severity: "required",
|
|
67
|
+
guidance: "An entry names the clause it dials by the address the finding printed as its `rule` id — spell it back verbatim. An entry naming a label no clause in this harness carries is a finding, never a silent no-op.",
|
|
68
|
+
}),
|
|
69
|
+
clause(type("clause[*].label", ["string"]), { severity: "required" }),
|
|
70
|
+
clause(required("clause[*].severity"), {
|
|
71
|
+
severity: "required",
|
|
72
|
+
guidance: "Severity is an entry's only verb: it is what a dial says, and all a dial says.",
|
|
73
|
+
}),
|
|
74
|
+
clause(enumOf("clause[*].severity", ["required", "advisory"]), {
|
|
75
|
+
severity: "required",
|
|
76
|
+
guidance: "The two severities an authored clause declares under are the two a dial re-declares under — there is no third value that means `off`. Softening a clause to `advisory` still reports it, and is inert in block mode; hardening one to `required` binds in every mode.",
|
|
77
|
+
}),
|
|
78
|
+
clause(closedKeys(), {
|
|
79
|
+
severity: "required",
|
|
80
|
+
guidance: "The dial's key set is exhaustive: `name` and `clause`, nothing else. A key outside it is a verb this schema does not have — most likely an attempt to spell deletion, which it cannot.",
|
|
81
|
+
}),
|
|
82
|
+
];
|
package/dist/src/emit.d.ts
CHANGED
|
@@ -9,14 +9,48 @@
|
|
|
9
9
|
* run.
|
|
10
10
|
*/
|
|
11
11
|
import type { Harness } from "./assembly.js";
|
|
12
|
-
import type {
|
|
12
|
+
import type { Member } from "./kind.js";
|
|
13
|
+
import type { Declarations, RenderedExtent } from "./declarations.js";
|
|
13
14
|
import type { PayloadMember } from "./generated/index.js";
|
|
14
15
|
export type { PayloadMember } from "./generated/index.js";
|
|
15
16
|
/** What a mention may resolve against at emit. */
|
|
16
17
|
export interface ResolveOptions {
|
|
17
18
|
/** The addresses a mention may name — resolution-checked; a mention cannot dangle. */
|
|
18
19
|
readonly mentionable?: ReadonlySet<string>;
|
|
20
|
+
/**
|
|
21
|
+
* The discoverable (`at`-locus) kinds the program declares. A mention naming one of
|
|
22
|
+
* these whose member is not composed defers to `check` rather than refusing at emit.
|
|
23
|
+
*/
|
|
24
|
+
readonly deferrableKinds?: ReadonlySet<string>;
|
|
25
|
+
/**
|
|
26
|
+
* The program's composed members by `kind:name` address — what an embedded value's
|
|
27
|
+
* edge field resolves against to derive its target facts. An edge target never defers
|
|
28
|
+
* to the gate the way a bare mention may: the facts are rendered into the projection
|
|
29
|
+
* now, so an unresolved one has nothing true to place.
|
|
30
|
+
*/
|
|
31
|
+
readonly members?: ReadonlyMap<string, Member>;
|
|
19
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Every composed embedded value's placed edge fields, keyed by the value's
|
|
35
|
+
* {@link placementKey} — what `emit` hands {@link compileDeclarations} so each
|
|
36
|
+
* `nested_member` row carries its own format's placement record. Iterates exactly the
|
|
37
|
+
* values `nestedMemberRows` does, so every edge-bearing row it builds has an observation.
|
|
38
|
+
*/
|
|
39
|
+
export declare function edgePlacements(harness: Harness, options: ResolveOptions): Map<string, string[]>;
|
|
40
|
+
/**
|
|
41
|
+
* Every composed embedded value's rendered extent — the line and character count of the
|
|
42
|
+
* block `emit` projected for it — keyed by its {@link placementKey}, what `emit` hands
|
|
43
|
+
* {@link compileDeclarations} so each `nested_member` row carries the span an `extent`
|
|
44
|
+
* clause budgets. Iterates exactly the values {@link edgePlacements} does, rendering each
|
|
45
|
+
* through the same {@link renderMemberBlock} the body projection uses (a hook is pure, so
|
|
46
|
+
* the measured render and the projected one cannot disagree), never a second renderer.
|
|
47
|
+
*
|
|
48
|
+
* A value the SDK composes is always rendered here, so it always captures a span; a value
|
|
49
|
+
* no format rendered — an embedded member read off a layout host's source — is lowered by
|
|
50
|
+
* the engine, not this pass, and reaches its row with no span (the `placed_edges`
|
|
51
|
+
* distinction between an observed empty and an unobserved absence).
|
|
52
|
+
*/
|
|
53
|
+
export declare function renderedExtents(harness: Harness, options: ResolveOptions): Map<string, RenderedExtent>;
|
|
20
54
|
/**
|
|
21
55
|
* One fields-only registration member erased for the manifest write face: its key
|
|
22
56
|
* (a hook's lifecycle event, an MCP server's name), the collection address it keys
|