haltija 1.6.1 → 1.11.2
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 +214 -0
- package/apps/desktop/package.json +1 -1
- package/apps/desktop/resources/component.js +618 -22
- package/bin/cli-subcommand.mjs +47 -10
- package/bin/hints.json +1 -0
- package/bin/hints.mjs +27 -0
- package/bin/hj.mjs +54 -0
- package/bin/project-origins.mjs +77 -0
- package/bin/version.mjs +1 -1
- package/dist/api-schema.d.ts +29 -0
- package/dist/component.d.ts +1 -1
- package/dist/component.esm.js +618 -22
- package/dist/component.js +618 -22
- package/dist/hj.js +188 -18
- package/dist/index.js +930 -38
- package/dist/project-origins.d.ts +67 -0
- package/dist/server.js +930 -38
- package/dist/version.d.ts +1 -1
- package/llms.txt +22 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,219 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.11.2
|
|
4
|
+
|
|
5
|
+
Patch. Four field reports from tosijs-3d and tosijs-ui, all confirmed.
|
|
6
|
+
|
|
7
|
+
### Fixed: `--canvas` couldn't reach a canvas in a shadow root ([#15](https://github.com/tonioloewald/haltija/issues/15))
|
|
8
|
+
|
|
9
|
+
Which is where every component-based renderer puts it — so the exact-pixels escape hatch failed on
|
|
10
|
+
exactly the pages where pixels are the only thing worth looking at. Canvas resolution now pierces
|
|
11
|
+
shadow DOM and accepts every shape someone would reasonably write:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
hj screenshot --canvas "tosi-b3d canvas" # descendant, crossing the boundary
|
|
15
|
+
hj screenshot --canvas "tosi-b3d >>> canvas" # explicit piercing form
|
|
16
|
+
hj screenshot --canvas "canvas" # found inside shadow roots too
|
|
17
|
+
hj screenshot --canvas # no selector: the largest canvas on the page
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
A genuine miss now lists the canvases that *do* exist, with working selectors. The **schematic**
|
|
21
|
+
embeds shadow-root canvases as well — previously it silently showed none on these pages.
|
|
22
|
+
|
|
23
|
+
### Fixed: advisory hints were printed to stdout ([#14](https://github.com/tonioloewald/haltija/issues/14))
|
|
24
|
+
|
|
25
|
+
A dim hint line was appended to **stdout** after JSON output, so `JSON.parse(await $\`hj windows\`)`
|
|
26
|
+
threw — and an adopter's readiness probe fell into an open catch and silently did nothing. All
|
|
27
|
+
advisory text is on stderr now; stdout is the data channel.
|
|
28
|
+
|
|
29
|
+
Two related fixes from the same report:
|
|
30
|
+
|
|
31
|
+
- **`hj <cmd> --help` now describes that command** instead of falling through to global help, which
|
|
32
|
+
read exactly like "unknown command" (a reporter concluded `doctor` and `map` didn't exist in their
|
|
33
|
+
build). haltija's own error messages recommend this form, so the remedy we printed was broken.
|
|
34
|
+
- **The standalone `hj` bundle now carries its hints.** They were read from a sibling `hints.json`,
|
|
35
|
+
which doesn't exist next to `~/.local/bin/hj` — so two distributions reporting the same version
|
|
36
|
+
produced different output. Hints are compiled in, like the version and semver helpers.
|
|
37
|
+
|
|
38
|
+
### Fixed: contrast false positives on text-less ancestors ([#13](https://github.com/tonioloewald/haltija/issues/13))
|
|
39
|
+
|
|
40
|
+
A container propagates `color`/`background` but has no font size, so `large` is *unknowable* —
|
|
41
|
+
defaulting it to false held it to 4.5:1 and manufactured failures for text that passes as large on
|
|
42
|
+
the child that actually renders it. About half the findings on a typical page. Only elements with
|
|
43
|
+
their own direct text are graded now.
|
|
44
|
+
|
|
45
|
+
## 1.11.1
|
|
46
|
+
|
|
47
|
+
Patch, per the rule that a minor bump waits for a cleared backlog and a nine-lens review.
|
|
48
|
+
|
|
49
|
+
### Fixed: contrast audit noise
|
|
50
|
+
|
|
51
|
+
Two sources of false findings, fixed before anyone acts on a long list of them:
|
|
52
|
+
|
|
53
|
+
- **Containers with no text of their own were flagged.** A `<div>`/`<form>` inherits a colour but
|
|
54
|
+
displays nothing, so a "failure" there is noise. Only elements that actually render text, a label
|
|
55
|
+
or a value get a verdict now.
|
|
56
|
+
- **Text over a `background-image`** (gradient, photo) was judged against whatever background-*color*
|
|
57
|
+
sat beneath it — which can be wrong in either direction. Those are now reported as
|
|
58
|
+
`colors.uncertain` rather than asserted as pass or fail.
|
|
59
|
+
|
|
60
|
+
An audit people learn to skim is worth nothing, so the bar is: only claim what can be justified.
|
|
61
|
+
|
|
62
|
+
### Per-tab routing, by declaration ([#1](https://github.com/tonioloewald/haltija/issues/1), [#2](https://github.com/tonioloewald/haltija/issues/2))
|
|
63
|
+
|
|
64
|
+
cwd routing gets a command to the right *server*; which **tab** answers then fell back to focus, so
|
|
65
|
+
two projects on a shared server could drive each other's pages. Ranking tabs by "this origin looks
|
|
66
|
+
like your project" was rejected twice — there's no reliable origin→directory map, and a
|
|
67
|
+
usually-right guess reintroduces the silent misroute cwd routing exists to prevent.
|
|
68
|
+
|
|
69
|
+
So the project declares it. A `.haltija.json` at the project root:
|
|
70
|
+
|
|
71
|
+
```json
|
|
72
|
+
{ "origins": ["https://localhost:8030", "http://localhost:3000"] }
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
…and `hj`, run anywhere inside that project, pins commands to a connected tab on one of those
|
|
76
|
+
origins regardless of focus. **Entirely opt-in** (no file = unchanged behaviour) and it never
|
|
77
|
+
guesses: if you declared origins and no connected tab matches, `hj` says so loudly instead of
|
|
78
|
+
quietly driving another project's page — and refuses outright under `--strict`. `HALTIJA_ORIGINS`
|
|
79
|
+
overrides for one-off shells and CI.
|
|
80
|
+
|
|
81
|
+
### `hj screenshot --schematic`
|
|
82
|
+
|
|
83
|
+
Ask for the schematic even when real capture *is* available — it's cheaper, deterministic, and
|
|
84
|
+
carries the contrast audit. Canvases are still embedded as real pixels.
|
|
85
|
+
|
|
86
|
+
## 1.11.0
|
|
87
|
+
|
|
88
|
+
### Errors now tell you what to do
|
|
89
|
+
|
|
90
|
+
Following the tjs lesson that an error's job is the next action, not the diagnosis:
|
|
91
|
+
|
|
92
|
+
- **"Element not found"** branches on what you passed. A stale **ref** explains that refs are only
|
|
93
|
+
valid while the element is in the DOM and to re-run `hj tree` (or target by text, which survives
|
|
94
|
+
re-renders); a **selector** gets the recovery order — `hj map`/`hj tree` to see what's there, the
|
|
95
|
+
hidden-elements rule, prefer `:text()`/`[data-testid]` over structural selectors, and `hj wait` if
|
|
96
|
+
the page is still loading.
|
|
97
|
+
- **Unknown-action errors list the valid actions** instead of only rejecting yours.
|
|
98
|
+
- **"No active recording" / "No selection available" / "url is required"** now say how to reach a
|
|
99
|
+
valid state.
|
|
100
|
+
- **Schema-validation failures** carry a `hint` with the CLI form and a runnable example body — and
|
|
101
|
+
`hj` now prints `hint` on errors, which it previously discarded, so the teachable half reached
|
|
102
|
+
nobody.
|
|
103
|
+
|
|
104
|
+
### Fixed: six endpoints were missing from every generated doc
|
|
105
|
+
|
|
106
|
+
All three doc generators iterated a hardcoded category list and silently dropped anything not in it,
|
|
107
|
+
so every `/network/*` and `/dialog/*` endpoint appeared in **no** generated documentation. They now
|
|
108
|
+
append unlisted categories, so a new category can't vanish.
|
|
109
|
+
|
|
110
|
+
### New: a docs-coverage gate
|
|
111
|
+
|
|
112
|
+
`docs-drift` catches generated files going stale against the schema; it can't catch a feature
|
|
113
|
+
shipping that the prose never mentions — which is how `hj map`, `--canvas` and `hj shutdown` all
|
|
114
|
+
shipped undiscoverable. A test now asserts every public endpoint reaches the reference and
|
|
115
|
+
`llms.txt`, every agent-facing command is named in `SKILL.md`, and headline capabilities are
|
|
116
|
+
explained rather than merely listed — failing with exactly what to add.
|
|
117
|
+
|
|
118
|
+
## 1.10.0
|
|
119
|
+
|
|
120
|
+
### New: a screenshot you can't take now degrades to a labelled schematic
|
|
121
|
+
|
|
122
|
+
In a plain browser with no desktop app and no screen-share grant, `hj screenshot` used to just fail.
|
|
123
|
+
It now returns a **schematic** of the page instead — and because canvases need **no permission**, any
|
|
124
|
+
`<canvas>` is embedded as **real pixels** inside it. For a 3D app or a chart that's the actual visual
|
|
125
|
+
content, so the substitute is genuinely useful rather than a consolation prize.
|
|
126
|
+
|
|
127
|
+
Labelled three ways, because a schematic quietly standing in for a screenshot would be exactly the
|
|
128
|
+
plausible-but-wrong result this tool exists to prevent: `source: "schematic"`, a `warning` naming
|
|
129
|
+
both routes to real pixels, and a red banner burned across the image. `--no-fallback` restores the
|
|
130
|
+
hard error, and `--strict` turns the warning into a non-zero exit.
|
|
131
|
+
|
|
132
|
+
### New: the schematic surfaces contrast problems
|
|
133
|
+
|
|
134
|
+
The schematic is drawn in the **page's own colours** — element background as fill, border as stroke,
|
|
135
|
+
text colour for the caption — so a control the user can barely read is a box you can barely read.
|
|
136
|
+
Poor contrast shows itself instead of hiding in a JSON blob. It's machine-checkable too: DOM-tier
|
|
137
|
+
nodes carry `colors: {fg, bg, contrast, passes}` and a `contrastFail` string when they miss WCAG AA.
|
|
138
|
+
(The verdict is drawn in legible red on purpose — a warning about unreadable text mustn't itself be
|
|
139
|
+
unreadable.)
|
|
140
|
+
|
|
141
|
+
### Fixed: the widget was served without a charset
|
|
142
|
+
|
|
143
|
+
`Content-Type: application/javascript` carried no `; charset=utf-8`, so browsers parsed
|
|
144
|
+
`component.js` as Latin-1 and **every non-ASCII string literal in the widget was corrupted at parse
|
|
145
|
+
time** — em-dashes, `×`, `·`, and the `⟷`/`⟵` binding-arrow legend. The bytes on disk were always
|
|
146
|
+
valid UTF-8; the browser was mis-decoding them. Fixed on all five JS responses.
|
|
147
|
+
|
|
148
|
+
## 1.9.0
|
|
149
|
+
|
|
150
|
+
### New: `hj map --image` — the map as a rasterized schematic
|
|
151
|
+
|
|
152
|
+
Renders the affordance map as a PNG: one labeled box per control, nested by structure, each showing
|
|
153
|
+
its handle (`@ref` or `#index`) so the picture doubles as an **index** — glance at it, pick a
|
|
154
|
+
target, act on that one record.
|
|
155
|
+
|
|
156
|
+
It has to be a **bitmap** to be worth anything: an image of text costs a vision encoder far fewer
|
|
157
|
+
tokens than the same text tokenized, but that applies to rendered pixels, not to SVG markup (which
|
|
158
|
+
is just text tokens, and worse than the JSON it would replace). Rasterized in the browser, so there
|
|
159
|
+
is no new dependency.
|
|
160
|
+
|
|
161
|
+
**The win is density-dependent, and the response says so rather than assuming.** An image costs
|
|
162
|
+
~1000–1600 vision tokens regardless of content, so a small page is cheaper as JSON; the image pays
|
|
163
|
+
off once the map is large. `cost.approxJsonTokens` reports the JSON size for that page so the choice
|
|
164
|
+
is measurable. The schematic is also deterministic, which makes a diff between two runs a regression
|
|
165
|
+
a human can see.
|
|
166
|
+
|
|
167
|
+
## 1.8.0
|
|
168
|
+
|
|
169
|
+
### New: `hj map` — what can I interact with, and what is it wired to?
|
|
170
|
+
|
|
171
|
+
An affordance map of the page. Usually a better first move than `hj tree` or a screenshot when
|
|
172
|
+
you're deciding what to *do*: structural, deterministic (no fonts/theme/viewport/animation timing),
|
|
173
|
+
and dense — a small page is a few hundred bytes (~100 tokens) against ~1–1.5k vision tokens for a
|
|
174
|
+
screenshot.
|
|
175
|
+
|
|
176
|
+
Two tiers, and the response always says which one produced it:
|
|
177
|
+
|
|
178
|
+
- **`source: "tosi-agent"`** — when the page exposes an agent surface (`globalThis.tosiAgent`, a
|
|
179
|
+
tosijs app calling `enableAgentInterface()`), the map is the app's **own wiring records**, passed
|
|
180
|
+
through unchanged. Those carry what the DOM cannot: which state path each control is bound to and
|
|
181
|
+
in which **direction** (`⟷` two-way/user-writable, `⟵` display-only, absent = static), the handler
|
|
182
|
+
path each event calls, and the callable actions. Act through the paths rather than synthesizing
|
|
183
|
+
input — `hj eval "tosiAgent.write('app.filter','milk')"` — and note that writing a `⟵`
|
|
184
|
+
display-only path via the DOM won't stick, which is exactly the "I typed into it and nothing
|
|
185
|
+
happened" trap.
|
|
186
|
+
- **`source: "dom"`** — any other page: structural, visible-only, each node carrying a `ref` for
|
|
187
|
+
`hj click <ref>`. Labelled an approximation with **no** binding provenance, so it can't be
|
|
188
|
+
mistaken for real wiring.
|
|
189
|
+
|
|
190
|
+
Credit to the tosijs agent for the idea (#12).
|
|
191
|
+
|
|
192
|
+
## 1.7.0
|
|
193
|
+
|
|
194
|
+
### New: capture a `<canvas>` directly — `hj screenshot --canvas <selector>`
|
|
195
|
+
|
|
196
|
+
Reads the canvas's own pixels (`toDataURL`) instead of capturing the screen. For a WebGL scene
|
|
197
|
+
(Babylon/three.js) or a UI rendered into a texture that means **exact pixels at native resolution,
|
|
198
|
+
no screen-share grant, no desktop app required** — and it works even when the canvas is scrolled
|
|
199
|
+
out of view or the tab isn't frontmost. Takes the same `--scale`/`--format`/`--max-width`/file
|
|
200
|
+
options as any screenshot.
|
|
201
|
+
|
|
202
|
+
It also handles the trap that makes naive canvas capture untrustworthy: a WebGL context clears its
|
|
203
|
+
drawing buffer after compositing unless created with `{ preserveDrawingBuffer: true }`, so
|
|
204
|
+
`toDataURL` can hand back a **blank image with no error**. Haltija samples the result and returns a
|
|
205
|
+
`warning` explaining the likely cause instead of a silent empty picture — and deliberately doesn't
|
|
206
|
+
cry wolf: a canvas with real content warns not at all, and a uniform *opaque* colour (which may be a
|
|
207
|
+
perfectly legitimate solid background) gets a softer note than a fully transparent one. A canvas
|
|
208
|
+
tainted by cross-origin textures returns a clear CORS error rather than crashing.
|
|
209
|
+
|
|
210
|
+
### New: adopter-context test lane
|
|
211
|
+
|
|
212
|
+
The suite now includes tests that reproduce the *dirty machine* adopters actually have — a server
|
|
213
|
+
already running with zero windows, two projects in different directories each expecting their own,
|
|
214
|
+
and ambiguous targeting from an unrelated directory. Every field bug this project has shipped lived
|
|
215
|
+
in that gap, invisible to a suite that starts from nothing.
|
|
216
|
+
|
|
3
217
|
## 1.6.1
|
|
4
218
|
|
|
5
219
|
Makes haltija's detection reachable by automation ([#8](https://github.com/tonioloewald/haltija/issues/8),
|