@orkestrel/scaffold 0.0.67 → 0.0.69

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 (74) hide show
  1. package/dist/bin/main.js +67 -44
  2. package/dist/bin/main.js.map +1 -1
  3. package/dist/host/agents/templates/brief.md +9 -0
  4. package/dist/host/claude/agents/orkestrel.md +4 -4
  5. package/dist/host/claude/rules/names.md +15 -0
  6. package/dist/host/claude/rules/tests.md +33 -4
  7. package/dist/host/claude/rules/workspace.md +14 -2
  8. package/dist/host/dotfiles/prettierignore +3 -0
  9. package/dist/host/guides/README.md +65 -0
  10. package/dist/host/guides/abort.md +169 -0
  11. package/dist/host/guides/agent.md +1567 -0
  12. package/dist/host/guides/brief.md +1266 -0
  13. package/dist/host/guides/browser.md +2200 -0
  14. package/dist/host/guides/budget.md +196 -0
  15. package/dist/host/guides/codec.md +519 -0
  16. package/dist/host/guides/console.md +785 -0
  17. package/dist/host/guides/contract.md +1193 -0
  18. package/dist/host/guides/csv.md +541 -0
  19. package/dist/host/guides/database.md +2518 -0
  20. package/dist/host/guides/emitter.md +233 -0
  21. package/dist/host/guides/form.md +1791 -0
  22. package/dist/host/guides/html.md +717 -0
  23. package/dist/host/guides/indexeddb.md +505 -0
  24. package/dist/host/guides/interpret.md +1029 -0
  25. package/dist/host/guides/lsp.md +515 -0
  26. package/dist/host/guides/markdown.md +964 -0
  27. package/dist/host/guides/mcp.md +5554 -0
  28. package/dist/host/guides/middleware.md +927 -0
  29. package/dist/host/guides/msg.md +440 -0
  30. package/dist/host/guides/ndjson.md +120 -0
  31. package/dist/host/guides/ollama.md +380 -0
  32. package/dist/host/guides/pool.md +280 -0
  33. package/dist/host/guides/probe.md +1210 -0
  34. package/dist/host/guides/process.md +1620 -0
  35. package/dist/host/guides/program.md +1110 -0
  36. package/dist/host/guides/qualifier.md +854 -0
  37. package/dist/host/guides/queue.md +370 -0
  38. package/dist/host/guides/rater.md +330 -0
  39. package/dist/host/guides/reason.md +1122 -0
  40. package/dist/host/guides/relation.md +373 -0
  41. package/dist/host/guides/router.md +753 -0
  42. package/dist/host/guides/scaffold.md +192 -31
  43. package/dist/host/guides/sea.md +383 -0
  44. package/dist/host/guides/server.md +752 -0
  45. package/dist/host/guides/sqlite.md +330 -0
  46. package/dist/host/guides/sse.md +187 -0
  47. package/dist/host/guides/supervisor.md +4890 -0
  48. package/dist/host/guides/table.md +1556 -0
  49. package/dist/host/guides/template.md +280 -0
  50. package/dist/host/guides/terminal.md +1145 -0
  51. package/dist/host/guides/test.md +2969 -0
  52. package/dist/host/guides/timeout.md +252 -0
  53. package/dist/host/guides/tool.md +507 -0
  54. package/dist/host/guides/toolbox.md +1038 -0
  55. package/dist/host/guides/websocket.md +282 -0
  56. package/dist/host/guides/worker.md +615 -0
  57. package/dist/host/guides/workflow.md +1507 -0
  58. package/dist/host/guides/workspace.md +595 -0
  59. package/dist/host/manifest.json +1218 -10
  60. package/dist/host/tests/policy.test.ts +279 -2
  61. package/dist/host/tests/setupPolicy.ts +445 -6
  62. package/dist/src/core/index.cjs +38 -16
  63. package/dist/src/core/index.cjs.map +1 -1
  64. package/dist/src/core/index.d.cts +33 -9
  65. package/dist/src/core/index.d.ts +33 -9
  66. package/dist/src/core/index.js +37 -17
  67. package/dist/src/core/index.js.map +1 -1
  68. package/dist/src/server/index.cjs +1750 -1567
  69. package/dist/src/server/index.cjs.map +1 -1
  70. package/dist/src/server/index.d.cts +106 -24
  71. package/dist/src/server/index.d.ts +106 -24
  72. package/dist/src/server/index.js +1751 -1570
  73. package/dist/src/server/index.js.map +1 -1
  74. package/package.json +3 -3
@@ -0,0 +1,252 @@
1
+ # Timeout
2
+
3
+ > The time-bound half of the substrate's time-and-cancellation pair: a
4
+ > controllable `setTimeout` wrapper carrying a trace `id` and a deadline `ms`,
5
+ > whose native `AbortSignal` aborts on expiry.
6
+
7
+ Arm the deadline with `start()`, then race its `signal` against work to bound
8
+ how long that work may run; `clear()` cancels the deadline without firing it,
9
+ and a `start()` after an expiry swaps in a fresh signal, so one handle serves a
10
+ sequence of deadlines without re-construction. The package is deliberately
11
+ thin: not a scheduler, not a debounce, not a retry policy — one `setTimeout`
12
+ made re-armable, clearable, and parent-linkable. The native signal is the
13
+ complete observation surface, so there is no separate event map. Source:
14
+ [`src/core`](../src/core). Surfaced through the `@src/core` barrel.
15
+
16
+ ## Surface
17
+
18
+ Create a deadline handle, arm it, and hand its `signal` to deadline-aware
19
+ work — call `clear()` on the deadline if the work finishes first:
20
+
21
+ ```ts
22
+ import { createTimeout } from '@orkestrel/timeout'
23
+
24
+ const timeout = createTimeout({ ms: 5_000 })
25
+ timeout.start()
26
+
27
+ // `signal` aborts on expiry — pass it anywhere a native AbortSignal is accepted:
28
+ const response = await fetch(url, { signal: timeout.signal })
29
+
30
+ timeout.clear() // work finished first — cancel the deadline
31
+ ```
32
+
33
+ Construction is a strict JavaScript boundary. Options must be a plain readable
34
+ record; a defined `id` must be a string; `ms` must be an integer in the
35
+ inclusive range from `0` through `MAX_TIMEOUT_MS`; and a defined parent
36
+ `signal` must be a genuine native `AbortSignal`. Invalid input throws
37
+ `ContractError` from `@orkestrel/contract`: malformed or unreadable options use
38
+ code `bound`, while invalid `id`, `ms`, and `signal` values use `literal`,
39
+ `range`, and `placement`, respectively. Each error carries safe `path`, `limit`,
40
+ and `received` context. The package does not re-export `ContractError`.
41
+
42
+ An optional parent signal clears the timeout rather than expiring it if it
43
+ aborts before the deadline. An optional `id` labels the handle for tracing and
44
+ defaults to a random UUID.
45
+
46
+ ### Factories
47
+
48
+ | API | Kind | Summary |
49
+ | --------------- | -------- | ------------------------------------------------------------------------------------------------- |
50
+ | `createTimeout` | function | Creates a deadline handle from validated `TimeoutOptions` and returns it as a `TimeoutInterface`. |
51
+
52
+ ### Classes
53
+
54
+ | API | Kind | Summary |
55
+ | --------- | ----- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
56
+ | `Timeout` | class | Implements `TimeoutInterface` exactly, as a controllable `setTimeout` wrapper over one owned `AbortController` whose signal aborts when the deadline expires. |
57
+
58
+ ### Constants
59
+
60
+ A `Shape` cell holds the constant's declared type.
61
+
62
+ | API | Kind | Shape | Summary |
63
+ | ---------------- | ----- | -------- | ------------------------------------------------------------------------------------- |
64
+ | `MAX_TIMEOUT_MS` | const | `number` | Names the largest timeout duration the package accepts, `2_147_483_647` milliseconds. |
65
+
66
+ ### Validators
67
+
68
+ In a guard table a `Shape` cell holds the type the guard narrows to.
69
+
70
+ | API | Kind | Shape | Summary |
71
+ | ------------------- | -------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------------- |
72
+ | `isTimeoutDuration` | function | `number` | Determines whether a value is an integer in the inclusive range from `0` through `MAX_TIMEOUT_MS`, staying total for every input. |
73
+ | `isTimeoutSignal` | function | `AbortSignal` | Determines whether a value is a genuine native `AbortSignal`, staying total for a structural spoof and for a hostile or revoked proxy. |
74
+
75
+ ### Helpers
76
+
77
+ | API | Kind | Summary |
78
+ | ------------------------ | -------- | ------------------------------------------------------------------------------------------------------------------- |
79
+ | `validateTimeoutOptions` | function | Validates once-read timeout construction options and returns a fresh normalized copy omitting absent optional keys. |
80
+
81
+ ### Types
82
+
83
+ 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 `\|`.
84
+
85
+ | Type | Kind | Shape | Summary |
86
+ | ------------------ | --------- | ----------------------------------------------- | ----------------------------------------------------------------------------------------- |
87
+ | `TimeoutOptions` | interface | `{ id?, ms, signal? }` | Represents the options `createTimeout` and the `Timeout` constructor accept. |
88
+ | `TimeoutInterface` | interface | `{ id, ms, signal, expired } plus start, clear` | Represents a controllable deadline exposing a native `AbortSignal` that aborts on expiry. |
89
+
90
+ The `id`, `ms`, `signal`, and `expired` members of `TimeoutInterface` are
91
+ `readonly` data members (Shape cell, earlier) — its call-signature methods are
92
+ documented under [Methods](#methods). `expired` derives directly from the
93
+ owned signal's `aborted` state rather than storing a duplicate lifecycle flag.
94
+
95
+ ## Methods
96
+
97
+ The public methods of `TimeoutInterface` — every call-signature member listed
98
+ (its `readonly` members `id` / `ms` / `signal` / `expired` have no method row).
99
+ `Timeout` implements the interface exactly, so this doubles as the class's
100
+ instance-method surface (AGENTS.md, Documentation contract).
101
+
102
+ #### `TimeoutInterface`
103
+
104
+ The call-signature members, each with the type it returns:
105
+
106
+ | Method | Returns | Summary |
107
+ | ------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------------------- |
108
+ | `start` | `void` | Arms or re-arms the deadline for `ms`, installing a fresh `signal` when the current one has already aborted. |
109
+ | `clear` | `void` | Cancels an armed deadline without aborting its `signal`, and resets expiry by installing a fresh signal when the current one has already aborted. |
110
+
111
+ ## Contract
112
+
113
+ These invariants hold across `src/core` ↔ `timeout.md`:
114
+
115
+ 1. **DOC ↔ SOURCE bijection.** Every `function` / `class` / `const` /
116
+ `interface` row in the `## Surface` tables is a real export of the timeout
117
+ source, and every export appears as a Surface row — exhaustive, both
118
+ directions (AGENTS.md, Documentation contract).
119
+ 2. **Strict construction boundary.** `validateTimeoutOptions` requires a plain
120
+ readable record, reads `id`, `ms`, and `signal` exactly once inside a
121
+ contained boundary, validates them, and returns a fresh normalized copy that
122
+ omits absent optional keys. Defined identifiers must be strings, durations
123
+ must be integers in inclusive `[0, MAX_TIMEOUT_MS]`, and defined parent
124
+ signals must pass the native brand check. `Timeout` calls this helper before
125
+ allocating its controller or listener. Negative zero and zero are valid;
126
+ zero intentionally expires on the next turn. Invalid inputs throw the coded
127
+ `ContractError` taxonomy described under Surface.
128
+ 3. **Deadline signal and derived expiry.** The exposed `signal` fires (aborts)
129
+ on expiry. `expired` derives from that owned signal's `aborted` state, so
130
+ `expired` and `aborted` cannot drift apart.
131
+ 4. **Signal identity swaps only on a real expiry.** A cleared-but-never-fired
132
+ timeout keeps its original `signal` (not aborted); the identity is only
133
+ swapped for a fresh, non-aborted controller after the current controller has
134
+ fired — whether that swap happens inside `clear()` or at the next `start()`.
135
+ 5. **Parent linking clears, never expires.** A parent `options.signal` abort
136
+ clears the timeout — it does not expire the timeout, abort the timeout's own
137
+ signal, or forward the parent reason. The parent listener is attached only
138
+ while a timer is armed (added on `start()`, removed on expiry or `clear()`);
139
+ once the parent has aborted, a later `start()` is a no-op.
140
+ 6. **Identifiers are strict.** Omitted `id` values generate a random UUID and an
141
+ empty string is retained, but every other defined non-string value throws a
142
+ `literal`-coded `ContractError` rather than being coerced or replaced.
143
+ 7. **Native observation.** Consumers observe expiry through the complete native
144
+ `AbortSignal`; `Timeout` adds no `Emitter` or parallel event system.
145
+
146
+ ## Patterns
147
+
148
+ ### Race work against a deadline
149
+
150
+ Builds a deadline handle, arms it, and clears it in a `finally` once the race resolves:
151
+
152
+ ```ts
153
+ import { createTimeout } from '@orkestrel/timeout'
154
+
155
+ async function fetchWithDeadline(url: string, ms: number): Promise<Response> {
156
+ const timeout = createTimeout({ ms })
157
+ timeout.start()
158
+
159
+ try {
160
+ return await fetch(url, { signal: timeout.signal })
161
+ } finally {
162
+ timeout.clear() // cancels the still-armed deadline when the fetch won the race
163
+ }
164
+ }
165
+ ```
166
+
167
+ ### Link a parent signal
168
+
169
+ A parent `AbortSignal` clears the deadline instead of letting it expire — so
170
+ an outer cancellation (a request abort, a shutdown signal) short-circuits the
171
+ timer cleanly without aborting the timeout's own signal:
172
+
173
+ ```ts
174
+ import { createTimeout } from '@orkestrel/timeout'
175
+
176
+ function withDeadline(parent: AbortSignal, ms: number) {
177
+ const timeout = createTimeout({ id: 'request-deadline', ms, signal: parent })
178
+ timeout.start()
179
+
180
+ timeout.signal.addEventListener(
181
+ 'abort',
182
+ () => {
183
+ if (timeout.expired) giveUp() // only a real timeout expiry reaches this listener
184
+ },
185
+ { once: true },
186
+ )
187
+
188
+ return timeout
189
+ }
190
+ ```
191
+
192
+ ### Reuse a handle across deadlines
193
+
194
+ Clears an armed deadline before it fires, then arms the same handle again for a fresh window:
195
+
196
+ ```ts
197
+ import { createTimeout } from '@orkestrel/timeout'
198
+
199
+ const timeout = createTimeout({ ms: 100 })
200
+
201
+ timeout.start()
202
+ timeout.clear() // cancels before firing — expired stays false
203
+
204
+ timeout.start() // re-armed; a fresh deadline window begins
205
+ ```
206
+
207
+ ### Practices
208
+
209
+ - **Race, don't poll** — attach a listener to `signal` (or pass it straight to
210
+ an API that accepts an `AbortSignal`, for example `fetch`) rather than
211
+ polling `expired`.
212
+ - **`clear()` is always safe to call** — clearing an idle or already-cleared
213
+ handle is a no-op; after expiry it installs a fresh non-aborted signal. Call
214
+ it unconditionally in a `finally`.
215
+ - **Keep parent cancellation distinct** — a parent abort clears the timer but
216
+ does not abort the timeout signal or forward the parent reason.
217
+ - **Reuse, don't reconstruct** — call `start()` again on the same handle for a
218
+ new deadline window instead of constructing a fresh `Timeout`.
219
+
220
+ ## Tests
221
+
222
+ - [`tests/guides.test.ts`](../tests/guides.test.ts) — the `## Surface` ↔
223
+ `src/core` bijection over value and type exports, the `TimeoutInterface` ↔
224
+ `Timeout` method bijection, and the equality gate: every `Summary` cell
225
+ against its declaration's description paragraph, the titled fence against the
226
+ `@example` block of that title (pinned so the titled pair cannot be retired
227
+ silently), and the README pitch against this guide's tagline. It also runs the
228
+ flagship fences and asserts the values their comments claim.
229
+ - [`tests/src/core/Timeout.test.ts`](../tests/src/core/Timeout.test.ts) —
230
+ public-constructor integration, real expiry / clear / replacement / churn
231
+ behavior, signal identity and derived expiry, and the intentional parent-clear
232
+ lifecycle.
233
+ - [`tests/src/core/helpers.test.ts`](../tests/src/core/helpers.test.ts) — fresh
234
+ normalized copies, omitted optional keys, exactly-once property reads, hostile
235
+ getter containment, duration boundaries, and exact structured errors.
236
+ - [`tests/src/core/validators.test.ts`](../tests/src/core/validators.test.ts) —
237
+ total duration and native-signal validation, including spoofed values and a
238
+ revoked proxy.
239
+ - [`tests/src/core/factories.test.ts`](../tests/src/core/factories.test.ts) —
240
+ `createTimeout` returns a working `TimeoutInterface` and preserves the strict
241
+ construction boundary.
242
+
243
+ ## See also
244
+
245
+ - [`AGENTS.md`](../AGENTS.md) — the rules, including the documentation contract
246
+ and the fixed lifecycle meanings of `start` and `clear`.
247
+ - [`contract.md`](contract.md) — the mirrored guide for `@orkestrel/contract`,
248
+ the source of the validation primitives and `ContractError` used at the
249
+ construction boundary.
250
+ - [`guide.md`](guide.md) — the mirrored guide for `@orkestrel/guide`, the
251
+ devDependency powering this repo's guides-parity test suite.
252
+ - [`README.md`](README.md) — the guides index.