@dtmd/temper 0.0.4 → 0.0.7
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 +10 -12
- package/bin/temper.js +52 -0
- package/dist/src/assembly.d.ts +32 -16
- package/dist/src/assembly.js +11 -10
- package/dist/src/builtins.d.ts +206 -41
- package/dist/src/builtins.js +258 -54
- package/dist/src/claude-code.d.ts +7 -9
- package/dist/src/claude-code.js +6 -8
- package/dist/src/contract.d.ts +47 -24
- package/dist/src/contract.js +35 -9
- package/dist/src/declarations.d.ts +42 -101
- package/dist/src/declarations.js +375 -47
- package/dist/src/emit.d.ts +56 -28
- package/dist/src/emit.js +177 -54
- package/dist/src/generated/AssemblyFactRow.d.ts +29 -0
- package/dist/src/generated/AssemblyFactRow.js +2 -0
- package/dist/src/generated/BoundRow.d.ts +14 -0
- package/dist/src/generated/BoundRow.js +2 -0
- package/dist/src/generated/CharsetRow.d.ts +15 -0
- package/dist/src/generated/CharsetRow.js +2 -0
- package/dist/src/generated/ClauseRow.d.ts +97 -0
- package/dist/src/generated/ClauseRow.js +1 -0
- package/dist/src/generated/CollectionAddressRow.d.ts +17 -0
- package/dist/src/generated/CollectionAddressRow.js +2 -0
- package/dist/src/generated/CollectionEntryRow.d.ts +23 -0
- package/dist/src/generated/CollectionEntryRow.js +2 -0
- package/dist/src/generated/CollectionEntryWire.d.ts +17 -0
- package/dist/src/generated/CollectionEntryWire.js +2 -0
- package/dist/src/generated/CountBoundRow.d.ts +13 -0
- package/dist/src/generated/CountBoundRow.js +2 -0
- package/dist/src/generated/Declarations.d.ts +89 -0
- package/dist/src/generated/Declarations.js +1 -0
- package/dist/src/generated/DegreeBoundRow.d.ts +15 -0
- package/dist/src/generated/DegreeBoundRow.js +1 -0
- package/dist/src/generated/EdgeBoundRow.d.ts +13 -0
- package/dist/src/generated/EdgeBoundRow.js +2 -0
- package/dist/src/generated/EmbeddedMember.d.ts +45 -0
- package/dist/src/generated/EmbeddedMember.js +1 -0
- package/dist/src/generated/EmbeddedMemberCollectionEntry.d.ts +21 -0
- package/dist/src/generated/EmbeddedMemberCollectionEntry.js +1 -0
- package/dist/src/generated/FeatureValue.d.ts +23 -0
- package/dist/src/generated/FeatureValue.js +1 -0
- package/dist/src/generated/Features.d.ts +82 -0
- package/dist/src/generated/Features.js +1 -0
- package/dist/src/generated/FencedBlock.d.ts +24 -0
- package/dist/src/generated/FencedBlock.js +2 -0
- package/dist/src/generated/IncludeRow.d.ts +18 -0
- package/dist/src/generated/IncludeRow.js +2 -0
- package/dist/src/generated/KindFactRow.d.ts +65 -0
- package/dist/src/generated/KindFactRow.js +1 -0
- package/dist/src/generated/LayoutRegionRow.d.ts +29 -0
- package/dist/src/generated/LayoutRegionRow.js +2 -0
- package/dist/src/generated/LayoutRow.d.ts +12 -0
- package/dist/src/generated/LayoutRow.js +1 -0
- package/dist/src/generated/MentionRow.d.ts +17 -0
- package/dist/src/generated/MentionRow.js +2 -0
- package/dist/src/generated/NestedMemberRow.d.ts +39 -0
- package/dist/src/generated/NestedMemberRow.js +1 -0
- package/dist/src/generated/Payload.d.ts +25 -0
- package/dist/src/generated/Payload.js +1 -0
- package/dist/src/generated/PayloadMember.d.ts +31 -0
- package/dist/src/generated/PayloadMember.js +2 -0
- package/dist/src/generated/RangeBoundRow.d.ts +15 -0
- package/dist/src/generated/RangeBoundRow.js +2 -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 +40 -0
- package/dist/src/generated/RequirementRow.js +1 -0
- package/dist/src/generated/SatisfiesRow.d.ts +14 -0
- package/dist/src/generated/SatisfiesRow.js +2 -0
- package/dist/src/generated/Section.d.ts +21 -0
- package/dist/src/generated/Section.js +2 -0
- package/dist/src/generated/SectionContainsRow.d.ts +14 -0
- package/dist/src/generated/SectionContainsRow.js +2 -0
- package/dist/src/generated/SettingsRow.d.ts +25 -0
- package/dist/src/generated/SettingsRow.js +2 -0
- package/dist/src/generated/ValueType.d.ts +9 -0
- package/dist/src/generated/ValueType.js +2 -0
- package/dist/src/generated/index.d.ts +32 -0
- package/dist/src/generated/index.js +1 -0
- package/dist/src/index.d.ts +14 -18
- package/dist/src/index.js +10 -13
- package/dist/src/kind.d.ts +190 -43
- package/dist/src/kind.js +34 -30
- package/dist/src/needs.d.ts +8 -8
- package/dist/src/needs.js +7 -7
- package/dist/src/prose.d.ts +75 -28
- package/dist/src/prose.js +0 -0
- package/package.json +9 -1
- package/dist/src/genres.d.ts +0 -38
- package/dist/src/genres.js +0 -24
package/README.md
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# temper-sdk — the authoring face
|
|
2
2
|
|
|
3
3
|
The typed module library the ratified corpus names as temper's authoring
|
|
4
|
-
medium (`specs/intent
|
|
5
|
-
|
|
4
|
+
medium (`specs/intent.md`; `specs/model/pipeline.md`, "The SDK"). A harness
|
|
5
|
+
author composes members as typed
|
|
6
6
|
values in the **six-noun model**; `emit` compiles the whole into the declaration
|
|
7
7
|
rows the engine reads, a byte-faithful `.claude/**` projection, and the lock. The
|
|
8
8
|
SDK implements **no semantics** — every type erases at the seam, and the engine
|
|
@@ -11,14 +11,15 @@ consumes only declared data, offline, no Node.
|
|
|
11
11
|
## The six-noun face
|
|
12
12
|
|
|
13
13
|
- **`harness()`** — the assembly as one typed value: `members · expect ·
|
|
14
|
-
require · settings` (`specs/
|
|
15
|
-
- **`kind<T>()
|
|
14
|
+
require · settings` (`specs/model/pipeline.md`, "The SDK").
|
|
15
|
+
- **`kind<T>()`** — the engine room: a kind is a typed
|
|
16
16
|
constructor plus five facts of runtime residue (label, locus, layout,
|
|
17
|
-
registration, edge fields — `specs/
|
|
18
|
-
Claude Code kinds `rule` / `skill` / `memory` are ordinary `kind<T>()` values
|
|
17
|
+
registration, edge fields — `specs/model/representation.md`). The built-in
|
|
18
|
+
Claude Code kinds `rule` / `skill` / `memory` are ordinary `kind<T>()` values;
|
|
19
|
+
an embedded child kind is the same constructor at the `embedded` locus.
|
|
19
20
|
- **Clause values** — `clause(predicate, { severity, guidance, cite })` over the
|
|
20
21
|
closed predicate algebra (`required`, `maxLines`, …); a floor is an exported
|
|
21
|
-
clause array, adopted by spread in `expect` (`specs/
|
|
22
|
+
clause array, adopted by spread in `expect` (`specs/model/contract.md`).
|
|
22
23
|
- **`needs`** — the capabilities a member uses (`bash("git diff")`); emit derives
|
|
23
24
|
the permission union, so a permission is never authored twice.
|
|
24
25
|
- **`file()` / `` text`…` `` / `blocks()`** — the three prose constructors, one
|
|
@@ -26,7 +27,8 @@ consumes only declared data, offline, no Node.
|
|
|
26
27
|
|
|
27
28
|
## What `emit` produces
|
|
28
29
|
|
|
29
|
-
One deterministic pass over the harness, double-emit verified
|
|
30
|
+
One deterministic pass over the harness, double-emit verified
|
|
31
|
+
(`specs/model/pipeline.md`, "Emit"):
|
|
30
32
|
|
|
31
33
|
- **Declaration rows** — the erased program (kind facts, clauses, requirements,
|
|
32
34
|
assembly facts) on the internal versioned JSON pipe and in the lock's
|
|
@@ -43,12 +45,8 @@ projection on disk; the JSON pipe is in-flight, not a committed artifact.
|
|
|
43
45
|
|
|
44
46
|
## Stated bounds — each a named follow-on, never silently faked
|
|
45
47
|
|
|
46
|
-
- **`blocks()` composes now, renders later** — the shared genre fence format is
|
|
47
|
-
`(genre-fence-format)`, deferred until its first consumer; emit refuses to
|
|
48
|
-
project a `blocks()` body until then.
|
|
49
48
|
- **The permission union is carried as data** — the fold into the settings
|
|
50
49
|
artifact lands with the hook/MCP kinds it folds many-to-one.
|
|
51
|
-
- **Publish name/scope** pending the PACKAGING-CHANNELS ruling; `private: true`.
|
|
52
50
|
|
|
53
51
|
## Tests
|
|
54
52
|
|
package/bin/temper.js
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* The engine launcher — channel 2's npm face (`specs/distribution.md`,
|
|
4
|
+
* "What ships"): resolve the platform's prebuilt engine binary from its
|
|
5
|
+
* `optionalDependencies` package and exec it. Fail-loud invariant: a
|
|
6
|
+
* missing platform binary is an install error with instructions, never a
|
|
7
|
+
* silent skip — if it cannot check, it fails loud.
|
|
8
|
+
*/
|
|
9
|
+
import { createRequire } from "node:module";
|
|
10
|
+
import { spawnSync } from "node:child_process";
|
|
11
|
+
|
|
12
|
+
const require = createRequire(import.meta.url);
|
|
13
|
+
|
|
14
|
+
/** platform+arch → [platform package, binary path inside it]. */
|
|
15
|
+
const PLATFORMS = {
|
|
16
|
+
"linux x64": ["@dtmd/temper-linux-x64", "bin/temper"],
|
|
17
|
+
"win32 x64": ["@dtmd/temper-win32-x64", "bin/temper.exe"],
|
|
18
|
+
};
|
|
19
|
+
|
|
20
|
+
const key = `${process.platform} ${process.arch}`;
|
|
21
|
+
const entry = PLATFORMS[key];
|
|
22
|
+
|
|
23
|
+
if (!entry) {
|
|
24
|
+
const supported = Object.keys(PLATFORMS).join(", ");
|
|
25
|
+
process.stderr.write(
|
|
26
|
+
`temper: no prebuilt engine binary for ${key} yet (prebuilt: ${supported}).\n` +
|
|
27
|
+
`Build from source with a Rust 1.96+ toolchain instead:\n` +
|
|
28
|
+
` cargo install --git https://github.com/duct-tape-and-markdown/temper\n`,
|
|
29
|
+
);
|
|
30
|
+
process.exit(1);
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
const [pkg, binPath] = entry;
|
|
34
|
+
let bin;
|
|
35
|
+
try {
|
|
36
|
+
bin = require.resolve(`${pkg}/${binPath}`);
|
|
37
|
+
} catch {
|
|
38
|
+
process.stderr.write(
|
|
39
|
+
`temper: the platform engine package ${pkg} is not installed.\n` +
|
|
40
|
+
`It ships as an optionalDependency of @dtmd/temper — an installer run\n` +
|
|
41
|
+
`with optional dependencies disabled skips it. Restore it with:\n` +
|
|
42
|
+
` npm install ${pkg}\n`,
|
|
43
|
+
);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const result = spawnSync(bin, process.argv.slice(2), { stdio: "inherit" });
|
|
48
|
+
if (result.error) {
|
|
49
|
+
process.stderr.write(`temper: failed to run ${bin}: ${result.error.message}\n`);
|
|
50
|
+
process.exit(1);
|
|
51
|
+
}
|
|
52
|
+
process.exit(result.status ?? 1);
|
package/dist/src/assembly.d.ts
CHANGED
|
@@ -1,26 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The assembly — `harness()` takes the whole as one typed value
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* harnesses is ordinary code.
|
|
2
|
+
* The assembly — `harness()` takes the whole as one typed value: `Harness =
|
|
3
|
+
* members · expect · require · settings · mode`. Like every SDK type it
|
|
4
|
+
* erases at the seam — the engine never sees the constructor, only the
|
|
5
|
+
* declaration rows it compiles to. There is no second authoring surface: no
|
|
6
|
+
* `temper.toml`, no roster/bindings dialect (the Decision rejects both);
|
|
7
|
+
* composing partial harnesses is ordinary code.
|
|
9
8
|
*/
|
|
10
9
|
import type { Member, KindDefinition } from "./kind.js";
|
|
11
10
|
import type { Clause, Requirement } from "./contract.js";
|
|
12
11
|
/**
|
|
13
|
-
* One `expect` binding — universal: every member of `kind` owes these clauses
|
|
14
|
-
*
|
|
15
|
-
*
|
|
12
|
+
* One `expect` binding — universal: every member of `kind` owes these clauses.
|
|
13
|
+
* Keyed by the kind **value**, an import never a string; binding is implicit
|
|
14
|
+
* — a floor is just a clause array spread into `clauses`.
|
|
16
15
|
*/
|
|
17
16
|
export interface ExpectBinding {
|
|
18
|
-
readonly kind: KindDefinition<
|
|
17
|
+
readonly kind: KindDefinition<never>;
|
|
19
18
|
readonly clauses: readonly Clause[];
|
|
20
19
|
}
|
|
21
|
-
/**
|
|
20
|
+
/**
|
|
21
|
+
* The declared enforcement-mode vocabulary — how firmly the `PreToolUse` guard
|
|
22
|
+
* binds a tool call, split by where the finding goes.
|
|
23
|
+
* `block`: denies the call.
|
|
24
|
+
* `warn` (default): allows the call and surfaces the finding in-band, into the
|
|
25
|
+
* live context. `note`: allows the call and records the finding out-of-band
|
|
26
|
+
* only — the next report, never the session.
|
|
27
|
+
*/
|
|
28
|
+
export type EnforcementMode = "note" | "warn" | "block";
|
|
29
|
+
/** The composed harness — the root member's own fields, erased to rows at the seam. */
|
|
22
30
|
export interface Harness {
|
|
23
|
-
/** The member roster — the assembly's imports
|
|
31
|
+
/** The member roster — the assembly's imports. */
|
|
24
32
|
readonly members: readonly Member[];
|
|
25
33
|
/** Universal clause bindings, keyed by kind value. */
|
|
26
34
|
readonly expect: readonly ExpectBinding[];
|
|
@@ -28,15 +36,23 @@ export interface Harness {
|
|
|
28
36
|
readonly require: Readonly<Record<string, Requirement>>;
|
|
29
37
|
/** The residual harness-level settings with no member home (a shrinking list). */
|
|
30
38
|
readonly settings: Readonly<Record<string, unknown>>;
|
|
39
|
+
/**
|
|
40
|
+
* The root member's declared enforcement mode — harness-wide, overridable
|
|
41
|
+
* per member. Defaults to `warn`: temper fabricates no enforcement the
|
|
42
|
+
* author did not declare.
|
|
43
|
+
*/
|
|
44
|
+
readonly mode: EnforcementMode;
|
|
31
45
|
}
|
|
32
46
|
/**
|
|
33
|
-
* Compose the harness from its
|
|
34
|
-
* quarantined at authoring time
|
|
35
|
-
* fields default empty; the member list is the
|
|
47
|
+
* Compose the harness from its five fields — ordinary code, Turing-completeness
|
|
48
|
+
* quarantined at authoring time. Absent
|
|
49
|
+
* fields default empty (`mode` defaults `warn`); the member list is the
|
|
50
|
+
* only required part.
|
|
36
51
|
*/
|
|
37
52
|
export declare function harness(init: {
|
|
38
53
|
members: readonly Member[];
|
|
39
54
|
expect?: readonly ExpectBinding[];
|
|
40
55
|
require?: Readonly<Record<string, Requirement>>;
|
|
41
56
|
settings?: Readonly<Record<string, unknown>>;
|
|
57
|
+
mode?: EnforcementMode;
|
|
42
58
|
}): Harness;
|
package/dist/src/assembly.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The assembly — `harness()` takes the whole as one typed value
|
|
3
|
-
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
6
|
-
*
|
|
7
|
-
*
|
|
8
|
-
* harnesses is ordinary code.
|
|
2
|
+
* The assembly — `harness()` takes the whole as one typed value: `Harness =
|
|
3
|
+
* members · expect · require · settings · mode`. Like every SDK type it
|
|
4
|
+
* erases at the seam — the engine never sees the constructor, only the
|
|
5
|
+
* declaration rows it compiles to. There is no second authoring surface: no
|
|
6
|
+
* `temper.toml`, no roster/bindings dialect (the Decision rejects both);
|
|
7
|
+
* composing partial harnesses is ordinary code.
|
|
9
8
|
*/
|
|
10
9
|
/**
|
|
11
|
-
* Compose the harness from its
|
|
12
|
-
* quarantined at authoring time
|
|
13
|
-
* fields default empty; the member list is the
|
|
10
|
+
* Compose the harness from its five fields — ordinary code, Turing-completeness
|
|
11
|
+
* quarantined at authoring time. Absent
|
|
12
|
+
* fields default empty (`mode` defaults `warn`); the member list is the
|
|
13
|
+
* only required part.
|
|
14
14
|
*/
|
|
15
15
|
export function harness(init) {
|
|
16
16
|
return {
|
|
@@ -18,5 +18,6 @@ export function harness(init) {
|
|
|
18
18
|
expect: init.expect ?? [],
|
|
19
19
|
require: init.require ?? {},
|
|
20
20
|
settings: init.settings ?? {},
|
|
21
|
+
mode: init.mode ?? "warn",
|
|
21
22
|
};
|
|
22
23
|
}
|
package/dist/src/builtins.d.ts
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* The built-in Claude Code kinds — the face nouns a harness author imports
|
|
3
|
-
*
|
|
2
|
+
* The built-in Claude Code kinds — the face nouns a harness author imports.
|
|
3
|
+
* Each is an
|
|
4
4
|
* ordinary `kind<T>()` value built with the same constructor every provider uses
|
|
5
5
|
* (ownership not privilege). Their five facts are external facts about the Claude
|
|
6
6
|
* Code harness, cited at the point of claim.
|
|
7
7
|
*
|
|
8
8
|
* These are the SDK's own provider-face exports, surfaced through the
|
|
9
|
-
* `@dtmd/temper/claude-code` subpath
|
|
10
|
-
*
|
|
9
|
+
* `@dtmd/temper/claude-code` subpath
|
|
10
|
+
* — never from the root.
|
|
11
11
|
*/
|
|
12
12
|
import type { KindDefinition } from "./kind.js";
|
|
13
13
|
import type { Prose } from "./prose.js";
|
|
@@ -15,27 +15,67 @@ import type { Clause } from "./contract.js";
|
|
|
15
15
|
/** A Claude Code skill — a directory whose entry file is `SKILL.md` with YAML frontmatter. */
|
|
16
16
|
export interface Skill {
|
|
17
17
|
/**
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
* The description trigger — always in context; the body loads on invocation
|
|
19
|
+
* (code.claude.com/docs/en/skills, retrieved 2026-07-02).
|
|
20
|
+
*/
|
|
21
21
|
readonly description: string;
|
|
22
22
|
/** The optional license field the skill spec carries (agentskills.io/specification). */
|
|
23
23
|
readonly license?: string;
|
|
24
|
+
/**
|
|
25
|
+
* Set `true` to prevent Claude from automatically loading this skill — only
|
|
26
|
+
* the user-invoked channel stays live (code.claude.com/docs/en/skills,
|
|
27
|
+
* "Control who invokes a skill", retrieved 2026-07-07). Default: `false`.
|
|
28
|
+
*/
|
|
29
|
+
readonly "disable-model-invocation"?: boolean;
|
|
30
|
+
/**
|
|
31
|
+
* Set `false` to hide the skill from the `/` menu — only the
|
|
32
|
+
* description-trigger channel stays live (code.claude.com/docs/en/skills,
|
|
33
|
+
* "Control who invokes a skill", retrieved 2026-07-07). Default: `true`.
|
|
34
|
+
*/
|
|
35
|
+
readonly "user-invocable"?: boolean;
|
|
24
36
|
readonly prose?: Prose;
|
|
25
37
|
}
|
|
26
38
|
/**
|
|
27
39
|
* `skill` — `.claude/skills/<name>/SKILL.md`, a directory unit, YAML frontmatter
|
|
28
|
-
* carrying `name` then `description`; registers
|
|
40
|
+
* carrying `name` then `description`; registers on both documented invocation
|
|
41
|
+
* channels — user-invoked (`/name`) and description-trigger — modulated per
|
|
42
|
+
* member by the `disable-model-invocation`/`user-invocable` fields
|
|
29
43
|
* (code.claude.com/docs/en/skills, agentskills.io/specification, retrieved
|
|
30
|
-
* 2026-07-
|
|
44
|
+
* 2026-07-07).
|
|
31
45
|
*/
|
|
32
46
|
export declare const skill: KindDefinition<Skill>;
|
|
47
|
+
/**
|
|
48
|
+
* `command` — `.claude/commands/*.md`, the skill surface's legacy file placement
|
|
49
|
+
* (Claude Code merged commands into skills; code.claude.com/docs/en/skills,
|
|
50
|
+
* retrieved 2026-07-07): a lone file (identity from the stem, so no
|
|
51
|
+
* `identityField` — like `rule`), the skill's field schema by import, registering
|
|
52
|
+
* on the same two documented invocation channels as `skill`.
|
|
53
|
+
*/
|
|
54
|
+
export declare const command: KindDefinition<Skill>;
|
|
55
|
+
/** A Claude Code subagent definition. */
|
|
56
|
+
export interface Agent {
|
|
57
|
+
/**
|
|
58
|
+
* When Claude should delegate to this subagent — the sole registration
|
|
59
|
+
* channel (code.claude.com/docs/en/sub-agents, retrieved 2026-07-07).
|
|
60
|
+
*/
|
|
61
|
+
readonly description: string;
|
|
62
|
+
readonly prose?: Prose;
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* `agent` — every markdown file under `.claude/agents`, discovered recursively (a
|
|
66
|
+
* containing subdirectory is purely organizational), YAML frontmatter carrying
|
|
67
|
+
* `name` then `description`; identity is the `name` field (never the filename),
|
|
68
|
+
* the named-field mode; registers on the description-trigger channel only — no
|
|
69
|
+
* user-invoked slash command (code.claude.com/docs/en/sub-agents, retrieved
|
|
70
|
+
* 2026-07-07).
|
|
71
|
+
*/
|
|
72
|
+
export declare const agent: KindDefinition<Agent>;
|
|
33
73
|
/** A Claude Code rule — a flat markdown file with an optional `paths` scope. */
|
|
34
74
|
export interface Rule {
|
|
35
75
|
/**
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
76
|
+
* The path scope — a present list matching zero files is a dead edge; an absent
|
|
77
|
+
* one loads unconditionally (code.claude.com/docs/en/memory, retrieved 2026-07-02).
|
|
78
|
+
*/
|
|
39
79
|
readonly paths?: readonly string[];
|
|
40
80
|
readonly prose?: Prose;
|
|
41
81
|
}
|
|
@@ -58,11 +98,75 @@ export interface Memory {
|
|
|
58
98
|
*/
|
|
59
99
|
export declare const memory: KindDefinition<Memory>;
|
|
60
100
|
/**
|
|
61
|
-
*
|
|
101
|
+
* A Claude Code hook — a fields-only registration member surfacing inside
|
|
102
|
+
* `settings.json`, keyed under its lifecycle event. It owns no artifact of its own; a
|
|
103
|
+
* handler names how it fires (`command`/`http`/`mcp_tool`/`prompt`/`agent`) plus the
|
|
104
|
+
* documented common fields (code.claude.com/docs/en/hooks, retrieved 2026-07-10).
|
|
105
|
+
* Authoring `hook(...)` builds a member whose typed fields fold into its manifest entry;
|
|
106
|
+
* emit erases it into a registration write fact (`emit.ts`).
|
|
107
|
+
*/
|
|
108
|
+
export interface Hook {
|
|
109
|
+
/** The handler kind — how the hook fires when its event matches. */
|
|
110
|
+
readonly type?: "command" | "http" | "mcp_tool" | "prompt" | "agent";
|
|
111
|
+
/** The shell command or executable a `command` handler runs. */
|
|
112
|
+
readonly command?: string;
|
|
113
|
+
/** Seconds before the handler is canceled. */
|
|
114
|
+
readonly timeout?: number;
|
|
115
|
+
/** The tool-name filter a tool-scoped event fires on (`"*"`/`""`/absent = all). */
|
|
116
|
+
readonly matcher?: string;
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* `hook` — a `settings.json` `hooks.<Event>` registration member: a fields-only kind (no
|
|
120
|
+
* body slot), its members discovered off the `.claude/settings.json` manifest at the
|
|
121
|
+
* `hooks.<Event>` collection address, keyed by lifecycle event; registers on the `event`
|
|
122
|
+
* channel (code.claude.com/docs/en/hooks, retrieved 2026-07-10). The first manifest kind
|
|
123
|
+
* temper ships — the read side of 0021's manifest-authoring surface.
|
|
124
|
+
*/
|
|
125
|
+
export declare const hook: KindDefinition<Hook>;
|
|
126
|
+
/**
|
|
127
|
+
* A Claude Code MCP server — a fields-only registration member surfacing inside
|
|
128
|
+
* `.mcp.json`, keyed by name under `mcpServers`. It owns no artifact of its own; its
|
|
129
|
+
* `type` names the transport (`stdio` default, or `http`/`streamable-http`/`sse`/`ws`),
|
|
130
|
+
* and each transport reads a different field set — `command`/`args`/`env` for a local
|
|
131
|
+
* stdio process, `url`/`headers` for a remote connection
|
|
132
|
+
* (code.claude.com/docs/en/mcp, retrieved 2026-07-10). Authoring `mcpServer(...)` builds a
|
|
133
|
+
* member whose typed fields fold into its `mcpServers.*` entry; emit erases it into a
|
|
134
|
+
* registration write fact (`emit.ts`).
|
|
135
|
+
*/
|
|
136
|
+
export interface McpServer {
|
|
137
|
+
/**
|
|
138
|
+
* The transport. Absent reads as `stdio`, so an entry that carries a `url` but no
|
|
139
|
+
* `type` is a configuration error — Claude Code treats it as a stdio server and skips
|
|
140
|
+
* it. `streamable-http` is an alias for `http`.
|
|
141
|
+
*/
|
|
142
|
+
readonly type?: "stdio" | "http" | "streamable-http" | "sse" | "ws";
|
|
143
|
+
/** The executable a stdio server runs. */
|
|
144
|
+
readonly command?: string;
|
|
145
|
+
/** The arguments passed to a stdio server's `command`. */
|
|
146
|
+
readonly args?: readonly string[];
|
|
147
|
+
/** Environment variables set in a stdio server's process. */
|
|
148
|
+
readonly env?: Readonly<Record<string, string>>;
|
|
149
|
+
/** The endpoint a remote (`http`/`sse`/`ws`) server connects to. */
|
|
150
|
+
readonly url?: string;
|
|
151
|
+
/** Static headers sent to a remote server. */
|
|
152
|
+
readonly headers?: Readonly<Record<string, string>>;
|
|
153
|
+
/** Milliseconds before a tool call to this server aborts. */
|
|
154
|
+
readonly timeout?: number;
|
|
155
|
+
}
|
|
156
|
+
/**
|
|
157
|
+
* `mcpServer` — a `.mcp.json` `mcpServers.*` registration member: a fields-only kind (no
|
|
158
|
+
* body slot), its members discovered off the `.mcp.json` manifest at the `mcpServers.*`
|
|
159
|
+
* collection address, keyed by server name; registers on the `connection` channel
|
|
160
|
+
* (code.claude.com/docs/en/mcp, retrieved 2026-07-10). The second manifest kind temper
|
|
161
|
+
* ships, and the first whose entries are objects — each server's fields fold into the
|
|
162
|
+
* member the read surfaces.
|
|
163
|
+
*/
|
|
164
|
+
export declare const mcpServer: KindDefinition<McpServer>;
|
|
165
|
+
/**
|
|
166
|
+
* The default contract for `skill` — Anthropic's documented skill contract: the Agent
|
|
62
167
|
* Skills open standard (agentskills.io), Anthropic's platform upload
|
|
63
|
-
* validation, and Claude Code's own docs
|
|
64
|
-
*
|
|
65
|
-
* "named for its source"). All sources retrieved 2026-07-01.
|
|
168
|
+
* validation, and Claude Code's own docs.
|
|
169
|
+
* All sources retrieved 2026-07-09.
|
|
66
170
|
*
|
|
67
171
|
* Checks the strictest documented profile: the spec and upload validation are
|
|
68
172
|
* hard, Claude Code's runtime is deliberately forgiving ("All fields are
|
|
@@ -74,7 +178,7 @@ export declare const memory: KindDefinition<Memory>;
|
|
|
74
178
|
* description actually triggers well or reads third-person (semantic);
|
|
75
179
|
* vagueness/no-op detection (semantic); gerund naming (judgment). Two
|
|
76
180
|
* decidable spec rules are also absent, pending a vocabulary addition (a
|
|
77
|
-
* narrow shape predicate
|
|
181
|
+
* narrow shape predicate governs additions): the name
|
|
78
182
|
* must not start/end with a hyphen or contain consecutive hyphens; likewise
|
|
79
183
|
* the platform's "no XML tags in the description."
|
|
80
184
|
*
|
|
@@ -85,12 +189,34 @@ export declare const memory: KindDefinition<Memory>;
|
|
|
85
189
|
* that is not a command; `metadata` is the sanctioned home for versioning —
|
|
86
190
|
* there is no top-level `version` field.
|
|
87
191
|
*/
|
|
88
|
-
export declare const
|
|
192
|
+
export declare const skillDefaultContract: readonly Clause[];
|
|
89
193
|
/**
|
|
90
|
-
* The
|
|
194
|
+
* The default contract for `command` — `skillDefaultContract`'s clauses minus `nameMatchesDir`: a
|
|
195
|
+
* command is a lone file with no parent directory to match, so the one clause
|
|
196
|
+
* that ranges over the directory relationship does not apply; every other
|
|
197
|
+
* documented skill-schema recommendation, name-requiredness included, still
|
|
198
|
+
* governs a command by the same import (code.claude.com/docs/en/skills,
|
|
199
|
+
* retrieved 2026-07-07).
|
|
200
|
+
*/
|
|
201
|
+
export declare const commandDefaultContract: readonly Clause[];
|
|
202
|
+
/**
|
|
203
|
+
* The default contract for `agent` — Anthropic's documented subagent contract
|
|
204
|
+
* (code.claude.com/docs/en/sub-agents, retrieved 2026-07-07): `name` and
|
|
205
|
+
* `description` are the only required fields, `name` is a "unique identifier
|
|
206
|
+
* using lowercase letters and hyphens" (no digits, unlike a skill's `name`), and
|
|
207
|
+
* "keep `name` values unique across the whole tree" — a same-scope collision
|
|
208
|
+
* loads only one definition.
|
|
209
|
+
*
|
|
210
|
+
* Deliberately narrow, like `ruleDefaultContract`: undecidable properties (whether the
|
|
211
|
+
* description triggers well, model/permissionMode's semi-open vocabularies) stay
|
|
212
|
+
* out of the gate — the format documents little else that is decidable.
|
|
213
|
+
*/
|
|
214
|
+
export declare const agentDefaultContract: readonly Clause[];
|
|
215
|
+
/**
|
|
216
|
+
* The default contract for `rule` — Anthropic's documented contract for a Claude Code
|
|
91
217
|
* rules file, sourced from the memory docs (`.claude/rules/` landed in
|
|
92
218
|
* v2.0.64; `packages/rule.anthropic/PACKAGE.md`, the curated authoring
|
|
93
|
-
* reference this migrates verbatim). All sources retrieved 2026-07-
|
|
219
|
+
* reference this migrates verbatim). All sources retrieved 2026-07-09.
|
|
94
220
|
*
|
|
95
221
|
* `paths` is the one documented frontmatter key for rules: glob patterns
|
|
96
222
|
* (brace expansion supported) that scope the rule to matching files. Rules
|
|
@@ -98,9 +224,9 @@ export declare const skillFloor: readonly Clause[];
|
|
|
98
224
|
* rules load when Claude reads a matching file. Note skills now take a
|
|
99
225
|
* `paths` key too — the two schemas are separate. (Guidance only: an
|
|
100
226
|
* optional field asserts nothing decidable, so it carries no clause of its
|
|
101
|
-
* own
|
|
227
|
+
* own: `required` is the one
|
|
102
228
|
* presence predicate, and its absence is not itself a predicate.)
|
|
103
|
-
* https://code.claude.com/docs/en/memory#path-specific-rules (retrieved 2026-07-
|
|
229
|
+
* https://code.claude.com/docs/en/memory#path-specific-rules (retrieved 2026-07-09)
|
|
104
230
|
*
|
|
105
231
|
* What the clauses cannot carry, as guidance: keep a rule to facts Claude
|
|
106
232
|
* should hold whenever the rule is in scope — concrete enough to verify ("use
|
|
@@ -112,18 +238,17 @@ export declare const skillFloor: readonly Clause[];
|
|
|
112
238
|
* behavior drifts, and test a change by watching whether Claude's behavior
|
|
113
239
|
* actually shifts.
|
|
114
240
|
*/
|
|
115
|
-
export declare const
|
|
241
|
+
export declare const ruleDefaultContract: readonly Clause[];
|
|
116
242
|
/**
|
|
117
|
-
* The
|
|
243
|
+
* The default contract for the qualified `claude-code.memory` kind — Anthropic's
|
|
118
244
|
* documented contract for a project `CLAUDE.md` (`packages/memory.anthropic/PACKAGE.md`,
|
|
119
|
-
* the curated authoring reference this migrates verbatim). Retrieved 2026-07-
|
|
245
|
+
* the curated authoring reference this migrates verbatim). Retrieved 2026-07-09.
|
|
120
246
|
*
|
|
121
247
|
* Deliberately near-empty, because the format is: `CLAUDE.md` is plain
|
|
122
248
|
* markdown with no documented frontmatter and no required fields
|
|
123
|
-
* (code.claude.com/docs/en/memory, retrieved 2026-07-
|
|
249
|
+
* (code.claude.com/docs/en/memory, retrieved 2026-07-09), so there is no
|
|
124
250
|
* schema to gate — manufacturing a required field or a forbidden-key list
|
|
125
|
-
* would fake a check the format does not carry
|
|
126
|
-
* law 3: decidable clauses only). The single clause is a context-cost
|
|
251
|
+
* would fake a check the format does not carry. The single clause is a context-cost
|
|
127
252
|
* budget; everything else the contract could say is guidance.
|
|
128
253
|
*
|
|
129
254
|
* What the clauses cannot carry, as guidance: a `paths:` frontmatter block
|
|
@@ -141,23 +266,63 @@ export declare const ruleFloor: readonly Clause[];
|
|
|
141
266
|
* directory, not below it. Personal, un-shared notes go in `CLAUDE.local.md`
|
|
142
267
|
* (gitignored), appended after `CLAUDE.md` at its level.
|
|
143
268
|
*/
|
|
144
|
-
export declare const
|
|
269
|
+
export declare const memoryAnthropicDefaultContract: readonly Clause[];
|
|
145
270
|
/**
|
|
146
|
-
* The
|
|
271
|
+
* The default contract for the qualified `agents-md.memory` kind — the AGENTS.md
|
|
147
272
|
* standard's contract for a memory file, which is that there is almost none
|
|
148
273
|
* (`packages/memory.agents-md/PACKAGE.md`, the curated authoring reference
|
|
149
274
|
* this migrates). Guidance-only, and that is the honest encoding: `AGENTS.md`
|
|
150
275
|
* "is just standard Markdown" with no required fields, no sections, and no
|
|
151
|
-
* frontmatter (agents.md, retrieved 2026-07-
|
|
152
|
-
* constrains nothing. A
|
|
276
|
+
* frontmatter (agents.md, retrieved 2026-07-09); the format deliberately
|
|
277
|
+
* constrains nothing. A default contract that manufactured a required field, a size
|
|
153
278
|
* gate, or a forbidden-key list would assert a contract the standard
|
|
154
|
-
* disclaims
|
|
279
|
+
* disclaims. Even the tempting size
|
|
155
280
|
* number is a *tool's* rule, not the format's: agents read the closest
|
|
156
|
-
* `AGENTS.md` in the tree (nested, nearest-wins
|
|
157
|
-
* chain root-to-cwd and stops once
|
|
158
|
-
*
|
|
159
|
-
*
|
|
160
|
-
*
|
|
161
|
-
*
|
|
162
|
-
|
|
163
|
-
|
|
281
|
+
* `AGENTS.md` in the tree (nested, nearest-wins; agents.md, retrieved
|
|
282
|
+
* 2026-07-09); Codex concatenates the chain root-to-cwd and stops once
|
|
283
|
+
* combined size hits a byte budget, not a per-file line count
|
|
284
|
+
* (`project_doc_max_bytes`, 32 KiB default;
|
|
285
|
+
* developers.openai.com/codex/guides/agents-md, retrieved 2026-07-09);
|
|
286
|
+
* Gemini CLI reads `GEMINI.md` by default and only treats `AGENTS.md` as an
|
|
287
|
+
* alias when configured via `context.fileName` (geminicli.com/docs/cli/gemini-md,
|
|
288
|
+
* retrieved 2026-07-09); Claude Code does not read `AGENTS.md` natively —
|
|
289
|
+
* bridge it with a `CLAUDE.md` that `@AGENTS.md`-imports it
|
|
290
|
+
* (code.claude.com/docs/en/memory, retrieved 2026-07-09).
|
|
291
|
+
*/
|
|
292
|
+
export declare const memoryAgentsMdDefaultContract: readonly Clause[];
|
|
293
|
+
/**
|
|
294
|
+
* The default contract for `hook` — Anthropic's documented hooks contract
|
|
295
|
+
* (code.claude.com/docs/en/hooks, retrieved 2026-07-10). A hook surfaces at
|
|
296
|
+
* `hooks.<Event>`, so the member the gate reads is the lifecycle event itself, its name
|
|
297
|
+
* carried as the `event` field off the collection key. The one decidable, cited property
|
|
298
|
+
* of that member is its event: a key outside the documented set is dead configuration —
|
|
299
|
+
* Claude Code silently never fires a hook under an unrecognized event, so the strictest
|
|
300
|
+
* documented profile is that the event is one temper's cited docs name.
|
|
301
|
+
*
|
|
302
|
+
* Deliberately absent — the handler's own schema (`type`/`command`/`url`/`timeout`, the
|
|
303
|
+
* matcher grammar) lives one array level deeper than `hooks.<Event>`, inside each event's
|
|
304
|
+
* matcher-group list, which the collection address does not walk into; a clause over it
|
|
305
|
+
* would range over a field the read never surfaces, so it is no clause at all. What the
|
|
306
|
+
* clauses cannot carry, as guidance: keep a handler's `type` among
|
|
307
|
+
* `command`/`http`/`mcp_tool`/`prompt`/`agent`; a `command` handler needs a `command`, an
|
|
308
|
+
* `http` handler a `url`; the `matcher` filters tool-scoped events and is inert on events
|
|
309
|
+
* that carry no tool (`UserPromptSubmit`, `Stop`, and their siblings).
|
|
310
|
+
*/
|
|
311
|
+
export declare const hookDefaultContract: readonly Clause[];
|
|
312
|
+
/**
|
|
313
|
+
* The default contract for `mcpServer` — Anthropic's documented `.mcp.json` contract
|
|
314
|
+
* (code.claude.com/docs/en/mcp, retrieved 2026-07-10). A server surfaces at `mcpServers.*`,
|
|
315
|
+
* keyed by name, its transport-specific fields folded into the member. The one decidable,
|
|
316
|
+
* cited property that holds across every transport is `type`: a value outside the
|
|
317
|
+
* documented set is a transport Claude Code cannot honor, so the strictest documented
|
|
318
|
+
* profile is that a present `type` names one temper's cited docs carry. An absent `type`
|
|
319
|
+
* passes — Claude Code reads it as `stdio`, the documented default.
|
|
320
|
+
*
|
|
321
|
+
* Deliberately absent — the per-transport requirements are conditional on `type`, which no
|
|
322
|
+
* single-field clause can decide: a `url` with no `type` is a configuration error (Claude
|
|
323
|
+
* Code reads it as a stdio server and skips it), a stdio server needs a `command`, and a
|
|
324
|
+
* remote server needs a `url` — each a two-field implication the closed predicate
|
|
325
|
+
* vocabulary cannot express, so it rides guidance rather than a clause that would range
|
|
326
|
+
* over a field the shape of the check cannot see.
|
|
327
|
+
*/
|
|
328
|
+
export declare const mcpServerDefaultContract: readonly Clause[];
|