@orkestrel/scaffold 0.0.72 → 0.0.73
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/host/claude/agents/orkestrel.md +46 -46
- package/dist/host/dotfiles/gitignore +3 -0
- package/dist/host/guides/test.md +77 -55
- package/dist/host/manifest.json +8 -18
- package/dist/host/tests/config.test.ts +113 -57
- package/dist/src/core/index.cjs +1 -1
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.js +1 -1
- package/dist/src/core/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -45,56 +45,56 @@ so network-controlled descriptions never enter agent instruction context.
|
|
|
45
45
|
|
|
46
46
|
| Package | Version | Layer | Runtime dependencies | Peer dependencies |
|
|
47
47
|
| ----------------------- | -------- | ----- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------- |
|
|
48
|
-
| `@orkestrel/abort` | `0.0.
|
|
49
|
-
| `@orkestrel/agent` | `0.0.
|
|
50
|
-
| `@orkestrel/brief` | `0.0.
|
|
51
|
-
| `@orkestrel/browser` | `0.0.
|
|
52
|
-
| `@orkestrel/budget` | `0.0.
|
|
53
|
-
| `@orkestrel/codec` | `0.0.
|
|
54
|
-
| `@orkestrel/console` | `0.0.
|
|
48
|
+
| `@orkestrel/abort` | `0.0.11` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
49
|
+
| `@orkestrel/agent` | `0.0.24` | L5 | `@orkestrel/abort` `^0.0.11`, `@orkestrel/budget` `^0.0.11`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/queue` `^0.0.14`, `@orkestrel/timeout` `^0.0.11`, `@orkestrel/tool` `^0.0.16`, `@orkestrel/workflow` `^0.0.19`, `@orkestrel/workspace` `^0.0.9` | |
|
|
50
|
+
| `@orkestrel/brief` | `0.0.9` | L4 | `@orkestrel/reason` `^0.0.11`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/interpret` `^0.0.14` | |
|
|
51
|
+
| `@orkestrel/browser` | `0.0.17` | L3 | `@orkestrel/html` `^0.0.10`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/websocket` `^0.0.13` | |
|
|
52
|
+
| `@orkestrel/budget` | `0.0.11` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
53
|
+
| `@orkestrel/codec` | `0.0.4` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
54
|
+
| `@orkestrel/console` | `0.0.14` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
55
55
|
| `@orkestrel/contract` | `0.0.17` | L0 | | |
|
|
56
|
-
| `@orkestrel/csv` | `0.0.
|
|
57
|
-
| `@orkestrel/database` | `0.0.
|
|
56
|
+
| `@orkestrel/csv` | `0.0.8` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
57
|
+
| `@orkestrel/database` | `0.0.15` | L2 | `@orkestrel/sqlite` `^0.0.12`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/indexeddb` `^0.0.12` | |
|
|
58
58
|
| `@orkestrel/emitter` | `0.0.10` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
59
|
-
| `@orkestrel/form` | `0.0.
|
|
60
|
-
| `@orkestrel/guide` | `0.0.
|
|
61
|
-
| `@orkestrel/html` | `0.0.
|
|
62
|
-
| `@orkestrel/indexeddb` | `0.0.
|
|
63
|
-
| `@orkestrel/interpret` | `0.0.
|
|
64
|
-
| `@orkestrel/lsp` | `0.0.
|
|
65
|
-
| `@orkestrel/markdown` | `0.0.
|
|
66
|
-
| `@orkestrel/mcp` | `0.0.
|
|
67
|
-
| `@orkestrel/middleware` | `0.0.
|
|
68
|
-
| `@orkestrel/msg` | `0.0.
|
|
59
|
+
| `@orkestrel/form` | `0.0.7` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
60
|
+
| `@orkestrel/guide` | `0.0.20` | L3 | `@orkestrel/contract` `^0.0.17`, `@orkestrel/markdown` `^0.0.15` | |
|
|
61
|
+
| `@orkestrel/html` | `0.0.10` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
62
|
+
| `@orkestrel/indexeddb` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
63
|
+
| `@orkestrel/interpret` | `0.0.14` | L3 | `@orkestrel/reason` `^0.0.11`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/template` `^0.0.8` | |
|
|
64
|
+
| `@orkestrel/lsp` | `0.0.9` | L3 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/process` `^0.0.13`, `@orkestrel/contract` `^0.0.17` | |
|
|
65
|
+
| `@orkestrel/markdown` | `0.0.15` | L2 | `@orkestrel/html` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
66
|
+
| `@orkestrel/mcp` | `0.0.32` | L4 | `@orkestrel/sse` `^0.0.8`, `@orkestrel/tool` `^0.0.16`, `@orkestrel/codec` `^0.0.4`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/process` `^0.0.13`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/websocket` `^0.0.13` | `@orkestrel/router` `^0.0.15`, `@orkestrel/server` `^0.0.20` |
|
|
67
|
+
| `@orkestrel/middleware` | `0.0.21` | L4 | `@orkestrel/abort` `^0.0.11`, `@orkestrel/budget` `^0.0.11`, `@orkestrel/timeout` `^0.0.11`, `@orkestrel/contract` `^0.0.17` | `@orkestrel/server` `^0.0.20`, `@orkestrel/database` `^0.0.15` |
|
|
68
|
+
| `@orkestrel/msg` | `0.0.11` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
69
69
|
| `@orkestrel/ndjson` | `0.0.10` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
70
|
-
| `@orkestrel/ollama` | `0.0.
|
|
71
|
-
| `@orkestrel/pool` | `0.0.
|
|
72
|
-
| `@orkestrel/probe` | `0.0.
|
|
73
|
-
| `@orkestrel/process` | `0.0.
|
|
74
|
-
| `@orkestrel/program` | `0.0.
|
|
75
|
-
| `@orkestrel/qualifier` | `0.0.
|
|
76
|
-
| `@orkestrel/queue` | `0.0.
|
|
77
|
-
| `@orkestrel/rater` | `0.0.
|
|
78
|
-
| `@orkestrel/reason` | `0.0.
|
|
79
|
-
| `@orkestrel/relation` | `0.0.
|
|
80
|
-
| `@orkestrel/router` | `0.0.
|
|
81
|
-
| `@orkestrel/scaffold` | `0.0.
|
|
82
|
-
| `@orkestrel/sea` | `0.0.
|
|
83
|
-
| `@orkestrel/server` | `0.0.
|
|
84
|
-
| `@orkestrel/sqlite` | `0.0.
|
|
85
|
-
| `@orkestrel/sse` | `0.0.
|
|
70
|
+
| `@orkestrel/ollama` | `0.0.18` | L6 | `@orkestrel/tool` `^0.0.16`, `@orkestrel/agent` `^0.0.24`, `@orkestrel/budget` `^0.0.11`, `@orkestrel/ndjson` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
71
|
+
| `@orkestrel/pool` | `0.0.12` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
72
|
+
| `@orkestrel/probe` | `0.0.16` | L5 | `@orkestrel/lsp` `^0.0.9`, `@orkestrel/mcp` `^0.0.32`, `@orkestrel/tool` `^0.0.16`, `@orkestrel/queue` `^0.0.14`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/timeout` `^0.0.11`, `@orkestrel/contract` `^0.0.17` | `oxlint` `^1.82.0`, `vitest` `^4.1.11`, `typescript` `^6.0.3` |
|
|
73
|
+
| `@orkestrel/process` | `0.0.13` | L2 | `@orkestrel/contract` `^0.0.17`, `@orkestrel/emitter` `^0.0.10` | |
|
|
74
|
+
| `@orkestrel/program` | `0.0.14` | L4 | `@orkestrel/contract` `^0.0.17`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/qualifier` `^0.0.15`, `@orkestrel/rater` `^0.0.15`, `@orkestrel/reason` `^0.0.11` | |
|
|
75
|
+
| `@orkestrel/qualifier` | `0.0.15` | L3 | `@orkestrel/reason` `^0.0.11`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
76
|
+
| `@orkestrel/queue` | `0.0.14` | L3 | `@orkestrel/abort` `^0.0.11`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/timeout` `^0.0.11` | |
|
|
77
|
+
| `@orkestrel/rater` | `0.0.15` | L3 | `@orkestrel/reason` `^0.0.11`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
78
|
+
| `@orkestrel/reason` | `0.0.11` | L2 | `@orkestrel/contract` `^0.0.17`, `@orkestrel/emitter` `^0.0.10` | |
|
|
79
|
+
| `@orkestrel/relation` | `0.0.13` | L3 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15` | |
|
|
80
|
+
| `@orkestrel/router` | `0.0.15` | L2 | `@orkestrel/abort` `^0.0.11`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
81
|
+
| `@orkestrel/scaffold` | `0.0.72` | L3 | `@orkestrel/console` `^0.0.14`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/markdown` `^0.0.15`, `@orkestrel/process` `^0.0.13`, `@orkestrel/template` `^0.0.8` | |
|
|
82
|
+
| `@orkestrel/sea` | `0.0.17` | L3 | `@orkestrel/contract` `^0.0.17`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/process` `^0.0.13` | |
|
|
83
|
+
| `@orkestrel/server` | `0.0.20` | L3 | `@orkestrel/abort` `^0.0.11`, `@orkestrel/codec` `^0.0.4`, `@orkestrel/router` `^0.0.15`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/timeout` `^0.0.11`, `@orkestrel/contract` `^0.0.17` | |
|
|
84
|
+
| `@orkestrel/sqlite` | `0.0.12` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
85
|
+
| `@orkestrel/sse` | `0.0.8` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
86
86
|
| `@orkestrel/supervisor` | `0.0.1` | L5 | `@orkestrel/contract` `^0.0.11`, `@orkestrel/database` `^0.0.9`, `@orkestrel/emitter` `^0.0.6`, `@orkestrel/workflow` `^0.0.12` | |
|
|
87
|
-
| `@orkestrel/table` | `0.0.
|
|
88
|
-
| `@orkestrel/template` | `0.0.
|
|
89
|
-
| `@orkestrel/terminal` | `0.0.
|
|
90
|
-
| `@orkestrel/test` | `0.0.
|
|
91
|
-
| `@orkestrel/timeout` | `0.0.
|
|
92
|
-
| `@orkestrel/tool` | `0.0.
|
|
93
|
-
| `@orkestrel/toolbox` | `0.0.
|
|
94
|
-
| `@orkestrel/websocket` | `0.0.
|
|
95
|
-
| `@orkestrel/worker` | `0.0.
|
|
96
|
-
| `@orkestrel/workflow` | `0.0.
|
|
97
|
-
| `@orkestrel/workspace` | `0.0.
|
|
87
|
+
| `@orkestrel/table` | `0.0.6` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
88
|
+
| `@orkestrel/template` | `0.0.8` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
89
|
+
| `@orkestrel/terminal` | `0.0.16` | L3 | `@orkestrel/sse` `^0.0.8`, `@orkestrel/form` `^0.0.7`, `@orkestrel/console` `^0.0.14`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15` | |
|
|
90
|
+
| `@orkestrel/test` | `0.0.16` | L1 | `@orkestrel/contract` `^0.0.17` | `vitest` `^4.1.11` |
|
|
91
|
+
| `@orkestrel/timeout` | `0.0.11` | L1 | `@orkestrel/contract` `^0.0.17` | |
|
|
92
|
+
| `@orkestrel/tool` | `0.0.16` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
93
|
+
| `@orkestrel/toolbox` | `0.0.15` | L6 | `@orkestrel/form` `^0.0.7`, `@orkestrel/tool` `^0.0.16`, `@orkestrel/agent` `^0.0.24`, `@orkestrel/server` `^0.0.20`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15`, `@orkestrel/relation` `^0.0.13`, `@orkestrel/terminal` `^0.0.16`, `@orkestrel/workflow` `^0.0.19`, `@orkestrel/workspace` `^0.0.9` | |
|
|
94
|
+
| `@orkestrel/websocket` | `0.0.13` | L2 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17` | |
|
|
95
|
+
| `@orkestrel/worker` | `0.0.13` | L4 | `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/pool` `^0.0.12`, `@orkestrel/queue` `^0.0.14` | |
|
|
96
|
+
| `@orkestrel/workflow` | `0.0.19` | L4 | `@orkestrel/abort` `^0.0.11`, `@orkestrel/budget` `^0.0.11`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15`, `@orkestrel/emitter` `^0.0.10`, `@orkestrel/queue` `^0.0.14`, `@orkestrel/timeout` `^0.0.11` | |
|
|
97
|
+
| `@orkestrel/workspace` | `0.0.9` | L3 | `@orkestrel/emitter` `^0.0.10`, `@orkestrel/contract` `^0.0.17`, `@orkestrel/database` `^0.0.15` | |
|
|
98
98
|
|
|
99
99
|
<!-- /orkestrel:catalog -->
|
|
100
100
|
|
package/dist/host/guides/test.md
CHANGED
|
@@ -43,11 +43,12 @@ package holds one implementation of each and ships as a `devDependency`. Nothing
|
|
|
43
43
|
production code. Source: [`src/core`](../src/core), [`src/browser`](../src/browser), and
|
|
44
44
|
[`src/server`](../src/server).
|
|
45
45
|
|
|
46
|
-
|
|
46
|
+
This package runtime-depends on `@orkestrel/contract` for the outcome type `retryUntil` reads
|
|
47
|
+
internally. That type is not re-exported. No exported type here names an `@orkestrel/*` type. A
|
|
47
48
|
dependency on `@orkestrel/emitter` would install a second copy of it beside the one a consumer
|
|
48
49
|
already pins, and the compiler reads two copies as two distinct types. A foreign type in a
|
|
49
50
|
signature fails the other way, rejecting the consumer's own local value inside the consumer's own
|
|
50
|
-
repository.
|
|
51
|
+
repository. Those rules hold both.
|
|
51
52
|
|
|
52
53
|
## Install
|
|
53
54
|
|
|
@@ -110,31 +111,27 @@ member and `plus` introducing its call-signature members, and a type alias's own
|
|
|
110
111
|
a union's arms escaped as `\|`. An extended interface's name comes before `plus`, with the members
|
|
111
112
|
it adds after.
|
|
112
113
|
|
|
113
|
-
| Type | Kind | Shape
|
|
114
|
-
| -------------------------- | --------- |
|
|
115
|
-
| `WaitOptions` | interface | `{ budget?, interval?, signal? }`
|
|
116
|
-
| `RetryOptions` | interface | `WaitOptions` plus `{ attempts? }`
|
|
117
|
-
| `EventSubscriber` | type | `(listener) => cleanup \| void`
|
|
118
|
-
| `RecorderInterface` | interface | `{ calls, count, handler }` plus `clear`
|
|
119
|
-
| `EventSourceInterface` | interface | `{} plus on`
|
|
120
|
-
| `RecorderMap` | type | `{ readonly [K in TName]: RecorderInterface<TMap[K]> }`
|
|
121
|
-
| `
|
|
122
|
-
| `
|
|
123
|
-
| `
|
|
124
|
-
| `
|
|
125
|
-
| `
|
|
126
|
-
| `
|
|
127
|
-
| `
|
|
128
|
-
| `
|
|
129
|
-
| `
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
Each interface's call-signature members are listed under [Methods](#methods). `Result` defaults `E`
|
|
136
|
-
to `Error`, where `@orkestrel/contract` publishes the same name defaulting to `unknown`;
|
|
137
|
-
[Limits](#limits) rules that divergence.
|
|
114
|
+
| Type | Kind | Shape | Summary |
|
|
115
|
+
| -------------------------- | --------- | ------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
116
|
+
| `WaitOptions` | interface | `{ budget?, interval?, signal? }` | Configures a bounded asynchronous wait with an elapsed-time limit, a delay between readings, and an abort signal. |
|
|
117
|
+
| `RetryOptions` | interface | `WaitOptions` plus `{ attempts? }` | Configures a bounded retry, adding an optional producer-call limit to a bounded wait's bounds. |
|
|
118
|
+
| `EventSubscriber` | type | `(listener) => cleanup \| void` | Subscribes a listener to one event source. |
|
|
119
|
+
| `RecorderInterface` | interface | `{ calls, count, handler }` plus `clear` | Records every call made to its handler. |
|
|
120
|
+
| `EventSourceInterface` | interface | `{} plus on` | Subscribes handlers to a typed event source. |
|
|
121
|
+
| `RecorderMap` | type | `{ readonly [K in TName]: RecorderInterface<TMap[K]> }` | Maps event names to recorders for their delivered argument tuples. |
|
|
122
|
+
| `SignalInterface` | interface | `{ controller, signal, count }` | Holds a real abort signal and controller instrumented with its live abort-listener tally. |
|
|
123
|
+
| `SignalRegistration` | type | `readonly [listener, installed, capture, cleanup]` | Represents one abort listener an instrumented signal installed, as its tally holds it. |
|
|
124
|
+
| `ResourceFactoryInterface` | interface | `{ created, destroyed }` plus `create` / `destroy` | Represents a numbered resource factory with records of every creation and destruction. |
|
|
125
|
+
| `TeardownInterface` | interface | `{ count }` plus `add` / `destroy` | Represents the cleanup a test adds as it goes and runs once, newest first, when it is done. |
|
|
126
|
+
| `TeardownHandler` | type | `() => void \| Promise<void>` | Represents the work one teardown entry performs when the list is destroyed. |
|
|
127
|
+
| `JSONSafe` | type | `JSONSafe<T>` | Represents the JSON-safe projection of a type: every member JSON preserves, mapped to itself, and every member it does not, mapped to `never`. |
|
|
128
|
+
| `HeadersSource` | type | `NonNullable<ConstructorParameters<typeof Headers>[0]>` | Covers any value the host `Headers` constructor accepts. |
|
|
129
|
+
| `StateTransition` | interface | `{ name, from, event, to }` | Represents one row of a statechart table: the entity's state before an event, the event, and the state that event must leave it in. |
|
|
130
|
+
| `StateScenario` | interface | `{ transition }` plus `arrange` / `act` / `assert` | Drives one `StateTransition` through the three phases that prove it. |
|
|
131
|
+
|
|
132
|
+
Each interface's call-signature members are listed under [Methods](#methods). `Result`, `Success`,
|
|
133
|
+
and `Failure` come from `@orkestrel/contract` (mirrored at [`contract.md`](contract.md)) and are not
|
|
134
|
+
re-exported; `retryUntil` reads `Result` internally.
|
|
138
135
|
|
|
139
136
|
#### Constants
|
|
140
137
|
|
|
@@ -221,15 +218,15 @@ The fixture builders, the readers, and the field writers do take an element, and
|
|
|
221
218
|
journey verb. `build` creates a node, `mount` attaches one, and `render` does both from
|
|
222
219
|
markup or from a tag and its classes; `clearStorage` takes nothing at all, and `removeDatabase`
|
|
223
220
|
takes a database name. The predicates, the element readers, and the describers name a node the
|
|
224
|
-
caller already has — `isRendered`, `isReachable`, `readText`, `readRole`, `readName`,
|
|
225
|
-
`describeTree`, `describeFocus`, `extractOrphans`, `readRows`, `readStyle`,
|
|
226
|
-
`readPixels`, `readContrast`, `readLayers`, `readBackdrop`, and `readRing` — and each
|
|
227
|
-
node rather than acting on a target it was handed. `captureFrame` and `place` take an
|
|
228
|
-
well, and photographing one is a reading too: neither moves focus, dispatches an event,
|
|
229
|
-
what the element renders. `typeInput` and `commitInput` are the exception, and it stays
|
|
230
|
-
write into the field they are given, as the synthetic counterpart of `typeAccessible`
|
|
231
|
-
component that listens for `input`. The color leaves, the cascade readers, the pane verbs,
|
|
232
|
-
whole-document readers take a value or nothing at all, so they name no target either.
|
|
221
|
+
caller already has — `isRendered`, `isReachable`, `readHit`, `readText`, `readRole`, `readName`,
|
|
222
|
+
`readStates`, `describeTree`, `describeFocus`, `extractOrphans`, `readRows`, `readStyle`,
|
|
223
|
+
`readToken`, `readPixels`, `readContrast`, `readLayers`, `readBackdrop`, and `readRing` — and each
|
|
224
|
+
reads that node rather than acting on a target it was handed. `captureFrame` and `place` take an
|
|
225
|
+
element as well, and photographing one is a reading too: neither moves focus, dispatches an event,
|
|
226
|
+
or changes what the element renders. `typeInput` and `commitInput` are the exception, and it stays
|
|
227
|
+
narrow: they write into the field they are given, as the synthetic counterpart of `typeAccessible`
|
|
228
|
+
for a component that listens for `input`. The color leaves, the cascade readers, the pane verbs,
|
|
229
|
+
and the whole-document readers take a value or nothing at all, so they name no target either.
|
|
233
230
|
|
|
234
231
|
#### Types
|
|
235
232
|
|
|
@@ -275,6 +272,7 @@ A `Shape` cell holds the constant's declared type.
|
|
|
275
272
|
| `isOutsideViewport` | function | `(rectangle: DOMRectReadOnly) => boolean` | Determines whether a rectangle lies wholly outside the browser viewport. |
|
|
276
273
|
| `isRendered` | function | `(element: Element) => boolean` | Determines whether the accessibility tree presents one element at all. |
|
|
277
274
|
| `isReachable` | function | `(element: Element) => boolean` | Determines whether a person can click one element where it sits. |
|
|
275
|
+
| `readHit` | function | `(element: Element) => Element \| undefined` | Reads the topmost element at one element's bounding-box centre. |
|
|
278
276
|
| `clickAccessible` | function | `(name: string) => Promise<void>` / `(role: string, name: string) => Promise<void>` | Clicks one visible, focus-reachable control by its accessible name through the browser provider. |
|
|
279
277
|
| `clickAccessibleWithin` | function | `(region: string, role: string, name: string) => Promise<void>` | Clicks one human-reachable control by role and accessible-name text inside a named region. |
|
|
280
278
|
| `clickDisclosure` | function | `(name: string) => Promise<void>` | Opens or closes one native details disclosure by its rendered summary. |
|
|
@@ -1188,24 +1186,24 @@ These hold across `src/core`, `src/browser`, `src/server`, and this guide.
|
|
|
1188
1186
|
into a description of the markup. `build` creates a node, `mount` attaches one, `render` does
|
|
1189
1187
|
both, `clearStorage` takes nothing at all, and `removeDatabase` takes a database name. The
|
|
1190
1188
|
predicates, the element readers, and the describers do take a node —
|
|
1191
|
-
`isRendered`, `isReachable`, `readText`, `readRole`, `readName`, `readStates`,
|
|
1192
|
-
`describeFocus`, `extractOrphans`, `readRows`, `readStyle`, `readToken`,
|
|
1193
|
-
`readContrast`, `readLayers`, `readBackdrop`, and `readRing` — and each is a
|
|
1194
|
-
the caller already has rather than a verb that acts on a target. `captureFrame`
|
|
1195
|
-
one as the subject of a photograph, which is a reading too: neither moves
|
|
1196
|
-
event, nor changes what the element renders. `typeInput` and `commitInput`
|
|
1197
|
-
acts on the element it is handed, and the exception is deliberately
|
|
1198
|
-
synthetic counterpart of `typeAccessible`, for a component that listens for
|
|
1199
|
-
that already holds the field. Drive the field by name wherever the keystrokes
|
|
1200
|
-
the journey claims. `readRing` is the case that makes the split explicit. It
|
|
1201
|
-
chrome a browser painted and never brings the focus about, so a journey
|
|
1202
|
-
through `traverseAccessible` or `userEvent.keyboard` from `vitest/browser`
|
|
1203
|
-
landed. The whole environment imports `vitest/browser` and DOM globals
|
|
1204
|
-
`src/core` import, no framework, no `node:*`, and no `import.meta.env`, so
|
|
1205
|
-
captures is the consumer's decision through `PortfolioOptions.enabled`
|
|
1206
|
-
variable this package reads. `vitest` is a peer dependency, so the
|
|
1207
|
-
the one the consumer already installed, and the
|
|
1208
|
-
`dependencies` is untouched.
|
|
1189
|
+
`isRendered`, `isReachable`, `readHit`, `readText`, `readRole`, `readName`, `readStates`,
|
|
1190
|
+
`describeTree`, `describeFocus`, `extractOrphans`, `readRows`, `readStyle`, `readToken`,
|
|
1191
|
+
`readPixels`, `readContrast`, `readLayers`, `readBackdrop`, and `readRing` — and each is a
|
|
1192
|
+
reader of a node the caller already has rather than a verb that acts on a target. `captureFrame`
|
|
1193
|
+
and `place` take one as the subject of a photograph, which is a reading too: neither moves
|
|
1194
|
+
focus, dispatches an event, nor changes what the element renders. `typeInput` and `commitInput`
|
|
1195
|
+
are the one pair that acts on the element it is handed, and the exception is deliberately
|
|
1196
|
+
narrow: they are the synthetic counterpart of `typeAccessible`, for a component that listens for
|
|
1197
|
+
`input` and a test that already holds the field. Drive the field by name wherever the keystrokes
|
|
1198
|
+
are part of what the journey claims. `readRing` is the case that makes the split explicit. It
|
|
1199
|
+
measures the focus chrome a browser painted and never brings the focus about, so a journey
|
|
1200
|
+
reaches the control through `traverseAccessible` or `userEvent.keyboard` from `vitest/browser`
|
|
1201
|
+
and then measures what landed. The whole environment imports `vitest/browser` and DOM globals
|
|
1202
|
+
and nothing else — no `src/core` import, no framework, no `node:*`, and no `import.meta.env`, so
|
|
1203
|
+
whether a run writes captures is the consumer's decision through `PortfolioOptions.enabled`
|
|
1204
|
+
rather than an environment variable this package reads. `vitest` is a peer dependency, so the
|
|
1205
|
+
provider the layer drives is the one the consumer already installed, and the
|
|
1206
|
+
zero-runtime-dependencies contract's empty `dependencies` is untouched.
|
|
1209
1207
|
14. **The wait family polls only where nothing publishes an event.** The no-polling architecture law
|
|
1210
1208
|
governs a product's idle wakeup: a running system parks on the event or the abort signal that
|
|
1211
1209
|
fires. A test instrument is the other case. It waits on a fact another process produces — a file
|
|
@@ -1250,6 +1248,13 @@ These hold across `src/core`, `src/browser`, `src/server`, and this guide.
|
|
|
1250
1248
|
narrow their own candidates and then keep the ones it accepts — so a journey meets one rule
|
|
1251
1249
|
rather than near-copies of it. Neither asks about the viewport; `resolveAccessible` scrolls a
|
|
1252
1250
|
wholly off-viewport target into view and measures that separately with `isOutsideViewport`.
|
|
1251
|
+
`readHit` reads beside that pair rather than filtering with it. It hit-tests one point — the
|
|
1252
|
+
element's own bounding-box centre — which is how it sees what neither predicate can: a cover
|
|
1253
|
+
over a control they both accept, and a wrapped inline target whose centre falls between its line
|
|
1254
|
+
boxes. No acting verb consults it, because it names a node rather than ruling, and `isReachable`
|
|
1255
|
+
stays the one reachability filter the verbs apply. It is also the reader that needs the pair run
|
|
1256
|
+
first, and [Bounds a shipped helper carries](#bounds-a-shipped-helper-carries) states what it
|
|
1257
|
+
reports for an element that failed them.
|
|
1253
1258
|
17. **A journal forwards every console call and swallows nothing.** A browser publishes no listener
|
|
1254
1259
|
for its own output, so `createJournal` stands in front of the console and hands each call on to
|
|
1255
1260
|
the channel that was there when `start` armed it. A run under a journal therefore prints exactly
|
|
@@ -1373,13 +1378,14 @@ or when a consumer appears the ruling did not consider.
|
|
|
1373
1378
|
| A DOM element builder | Ships | It ships as `build` for the element and `mount` for the attachment, and `render` widened to take a tag and its class list as well as markup. A class list, a text, and an attribute map are what a fixture actually varies, and expressing that variation through markup means assembling a string. Nothing here assembles a tree one call at a time: a fixture with children is still written as markup. |
|
|
1374
1379
|
| A surface digest — `describeSurface` | Refused | Its digest format is one workspace's policy about what a summary of a surface contains, and it is assembled from the excluded `extractControls` besides. `describeTree` and `describeFocus` publish the readings a digest is built from instead. |
|
|
1375
1380
|
| A control extractor — `extractControls` | Refused | Generalized past its one caller it is a wrapper over `querySelectorAll` that adds no boundary, invariant, composition, or narrower contract, which is what the superfluous-wrapper rule refuses. |
|
|
1381
|
+
| A pointer-centre hit reading — `readHit` | Ships | It ships as `readHit`. `extractControls` is the bar it has to clear, and it does: the centre computation composes a rectangle reading with a hit test, the `undefined` translation is this package's absence convention for a reader, and "the point is always this element's centre" is a materially narrower contract than `elementFromPoint`. `roughnotes` writes that composition inline in `App.test.ts`, `integration.test.ts`, and the `ContactForm`, `PaymentForm`, and `SubscribeForm` suites, each against the cover and the wrapped target `isReachable` cannot see. |
|
|
1376
1382
|
| Text resolution by selector — `resolveText` | Refused | The journey-layer contract is the one it breaks: a journey verb resolves its own target from a role and an accessible name, and one that takes a selector turns a journey into a description of the markup. Taking a node the test already holds is a different thing, which is what the element readers do; `findRule` takes a selector because its subject is the stylesheet rather than a target to act on. |
|
|
1377
1383
|
| A hand-driven timer — `terminal`, `toolbox` | Refused | `toolbox` runtime-depends on `terminal`, so the two are one implementation rather than independent demand. The shape is also `@orkestrel/terminal`'s published `TimerHandler`, which a copy here would redeclare unversioned and hand consumers a second incompatible type. |
|
|
1378
1384
|
| A hand-driven clock — `mcp`, `middleware` | Refused | `AGENTS.md` bans replacing the host clock outright, so publishing one from the fleet's own test package would sanction across every workspace the substitution those rules refuse. `waitForDelay` waits on a real host timer and `waitForCondition` bounds a real elapsed interval with `performance.now()`. |
|
|
1379
1385
|
| A reserve-then-release port picker | Refused | It binds a port, closes it, and hands the number to a child that binds it again, and the window between that close and that rebind is a race another process on the host can win. Have the child bind `0` and report back the port it was given; `createLoopback` does exactly that for a server the test owns itself. |
|
|
1380
1386
|
| An abort-signal wait — `waitForAbort` | Ships | It ships as `waitForAbort`. Every bounded member still takes `WaitOptions.signal` and rejects with the signal's own reason, so a bounded wait needs nothing here; this answers the other case, where the abort is itself the fact the test waits for. It parks on a one-shot listener with no timer and no budget, so a signal that never aborts is the caller's own deadlock rather than a timeout this could name. |
|
|
1381
1387
|
| Abort-signal instrumentation | Ships | It ships as `createSignal`. A recorder handed to `addEventListener('abort', …)` still records what one listener heard; what no recorder can answer is how many listeners stand on the signal at this moment, which is the question a leak asks. The instrumented signal counts its own abort registrations, keyed by the original callback and the capture mode, so a helper that removes what it added proves the removal. A registration leaves the tally on removal, on a one-shot delivery, and when a signal scoping it aborts, which is what makes the reading a live tally rather than an install count. |
|
|
1382
|
-
| An outcome triple — a produced arm, a failed arm, and their union |
|
|
1388
|
+
| An outcome triple — a produced arm, a failed arm, and their union | Adopted | This package runtime-depends on `@orkestrel/contract` and imports `Result`, `Success`, and `Failure` from it rather than shipping a second copy. No signature published here returns one — `retryUntil` reads the type internally — and the names are not re-exported. |
|
|
1383
1389
|
| A statechart transition table and its runner | Ships | It ships as `StateTransition` and `StateScenario`, driven by `executeScenario` and `executeScenarios`, with `STATECHART_ATTRIBUTES` and `STATECHART_STATUSES` for the harness a browser workspace renders. `elements` and `veneer` each declare the field-identical pair of interfaces in their own setup file, so the fleet already writes this twice and a third copy drifts the moment one of them adds a phase. The runner ships in its walking form rather than its registering one: a package helper registers no test, so `describe` and `it.each` stay in the workspace and this drives whatever rows it is handed. The row's name is what a failure carries, because a table's rows run under one test name and a bare assertion message never says which row produced it. No published package declares a generic transition record or a closure-walking runner. `@orkestrel/workflow` names a task's behavior with a string and sequences structurally, so it neither takes a scenario's closures nor drives `arrange`, `act`, and `assert` in order, and adopting it would move this package off layer 0 and pull that package's whole runtime graph into every consumer's test install. `STATECHART_STATUSES` names a harness's reported run state rather than a task's derived status, so it does not restate `LifecycleStatus`. `STATECHART_ATTRIBUTES` is the fleet contract the journey skill's statechart reference fixes for every harness and every gate, so it is a mechanism the fleet shares rather than one suite's policy. |
|
|
1384
1390
|
|
|
1385
1391
|
`ScratchInterface`'s own members were ruled the same way, and coherence rather than demand decided
|
|
@@ -1430,6 +1436,19 @@ the helper rather than to the host, and each names what to reach for instead.
|
|
|
1430
1436
|
carrying no leading number — `'auto'`, `'none'`, `''` — reads as `0`, because none of them
|
|
1431
1437
|
contributes a pixel to what a reader sees, so a caller cannot tell an unparsable value from a
|
|
1432
1438
|
genuine zero. Read the text with `readStyle` where that distinction is the subject.
|
|
1439
|
+
- **`readHit` answers for one point, and a node it returns is no proof of a cover.** An element the
|
|
1440
|
+
document does not render measures a zero rectangle at the origin, and a zero-area element measures
|
|
1441
|
+
a point on its own edge, so each is hit-tested like any other point and names whatever paints
|
|
1442
|
+
there — the surrounding container, or the document body for a rectangle collapsed at the origin —
|
|
1443
|
+
while `contains` reads false. A cover painted with `pointer-events: none` is absent from the hit
|
|
1444
|
+
test, so the reading names the element underneath it and the caller reads reachable for a cover a
|
|
1445
|
+
person can see. An element inside a shadow tree retargets in an open root and a closed one alike:
|
|
1446
|
+
the document-level hit test names the host, which the inner element does not contain. Run
|
|
1447
|
+
`isRendered` and `isReachable` first, and ask `element.getRootNode()` for its own
|
|
1448
|
+
`elementFromPoint` where the subject sits in a shadow tree. `undefined` carries the other silence:
|
|
1449
|
+
a centre outside the viewport reads the same as a centre that reaches nothing, and
|
|
1450
|
+
`isOutsideViewport` does not separate them, because it asks whether the whole rectangle misses the
|
|
1451
|
+
viewport while this asks where one point lands.
|
|
1433
1452
|
|
|
1434
1453
|
## Patterns
|
|
1435
1454
|
|
|
@@ -2783,6 +2802,9 @@ Each entry names the contracts its file proves. The test names carry the cases.
|
|
|
2783
2802
|
document no longer holds, a focusable SVG against an element from a foreign namespace, and the
|
|
2784
2803
|
refused summary that proves it is the one filter the acting verbs apply; `isRendered` takes each
|
|
2785
2804
|
removal a browser honours and, as the split from `isReachable`, a zero-size announced control.
|
|
2805
|
+
`readHit` takes a centre that reaches the element itself, a reachable control under a cover that
|
|
2806
|
+
the reading names instead, a soft-wrapped inline target whose two line rectangles leave the box
|
|
2807
|
+
centre on its list item, and a control fixed outside the viewport, whose centre reaches nothing.
|
|
2786
2808
|
Each acting verb takes its happy path and every voice it owns, including both
|
|
2787
2809
|
region-scoped refusals and both native-disclosure ones; `clickAccessibleWithin` also takes a
|
|
2788
2810
|
glyph-captioned control inside a region a glyph-carrying heading labels, which is the loose match
|
package/dist/host/manifest.json
CHANGED
|
@@ -364,7 +364,7 @@
|
|
|
364
364
|
"storage": "claude/agents/orkestrel.md",
|
|
365
365
|
"destination": ".claude/agents/orkestrel.md",
|
|
366
366
|
"executable": false,
|
|
367
|
-
"digest": "
|
|
367
|
+
"digest": "7627d1ac3ac59bc14f9d35d002778e018003c8ea469ceff3f9a42d65cbdd1be3"
|
|
368
368
|
},
|
|
369
369
|
{
|
|
370
370
|
"storage": "claude/agents/planner.md",
|
|
@@ -670,7 +670,7 @@
|
|
|
670
670
|
"storage": "dotfiles/gitignore",
|
|
671
671
|
"destination": ".gitignore",
|
|
672
672
|
"executable": false,
|
|
673
|
-
"digest": "
|
|
673
|
+
"digest": "e8789a7b46ab16a8a4127127fa5e9f131f7fb559936c878ef07d59afafcc08cb"
|
|
674
674
|
},
|
|
675
675
|
{
|
|
676
676
|
"storage": "dotfiles/mcp.json",
|
|
@@ -964,7 +964,7 @@
|
|
|
964
964
|
"storage": "guides/test.md",
|
|
965
965
|
"destination": "guides/test.md",
|
|
966
966
|
"executable": false,
|
|
967
|
-
"digest": "
|
|
967
|
+
"digest": "a230d2a918d18f0596a7c2a295054b9c994e5c90be03771e224a024edf7d1049"
|
|
968
968
|
},
|
|
969
969
|
{
|
|
970
970
|
"storage": "guides/timeout.md",
|
|
@@ -1036,7 +1036,7 @@
|
|
|
1036
1036
|
"storage": "tests/config.test.ts",
|
|
1037
1037
|
"destination": "tests/config.test.ts",
|
|
1038
1038
|
"executable": false,
|
|
1039
|
-
"digest": "
|
|
1039
|
+
"digest": "9c7fb4dab82b46c5fb436116929c8214fd54a94511272d2c574714b65218152f"
|
|
1040
1040
|
},
|
|
1041
1041
|
{
|
|
1042
1042
|
"storage": "tests/policy.test.ts",
|
|
@@ -1173,8 +1173,7 @@
|
|
|
1173
1173
|
"name": "Failure",
|
|
1174
1174
|
"owners": [
|
|
1175
1175
|
"contract",
|
|
1176
|
-
"msg"
|
|
1177
|
-
"test"
|
|
1176
|
+
"msg"
|
|
1178
1177
|
]
|
|
1179
1178
|
},
|
|
1180
1179
|
{
|
|
@@ -1289,13 +1288,6 @@
|
|
|
1289
1288
|
"mcp"
|
|
1290
1289
|
]
|
|
1291
1290
|
},
|
|
1292
|
-
{
|
|
1293
|
-
"name": "JSONValue",
|
|
1294
|
-
"owners": [
|
|
1295
|
-
"contract",
|
|
1296
|
-
"test"
|
|
1297
|
-
]
|
|
1298
|
-
},
|
|
1299
1291
|
{
|
|
1300
1292
|
"name": "JournalInterface",
|
|
1301
1293
|
"owners": [
|
|
@@ -1370,8 +1362,7 @@
|
|
|
1370
1362
|
"name": "Result",
|
|
1371
1363
|
"owners": [
|
|
1372
1364
|
"contract",
|
|
1373
|
-
"msg"
|
|
1374
|
-
"test"
|
|
1365
|
+
"msg"
|
|
1375
1366
|
]
|
|
1376
1367
|
},
|
|
1377
1368
|
{
|
|
@@ -1463,8 +1454,7 @@
|
|
|
1463
1454
|
"name": "Success",
|
|
1464
1455
|
"owners": [
|
|
1465
1456
|
"contract",
|
|
1466
|
-
"msg"
|
|
1467
|
-
"test"
|
|
1457
|
+
"msg"
|
|
1468
1458
|
]
|
|
1469
1459
|
},
|
|
1470
1460
|
{
|
|
@@ -2011,5 +2001,5 @@
|
|
|
2011
2001
|
]
|
|
2012
2002
|
}
|
|
2013
2003
|
],
|
|
2014
|
-
"digest": "
|
|
2004
|
+
"digest": "03594a395e4569cb0ee56bca94f8f3384cd282b9883ff2e75c5348b760db9eae"
|
|
2015
2005
|
}
|