@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.
Files changed (44) hide show
  1. package/README.md +84 -53
  2. package/bin/temper.js +0 -0
  3. package/dist/src/assembly.d.ts +15 -1
  4. package/dist/src/assembly.js +2 -1
  5. package/dist/src/builtins.d.ts +682 -66
  6. package/dist/src/builtins.js +664 -92
  7. package/dist/src/claude-code.d.ts +2 -2
  8. package/dist/src/claude-code.js +1 -1
  9. package/dist/src/contract.d.ts +180 -29
  10. package/dist/src/contract.js +128 -15
  11. package/dist/src/declarations.d.ts +72 -5
  12. package/dist/src/declarations.js +389 -107
  13. package/dist/src/dial.d.ts +75 -0
  14. package/dist/src/dial.js +82 -0
  15. package/dist/src/emit.d.ts +35 -1
  16. package/dist/src/emit.js +369 -63
  17. package/dist/src/generated/AssemblyFactRow.d.ts +2 -2
  18. package/dist/src/generated/BoundRow.d.ts +2 -2
  19. package/dist/src/generated/ClauseRow.d.ts +73 -3
  20. package/dist/src/generated/CollectionAddressRow.d.ts +4 -0
  21. package/dist/src/generated/EmbeddedMember.d.ts +3 -3
  22. package/dist/src/generated/FeatureValue.d.ts +2 -2
  23. package/dist/src/generated/Features.d.ts +52 -3
  24. package/dist/src/generated/KindFactRow.d.ts +24 -7
  25. package/dist/src/generated/MentionRow.d.ts +5 -3
  26. package/dist/src/generated/NestedMemberRow.d.ts +32 -0
  27. package/dist/src/generated/PayloadMember.d.ts +6 -0
  28. package/dist/src/generated/RequirementRow.d.ts +4 -2
  29. package/dist/src/generated/SatisfiesRow.d.ts +2 -1
  30. package/dist/src/generated/Shape.d.ts +15 -0
  31. package/dist/src/generated/Shape.js +2 -0
  32. package/dist/src/generated/TemplateRow.d.ts +24 -0
  33. package/dist/src/generated/TemplateRow.js +2 -0
  34. package/dist/src/generated/ValueType.d.ts +11 -2
  35. package/dist/src/generated/Verifier.d.ts +20 -0
  36. package/dist/src/generated/Verifier.js +2 -0
  37. package/dist/src/generated/index.d.ts +3 -0
  38. package/dist/src/index.d.ts +8 -8
  39. package/dist/src/index.js +3 -3
  40. package/dist/src/kind.d.ts +135 -29
  41. package/dist/src/kind.js +35 -8
  42. package/dist/src/prose.d.ts +81 -25
  43. package/dist/src/prose.js +91 -21
  44. 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[];
@@ -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
+ ];
@@ -9,14 +9,48 @@
9
9
  * run.
10
10
  */
11
11
  import type { Harness } from "./assembly.js";
12
- import type { Declarations } from "./declarations.js";
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