@variance-authority/mcp 0.1.0
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/CHANGELOG.md +89 -0
- package/LICENSE +21 -0
- package/README.md +407 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.js +32 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +35 -0
- package/dist/index.js +31 -0
- package/dist/index.js.map +1 -0
- package/dist/observability-subject.d.ts +22 -0
- package/dist/observability-subject.js +2 -0
- package/dist/observability-subject.js.map +1 -0
- package/dist/presentation.d.ts +6 -0
- package/dist/presentation.js +64 -0
- package/dist/presentation.js.map +1 -0
- package/dist/protocol.d.ts +82 -0
- package/dist/protocol.js +186 -0
- package/dist/protocol.js.map +1 -0
- package/dist/server.d.ts +71 -0
- package/dist/server.js +103 -0
- package/dist/server.js.map +1 -0
- package/dist/tools/adjudicate.d.ts +25 -0
- package/dist/tools/adjudicate.js +122 -0
- package/dist/tools/adjudicate.js.map +1 -0
- package/dist/tools/attention.d.ts +13 -0
- package/dist/tools/attention.js +151 -0
- package/dist/tools/attention.js.map +1 -0
- package/dist/tools/changelog.d.ts +38 -0
- package/dist/tools/changelog.js +201 -0
- package/dist/tools/changelog.js.map +1 -0
- package/dist/tools/changes.d.ts +31 -0
- package/dist/tools/changes.js +120 -0
- package/dist/tools/changes.js.map +1 -0
- package/dist/tools/composition.d.ts +13 -0
- package/dist/tools/composition.js +366 -0
- package/dist/tools/composition.js.map +1 -0
- package/dist/tools/describe.d.ts +20 -0
- package/dist/tools/describe.js +279 -0
- package/dist/tools/describe.js.map +1 -0
- package/dist/tools/diff.d.ts +20 -0
- package/dist/tools/diff.js +85 -0
- package/dist/tools/diff.js.map +1 -0
- package/dist/tools/explain-verdict.d.ts +25 -0
- package/dist/tools/explain-verdict.js +92 -0
- package/dist/tools/explain-verdict.js.map +1 -0
- package/dist/tools/findings.d.ts +40 -0
- package/dist/tools/findings.js +130 -0
- package/dist/tools/findings.js.map +1 -0
- package/dist/tools/narrowing.d.ts +26 -0
- package/dist/tools/narrowing.js +38 -0
- package/dist/tools/narrowing.js.map +1 -0
- package/dist/tools/observability.d.ts +7 -0
- package/dist/tools/observability.js +199 -0
- package/dist/tools/observability.js.map +1 -0
- package/dist/tools/presentations.d.ts +6 -0
- package/dist/tools/presentations.js +74 -0
- package/dist/tools/presentations.js.map +1 -0
- package/dist/tools/run-signals.d.ts +12 -0
- package/dist/tools/run-signals.js +115 -0
- package/dist/tools/run-signals.js.map +1 -0
- package/dist/tools/scenarios.d.ts +6 -0
- package/dist/tools/scenarios.js +62 -0
- package/dist/tools/scenarios.js.map +1 -0
- package/dist/tools/source-tests.d.ts +5 -0
- package/dist/tools/source-tests.js +95 -0
- package/dist/tools/source-tests.js.map +1 -0
- package/dist/tools/subject.d.ts +45 -0
- package/dist/tools/subject.js +57 -0
- package/dist/tools/subject.js.map +1 -0
- package/dist/tools/summary.d.ts +31 -0
- package/dist/tools/summary.js +436 -0
- package/dist/tools/summary.js.map +1 -0
- package/dist/tools/test-signals.d.ts +16 -0
- package/dist/tools/test-signals.js +106 -0
- package/dist/tools/test-signals.js.map +1 -0
- package/dist/tools/tool.d.ts +64 -0
- package/dist/tools/tool.js +9 -0
- package/dist/tools/tool.js.map +1 -0
- package/dist/tools/trace-component.d.ts +17 -0
- package/dist/tools/trace-component.js +50 -0
- package/dist/tools/trace-component.js.map +1 -0
- package/dist/tools/vantage-lines.d.ts +44 -0
- package/dist/tools/vantage-lines.js +66 -0
- package/dist/tools/vantage-lines.js.map +1 -0
- package/dist/tools/variations.d.ts +27 -0
- package/dist/tools/variations.js +125 -0
- package/dist/tools/variations.js.map +1 -0
- package/dist/tools.d.ts +120 -0
- package/dist/tools.js +127 -0
- package/dist/tools.js.map +1 -0
- package/mark.svg +30 -0
- package/package.json +64 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
# @variance-authority/mcp
|
|
2
|
+
|
|
3
|
+
## 0.1.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1d402d1: Carry the narrowing coordinate in the report, and print it in the summary header.
|
|
8
|
+
|
|
9
|
+
A `RunReport` now holds `narrowing`: the ref the run was told to observe from,
|
|
10
|
+
and where the recorded execution index stands — the commit it was written at and
|
|
11
|
+
how many files the working tree differs from it by. A run that narrowed nothing
|
|
12
|
+
carries the second half alone, so the coordinate is present whether or not it was
|
|
13
|
+
spent.
|
|
14
|
+
|
|
15
|
+
`variance_summary` prints it. Narrowing is an option and stays one; what this
|
|
16
|
+
refuses is the state where an agent works against a suite for weeks without ever
|
|
17
|
+
learning that an index is on disk and that the distance from it is a number. The
|
|
18
|
+
line names the commit and spells out the `variance run --since` that would use
|
|
19
|
+
it, and is omitted when there is no index, no position, or no distance.
|
|
20
|
+
|
|
21
|
+
`run` takes the coordinate as `index` and acts on it for nothing else.
|
|
22
|
+
`narrowingFor` resolves `since`, `against` and `index` together, so a caller
|
|
23
|
+
assembling a run reaches one call rather than three.
|
|
24
|
+
- 26ae9ed: Distinguish the React component instance that initiated a commit from every
|
|
25
|
+
component whose render body ran because of it.
|
|
26
|
+
|
|
27
|
+
The commit tap retains `memoizedUpdaters` as bounded structural component paths,
|
|
28
|
+
and Eyes records those commits in the authored test chronology. The MCP testing
|
|
29
|
+
surface places update initiators inside or outside the component paths a test
|
|
30
|
+
addressed while keeping whole-test source execution separate.
|
|
31
|
+
|
|
32
|
+
Export bounded read-only Fiber subtree, parent-chain, component-path, and source
|
|
33
|
+
location helpers for diagnostics that already hold a Fiber.
|
|
34
|
+
- a87d008: Hold what a running suite is saying in a process an agent can ask, so a test in
|
|
35
|
+
flight is something to look at rather than something to wait for.
|
|
36
|
+
|
|
37
|
+
A suite already knows what nothing outside it can see: which realms answered and
|
|
38
|
+
in what order, which work began and never finished, that a service is plainly
|
|
39
|
+
talking while the test hearing it hears nothing. All of it is spent settling
|
|
40
|
+
waits and then discarded, so nobody can ask it while it is true. A runner's
|
|
41
|
+
timeout reports what a test *wanted* — the last thing the failure knows and the
|
|
42
|
+
first thing the reader already knew.
|
|
43
|
+
|
|
44
|
+
`@variance-authority/vantage` is the second reader. A watching process listens,
|
|
45
|
+
the run reports, and the signals live in memory that outlives the test.
|
|
46
|
+
`variance-authority-mcp --watch` is that process for an agent: it prints the one
|
|
47
|
+
line the suite has to be started with, then answers `variance_run_signals` for
|
|
48
|
+
where the run has got to and `variance_test_signals` for everything one
|
|
49
|
+
execution has heard, in order, with the realm that said each and the work that
|
|
50
|
+
started and never ended. Both answer while the test is still running, which is
|
|
51
|
+
the point.
|
|
52
|
+
|
|
53
|
+
The address is in the handshake, not only on stderr. A `Served` may carry
|
|
54
|
+
`instructions`, and the watching one does: a set of tools about a run nobody has
|
|
55
|
+
started yet reads as broken, and an agent told the variable after it has started
|
|
56
|
+
the suite has been told one run too late.
|
|
57
|
+
|
|
58
|
+
None of it is about visual regression. A test that takes no screenshot reports
|
|
59
|
+
exactly what one that does reports, and a run started without
|
|
60
|
+
`VARIANCE_AUTHORITY_VANTAGE` pays one environment read per worker.
|
|
61
|
+
|
|
62
|
+
The medium is the wire the announcements already travel: one participant, `run`,
|
|
63
|
+
and `channelTo` for a participant handed an address rather than sent one.
|
|
64
|
+
`createEventLog` takes `onRecord` and `onRemark`, called at the moment of
|
|
65
|
+
recording rather than at teardown — an answer that arrives when the test
|
|
66
|
+
finishes answers a different question. `varianceWatched` is automatic so a
|
|
67
|
+
listing has no holes.
|
|
68
|
+
|
|
69
|
+
Still nothing written down. There is no report directory and no artifact to
|
|
70
|
+
mistake for evidence later; what changes is only how long one execution lasts
|
|
71
|
+
when somebody is watching.
|
|
72
|
+
|
|
73
|
+
### Patch Changes
|
|
74
|
+
|
|
75
|
+
- Updated dependencies [1d402d1]
|
|
76
|
+
- Updated dependencies [9587133]
|
|
77
|
+
- Updated dependencies [5b2a28f]
|
|
78
|
+
- Updated dependencies [26ae9ed]
|
|
79
|
+
- Updated dependencies [92f62d4]
|
|
80
|
+
- Updated dependencies [f09528d]
|
|
81
|
+
- Updated dependencies [cfb333d]
|
|
82
|
+
- Updated dependencies [48d32eb]
|
|
83
|
+
- Updated dependencies [a87d008]
|
|
84
|
+
- @variance-authority/report@0.1.0
|
|
85
|
+
- @variance-authority/sense@0.1.0
|
|
86
|
+
- @variance-authority/presentation@0.1.0
|
|
87
|
+
- @variance-authority/eyes@0.1.0
|
|
88
|
+
- @variance-authority/scenario@0.1.0
|
|
89
|
+
- @variance-authority/vantage@0.1.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Machine Garden
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,407 @@
|
|
|
1
|
+
<p align="center"><img src="./mark.svg" alt="Variance Authority mark" width="72"></p>
|
|
2
|
+
|
|
3
|
+
# @variance-authority/mcp
|
|
4
|
+
|
|
5
|
+
> Expose independently supplied observability evidence to an MCP client.
|
|
6
|
+
|
|
7
|
+
Use this package when an MCP client needs to inspect a visual run, presentation
|
|
8
|
+
signals, source-to-test journeys, live events, test attention, or retained
|
|
9
|
+
scenarios. The server reads supplied evidence and returns text; it never runs
|
|
10
|
+
tests, rerenders a subject, changes a baseline, or infers evidence that is not
|
|
11
|
+
there.
|
|
12
|
+
|
|
13
|
+
The supplied evidence remains canonical. This package makes visual causes,
|
|
14
|
+
regions, verdicts, findings, composition, variation, acceptance preview, and
|
|
15
|
+
source-to-test reach available from another process after collection finishes.
|
|
16
|
+
It also holds one previous invocation state in memory so an agent can compare
|
|
17
|
+
the evidence it sees now with the evidence it saw one call ago.
|
|
18
|
+
|
|
19
|
+
## Entrypoints
|
|
20
|
+
|
|
21
|
+
| entrypoint | requires | holds |
|
|
22
|
+
|---|---|---|
|
|
23
|
+
| `.` | stdio | everything, plus `serve`, `serveReportFile` and `serveVantage` |
|
|
24
|
+
| `./tools` | nothing | observability answers as pure functions over their native evidence |
|
|
25
|
+
| `./protocol` | nothing | MCP framing, as a pure function from a request to a response |
|
|
26
|
+
|
|
27
|
+
Two of the three halves are pure, and that is deliberate. The question that
|
|
28
|
+
matters — *does this actually help an agent fix it?* — has to stay cheap to ask,
|
|
29
|
+
and it stops being asked the moment answering it requires speaking a protocol
|
|
30
|
+
over a pipe.
|
|
31
|
+
|
|
32
|
+
What a producer *wrote* is not here either. Reports, execution indexes, live
|
|
33
|
+
state, Eyes archives, and scenario manifests belong to their producing
|
|
34
|
+
packages. MCP reads those contracts; it owns none.
|
|
35
|
+
|
|
36
|
+
## Give an agent all observability
|
|
37
|
+
|
|
38
|
+
`OBSERVABILITY` serves one connection over an `ObservabilitySubject`. Each field
|
|
39
|
+
is optional because each instrument has its own lifecycle and retention rules:
|
|
40
|
+
|
|
41
|
+
```ts
|
|
42
|
+
import { OBSERVABILITY, serve } from '@variance-authority/mcp';
|
|
43
|
+
import type { ObservabilitySubject } from '@variance-authority/mcp';
|
|
44
|
+
|
|
45
|
+
export function serveObservability(current: () => ObservabilitySubject) {
|
|
46
|
+
return serve({
|
|
47
|
+
input: process.stdin,
|
|
48
|
+
output: process.stdout,
|
|
49
|
+
served: OBSERVABILITY,
|
|
50
|
+
subject: current,
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The handshake tells the client to call `variance_observability` first. Its
|
|
56
|
+
answer distinguishes a missing domain from a supplied domain that measured zero
|
|
57
|
+
members. Native tools remain available on the same connection:
|
|
58
|
+
|
|
59
|
+
| tool | evidence | answers |
|
|
60
|
+
|---|---|---|
|
|
61
|
+
| `variance_test_attention` | Eyes archive | one test's selectors, Locator consumption, DOM events, synchronous Fiber attribution, and authored AAA markers |
|
|
62
|
+
| `variance_presentations` | presentation reports | full presentation graphs, telemetry, semantic evidence, measured structures, and findings |
|
|
63
|
+
| `variance_source_tests` | Sense execution index | which named tests entered source and their minimum observed distance |
|
|
64
|
+
| `variance_run_signals`, `variance_test_signals` | Vantage state | what an in-flight suite and one test have announced |
|
|
65
|
+
| visual report tools | run report | visual decisions, presentation signals, composition, variation, history, and review evidence |
|
|
66
|
+
| `variance_scenarios` | scenario manifests | the witnessed Arrange state and observed or unobserved Act outcomes |
|
|
67
|
+
|
|
68
|
+
`variance_testing_surface` is the deliberate cross-domain answer. It maps the
|
|
69
|
+
DOM owners and source locations a test addressed in each authored phase, then
|
|
70
|
+
places React update initiators inside or outside those exact structural component
|
|
71
|
+
paths and contrasts both with files that the same exact test id entered.
|
|
72
|
+
`PerformedWork` says a render body ran; it is not substituted for an updater.
|
|
73
|
+
An executed file with no addressed target is a replay candidate, not proof that
|
|
74
|
+
the branch is unrelated or safe to mock. The tool does not join by title or file
|
|
75
|
+
when stable producer identities disagree. `ExecutionIndex` retains whole-test
|
|
76
|
+
crossings, not AAA intervals, so runtime files remain test-scoped rather than
|
|
77
|
+
phase-scoped.
|
|
78
|
+
|
|
79
|
+
The individual served sets remain available as `REPORTS`, `PRESENTATIONS`,
|
|
80
|
+
`SOURCE_TESTS`, `VANTAGE`, `EYES`, and `SCENARIOS`. Use one when the integration owns only that
|
|
81
|
+
domain. React Testing Library and Playwright remain optional peer dependencies
|
|
82
|
+
of `@variance-authority/eyes`; installing MCP does not add either runner.
|
|
83
|
+
|
|
84
|
+
## Give an agent the tests for source
|
|
85
|
+
|
|
86
|
+
`variance_source_tests` answers the question a coding agent needs before and
|
|
87
|
+
after an edit: which named tests reached this source, and how directly? A line
|
|
88
|
+
or function query returns tests ordered by minimum observed call-stack depth. A
|
|
89
|
+
file query returns every indexed line as compact ranges, including ranges no
|
|
90
|
+
test reached.
|
|
91
|
+
|
|
92
|
+
An integration that owns the current `ExecutionIndex` serves it directly; the
|
|
93
|
+
supplier is called for every request so a rerun is visible without restarting
|
|
94
|
+
the agent's MCP connection:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
import { SOURCE_TESTS, serve } from '@variance-authority/mcp';
|
|
98
|
+
import type { ExecutionIndex } from '@variance-authority/sense/test-selection';
|
|
99
|
+
|
|
100
|
+
export function serveSourceTests(current: () => ExecutionIndex | Promise<ExecutionIndex>) {
|
|
101
|
+
return serve({
|
|
102
|
+
input: process.stdin,
|
|
103
|
+
output: process.stdout,
|
|
104
|
+
served: SOURCE_TESTS,
|
|
105
|
+
subject: current,
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
The tool takes `file` and optionally one of `line` or `function`. With neither,
|
|
111
|
+
it answers the whole file. It distinguishes an indexed range reached by no test
|
|
112
|
+
from a line absent from the execution index. The index is supplied by the test
|
|
113
|
+
collector or editor integration; MCP does not manufacture coverage or control
|
|
114
|
+
the test runner.
|
|
115
|
+
|
|
116
|
+
## Watch a suite that has not finished
|
|
117
|
+
|
|
118
|
+
Every tool above answers about a run that is over. `--watch` answers about one
|
|
119
|
+
that is not.
|
|
120
|
+
|
|
121
|
+
```bash
|
|
122
|
+
npx variance-authority-mcp --watch
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
It prints, on stderr, the one line the suite has to be started with:
|
|
126
|
+
|
|
127
|
+
```
|
|
128
|
+
variance-authority is watching. Start the suite with:
|
|
129
|
+
VARIANCE_AUTHORITY_VANTAGE=http://127.0.0.1:54321
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
That variable goes wherever `VARIANCE_AUTHORITY_EVENTS` goes. The suite needs
|
|
133
|
+
`varianceFixtures` from `@variance-authority/playwright-test` and nothing else,
|
|
134
|
+
**and none of it is about visual regression** — a test that takes no screenshot
|
|
135
|
+
reports exactly what one that does reports.
|
|
136
|
+
|
|
137
|
+
The same line is handed to the client at the handshake, as the server's
|
|
138
|
+
`instructions`, because stderr goes to a log the model never reads. An agent
|
|
139
|
+
that is told the address only after it has already started the suite has been
|
|
140
|
+
told it one run too late.
|
|
141
|
+
|
|
142
|
+
| tool | answers | ask it when |
|
|
143
|
+
|---|---|---|
|
|
144
|
+
| `variance_run_signals` | every test that has reported, in the order the run opened them, its state, and how much each has announced | you want to know where the suite has got to, or which test is the one still going |
|
|
145
|
+
| `variance_test_signals` | everything one test has announced, in order, with the realm that said each, plus work that started and never ended | a test is hanging, or failed, and the assertion that did not settle is the part you already know |
|
|
146
|
+
|
|
147
|
+
`variance_run_signals` takes `state`, `file` and `limit`, and marks a running
|
|
148
|
+
test with `▸`. `variance_test_signals` takes `test` — an id from the listing, a
|
|
149
|
+
title, or enough of one to be unambiguous; where it is not unambiguous, the
|
|
150
|
+
answer is the candidates and their ids.
|
|
151
|
+
|
|
152
|
+
The second is the one a timeout cannot give. A runner reports what a test
|
|
153
|
+
*wanted*; this reports what its execution actually **heard**, and from whom.
|
|
154
|
+
Nothing at all is a wiring fact — no listener installed, or code that does not
|
|
155
|
+
announce yet. A page that spoke while a service did not is a request that never
|
|
156
|
+
arrived or never came back. Three announcements and then silence, with one
|
|
157
|
+
`vaStart` still open, names the call that is hanging.
|
|
158
|
+
|
|
159
|
+
Nothing is written down and nothing is added to the run's evidence: a report file
|
|
160
|
+
records what a run **decided**, and this records what it **is doing**, which
|
|
161
|
+
stops being a fact the moment this process exits. What it holds is bounded, and
|
|
162
|
+
it says so when it dropped something, because a reader who cannot tell *nothing
|
|
163
|
+
was announced* from *the beginning was forgotten* draws the first conclusion.
|
|
164
|
+
|
|
165
|
+
`variance_diff` is served here too, so *what changed since I last asked* works
|
|
166
|
+
against a suite in flight the same way it works against a report.
|
|
167
|
+
|
|
168
|
+
## Diff the current state
|
|
169
|
+
|
|
170
|
+
A **subject** is whatever data the server currently holds and answers questions
|
|
171
|
+
about — a `RunReport` for the visual tools, an `ExecutionIndex` for the
|
|
172
|
+
source-test tool, a `VantageState` for a suite that is still running, or an
|
|
173
|
+
`ObservabilitySubject` carrying independently optional domains. (Inside a `RunReport`, each individually observed
|
|
174
|
+
rendering, such as `story:card--dark`, is also called a subject; the tool
|
|
175
|
+
contract below works at that finer grain.)
|
|
176
|
+
|
|
177
|
+
`variance_diff` compares the current supplied subject with the subject from the
|
|
178
|
+
previous successful tool call. The first call records the current state and says
|
|
179
|
+
there is nothing to compare. Each successful call then replaces that one value.
|
|
180
|
+
|
|
181
|
+
The value lives only in the MCP process. It is not written to disk, does not move
|
|
182
|
+
or replace a baseline, and disappears when the process exits. Initialization,
|
|
183
|
+
tool discovery, invalid calls, and failed calls do not replace it.
|
|
184
|
+
|
|
185
|
+
`diffState(before, after)` exposes the same JSON-compatible state comparison
|
|
186
|
+
without MCP framing.
|
|
187
|
+
|
|
188
|
+
## Run the report server
|
|
189
|
+
|
|
190
|
+
Install it wherever the MCP client will launch it from:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
npm install @variance-authority/mcp
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
No install is needed to just run the published binary:
|
|
197
|
+
|
|
198
|
+
```bash
|
|
199
|
+
npx variance serve # via the CLI, reading .variance/run.json
|
|
200
|
+
npx variance-authority-mcp .variance/run.json # directly
|
|
201
|
+
npx variance-authority-mcp --watch # a run that has not finished
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
```jsonc
|
|
205
|
+
// claude_desktop_config.json, or any MCP client
|
|
206
|
+
{
|
|
207
|
+
"mcpServers": {
|
|
208
|
+
"variance": { "command": "npx", "args": ["variance-authority-mcp", ".variance/run.json"] }
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
Skip this package if there is no MCP client in the loop: running the suite and
|
|
214
|
+
reading its output yourself is `@variance-authority/cli` (`variance run`,
|
|
215
|
+
`variance accept`), with no server or protocol involved. Reach for this package
|
|
216
|
+
only to hand an already-finished run, or an execution index, to an agent that
|
|
217
|
+
speaks MCP.
|
|
218
|
+
|
|
219
|
+
## Visual report tool contract
|
|
220
|
+
|
|
221
|
+
Eleven tools, all answering from the artifact and **never re-running anything**.
|
|
222
|
+
The run may have happened on a pinned machine in CI an hour ago; the questions
|
|
223
|
+
are asked wherever the agent is. One compares invocations; the other ten inspect
|
|
224
|
+
the current artifact.
|
|
225
|
+
|
|
226
|
+
A **component** is a named unit inside a rendering, such as `Button`; the same
|
|
227
|
+
component can appear inside several subjects, which is what
|
|
228
|
+
`variance_composition` and `variance_trace_component` below compare.
|
|
229
|
+
|
|
230
|
+
```ts
|
|
231
|
+
import { toolByName } from '@variance-authority/mcp/tools';
|
|
232
|
+
|
|
233
|
+
const priorReport = report;
|
|
234
|
+
toolByName('variance_summary')?.run(report, {});
|
|
235
|
+
toolByName('variance_diff')?.run(report, {}, { previous: priorReport });
|
|
236
|
+
toolByName('variance_changes')?.run(report, {});
|
|
237
|
+
toolByName('variance_adjudicate')?.run(report, {
|
|
238
|
+
claims: [{ root: 'component:Button', reason: 'new brand accent', maxSubjects: 3 }],
|
|
239
|
+
});
|
|
240
|
+
toolByName('variance_composition')?.run(report, {});
|
|
241
|
+
toolByName('variance_variations')?.run(report, { subject: 'story:card--dark' });
|
|
242
|
+
toolByName('variance_changelog')?.run(report, { shape: 'v1:9a3f1c2e04' });
|
|
243
|
+
toolByName('variance_describe')?.run(report, { subject: 'story:card--populated' });
|
|
244
|
+
toolByName('variance_findings')?.run(report, {});
|
|
245
|
+
toolByName('variance_trace_component')?.run(report, { component: 'Button' });
|
|
246
|
+
toolByName('variance_explain_verdict')?.run(report, { subject: 'story:card--populated' });
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
| tool | answers | ask it when |
|
|
250
|
+
|---|---|---|
|
|
251
|
+
| `variance_summary` | how the run came out across every subject, including the ones nobody observed | starting from nothing: *did anything change, and was anything missed?* |
|
|
252
|
+
| `variance_diff` | how the current supplied state differs from the previous successful MCP tool invocation | after rerunning or replacing the supplied evidence |
|
|
253
|
+
| `variance_changes` | the distinct changes behind the changed subjects, most decidable first, each with the command that settles it | immediately after the summary, before touching any individual subject |
|
|
254
|
+
| `variance_adjudicate` | this run against **what you said you were doing**: declared and delivered, moved and undeclared, and declared and never happened | you edited something and are reading your own run — declare before you read the diff |
|
|
255
|
+
| `variance_composition` | the run's subjects compared to **each other**: the component graph, the renderings two examples share, and why each component that moved moved — including *nothing here explains it* | a change has no obvious author, or you are about to call something flaky |
|
|
256
|
+
| `variance_variations` | the measured difference between a subject and the subject it declares as its parent, such as a feature arm, theme, or viewport | reviewing what a variant changes rather than whether it regressed |
|
|
257
|
+
| `variance_changelog` | what accepting this run would write into the baseline record: the lines the commit will carry, and the subjects that would be refused | before proposing an `accept` command, because the record is written once and outlives the run |
|
|
258
|
+
| `variance_describe` | what changed inside one subject — regions, components, files | the summary named a subject and you need the detail |
|
|
259
|
+
| `variance_findings` | accessibility defects in the renders themselves, grouped by rule, with no baseline involved | fixing a component, whether or not it changed |
|
|
260
|
+
| `variance_trace_component` | every subject one component appears in, with pixels and cause-or-displaced | sizing the blast radius of a design-system or token edit |
|
|
261
|
+
| `variance_explain_verdict` | why a subject was **not compared** — `incomparable`, `new`, or never observed | before attempting a fix, because none of those is a code problem |
|
|
262
|
+
|
|
263
|
+
`variance_changes` is the one that decides how many of the others get called. A
|
|
264
|
+
design-token edit reaching forty stories is one decision presented as forty, and
|
|
265
|
+
an agent that walks them one at a time spends forty calls learning what one call
|
|
266
|
+
says. It is also the only tool that hands back a *command* — the shape digest
|
|
267
|
+
cannot be derived from anything else in the report, and it names which subjects
|
|
268
|
+
the command will refuse, so the agent proposes something that works rather than
|
|
269
|
+
something that gets rejected.
|
|
270
|
+
|
|
271
|
+
`variance_adjudicate` is the only tool that takes evidence *in*, and the only
|
|
272
|
+
one that can report an **absence**. Everything else answers about the run;
|
|
273
|
+
this answers about the agent. `variance_changes` can say that `Button` moved in
|
|
274
|
+
twelve subjects. It cannot say that `Card` — which the agent believes it just
|
|
275
|
+
edited — did not move at all, because a diff has no opinion about what was
|
|
276
|
+
supposed to happen. That third arm is where a wrong file, a dead branch, an
|
|
277
|
+
overridden rule or a stale build surfaces, and no screenshot comparison reaches
|
|
278
|
+
it.
|
|
279
|
+
|
|
280
|
+
The declaration has to come first: the tool takes claims as an argument rather
|
|
281
|
+
than deriving them, so an agent must state what it expected before reading what
|
|
282
|
+
happened. A claim that reaches more subjects than it declared comes back
|
|
283
|
+
`overreached`.
|
|
284
|
+
|
|
285
|
+
A claim carrying a field this resolution cannot check is named rather than
|
|
286
|
+
dropped. A **band** is a category of visual difference, such as `content` or
|
|
287
|
+
`geometry`; an agent told `delivered` about a band nothing looked at has been
|
|
288
|
+
told something the run never established, so the answer ends `Not checked here:
|
|
289
|
+
bands`. `examples/agent-claim` runs the whole
|
|
290
|
+
boundary — CLI and this tool, every verdict, one process.
|
|
291
|
+
|
|
292
|
+
`variance_changelog` previews what accepting this run would write into the
|
|
293
|
+
baseline record, before the write happens — otherwise a baseline update is only
|
|
294
|
+
explained in the commit that carries it, which does not exist until `accept`
|
|
295
|
+
runs. The preview renders the record's own lines through the same function that
|
|
296
|
+
writes the commit, over the subject set the same rules select, so the preview
|
|
297
|
+
and the eventual commit cannot disagree. It stops short of the commit trailers:
|
|
298
|
+
those are written only once a promotion has actually happened.
|
|
299
|
+
|
|
300
|
+
`variance_composition` is the only one that reads the other axis. Everything
|
|
301
|
+
else compares a subject to its baseline — two revisions, one thing. This
|
|
302
|
+
compares the run's subjects to each other, at one commit, because **a
|
|
303
|
+
visual-regression example is a component built from components**: the example
|
|
304
|
+
*is* a component at a boundary, and the same component appears again, with the
|
|
305
|
+
same or different props, inside larger examples. Once those boundaries are
|
|
306
|
+
addressable the run can say which of its examples are watching literally the
|
|
307
|
+
same bytes, which of them disagree at one commit, and — for anything that moved
|
|
308
|
+
— whether an edited file, a moved token or an edited *caller* accounts for it.
|
|
309
|
+
|
|
310
|
+
This is also where an unexplained movement gets a **control group**: the
|
|
311
|
+
subjects where that same component, with the same props, held — did not move —
|
|
312
|
+
the stable states to compare against. Given one, an unexplained movement is
|
|
313
|
+
`flake` if the subject also failed to read the same way twice, or `suspect` — a
|
|
314
|
+
shortlist, not a verdict — if nobody has read it twice yet.
|
|
315
|
+
|
|
316
|
+
`variance_summary` labels a subject by what it *is*, which is not always its
|
|
317
|
+
verdict. Three subjects can all be `changed` — the pixels did move — and need
|
|
318
|
+
three different people:
|
|
319
|
+
|
|
320
|
+
| label | what happened | what to do |
|
|
321
|
+
|---|---|---|
|
|
322
|
+
| `unstable` | read twice, seconds apart, nothing changed in between, and the two readings disagreed | fix what moves between readings; the named component and band say where. Do not review the regions — which ones appear was decided by a race |
|
|
323
|
+
| `order-dependent` | the difference is gone when the subject is collected with nothing else in the world | do not change the component; bisect run order to find the subject that writes the state this one reads |
|
|
324
|
+
| `changed` | it survived both | review it |
|
|
325
|
+
|
|
326
|
+
A fourth state is deliberately *not* on that table. A **sensitivity level** is a
|
|
327
|
+
per-subject declaration of which bands it asserts on — a route declared `layout`
|
|
328
|
+
has said, in its config, that it does not assert on what the page is painted
|
|
329
|
+
with, so a clock inside it is a fact about the page rather than a defect. A
|
|
330
|
+
subject whose two readings differed entirely in bands outside its declared level
|
|
331
|
+
is listed under **not asserted on** and carries no instruction. It is still named
|
|
332
|
+
and counted, with the rule that absorbed it — the same reason a subject whose
|
|
333
|
+
pixels were excluded by an ignore rule is reported as `ignored` rather than
|
|
334
|
+
folded into `unchanged`: an exclusion nobody can see again is one nobody is
|
|
335
|
+
really watching.
|
|
336
|
+
|
|
337
|
+
`accept` refuses `unstable` and `order-dependent` subjects; only `changed` can be
|
|
338
|
+
promoted. Instability is checked first: the clean-vs-shared comparison behind
|
|
339
|
+
`order-dependent` only means something when a subject's two readings would
|
|
340
|
+
otherwise agree.
|
|
341
|
+
|
|
342
|
+
`variance_findings` is the one that is not about a change. A control that never
|
|
343
|
+
had an accessible name compares equal to itself on every run, so a comparison can
|
|
344
|
+
never report it — and an agent asked to fix a component wants it anyway. Its
|
|
345
|
+
findings do not affect the verdict, and an empty answer distinguishes *inspected
|
|
346
|
+
and clean* from *nobody looked* — the same distinction `variance_summary` keeps
|
|
347
|
+
when it accounts for the subjects nobody observed.
|
|
348
|
+
|
|
349
|
+
## Coverage boundary
|
|
350
|
+
|
|
351
|
+
An agent told **"no changes"** concludes the product is fine. If what actually
|
|
352
|
+
happened is that eleven subjects failed to render, that sentence is a lie the
|
|
353
|
+
agent will act on — and unlike a human reading a dashboard, it has nothing else
|
|
354
|
+
to check against.
|
|
355
|
+
|
|
356
|
+
So the summary accounts for every subject including the ones nobody observed, and
|
|
357
|
+
a run with unobserved subjects never reads as clean. `notObserved` is the list of
|
|
358
|
+
subjects the run planned and has no result for; it distinguishes `excluded` from
|
|
359
|
+
`failed`, and a malformed entry is refused rather than defaulted: guessing
|
|
360
|
+
`excluded` turns a coverage hole into a decision somebody made, and guessing
|
|
361
|
+
`failed` turns every deliberate exclusion into a permanently red build.
|
|
362
|
+
|
|
363
|
+
## The narrowing coordinate
|
|
364
|
+
|
|
365
|
+
`variance_summary` prints, in its header, where the recorded execution index
|
|
366
|
+
stands and how many files the working tree differs from it by — followed by the
|
|
367
|
+
`variance run --since <commit>` that would observe only what those files reach.
|
|
368
|
+
|
|
369
|
+
It is in the header rather than in a tool of its own because an option an agent
|
|
370
|
+
is never told about is an option it does not have. Nothing about the line
|
|
371
|
+
proposes that a run should have skipped anything; narrowing stays the operator's
|
|
372
|
+
decision, and the header carries the coordinate the decision needs. It is omitted
|
|
373
|
+
when there is nothing to offer: no index on disk, an index with no position, or a
|
|
374
|
+
tree that has not moved from it.
|
|
375
|
+
|
|
376
|
+
## Serve a custom subject
|
|
377
|
+
|
|
378
|
+
`serveReportFile(path)` is the whole executable, and `serve(options)` is what it
|
|
379
|
+
composes when the report does not come from a file:
|
|
380
|
+
|
|
381
|
+
| option | what it decides |
|
|
382
|
+
|---|---|
|
|
383
|
+
| `input` | the `Readable` requests arrive on |
|
|
384
|
+
| `output` | the `Writable` responses leave on |
|
|
385
|
+
| `served` | the `Served<Subject>` name and tools for the subject; use `REPORTS` for a `RunReport` or supply a set for another serializable subject |
|
|
386
|
+
| `subject` | supplies the current subject. A function rather than a value, so a long-lived server picks up a re-run without a restart — an agent that fixes something and asks again should be answered from the new report, not from the one loaded at boot. It may be async, and the request waits for it: a supplier that started a refresh and answered from the previous value would make *this* request the stale one, and this request is the agent that just re-ran |
|
|
387
|
+
|
|
388
|
+
A `Served` is a name, a version and the tools. It may also carry
|
|
389
|
+
`instructions`, a function of the subject whose answer the client puts in front
|
|
390
|
+
of the model before it has called anything — for a set of tools whose subject
|
|
391
|
+
has to be *arranged* first, and which therefore reads as broken to an agent that
|
|
392
|
+
finds it empty. `REPORTS` has none: a report on disk is already there.
|
|
393
|
+
|
|
394
|
+
Both return a function that detaches the server from its streams.
|
|
395
|
+
`serveVantage()` is the third: it opens the listener, serves the watch tools over
|
|
396
|
+
the same streams, and returns the `address` to start a run with alongside the
|
|
397
|
+
call that stops both. Its subject is a snapshot taken per request, which is why a
|
|
398
|
+
subject that is moving fits a surface built for one that is not.
|
|
399
|
+
|
|
400
|
+
## Stability
|
|
401
|
+
|
|
402
|
+
**The tool names, their argument shapes and the wording of their answers carry no
|
|
403
|
+
compatibility guarantee.** They are answers chosen to be useful to an agent
|
|
404
|
+
rather than a published interface, and an answer that turns out to be the wrong
|
|
405
|
+
one to give will change without a deprecation. If you need them to hold still,
|
|
406
|
+
import `@variance-authority/mcp/tools` behind an adapter of your own and pin the
|
|
407
|
+
version.
|
package/dist/bin.d.ts
ADDED
package/dist/bin.js
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { serveReportFile, serveVantage } from './server.js';
|
|
3
|
+
/**
|
|
4
|
+
* `variance-authority-mcp <report.json>` — answer about a run that finished.
|
|
5
|
+
* `variance-authority-mcp --watch` — answer about one that has not.
|
|
6
|
+
*
|
|
7
|
+
* One argument either way, no flags beyond it and no config file. The two modes
|
|
8
|
+
* are two subjects, not two servers: a report is a file somebody produced, and a
|
|
9
|
+
* watcher is a socket a run reports to for as long as this process is running.
|
|
10
|
+
* Nothing it could be configured to *do* would be work the run should have done,
|
|
11
|
+
* on the machine the run was on.
|
|
12
|
+
*
|
|
13
|
+
* The address goes to stderr because stdout is the protocol. It is printed
|
|
14
|
+
* rather than merely available, because a watcher nobody attached a run to is
|
|
15
|
+
* indistinguishable from a broken one, and one line at startup is the cheapest
|
|
16
|
+
* place to make attaching obvious.
|
|
17
|
+
*/
|
|
18
|
+
const [, , path] = process.argv;
|
|
19
|
+
if (path === '--watch') {
|
|
20
|
+
const { address } = await serveVantage();
|
|
21
|
+
process.stderr.write(`variance-authority is watching. Start the suite with:\n` +
|
|
22
|
+
` VARIANCE_AUTHORITY_VANTAGE=${address}\n`);
|
|
23
|
+
}
|
|
24
|
+
else if (path === undefined) {
|
|
25
|
+
process.stderr.write('usage: variance-authority-mcp <run-report.json>\n' +
|
|
26
|
+
' variance-authority-mcp --watch\n');
|
|
27
|
+
process.exit(2);
|
|
28
|
+
}
|
|
29
|
+
else {
|
|
30
|
+
await serveReportFile(path);
|
|
31
|
+
}
|
|
32
|
+
//# sourceMappingURL=bin.js.map
|
package/dist/bin.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"bin.js","sourceRoot":"","sources":["../src/bin.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE5D;;;;;;;;;;;;;;GAcG;AACH,MAAM,CAAC,EAAE,AAAD,EAAG,IAAI,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC;AAEhC,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;IACvB,MAAM,EAAE,OAAO,EAAE,GAAG,MAAM,YAAY,EAAE,CAAC;IACzC,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,yDAAyD;QACvD,gCAAgC,OAAO,IAAI,CAC9C,CAAC;AACJ,CAAC;KAAM,IAAI,IAAI,KAAK,SAAS,EAAE,CAAC;IAC9B,OAAO,CAAC,MAAM,CAAC,KAAK,CAClB,mDAAmD;QACjD,yCAAyC,CAC5C,CAAC;IACF,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;KAAM,CAAC;IACN,MAAM,eAAe,CAAC,IAAI,CAAC,CAAC;AAC9B,CAAC","sourcesContent":["#!/usr/bin/env node\nimport { serveReportFile, serveVantage } from './server.js';\n\n/**\n * `variance-authority-mcp <report.json>` — answer about a run that finished.\n * `variance-authority-mcp --watch` — answer about one that has not.\n *\n * One argument either way, no flags beyond it and no config file. The two modes\n * are two subjects, not two servers: a report is a file somebody produced, and a\n * watcher is a socket a run reports to for as long as this process is running.\n * Nothing it could be configured to *do* would be work the run should have done,\n * on the machine the run was on.\n *\n * The address goes to stderr because stdout is the protocol. It is printed\n * rather than merely available, because a watcher nobody attached a run to is\n * indistinguishable from a broken one, and one line at startup is the cheapest\n * place to make attaching obvious.\n */\nconst [, , path] = process.argv;\n\nif (path === '--watch') {\n const { address } = await serveVantage();\n process.stderr.write(\n `variance-authority is watching. Start the suite with:\\n` +\n ` VARIANCE_AUTHORITY_VANTAGE=${address}\\n`,\n );\n} else if (path === undefined) {\n process.stderr.write(\n 'usage: variance-authority-mcp <run-report.json>\\n' +\n ' variance-authority-mcp --watch\\n',\n );\n process.exit(2);\n} else {\n await serveReportFile(path);\n}\n"]}
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@variance-authority/mcp` — observed evidence, exposed to an agent.
|
|
3
|
+
*
|
|
4
|
+
* The chain the rest of this repository builds ends at a sentence: a cause, a
|
|
5
|
+
* place, and a file. This package is what puts that sentence somewhere an agent
|
|
6
|
+
* can reach it *after the fact*, from a different process, without access to
|
|
7
|
+
* whatever was in scope when the change was sensed.
|
|
8
|
+
*
|
|
9
|
+
* Two concerns, two entrypoints, and the split is load-bearing:
|
|
10
|
+
*
|
|
11
|
+
* - `mcp/tools` — the answers, as pure functions from a report to text. Testable
|
|
12
|
+
* without speaking a protocol, which is the only way the question that matters
|
|
13
|
+
* ("does this help an agent fix it?") stays cheap to ask.
|
|
14
|
+
* - `mcp/protocol` — MCP framing, as a pure function from a request to a
|
|
15
|
+
* response. Also pure, and separately exercisable, and generic in what it
|
|
16
|
+
* serves: a request, a subject, and a set of tools that read that subject.
|
|
17
|
+
* `REPORTS` is the set this package ships; a server over some other subject
|
|
18
|
+
* passes its own and reuses every line of the framing.
|
|
19
|
+
*
|
|
20
|
+
* `server.ts` is the stdio plumbing left over once those two are removed, and it
|
|
21
|
+
* deliberately contains no decisions.
|
|
22
|
+
*
|
|
23
|
+
* What a producer *wrote* is not here. The report format is
|
|
24
|
+
* `@variance-authority/report`, because the CLI writes it, a PR comment renders
|
|
25
|
+
* it and these tools read it — and a format owned by one reader bends towards
|
|
26
|
+
* that reader.
|
|
27
|
+
*/
|
|
28
|
+
export { NO_ARGS, EYES_TOOLS, OBSERVABILITY_TOOLS, PRESENTATION_TOOLS, SCENARIO_TOOLS, SOURCE_TEST_TOOLS, TOOLS, VANTAGE_TOOLS, eyesToolByName, observabilityToolByName, presentationToolByName, scenarioToolByName, sourceTestToolByName, stringArg, toolByName, vantageToolByName, diffState, } from './tools.js';
|
|
29
|
+
export type { Served, StateDifference, Tool, ToolInvocation } from './tools.js';
|
|
30
|
+
export { EYES, OBSERVABILITY, PRESENTATIONS, REPORTS, SCENARIOS, SOURCE_TESTS, VANTAGE, handle, createLineReader, PROTOCOL_VERSION, SERVER_NAME, SERVER_VERSION, } from './protocol.js';
|
|
31
|
+
export type { JsonRpcRequest, JsonRpcResponse } from './protocol.js';
|
|
32
|
+
export type { ObservabilitySubject } from './observability-subject.js';
|
|
33
|
+
export { serve, serveReportFile, serveVantage } from './server.js';
|
|
34
|
+
export type { ReportFileOptions, ServerOptions, ServedVantage } from './server.js';
|
|
35
|
+
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* `@variance-authority/mcp` — observed evidence, exposed to an agent.
|
|
3
|
+
*
|
|
4
|
+
* The chain the rest of this repository builds ends at a sentence: a cause, a
|
|
5
|
+
* place, and a file. This package is what puts that sentence somewhere an agent
|
|
6
|
+
* can reach it *after the fact*, from a different process, without access to
|
|
7
|
+
* whatever was in scope when the change was sensed.
|
|
8
|
+
*
|
|
9
|
+
* Two concerns, two entrypoints, and the split is load-bearing:
|
|
10
|
+
*
|
|
11
|
+
* - `mcp/tools` — the answers, as pure functions from a report to text. Testable
|
|
12
|
+
* without speaking a protocol, which is the only way the question that matters
|
|
13
|
+
* ("does this help an agent fix it?") stays cheap to ask.
|
|
14
|
+
* - `mcp/protocol` — MCP framing, as a pure function from a request to a
|
|
15
|
+
* response. Also pure, and separately exercisable, and generic in what it
|
|
16
|
+
* serves: a request, a subject, and a set of tools that read that subject.
|
|
17
|
+
* `REPORTS` is the set this package ships; a server over some other subject
|
|
18
|
+
* passes its own and reuses every line of the framing.
|
|
19
|
+
*
|
|
20
|
+
* `server.ts` is the stdio plumbing left over once those two are removed, and it
|
|
21
|
+
* deliberately contains no decisions.
|
|
22
|
+
*
|
|
23
|
+
* What a producer *wrote* is not here. The report format is
|
|
24
|
+
* `@variance-authority/report`, because the CLI writes it, a PR comment renders
|
|
25
|
+
* it and these tools read it — and a format owned by one reader bends towards
|
|
26
|
+
* that reader.
|
|
27
|
+
*/
|
|
28
|
+
export { NO_ARGS, EYES_TOOLS, OBSERVABILITY_TOOLS, PRESENTATION_TOOLS, SCENARIO_TOOLS, SOURCE_TEST_TOOLS, TOOLS, VANTAGE_TOOLS, eyesToolByName, observabilityToolByName, presentationToolByName, scenarioToolByName, sourceTestToolByName, stringArg, toolByName, vantageToolByName, diffState, } from './tools.js';
|
|
29
|
+
export { EYES, OBSERVABILITY, PRESENTATIONS, REPORTS, SCENARIOS, SOURCE_TESTS, VANTAGE, handle, createLineReader, PROTOCOL_VERSION, SERVER_NAME, SERVER_VERSION, } from './protocol.js';
|
|
30
|
+
export { serve, serveReportFile, serveVantage } from './server.js';
|
|
31
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,EACL,OAAO,EACP,UAAU,EACV,mBAAmB,EACnB,kBAAkB,EAClB,cAAc,EACd,iBAAiB,EACjB,KAAK,EACL,aAAa,EACb,cAAc,EACd,uBAAuB,EACvB,sBAAsB,EACtB,kBAAkB,EAClB,oBAAoB,EACpB,SAAS,EACT,UAAU,EACV,iBAAiB,EACjB,SAAS,GACV,MAAM,YAAY,CAAC;AAGpB,OAAO,EACL,IAAI,EACJ,aAAa,EACb,aAAa,EACb,OAAO,EACP,SAAS,EACT,YAAY,EACZ,OAAO,EACP,MAAM,EACN,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,cAAc,GACf,MAAM,eAAe,CAAC;AAIvB,OAAO,EAAE,KAAK,EAAE,eAAe,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC","sourcesContent":["/**\n * `@variance-authority/mcp` — observed evidence, exposed to an agent.\n *\n * The chain the rest of this repository builds ends at a sentence: a cause, a\n * place, and a file. This package is what puts that sentence somewhere an agent\n * can reach it *after the fact*, from a different process, without access to\n * whatever was in scope when the change was sensed.\n *\n * Two concerns, two entrypoints, and the split is load-bearing:\n *\n * - `mcp/tools` — the answers, as pure functions from a report to text. Testable\n * without speaking a protocol, which is the only way the question that matters\n * (\"does this help an agent fix it?\") stays cheap to ask.\n * - `mcp/protocol` — MCP framing, as a pure function from a request to a\n * response. Also pure, and separately exercisable, and generic in what it\n * serves: a request, a subject, and a set of tools that read that subject.\n * `REPORTS` is the set this package ships; a server over some other subject\n * passes its own and reuses every line of the framing.\n *\n * `server.ts` is the stdio plumbing left over once those two are removed, and it\n * deliberately contains no decisions.\n *\n * What a producer *wrote* is not here. The report format is\n * `@variance-authority/report`, because the CLI writes it, a PR comment renders\n * it and these tools read it — and a format owned by one reader bends towards\n * that reader.\n */\n\nexport {\n NO_ARGS,\n EYES_TOOLS,\n OBSERVABILITY_TOOLS,\n PRESENTATION_TOOLS,\n SCENARIO_TOOLS,\n SOURCE_TEST_TOOLS,\n TOOLS,\n VANTAGE_TOOLS,\n eyesToolByName,\n observabilityToolByName,\n presentationToolByName,\n scenarioToolByName,\n sourceTestToolByName,\n stringArg,\n toolByName,\n vantageToolByName,\n diffState,\n} from './tools.js';\nexport type { Served, StateDifference, Tool, ToolInvocation } from './tools.js';\n\nexport {\n EYES,\n OBSERVABILITY,\n PRESENTATIONS,\n REPORTS,\n SCENARIOS,\n SOURCE_TESTS,\n VANTAGE,\n handle,\n createLineReader,\n PROTOCOL_VERSION,\n SERVER_NAME,\n SERVER_VERSION,\n} from './protocol.js';\nexport type { JsonRpcRequest, JsonRpcResponse } from './protocol.js';\nexport type { ObservabilitySubject } from './observability-subject.js';\n\nexport { serve, serveReportFile, serveVantage } from './server.js';\nexport type { ReportFileOptions, ServerOptions, ServedVantage } from './server.js';\n"]}
|