haltija 1.6.0 → 1.11.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 +166 -0
- package/apps/desktop/package.json +1 -1
- package/apps/desktop/resources/component.js +503 -22
- package/bin/cli-subcommand.mjs +39 -3
- package/bin/hints.json +1 -0
- package/bin/hj.mjs +135 -0
- package/bin/version.mjs +1 -1
- package/dist/api-handlers.d.ts +2 -0
- package/dist/api-schema.d.ts +26 -0
- package/dist/component.d.ts +1 -1
- package/dist/component.esm.js +503 -22
- package/dist/component.js +503 -22
- package/dist/hj.js +138 -4
- package/dist/index.js +861 -50
- package/dist/server.js +861 -50
- package/dist/types.d.ts +6 -0
- package/dist/version.d.ts +1 -1
- package/docs/CI-INTEGRATION.md +32 -15
- package/llms.txt +27 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,171 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.11.0
|
|
4
|
+
|
|
5
|
+
### Errors now tell you what to do
|
|
6
|
+
|
|
7
|
+
Following the tjs lesson that an error's job is the next action, not the diagnosis:
|
|
8
|
+
|
|
9
|
+
- **"Element not found"** branches on what you passed. A stale **ref** explains that refs are only
|
|
10
|
+
valid while the element is in the DOM and to re-run `hj tree` (or target by text, which survives
|
|
11
|
+
re-renders); a **selector** gets the recovery order — `hj map`/`hj tree` to see what's there, the
|
|
12
|
+
hidden-elements rule, prefer `:text()`/`[data-testid]` over structural selectors, and `hj wait` if
|
|
13
|
+
the page is still loading.
|
|
14
|
+
- **Unknown-action errors list the valid actions** instead of only rejecting yours.
|
|
15
|
+
- **"No active recording" / "No selection available" / "url is required"** now say how to reach a
|
|
16
|
+
valid state.
|
|
17
|
+
- **Schema-validation failures** carry a `hint` with the CLI form and a runnable example body — and
|
|
18
|
+
`hj` now prints `hint` on errors, which it previously discarded, so the teachable half reached
|
|
19
|
+
nobody.
|
|
20
|
+
|
|
21
|
+
### Fixed: six endpoints were missing from every generated doc
|
|
22
|
+
|
|
23
|
+
All three doc generators iterated a hardcoded category list and silently dropped anything not in it,
|
|
24
|
+
so every `/network/*` and `/dialog/*` endpoint appeared in **no** generated documentation. They now
|
|
25
|
+
append unlisted categories, so a new category can't vanish.
|
|
26
|
+
|
|
27
|
+
### New: a docs-coverage gate
|
|
28
|
+
|
|
29
|
+
`docs-drift` catches generated files going stale against the schema; it can't catch a feature
|
|
30
|
+
shipping that the prose never mentions — which is how `hj map`, `--canvas` and `hj shutdown` all
|
|
31
|
+
shipped undiscoverable. A test now asserts every public endpoint reaches the reference and
|
|
32
|
+
`llms.txt`, every agent-facing command is named in `SKILL.md`, and headline capabilities are
|
|
33
|
+
explained rather than merely listed — failing with exactly what to add.
|
|
34
|
+
|
|
35
|
+
## 1.10.0
|
|
36
|
+
|
|
37
|
+
### New: a screenshot you can't take now degrades to a labelled schematic
|
|
38
|
+
|
|
39
|
+
In a plain browser with no desktop app and no screen-share grant, `hj screenshot` used to just fail.
|
|
40
|
+
It now returns a **schematic** of the page instead — and because canvases need **no permission**, any
|
|
41
|
+
`<canvas>` is embedded as **real pixels** inside it. For a 3D app or a chart that's the actual visual
|
|
42
|
+
content, so the substitute is genuinely useful rather than a consolation prize.
|
|
43
|
+
|
|
44
|
+
Labelled three ways, because a schematic quietly standing in for a screenshot would be exactly the
|
|
45
|
+
plausible-but-wrong result this tool exists to prevent: `source: "schematic"`, a `warning` naming
|
|
46
|
+
both routes to real pixels, and a red banner burned across the image. `--no-fallback` restores the
|
|
47
|
+
hard error, and `--strict` turns the warning into a non-zero exit.
|
|
48
|
+
|
|
49
|
+
### New: the schematic surfaces contrast problems
|
|
50
|
+
|
|
51
|
+
The schematic is drawn in the **page's own colours** — element background as fill, border as stroke,
|
|
52
|
+
text colour for the caption — so a control the user can barely read is a box you can barely read.
|
|
53
|
+
Poor contrast shows itself instead of hiding in a JSON blob. It's machine-checkable too: DOM-tier
|
|
54
|
+
nodes carry `colors: {fg, bg, contrast, passes}` and a `contrastFail` string when they miss WCAG AA.
|
|
55
|
+
(The verdict is drawn in legible red on purpose — a warning about unreadable text mustn't itself be
|
|
56
|
+
unreadable.)
|
|
57
|
+
|
|
58
|
+
### Fixed: the widget was served without a charset
|
|
59
|
+
|
|
60
|
+
`Content-Type: application/javascript` carried no `; charset=utf-8`, so browsers parsed
|
|
61
|
+
`component.js` as Latin-1 and **every non-ASCII string literal in the widget was corrupted at parse
|
|
62
|
+
time** — em-dashes, `×`, `·`, and the `⟷`/`⟵` binding-arrow legend. The bytes on disk were always
|
|
63
|
+
valid UTF-8; the browser was mis-decoding them. Fixed on all five JS responses.
|
|
64
|
+
|
|
65
|
+
## 1.9.0
|
|
66
|
+
|
|
67
|
+
### New: `hj map --image` — the map as a rasterized schematic
|
|
68
|
+
|
|
69
|
+
Renders the affordance map as a PNG: one labeled box per control, nested by structure, each showing
|
|
70
|
+
its handle (`@ref` or `#index`) so the picture doubles as an **index** — glance at it, pick a
|
|
71
|
+
target, act on that one record.
|
|
72
|
+
|
|
73
|
+
It has to be a **bitmap** to be worth anything: an image of text costs a vision encoder far fewer
|
|
74
|
+
tokens than the same text tokenized, but that applies to rendered pixels, not to SVG markup (which
|
|
75
|
+
is just text tokens, and worse than the JSON it would replace). Rasterized in the browser, so there
|
|
76
|
+
is no new dependency.
|
|
77
|
+
|
|
78
|
+
**The win is density-dependent, and the response says so rather than assuming.** An image costs
|
|
79
|
+
~1000–1600 vision tokens regardless of content, so a small page is cheaper as JSON; the image pays
|
|
80
|
+
off once the map is large. `cost.approxJsonTokens` reports the JSON size for that page so the choice
|
|
81
|
+
is measurable. The schematic is also deterministic, which makes a diff between two runs a regression
|
|
82
|
+
a human can see.
|
|
83
|
+
|
|
84
|
+
## 1.8.0
|
|
85
|
+
|
|
86
|
+
### New: `hj map` — what can I interact with, and what is it wired to?
|
|
87
|
+
|
|
88
|
+
An affordance map of the page. Usually a better first move than `hj tree` or a screenshot when
|
|
89
|
+
you're deciding what to *do*: structural, deterministic (no fonts/theme/viewport/animation timing),
|
|
90
|
+
and dense — a small page is a few hundred bytes (~100 tokens) against ~1–1.5k vision tokens for a
|
|
91
|
+
screenshot.
|
|
92
|
+
|
|
93
|
+
Two tiers, and the response always says which one produced it:
|
|
94
|
+
|
|
95
|
+
- **`source: "tosi-agent"`** — when the page exposes an agent surface (`globalThis.tosiAgent`, a
|
|
96
|
+
tosijs app calling `enableAgentInterface()`), the map is the app's **own wiring records**, passed
|
|
97
|
+
through unchanged. Those carry what the DOM cannot: which state path each control is bound to and
|
|
98
|
+
in which **direction** (`⟷` two-way/user-writable, `⟵` display-only, absent = static), the handler
|
|
99
|
+
path each event calls, and the callable actions. Act through the paths rather than synthesizing
|
|
100
|
+
input — `hj eval "tosiAgent.write('app.filter','milk')"` — and note that writing a `⟵`
|
|
101
|
+
display-only path via the DOM won't stick, which is exactly the "I typed into it and nothing
|
|
102
|
+
happened" trap.
|
|
103
|
+
- **`source: "dom"`** — any other page: structural, visible-only, each node carrying a `ref` for
|
|
104
|
+
`hj click <ref>`. Labelled an approximation with **no** binding provenance, so it can't be
|
|
105
|
+
mistaken for real wiring.
|
|
106
|
+
|
|
107
|
+
Credit to the tosijs agent for the idea (#12).
|
|
108
|
+
|
|
109
|
+
## 1.7.0
|
|
110
|
+
|
|
111
|
+
### New: capture a `<canvas>` directly — `hj screenshot --canvas <selector>`
|
|
112
|
+
|
|
113
|
+
Reads the canvas's own pixels (`toDataURL`) instead of capturing the screen. For a WebGL scene
|
|
114
|
+
(Babylon/three.js) or a UI rendered into a texture that means **exact pixels at native resolution,
|
|
115
|
+
no screen-share grant, no desktop app required** — and it works even when the canvas is scrolled
|
|
116
|
+
out of view or the tab isn't frontmost. Takes the same `--scale`/`--format`/`--max-width`/file
|
|
117
|
+
options as any screenshot.
|
|
118
|
+
|
|
119
|
+
It also handles the trap that makes naive canvas capture untrustworthy: a WebGL context clears its
|
|
120
|
+
drawing buffer after compositing unless created with `{ preserveDrawingBuffer: true }`, so
|
|
121
|
+
`toDataURL` can hand back a **blank image with no error**. Haltija samples the result and returns a
|
|
122
|
+
`warning` explaining the likely cause instead of a silent empty picture — and deliberately doesn't
|
|
123
|
+
cry wolf: a canvas with real content warns not at all, and a uniform *opaque* colour (which may be a
|
|
124
|
+
perfectly legitimate solid background) gets a softer note than a fully transparent one. A canvas
|
|
125
|
+
tainted by cross-origin textures returns a clear CORS error rather than crashing.
|
|
126
|
+
|
|
127
|
+
### New: adopter-context test lane
|
|
128
|
+
|
|
129
|
+
The suite now includes tests that reproduce the *dirty machine* adopters actually have — a server
|
|
130
|
+
already running with zero windows, two projects in different directories each expecting their own,
|
|
131
|
+
and ambiguous targeting from an unrelated directory. Every field bug this project has shipped lived
|
|
132
|
+
in that gap, invisible to a suite that starts from nothing.
|
|
133
|
+
|
|
134
|
+
## 1.6.1
|
|
135
|
+
|
|
136
|
+
Makes haltija's detection reachable by automation ([#8](https://github.com/tonioloewald/haltija/issues/8),
|
|
137
|
+
[#11](https://github.com/tonioloewald/haltija/issues/11)).
|
|
138
|
+
|
|
139
|
+
haltija already *detects* the situations that wreck a test lane — the wrong project's browser, a
|
|
140
|
+
hidden tab returning stale results, a server with nothing to drive. It only ever **warned on
|
|
141
|
+
stderr**, so scripts consumed plausible-but-wrong results and failed much later, pointing at the
|
|
142
|
+
caller's own code.
|
|
143
|
+
|
|
144
|
+
### New: `ready` — "server is up" is not "server is drivable"
|
|
145
|
+
|
|
146
|
+
`/status` and `/windows` now return **`ready`**: true when at least one top-level tab is connected.
|
|
147
|
+
A server running with *zero* windows answers `/status` 200, so an adopter's reuse probe skipped
|
|
148
|
+
starting its own browser and then had nothing to navigate. Gate a lane on `ready`, not on the 200.
|
|
149
|
+
|
|
150
|
+
### New: `hj doctor`
|
|
151
|
+
|
|
152
|
+
One-command preflight that **exits non-zero**: server reachable → a tab is connected → the target
|
|
153
|
+
isn't ambiguous → tabs aren't all hidden → versions aligned. `--json` for machine-readable output.
|
|
154
|
+
Use it as the wait-loop condition in CI.
|
|
155
|
+
|
|
156
|
+
### New: `hj --strict` / `HALTIJA_STRICT=1`
|
|
157
|
+
|
|
158
|
+
Turns the advisory warnings into **non-zero exits**, and refuses to print a suspect result to
|
|
159
|
+
stdout at all — a script must not consume a value that may be wrong. A warning is the right default
|
|
160
|
+
for a human at a prompt and the wrong one for a lane.
|
|
161
|
+
|
|
162
|
+
### Fixed
|
|
163
|
+
|
|
164
|
+
- **Warning de-duplication silently defeated strict mode.** The server withheld a repeated warning
|
|
165
|
+
entirely, so the first command in a lane failed and every later one within the cooldown passed.
|
|
166
|
+
The server now always reports the condition and marks repeats (`warningRepeated`); de-dup is a
|
|
167
|
+
presentation concern, so `hj` stays quiet on a repeat while `--strict` fails on any warning.
|
|
168
|
+
|
|
3
169
|
## 1.6.0
|
|
4
170
|
|
|
5
171
|
Consolidating release: rolls up everything from 1.5.2–1.5.7 (the last npm-published version was
|