@orkestrel/scaffold 0.0.66 → 0.0.68
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/bin/main.js +67 -44
- package/dist/bin/main.js.map +1 -1
- package/dist/host/agents/templates/brief.md +9 -0
- package/dist/host/claude/agents/orkestrel.md +8 -8
- package/dist/host/claude/rules/names.md +15 -0
- package/dist/host/claude/rules/tests.md +33 -4
- package/dist/host/claude/rules/workspace.md +14 -2
- package/dist/host/dotfiles/prettierignore +3 -0
- package/dist/host/guides/README.md +65 -0
- package/dist/host/guides/abort.md +169 -0
- package/dist/host/guides/agent.md +1509 -0
- package/dist/host/guides/brief.md +1266 -0
- package/dist/host/guides/browser.md +2200 -0
- package/dist/host/guides/budget.md +196 -0
- package/dist/host/guides/codec.md +519 -0
- package/dist/host/guides/console.md +785 -0
- package/dist/host/guides/contract.md +1193 -0
- package/dist/host/guides/csv.md +541 -0
- package/dist/host/guides/database.md +2518 -0
- package/dist/host/guides/emitter.md +233 -0
- package/dist/host/guides/form.md +1791 -0
- package/dist/host/guides/html.md +717 -0
- package/dist/host/guides/indexeddb.md +505 -0
- package/dist/host/guides/interpret.md +1029 -0
- package/dist/host/guides/lsp.md +515 -0
- package/dist/host/guides/markdown.md +964 -0
- package/dist/host/guides/mcp.md +5554 -0
- package/dist/host/guides/middleware.md +927 -0
- package/dist/host/guides/msg.md +440 -0
- package/dist/host/guides/ndjson.md +120 -0
- package/dist/host/guides/ollama.md +380 -0
- package/dist/host/guides/pool.md +280 -0
- package/dist/host/guides/probe.md +1210 -0
- package/dist/host/guides/process.md +1620 -0
- package/dist/host/guides/program.md +1110 -0
- package/dist/host/guides/qualifier.md +854 -0
- package/dist/host/guides/queue.md +370 -0
- package/dist/host/guides/rater.md +330 -0
- package/dist/host/guides/reason.md +1122 -0
- package/dist/host/guides/relation.md +373 -0
- package/dist/host/guides/router.md +753 -0
- package/dist/host/guides/scaffold.md +192 -31
- package/dist/host/guides/sea.md +383 -0
- package/dist/host/guides/server.md +752 -0
- package/dist/host/guides/sqlite.md +330 -0
- package/dist/host/guides/sse.md +187 -0
- package/dist/host/guides/supervisor.md +4890 -0
- package/dist/host/guides/table.md +1556 -0
- package/dist/host/guides/template.md +280 -0
- package/dist/host/guides/terminal.md +1145 -0
- package/dist/host/guides/test.md +2969 -0
- package/dist/host/guides/timeout.md +252 -0
- package/dist/host/guides/tool.md +311 -0
- package/dist/host/guides/toolbox.md +1038 -0
- package/dist/host/guides/websocket.md +282 -0
- package/dist/host/guides/worker.md +615 -0
- package/dist/host/guides/workflow.md +1507 -0
- package/dist/host/guides/workspace.md +595 -0
- package/dist/host/manifest.json +1218 -10
- package/dist/host/tests/policy.test.ts +279 -2
- package/dist/host/tests/setupPolicy.ts +437 -6
- package/dist/src/core/index.cjs +44 -22
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +33 -9
- package/dist/src/core/index.d.ts +33 -9
- package/dist/src/core/index.js +43 -23
- package/dist/src/core/index.js.map +1 -1
- package/dist/src/server/index.cjs +1750 -1567
- package/dist/src/server/index.cjs.map +1 -1
- package/dist/src/server/index.d.cts +106 -24
- package/dist/src/server/index.d.ts +106 -24
- package/dist/src/server/index.js +1751 -1570
- package/dist/src/server/index.js.map +1 -1
- package/package.json +9 -9
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
# Template
|
|
2
|
+
|
|
3
|
+
> A named, versionable template layer: `{{name}}` tokens in a `content`
|
|
4
|
+
> string, resolved against a values record by a single-pass fill engine, and
|
|
5
|
+
> registered and looked up by id through a self-owning `TemplateManager`.
|
|
6
|
+
|
|
7
|
+
`validate` predicts `fill`'s `'error'`-policy outcome exactly — a token it
|
|
8
|
+
reports `missing` is precisely a token that would throw. Every fill lookup is
|
|
9
|
+
prototype-pollution-safe: any field-path segment in `UNSAFE_FIELD_SEGMENTS`
|
|
10
|
+
(`__proto__`, `constructor`, `prototype`) is refused before `resolveField` is
|
|
11
|
+
ever called. Source: [`src/core`](../src/core). Surfaced through the
|
|
12
|
+
`@src/core` barrel.
|
|
13
|
+
|
|
14
|
+
## Surface
|
|
15
|
+
|
|
16
|
+
Create a template, fill it against a values record, then register it in a
|
|
17
|
+
manager for id-keyed lookup:
|
|
18
|
+
|
|
19
|
+
```ts
|
|
20
|
+
import { createTemplate, createTemplateManager } from '@orkestrel/template'
|
|
21
|
+
|
|
22
|
+
const greeting = createTemplate({ name: 'greeting', content: 'Hi {{name}}' })
|
|
23
|
+
greeting.fill({ name: 'Ada' }) // 'Hi Ada'
|
|
24
|
+
|
|
25
|
+
const templates = createTemplateManager({ templates: [greeting] })
|
|
26
|
+
templates.fill(greeting.id, { name: 'Grace' }) // 'Hi Grace'
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
An unresolved required placeholder is governed by `TemplateFillOptions.missing`
|
|
30
|
+
(default `'error'`, throwing a `TemplateError` coded `MISSING`); `'empty'`
|
|
31
|
+
substitutes `''`, `'literal'` re-emits the original `{{name}}` token. An
|
|
32
|
+
escaped `\{{` always emits a literal `{{`, regardless of policy.
|
|
33
|
+
|
|
34
|
+
### Types
|
|
35
|
+
|
|
36
|
+
A `Shape` cell holds an interface's data members as bare names in braces, `?` marking an optional member and `plus` introducing its call-signature members, and a type alias's own type literal with a union's arms escaped as `\|`. An extended interface's name comes before `plus`, with the members it adds after.
|
|
37
|
+
|
|
38
|
+
| Type | Kind | Shape | Summary |
|
|
39
|
+
| -------------------------- | --------- | --------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
40
|
+
| `MissingPolicy` | type | `'error' \| 'empty' \| 'literal'` | Names how `TemplateInterface#fill` handles an unresolved required placeholder. |
|
|
41
|
+
| `TemplateFillValues` | type | `Readonly<Record<string, unknown>>` | Represents the values a `TemplateInterface#fill` / `#validate` call resolves placeholders against. |
|
|
42
|
+
| `TemplateManagerEventMap` | type | `{ register, remove, clear }` | Declares the push observation surface of a `TemplateManagerInterface` — an id-keyed registry, so `register` / `remove` are the events (never ordered-list `append`/`prepend`). |
|
|
43
|
+
| `TemplateErrorCode` | type | `'MISSING' \| 'NOTFOUND' \| 'INVALID' \| 'CONFLICT'` | Names the coded misuse / failure conditions thrown as a `TemplateError`. |
|
|
44
|
+
| `TemplatePlaceholder` | interface | `{ name, path?, required?, fallback?, description? }` | Represents one placeholder a `TemplateDefinition`'s `content` declares — its lookup name, an optional field path into the values record, whether it is required, and a literal fallback. |
|
|
45
|
+
| `TemplateDefinition` | interface | `{ id, name, content, placeholders, summary?, description?, category?, tags? }` | Represents a named, versionable template record — pure data, no behavior. |
|
|
46
|
+
| `TemplateFillOptions` | interface | `{ missing?, locale? }` | Carries the per-call options for `TemplateInterface#fill` / `TemplateManagerInterface#fill`. |
|
|
47
|
+
| `TemplateFillContext` | interface | `TemplateFillOptions plus { placeholders? }` | Carries the full option bag `fillTemplate` takes — the per-call `TemplateFillOptions` plus the declared placeholders tokens resolve against. |
|
|
48
|
+
| `TemplateTokenResolution` | interface | `{ value, declared, required }` | Represents one `{{name}}` token's resolution — the single token rule `fillTemplate` and `TemplateInterface#validate` share. |
|
|
49
|
+
| `TemplateRegisterOptions` | interface | `{ replace? }` | Carries the options for `TemplateManagerInterface#register`. |
|
|
50
|
+
| `TemplateValidationResult` | interface | `{ valid, missing, extra }` | Reports the outcome of `TemplateInterface#validate` — which required placeholders are unresolved, and which supplied values are unused. |
|
|
51
|
+
| `TemplateOptions` | interface | `{ id?, name, content, placeholders?, summary?, description?, category?, tags?, missing?, locale? }` | Carries the options for `createTemplate` / the `Template` constructor. |
|
|
52
|
+
| `TemplateQuery` | interface | `{ name?, category?, tag? }` | Represents a query for `TemplateManagerInterface#find` — every supplied field must match. |
|
|
53
|
+
| `TemplateInterface` | interface | `{ id, name, content, placeholders, summary?, description?, category?, tags? } plus definition, fill, validate, parameters` | Declares the template contract a consumer holds — the readonly template record and the `definition`, `fill`, `validate`, and `parameters` calls over it. |
|
|
54
|
+
| `TemplateManagerOptions` | interface | `{ templates?, missing?, locale?, on?, error? }` | Carries the options for `createTemplateManager` / the `TemplateManager` constructor. |
|
|
55
|
+
| `TemplateManagerInterface` | interface | `{ emitter, count } plus register, template, templates, find, has, remove, clear, destroy, fill, validate, parameters` | Declares the registry contract a consumer holds — a self-owning, id-keyed record-holder with singular and plural accessors over the templates it registers. |
|
|
56
|
+
|
|
57
|
+
### Constants
|
|
58
|
+
|
|
59
|
+
A `Shape` cell holds the constant's declared type.
|
|
60
|
+
|
|
61
|
+
| API | Kind | Shape | Summary |
|
|
62
|
+
| ------------------------ | ----- | ------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
63
|
+
| `FILL_PATTERN` | const | `RegExp` | Holds the single-pass `{{name}}` substitution pattern shared by `Template#fill` and `Template#validate`. |
|
|
64
|
+
| `DEFAULT_MISSING_POLICY` | const | `MissingPolicy` | Holds `'error'`, the default `missing` policy for `Template#fill` / `TemplateManager#fill` when unspecified. |
|
|
65
|
+
| `DEFAULT_LOCALE` | const | `'en-US'` | Holds `'en-US'`, the default `locale` for `Template#fill` / `TemplateManager#fill` when unspecified. |
|
|
66
|
+
| `UNSAFE_FIELD_SEGMENTS` | const | `readonly string[]` | Lists the prototype-pollution-unsafe field-path segments `'__proto__'`, `'constructor'`, and `'prototype'` — a fill lookup refuses to resolve a path containing one of them, treating the placeholder as unresolved. |
|
|
67
|
+
|
|
68
|
+
```ts
|
|
69
|
+
import {
|
|
70
|
+
DEFAULT_LOCALE,
|
|
71
|
+
DEFAULT_MISSING_POLICY,
|
|
72
|
+
FILL_PATTERN,
|
|
73
|
+
UNSAFE_FIELD_SEGMENTS,
|
|
74
|
+
} from '@orkestrel/template'
|
|
75
|
+
|
|
76
|
+
DEFAULT_MISSING_POLICY // 'error'
|
|
77
|
+
DEFAULT_LOCALE // 'en-US'
|
|
78
|
+
UNSAFE_FIELD_SEGMENTS // ['__proto__', 'constructor', 'prototype']
|
|
79
|
+
FILL_PATTERN.source // the `{{name}}` / `\{{` substitution pattern
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Errors
|
|
83
|
+
|
|
84
|
+
| API | Kind | Summary |
|
|
85
|
+
| ----------------- | -------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
86
|
+
| `TemplateError` | class | Represents an error thrown by the template layer — a machine-readable `TemplateErrorCode` and an optional `context` record naming the offending id or placeholder name. |
|
|
87
|
+
| `isTemplateError` | function | Narrows an unknown caught value to a `TemplateError`. |
|
|
88
|
+
|
|
89
|
+
```ts
|
|
90
|
+
import { isTemplateError, TemplateError } from '@orkestrel/template'
|
|
91
|
+
|
|
92
|
+
try {
|
|
93
|
+
throw new TemplateError('NOTFOUND', 'Unknown template id: missing', { id: 'missing' })
|
|
94
|
+
} catch (error) {
|
|
95
|
+
if (isTemplateError(error)) error.code // 'NOTFOUND'
|
|
96
|
+
}
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### Helpers
|
|
100
|
+
|
|
101
|
+
Pure, exported utility functions — the referentially-transparent leaves behind
|
|
102
|
+
`Template#fill` / `#validate`.
|
|
103
|
+
|
|
104
|
+
| API | Kind | Summary |
|
|
105
|
+
| ------------------ | -------- | ------------------------------------------------------------------------------------------------------------------------ |
|
|
106
|
+
| `formatValue` | function | Formats a resolved fill value for substitution into a template's `content`. |
|
|
107
|
+
| `resolveSafeField` | function | Resolves a field path against a fill-values record, refusing any path that touches a prototype-pollution-unsafe segment. |
|
|
108
|
+
| `resolveToken` | function | Resolves one `{{name}}` token against the declared placeholders and the fill-values record. |
|
|
109
|
+
| `fillTemplate` | function | Substitutes every `{{name}}` token in `content` in a single pass. |
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
import { fillTemplate, formatValue, resolveSafeField, resolveToken } from '@orkestrel/template'
|
|
113
|
+
|
|
114
|
+
formatValue(5010, 'en-US') // '5,010'
|
|
115
|
+
formatValue(null, 'en-US') // 'null'
|
|
116
|
+
resolveSafeField({ a: { b: 1 } }, ['a', 'b']) // 1
|
|
117
|
+
resolveSafeField({}, ['__proto__', 'polluted']) // undefined
|
|
118
|
+
resolveToken({ name: 'Ada' }, [], 'name').value // 'Ada'
|
|
119
|
+
resolveToken({}, [{ name: 'nickname', required: false }], 'nickname').required // false
|
|
120
|
+
fillTemplate('Hi {{name}}', { name: 'Ada' }) // 'Hi Ada'
|
|
121
|
+
fillTemplate('Limit {{limit}}', { limit: 5010 }, { missing: 'empty' }) // 'Limit 5,010'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Shapers
|
|
125
|
+
|
|
126
|
+
The `@orkestrel/contract` shape values built from declared template data —
|
|
127
|
+
above the helper leaves, consuming them and never consumed by them.
|
|
128
|
+
|
|
129
|
+
| API | Kind | Summary |
|
|
130
|
+
| ------------------ | -------- | -------------------------------------------------------------------------------------------- |
|
|
131
|
+
| `placeholderShape` | function | Builds the `@orkestrel/contract` object shape describing a template's declared placeholders. |
|
|
132
|
+
|
|
133
|
+
```ts
|
|
134
|
+
import { placeholderShape } from '@orkestrel/template'
|
|
135
|
+
|
|
136
|
+
placeholderShape([{ name: 'city' }]) // an object ContractShape with a `city` string field
|
|
137
|
+
```
|
|
138
|
+
|
|
139
|
+
### Factories
|
|
140
|
+
|
|
141
|
+
| API | Kind | Summary |
|
|
142
|
+
| ----------------------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
143
|
+
| `createTemplate` | function | Creates a working `TemplateInterface` from a `TemplateOptions` bag, backed by the `Template` class. |
|
|
144
|
+
| `createTemplateManager` | function | Creates a working `TemplateManagerInterface`, optionally seeded with the templates the options carry, backed by the `TemplateManager` class. |
|
|
145
|
+
|
|
146
|
+
#### Create a template and a registry
|
|
147
|
+
|
|
148
|
+
Builds a template and fills it directly, then seeds a registry with several templates and queries them by category and id.
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
import { createTemplate, createTemplateManager } from '@orkestrel/template'
|
|
152
|
+
|
|
153
|
+
const greeting = createTemplate({ name: 'greeting', content: 'Hi {{name}}' })
|
|
154
|
+
greeting.fill({ name: 'Ada' }) // 'Hi Ada'
|
|
155
|
+
|
|
156
|
+
const templates = createTemplateManager({
|
|
157
|
+
templates: [
|
|
158
|
+
{ id: 'greeting', name: 'greeting', content: 'Hi {{name}}', category: 'mail' },
|
|
159
|
+
{ id: 'farewell', name: 'farewell', content: 'Bye {{name}}', category: 'mail' },
|
|
160
|
+
{ id: 'alert', name: 'alert', content: 'Alert: {{reason}}', category: 'ops' },
|
|
161
|
+
],
|
|
162
|
+
})
|
|
163
|
+
templates.fill('greeting', { name: 'Ada' }) // 'Hi Ada'
|
|
164
|
+
templates.find({ category: 'mail' }).map((one) => one.id) // ['greeting', 'farewell']
|
|
165
|
+
templates.has('alert') // true
|
|
166
|
+
templates.has('missing') // false
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
### Classes
|
|
170
|
+
|
|
171
|
+
| API | Kind | Summary |
|
|
172
|
+
| ----------------- | ----- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
173
|
+
| `Template` | class | Represents a named, versionable template — `{{name}}` tokens in `content`, filled against a values record — implementing `TemplateInterface` exactly. |
|
|
174
|
+
| `TemplateManager` | class | Represents the template registry — a self-owning, id-keyed record-holder for the `TemplateInterface` instances a consumer registers, looks up, fills, and validates by id — implementing `TemplateManagerInterface` exactly. |
|
|
175
|
+
|
|
176
|
+
## Methods
|
|
177
|
+
|
|
178
|
+
The public methods of each behavioral interface — one table per type, keyed
|
|
179
|
+
by its backticked name, every call-signature member listed (the `readonly`
|
|
180
|
+
data members — `id` / `name` / `content` / `placeholders` / catalog metadata
|
|
181
|
+
on `Template`; `emitter` / `count` on `TemplateManager` — stay off the method
|
|
182
|
+
tables). Each implementing class exposes exactly its interface's methods, so
|
|
183
|
+
this doubles as the per-instance method surface.
|
|
184
|
+
|
|
185
|
+
#### `TemplateInterface`
|
|
186
|
+
|
|
187
|
+
| Method | Returns | Summary |
|
|
188
|
+
| ------------ | -------------------------------------- | --------------------------------------------------------------------------------------------- |
|
|
189
|
+
| `definition` | `TemplateDefinition` | Returns the plain, JSON-serializable template data. |
|
|
190
|
+
| `fill` | `string` | Substitutes every `{{name}}` token in `content` against `values`. |
|
|
191
|
+
| `validate` | `TemplateValidationResult` | Reports which required placeholders would stay unresolved, and which `values` keys go unused. |
|
|
192
|
+
| `parameters` | `Record<string, unknown> \| undefined` | Projects the declared placeholders to the open tool-parameters record shape. |
|
|
193
|
+
|
|
194
|
+
```ts
|
|
195
|
+
import { createTemplate } from '@orkestrel/template'
|
|
196
|
+
|
|
197
|
+
const greeting = createTemplate({
|
|
198
|
+
name: 'greeting',
|
|
199
|
+
content: 'Hi {{name}}',
|
|
200
|
+
placeholders: [{ name: 'name' }],
|
|
201
|
+
})
|
|
202
|
+
greeting.definition().name // 'greeting'
|
|
203
|
+
greeting.fill({ name: 'Ada' }) // 'Hi Ada'
|
|
204
|
+
greeting.validate({}).missing // ['name']
|
|
205
|
+
greeting.parameters() // the compiled parameters record, or undefined
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
#### `TemplateManagerInterface`
|
|
209
|
+
|
|
210
|
+
The by-id calls split on what an unknown id means to each: the `template`
|
|
211
|
+
accessor returns `undefined`, while `fill`, `validate`, and `parameters` throw
|
|
212
|
+
a `TemplateError` coded `NOTFOUND`, because each needs a template to proceed.
|
|
213
|
+
A duplicate id throws a `TemplateError` coded `CONFLICT` unless
|
|
214
|
+
`options.replace` is `true`, and one absent id turns a batch `remove`'s answer
|
|
215
|
+
`false` while the present ids still remove.
|
|
216
|
+
|
|
217
|
+
| Method | Returns | Summary |
|
|
218
|
+
| ------------ | -------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
|
|
219
|
+
| `register` | `TemplateInterface` | Registers one template, or overwrites the entry sharing its id when `options.replace` is `true`, and emits `register`. |
|
|
220
|
+
| `template` | `TemplateInterface \| undefined` | Returns one registered template by id, or `undefined` when the id is unregistered. |
|
|
221
|
+
| `templates` | `readonly TemplateInterface[]` | Lists every registered template. |
|
|
222
|
+
| `find` | `readonly TemplateInterface[]` | Filters registered templates by `name`, `category`, and `tag` — every supplied field must match. |
|
|
223
|
+
| `has` | `boolean` | Reports whether a template with the given id is registered. |
|
|
224
|
+
| `remove` | `boolean` (or `void`) | Removes the listed templates by id, one template by id, or every registered template, emitting `remove` once per removed template. |
|
|
225
|
+
| `clear` | `void` | Removes every registered template, emitting `clear`. |
|
|
226
|
+
| `destroy` | `void` | Tears the registry down: drops every registered template and destroys the owned emitter. Idempotent. |
|
|
227
|
+
| `fill` | `string` | Fills a registered template by id. |
|
|
228
|
+
| `validate` | `TemplateValidationResult` | Validates values against a registered template by id. |
|
|
229
|
+
| `parameters` | `Record<string, unknown> \| undefined` | Projects a registered template's parameters by id. |
|
|
230
|
+
|
|
231
|
+
```ts
|
|
232
|
+
import { createTemplateManager } from '@orkestrel/template'
|
|
233
|
+
|
|
234
|
+
const templates = createTemplateManager()
|
|
235
|
+
const greeting = templates.register({ id: 'greeting', name: 'greeting', content: 'Hi {{name}}' })
|
|
236
|
+
templates.has('greeting') // true
|
|
237
|
+
templates.template('greeting') // the registered TemplateInterface, or undefined
|
|
238
|
+
templates.templates() // every registered template
|
|
239
|
+
templates.find({ name: 'greeting' }) // [greeting]
|
|
240
|
+
templates.fill('greeting', { name: 'Ada' }) // 'Hi Ada'
|
|
241
|
+
templates.validate('greeting', {}).missing // ['name']
|
|
242
|
+
templates.parameters('greeting') // the compiled parameters record, or undefined
|
|
243
|
+
templates.remove('greeting') // true
|
|
244
|
+
templates.clear()
|
|
245
|
+
templates.destroy()
|
|
246
|
+
```
|
|
247
|
+
|
|
248
|
+
## Tests
|
|
249
|
+
|
|
250
|
+
- [`tests/guides.test.ts`](../tests/guides.test.ts) — the `## Surface` ↔ `src/core`
|
|
251
|
+
bijection (value and type exports), the `TemplateInterface` ↔ `Template` and
|
|
252
|
+
`TemplateManagerInterface` ↔ `TemplateManager` method bijections, and the equality
|
|
253
|
+
gate: every `Summary` cell against its declaration's description paragraph, the titled
|
|
254
|
+
`Create a template and a registry` fence against the `@example` block of that title
|
|
255
|
+
(pinned so the titled pair cannot be retired silently), and the README pitch against
|
|
256
|
+
this guide's tagline. It also runs the flagship fences and asserts the values their
|
|
257
|
+
comments claim.
|
|
258
|
+
- [`tests/src/core/templates/Template.test.ts`](../tests/src/core/templates/Template.test.ts) —
|
|
259
|
+
construction validation, `definition` / `fill` / `validate` / `parameters`.
|
|
260
|
+
- [`tests/src/core/templates/TemplateManager.test.ts`](../tests/src/core/templates/TemplateManager.test.ts) —
|
|
261
|
+
`register` / `template` / `templates` / `find` / `has` / `remove` / `clear` /
|
|
262
|
+
`destroy` / `fill` / `validate` / `parameters`, including the `CONFLICT` / `NOTFOUND`
|
|
263
|
+
error paths and the apply-each-and-report batch `remove`.
|
|
264
|
+
- [`tests/src/core/factories.test.ts`](../tests/src/core/factories.test.ts) —
|
|
265
|
+
`createTemplate` / `createTemplateManager` return working instances backed
|
|
266
|
+
by real `Template` / `TemplateManager`.
|
|
267
|
+
- [`tests/src/core/helpers.test.ts`](../tests/src/core/helpers.test.ts) —
|
|
268
|
+
`formatValue` / `resolveSafeField` / `resolveToken` / `fillTemplate`,
|
|
269
|
+
including bare interpolation with no declared placeholders, the `{`-in-token
|
|
270
|
+
pattern limit, missing policies, fallback precedence, and
|
|
271
|
+
prototype-pollution-unsafe paths.
|
|
272
|
+
- [`tests/src/core/shapers.test.ts`](../tests/src/core/shapers.test.ts) —
|
|
273
|
+
`placeholderShape` over required, optional, and described placeholders.
|
|
274
|
+
|
|
275
|
+
## See also
|
|
276
|
+
|
|
277
|
+
- [`AGENTS.md`](../AGENTS.md) — the rules.
|
|
278
|
+
- [`guide.md`](guide.md) — the mirrored guide for `@orkestrel/guide`, the
|
|
279
|
+
devDependency powering this repo's guides-parity test suite.
|
|
280
|
+
- [`README.md`](README.md) — the guides index.
|