@ingcreators/annot-product-docs 0.3.0 → 0.4.1
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 +272 -0
- package/dist/annotations-yaml.d.ts +291 -0
- package/dist/config.d.ts +23 -141
- package/dist/deprecation.d.ts +58 -0
- package/dist/drift.d.ts +98 -3
- package/dist/index.d.ts +10 -4
- package/dist/index.js +1434 -241
- package/dist/mdx-annotations.d.ts +72 -1
- package/dist/migrate-overlays-to-annotations.d.ts +49 -0
- package/dist/migrate-to-element-tree.d.ts +102 -0
- package/dist/types-config.d.ts +22 -0
- package/dist/types.d.ts +45 -0
- package/package.json +14 -9
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,277 @@
|
|
|
1
1
|
# @ingcreators/annot-product-docs
|
|
2
2
|
|
|
3
|
+
## 0.4.1
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Updated dependencies [b47d896]
|
|
8
|
+
- @ingcreators/annot-core@0.3.1
|
|
9
|
+
- @ingcreators/annot-annotator@0.6.0
|
|
10
|
+
- @ingcreators/annot-playwright@0.4.2
|
|
11
|
+
|
|
12
|
+
## 0.4.0
|
|
13
|
+
|
|
14
|
+
### Minor Changes
|
|
15
|
+
|
|
16
|
+
- b5d52f6: **Annotation palette composes onto the annotated PNG** — Phase 3c
|
|
17
|
+
of `docs/plans/living-spec-authoring-roadmap.md`. The Astro Image
|
|
18
|
+
Service's `renderAnnotatedScreen` now reads the Phase 3a yaml
|
|
19
|
+
`annotations[]` section and bakes the full visual palette
|
|
20
|
+
(rect / circle / arrow / text / callout / freehand / redact /
|
|
21
|
+
focusMask) onto the base PNG, layered underneath the existing
|
|
22
|
+
numbered-badge overlays.
|
|
23
|
+
|
|
24
|
+
### New public surface — `@ingcreators/annot-product-docs`
|
|
25
|
+
|
|
26
|
+
`buildShapeAnnotationsFromYaml(annotations, boxed, dims) →
|
|
27
|
+
BboxAnnotation[]` maps each Phase 3a `AnnotationSpec` against the
|
|
28
|
+
page's `BoxedEntry[]` (from snapshot YAML or PNG XMP ElementTree)
|
|
29
|
+
and produces `BboxAnnotation` shapes the headless annotator's
|
|
30
|
+
`bboxAnnotationsToSvg` consumes. Per-variant resolution:
|
|
31
|
+
- **`rect`** — `match` / `coversElements[]` / `bbox`. `coversElements`
|
|
32
|
+
unions the per-element bboxes into one.
|
|
33
|
+
- **`circle`** — match-anchored circles centre on the element bbox
|
|
34
|
+
with radius defaulting to half the longer axis; `center` + `radius`
|
|
35
|
+
is the free-coord form.
|
|
36
|
+
- **`arrow`** — endpoints can be `{ match }` (centre-to-centre) or
|
|
37
|
+
`{ point }`.
|
|
38
|
+
- **`text`** — `anchor.position` (above / below / left / right /
|
|
39
|
+
center) offsets a centred / left- / right-anchored label by 8 px
|
|
40
|
+
outside the element bbox.
|
|
41
|
+
- **`callout`** — target = match-resolved or free-coord bbox; `at`
|
|
42
|
+
is the caption position.
|
|
43
|
+
- **`freehand`** — passes through verbatim.
|
|
44
|
+
- **`redact`** — style: `solid` renders as a filled rect (default
|
|
45
|
+
fill `#222222`, no stroke); `fill` / `stroke` overrides honoured.
|
|
46
|
+
- **`focusMask`** — cutout expands by `padding` (match-anchored);
|
|
47
|
+
outer rect collapses to the supplied image dims.
|
|
48
|
+
|
|
49
|
+
Intent mapping mirrors the existing badge path
|
|
50
|
+
(`required → error`, `action → warning`, others pass through).
|
|
51
|
+
|
|
52
|
+
Match resolution failures are silently skipped — the drift
|
|
53
|
+
detector (Phase 3d) surfaces them upstream so the build keeps
|
|
54
|
+
producing a useful PNG even when the snapshot has drifted.
|
|
55
|
+
|
|
56
|
+
### Behaviour change — `renderAnnotatedScreen`
|
|
57
|
+
|
|
58
|
+
When `<Screen annotations="…">` resolves to a yaml carrying
|
|
59
|
+
`annotations[]`, the renderer composes shapes (underneath) + badges
|
|
60
|
+
(on top) into one SVG fragment via `svgFromBboxAnnotations`. The
|
|
61
|
+
cache key already includes the annotations-yaml source from
|
|
62
|
+
Phase 2b, so edits to the yaml bust the cached PNG without extra
|
|
63
|
+
bookkeeping. Pre-Phase-3 yaml files (no `annotations` key) parse
|
|
64
|
+
- render unchanged.
|
|
65
|
+
|
|
66
|
+
### Compatibility
|
|
67
|
+
|
|
68
|
+
Additive. Existing callers that only use `overlays[]` see no
|
|
69
|
+
behaviour change. The new `buildShapeAnnotationsFromYaml` export
|
|
70
|
+
is opt-in.
|
|
71
|
+
|
|
72
|
+
- fa712fd: **Annotation palette drift + xlsx coverage (Phase 3d)** — closes
|
|
73
|
+
Phase 3 of `docs/plans/living-spec-authoring-roadmap.md`.
|
|
74
|
+
|
|
75
|
+
### Drift detector — `yamlAnnotations` opt-in
|
|
76
|
+
|
|
77
|
+
`detectDrift` / `detectDriftFromYaml` / `detectDriftFromElementTree`
|
|
78
|
+
gain an optional `yamlAnnotations: readonly AnnotationSpec[]`
|
|
79
|
+
field. When set, the detector walks the match keys reachable from
|
|
80
|
+
each Phase 3a `AnnotationSpec` (via the new
|
|
81
|
+
`collectMatchKeysFromAnnotation(spec) → MatchKey[]` helper) and
|
|
82
|
+
runs them through the same match-cycle as overlays — emitting
|
|
83
|
+
`removed` / `renamed` / `role-changed` / `duplicated` findings
|
|
84
|
+
with the annotation `id` referenced in the message.
|
|
85
|
+
|
|
86
|
+
Free-coord variants (`bbox`-only rect / `point`-only arrow
|
|
87
|
+
endpoint / `at`-only text / `bbox`-only callout target /
|
|
88
|
+
freehand / `bbox`-only redact / `bbox`-only focusMask cutout)
|
|
89
|
+
contribute zero keys and pass through silently.
|
|
90
|
+
|
|
91
|
+
`annotations[]` IDs are NEVER referenced from `<AnnotCallout for>`
|
|
92
|
+
(overlays[] owns that contract), so no
|
|
93
|
+
`description-missing` / `description-orphan` findings fire for
|
|
94
|
+
this source.
|
|
95
|
+
|
|
96
|
+
### Excel adapter — yaml-driven rows for migrated screens
|
|
97
|
+
|
|
98
|
+
`@ingcreators/annot-product-docs-xlsx`'s `extractFromParsed`
|
|
99
|
+
gains an optional `annotationsYamlByPath` context map. When a
|
|
100
|
+
`<Screen>` carries `annotations="…"` and the matching yaml is in
|
|
101
|
+
the map, the item-table rows are sourced from the yaml's
|
|
102
|
+
`overlays[]` (each row's body cross-referenced from
|
|
103
|
+
`screen.callouts` by id). `extractMdxFile` loads each
|
|
104
|
+
referenced yaml file from disk automatically — missing files are
|
|
105
|
+
a loud failure on the same "explicit reference, but file gone"
|
|
106
|
+
reasoning the Astro Image Service uses.
|
|
107
|
+
|
|
108
|
+
`annotations[]` entries in the yaml are deliberately NOT
|
|
109
|
+
surfaced as rows. The Astro Image Service composes them onto
|
|
110
|
+
the annotated PNG; the Excel adapter renders the resulting image
|
|
111
|
+
in the spreadsheet's picture column while the items table stays
|
|
112
|
+
scoped to overlays.
|
|
113
|
+
|
|
114
|
+
### workflow-app dogfood
|
|
115
|
+
|
|
116
|
+
`examples/workflow-app/docs/books/operation-manual/OM-001-login.mdx`
|
|
117
|
+
migrates from inline `<Overlay>` to the
|
|
118
|
+
`<Screen annotations="./OM-001-login.annotations.yaml">` +
|
|
119
|
+
`<AnnotCallout for>` form. The companion yaml ships three
|
|
120
|
+
overlays plus three `annotations[]` entries exercising
|
|
121
|
+
`rect` + `arrow` + `focusMask` — the full Phase 3 palette
|
|
122
|
+
end-to-end through the workflow-app's docs build.
|
|
123
|
+
|
|
124
|
+
### Compatibility
|
|
125
|
+
|
|
126
|
+
Additive. Existing drift callers see no behaviour change unless
|
|
127
|
+
they opt in to `yamlAnnotations`. Existing xlsx callers see no
|
|
128
|
+
behaviour change unless they migrate a screen to the yaml form;
|
|
129
|
+
inline-`<Overlay>` screens continue to drive rows as before.
|
|
130
|
+
|
|
131
|
+
- f09a6b1: **Annotation yaml `redact.style` accepts `mosaic` / `blur`** —
|
|
132
|
+
Phase 3f of `docs/plans/living-spec-authoring-roadmap.md`
|
|
133
|
+
(Phase 3 follow-up).
|
|
134
|
+
|
|
135
|
+
The Phase 3a parser shipped `redact.style: "solid"` only; mosaic
|
|
136
|
+
/ blur were explicitly rejected with a "reserved for follow-up"
|
|
137
|
+
message. Phase 3f widens the enum to all three (`solid` /
|
|
138
|
+
`mosaic` / `blur`) so authoring tools and the Astro Image
|
|
139
|
+
Service can use the values end-to-end.
|
|
140
|
+
|
|
141
|
+
### Parser behaviour
|
|
142
|
+
|
|
143
|
+
```yaml
|
|
144
|
+
# Phase 3a: accepted
|
|
145
|
+
annotations:
|
|
146
|
+
- id: redact-1
|
|
147
|
+
kind: redact
|
|
148
|
+
bbox: { x: 0, y: 0, width: 100, height: 30 }
|
|
149
|
+
style: solid
|
|
150
|
+
|
|
151
|
+
# Phase 3f: NEW — both accepted
|
|
152
|
+
annotations:
|
|
153
|
+
- id: redact-2
|
|
154
|
+
kind: redact
|
|
155
|
+
match: { role: textbox, name: Reason }
|
|
156
|
+
style: mosaic
|
|
157
|
+
- id: redact-3
|
|
158
|
+
kind: redact
|
|
159
|
+
bbox: { x: 421, y: 269, width: 438, height: 40 }
|
|
160
|
+
style: blur
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
Unknown style values still error with an updated message:
|
|
164
|
+
`redact.style must be one of "solid" / "mosaic" / "blur"`.
|
|
165
|
+
|
|
166
|
+
### Render behaviour (transitional)
|
|
167
|
+
|
|
168
|
+
Between 3f (this PR) and 3g (Astro Image Service raster
|
|
169
|
+
pre-processing), `mosaic` and `blur` redact entries are
|
|
170
|
+
parser-accepted but the Image Service still routes them
|
|
171
|
+
through the SVG-fragment filled-rect path — so they LOOK
|
|
172
|
+
identical to `solid` until 3g lands. 3g wires the raster
|
|
173
|
+
pass that gives `mosaic` / `blur` their distinct visual
|
|
174
|
+
output.
|
|
175
|
+
|
|
176
|
+
### New public type
|
|
177
|
+
|
|
178
|
+
`RedactAnnotationStyle` (the `"solid" | "mosaic" | "blur"` union)
|
|
179
|
+
is exported from `@ingcreators/annot-product-docs` so callers
|
|
180
|
+
can reference it directly.
|
|
181
|
+
|
|
182
|
+
### Compatibility
|
|
183
|
+
|
|
184
|
+
Additive within v1. Pre-3f files (no redact entries, or
|
|
185
|
+
`style: solid` only) parse identically. Files authored with
|
|
186
|
+
`style: "mosaic" | "blur"` are rejected by the pre-3f parser
|
|
187
|
+
(loud failure pointing at the unsupported style) — consumers
|
|
188
|
+
on older `@ingcreators/annot-product-docs` upgrade to consume
|
|
189
|
+
the new files.
|
|
190
|
+
|
|
191
|
+
- 0d19345: **Astro Image Service bakes mosaic / blur redacts onto the base
|
|
192
|
+
PNG** — Phase 3g of `docs/plans/living-spec-authoring-roadmap.md`
|
|
193
|
+
(Phase 3 follow-up).
|
|
194
|
+
|
|
195
|
+
When a screen's `annotations[]` yaml carries
|
|
196
|
+
`redact { style: "mosaic" | "blur" }` entries, the renderer now
|
|
197
|
+
calls `burnRedactions` from `@ingcreators/annot-annotator` on
|
|
198
|
+
the base PNG before SVG-fragment composition. `style: solid`
|
|
199
|
+
redacts continue to flow through the existing SVG filled-rect
|
|
200
|
+
path — avoiding an unnecessary PNG round-trip for the common
|
|
201
|
+
solid case.
|
|
202
|
+
|
|
203
|
+
### New public surface
|
|
204
|
+
|
|
205
|
+
`buildRasterRedactRegionsFromYaml(annotations, boxed) →
|
|
206
|
+
BboxRedactRegion[]` (exported from
|
|
207
|
+
`@ingcreators/annot-product-docs`) walks `annotations[]` for
|
|
208
|
+
raster-style redact entries, resolves each cutout to a bbox,
|
|
209
|
+
and emits regions ready for `burnRedactions`. Match-anchored
|
|
210
|
+
entries whose `match` doesn't resolve are skipped silently —
|
|
211
|
+
the drift detector (Phase 3d) surfaces them upstream so the
|
|
212
|
+
build keeps producing a useful PNG while the snapshot
|
|
213
|
+
catches up.
|
|
214
|
+
|
|
215
|
+
### `renderAnnotatedScreen` flow
|
|
216
|
+
|
|
217
|
+
```
|
|
218
|
+
load base PNG bytes
|
|
219
|
+
↓
|
|
220
|
+
read element-tree bboxes
|
|
221
|
+
↓
|
|
222
|
+
walk annotations[] → split into:
|
|
223
|
+
• raster redacts (mosaic / blur) → burnRedactions(base, regions)
|
|
224
|
+
• SVG annotations (rect / circle / arrow / text / callout
|
|
225
|
+
/ freehand / solid-redact / focusMask / numberedBadge)
|
|
226
|
+
↓
|
|
227
|
+
compose SVG fragments on top of the (possibly burned) base PNG
|
|
228
|
+
↓
|
|
229
|
+
emit final PNG (flat or editable)
|
|
230
|
+
```
|
|
231
|
+
|
|
232
|
+
### `mapRedact` change
|
|
233
|
+
|
|
234
|
+
`mapRedact` in `mdx-annotations.ts` now returns `null` for
|
|
235
|
+
`style: "mosaic" | "blur"` so those entries don't double-bake
|
|
236
|
+
as a filled rect on top of the already-pixelated bitmap. Solid
|
|
237
|
+
redacts continue to produce a `BboxRectAnnotation` for the SVG
|
|
238
|
+
path.
|
|
239
|
+
|
|
240
|
+
### `hadBoundingBoxes` semantics
|
|
241
|
+
|
|
242
|
+
The flag flips true when raster redacts resolved through bbox
|
|
243
|
+
data, even when no SVG annotations composed on top. This
|
|
244
|
+
matches the flag's intent ("we used the snapshot's bbox data
|
|
245
|
+
to produce a useful render") — a screen with only a mosaic
|
|
246
|
+
redact still benefited from the bbox tour.
|
|
247
|
+
|
|
248
|
+
### Caching
|
|
249
|
+
|
|
250
|
+
The cache key already includes the annotations-yaml source
|
|
251
|
+
bytes (Phase 2b), so editing a yaml `style: mosaic` → `style:
|
|
252
|
+
blur` value busts the cached PNG without additional
|
|
253
|
+
bookkeeping.
|
|
254
|
+
|
|
255
|
+
### Compatibility
|
|
256
|
+
|
|
257
|
+
Additive. Existing screens (no `annotations[]`, or
|
|
258
|
+
`annotations[]` with no raster-style redacts) render
|
|
259
|
+
byte-identical. mosaic / blur redacts that were parser-accepted
|
|
260
|
+
in 3f but rendered as solid rects now render as their proper
|
|
261
|
+
raster effect.
|
|
262
|
+
|
|
263
|
+
### Patch Changes
|
|
264
|
+
|
|
265
|
+
- Updated dependencies [6124d59]
|
|
266
|
+
- Updated dependencies [0c7ac26]
|
|
267
|
+
- Updated dependencies [64dc6e8]
|
|
268
|
+
- Updated dependencies [691bec5]
|
|
269
|
+
- Updated dependencies [9697f27]
|
|
270
|
+
- Updated dependencies [266b05a]
|
|
271
|
+
- @ingcreators/annot-annotator@0.6.0
|
|
272
|
+
- @ingcreators/annot-core@0.3.0
|
|
273
|
+
- @ingcreators/annot-playwright@0.4.1
|
|
274
|
+
|
|
3
275
|
## 0.3.0
|
|
4
276
|
|
|
5
277
|
### Minor Changes
|
|
@@ -0,0 +1,291 @@
|
|
|
1
|
+
import { MatchKey, OverlayIntent } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Current schema version. Per OQ-01 of the roadmap, future v2 / v3
|
|
4
|
+
* bumps go through strict version dispatch (the parser refuses
|
|
5
|
+
* unknown majors); within v1, additive optional fields are allowed
|
|
6
|
+
* without a version bump.
|
|
7
|
+
*/
|
|
8
|
+
export declare const ANNOTATIONS_YAML_VERSION: 1;
|
|
9
|
+
/**
|
|
10
|
+
* One numbered-badge overlay entry. Phase 2 supports `numberedBadge`
|
|
11
|
+
* only; Phase 3 of the roadmap extends `OverlayEntry` (and adds a
|
|
12
|
+
* sibling `AnnotationSpec`) for the full annotation palette
|
|
13
|
+
* (`rect` / `arrow` / `text` / `freehand` / `redact` / etc.).
|
|
14
|
+
*
|
|
15
|
+
* The shape mirrors the legacy {@link OverlaySpec} from `./types.ts`
|
|
16
|
+
* minus the inline `body` field — descriptions live in MDX
|
|
17
|
+
* `<AnnotCallout for="id">body</AnnotCallout>` blocks now, not in
|
|
18
|
+
* the yaml.
|
|
19
|
+
*/
|
|
20
|
+
export interface OverlayEntry {
|
|
21
|
+
/**
|
|
22
|
+
* Stable identifier targeted by `<AnnotCallout for="id">` in MDX.
|
|
23
|
+
* Author-supplied; the migration CLI (Phase 2d) defaults to
|
|
24
|
+
* `o1` / `o2` / … in `overlays[]` index order.
|
|
25
|
+
*/
|
|
26
|
+
id: string;
|
|
27
|
+
/**
|
|
28
|
+
* Discriminator — Phase 2 ships `numberedBadge` only. Adding a
|
|
29
|
+
* new kind here means extending the renderer in `AnnotFigure.astro`
|
|
30
|
+
* AND the drift validator in `./drift.ts`.
|
|
31
|
+
*/
|
|
32
|
+
kind: "numberedBadge";
|
|
33
|
+
/** Match key used to locate the element in the page's ElementTree. */
|
|
34
|
+
match: MatchKey;
|
|
35
|
+
/** Optional intent flavour for the rendered callout / border. */
|
|
36
|
+
intent?: OverlayIntent;
|
|
37
|
+
/**
|
|
38
|
+
* Numeric badge label rendered on the image. Author-supplied so
|
|
39
|
+
* the same yaml renders consistent numbering across re-captures
|
|
40
|
+
* even if `overlays[]` order changes. Required by the Astro
|
|
41
|
+
* Image Service today; future kinds may make it optional.
|
|
42
|
+
*/
|
|
43
|
+
number: number;
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Top-level wire shape for an `.annotations.yaml` file.
|
|
47
|
+
*
|
|
48
|
+
* `overlays[]` carries the numbered-badge entries the docs flow
|
|
49
|
+
* pairs with `<AnnotCallout for="id">` description blocks
|
|
50
|
+
* (Phase 2). `annotations[]` carries the wider visual palette
|
|
51
|
+
* (Phase 3 of the roadmap) — entries are pure visual marking
|
|
52
|
+
* with no MDX description slot; their `id` is self-contained
|
|
53
|
+
* and is NEVER targeted by `<AnnotCallout for>`.
|
|
54
|
+
*
|
|
55
|
+
* Both arrays default to empty when absent. Within v1 the
|
|
56
|
+
* `annotations[]` extension is additive: pre-Phase-3 files
|
|
57
|
+
* (no `annotations` key) keep parsing unchanged.
|
|
58
|
+
*
|
|
59
|
+
* `meta` is an open string map reserved for downstream tooling
|
|
60
|
+
* (book grouping, generator IDs, etc.) — readers must ignore
|
|
61
|
+
* unknown keys.
|
|
62
|
+
*/
|
|
63
|
+
export interface AnnotationsFile {
|
|
64
|
+
version: typeof ANNOTATIONS_YAML_VERSION;
|
|
65
|
+
overlays: OverlayEntry[];
|
|
66
|
+
/**
|
|
67
|
+
* Phase 3 of `docs/plans/living-spec-authoring-roadmap.md`.
|
|
68
|
+
* Optional sibling of `overlays[]` carrying the full visual
|
|
69
|
+
* palette (arrows / rects / text labels / callouts / freehand
|
|
70
|
+
* strokes / redact rects / focus masks). Each entry composes
|
|
71
|
+
* onto the annotated PNG but has no MDX `<AnnotCallout>`
|
|
72
|
+
* counterpart.
|
|
73
|
+
*/
|
|
74
|
+
annotations?: AnnotationSpec[];
|
|
75
|
+
/** Optional free-form metadata. Readers ignore unknown keys. */
|
|
76
|
+
meta?: Record<string, string>;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Common style fields any annotation kind may carry. Mirrors the
|
|
80
|
+
* `AnnotationStyle` shape in `@ingcreators/annot-annotator`'s DSL
|
|
81
|
+
* so the yaml → `BboxAnnotation` mapper (Phase 3c) flows straight
|
|
82
|
+
* through. Inlined here rather than imported so this Tier A module
|
|
83
|
+
* stays free of the annotator dependency at parse time.
|
|
84
|
+
*/
|
|
85
|
+
export interface AnnotationStyleFields {
|
|
86
|
+
/** Semantic colour shorthand. Renderer maps to design-system tokens. */
|
|
87
|
+
intent?: OverlayIntent;
|
|
88
|
+
/** CSS stroke colour override (wins over `intent`-derived default). */
|
|
89
|
+
stroke?: string;
|
|
90
|
+
/** Stroke width in image pixels. */
|
|
91
|
+
strokeWidth?: number;
|
|
92
|
+
/** CSS fill colour override (wins over `intent`-derived default). */
|
|
93
|
+
fill?: string;
|
|
94
|
+
/** CSS text-fill colour override. */
|
|
95
|
+
color?: string;
|
|
96
|
+
}
|
|
97
|
+
/** Axis-aligned bbox in page (image) pixels. */
|
|
98
|
+
export interface AnnotationBBox {
|
|
99
|
+
x: number;
|
|
100
|
+
y: number;
|
|
101
|
+
width: number;
|
|
102
|
+
height: number;
|
|
103
|
+
}
|
|
104
|
+
/** Point in page (image) pixels. */
|
|
105
|
+
export interface AnnotationPoint {
|
|
106
|
+
x: number;
|
|
107
|
+
y: number;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Where a text label sits relative to its anchor element. The
|
|
111
|
+
* renderer picks a sensible offset (image-pixel padding) per
|
|
112
|
+
* position. Default `above`.
|
|
113
|
+
*/
|
|
114
|
+
export type TextAnchorPosition = "above" | "below" | "left" | "right" | "center";
|
|
115
|
+
/**
|
|
116
|
+
* Outline (or filled) rect that highlights one element, a group of
|
|
117
|
+
* elements (bbox = union), or a free-coord region.
|
|
118
|
+
*
|
|
119
|
+
* Exactly one of `match` / `coversElements` / `bbox` is required;
|
|
120
|
+
* the parser rejects entries that supply zero or multiple.
|
|
121
|
+
*/
|
|
122
|
+
export interface RectAnnotation extends AnnotationStyleFields {
|
|
123
|
+
id: string;
|
|
124
|
+
kind: "rect";
|
|
125
|
+
match?: MatchKey;
|
|
126
|
+
coversElements?: MatchKey[];
|
|
127
|
+
bbox?: AnnotationBBox;
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* Circle centred on an element (radius derived from the element's
|
|
131
|
+
* bbox half-width) or on a free-coord point.
|
|
132
|
+
*/
|
|
133
|
+
export interface CircleAnnotation extends AnnotationStyleFields {
|
|
134
|
+
id: string;
|
|
135
|
+
kind: "circle";
|
|
136
|
+
/** Element to centre the circle on. Mutually exclusive with `center`. */
|
|
137
|
+
match?: MatchKey;
|
|
138
|
+
/** Free-coord centre. Mutually exclusive with `match`. */
|
|
139
|
+
center?: AnnotationPoint;
|
|
140
|
+
/**
|
|
141
|
+
* Radius in image pixels. Required for the `center` form;
|
|
142
|
+
* optional override for the `match` form (defaults to half the
|
|
143
|
+
* element's bbox width).
|
|
144
|
+
*/
|
|
145
|
+
radius?: number;
|
|
146
|
+
}
|
|
147
|
+
/** Arrow endpoint — either match-anchored or free-coord. */
|
|
148
|
+
export type ArrowEndpoint = {
|
|
149
|
+
match: MatchKey;
|
|
150
|
+
} | {
|
|
151
|
+
point: AnnotationPoint;
|
|
152
|
+
};
|
|
153
|
+
/** Arrow between two endpoints. */
|
|
154
|
+
export interface ArrowAnnotation extends AnnotationStyleFields {
|
|
155
|
+
id: string;
|
|
156
|
+
kind: "arrow";
|
|
157
|
+
from: ArrowEndpoint;
|
|
158
|
+
to: ArrowEndpoint;
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Text label anchored to an element or placed at a free-coord
|
|
162
|
+
* point. Exactly one of `anchor` / `at` is required.
|
|
163
|
+
*/
|
|
164
|
+
export interface TextAnnotation extends AnnotationStyleFields {
|
|
165
|
+
id: string;
|
|
166
|
+
kind: "text";
|
|
167
|
+
text: string;
|
|
168
|
+
/** Match-anchored. The renderer offsets per `position`. */
|
|
169
|
+
anchor?: {
|
|
170
|
+
match: MatchKey;
|
|
171
|
+
position?: TextAnchorPosition;
|
|
172
|
+
};
|
|
173
|
+
/** Free-coord placement. */
|
|
174
|
+
at?: AnnotationPoint;
|
|
175
|
+
/** Font size in image pixels. Default `14`. */
|
|
176
|
+
fontSize?: number;
|
|
177
|
+
}
|
|
178
|
+
/** Callout target — either match-anchored or free-coord. */
|
|
179
|
+
export type CalloutTarget = {
|
|
180
|
+
match: MatchKey;
|
|
181
|
+
} | {
|
|
182
|
+
bbox: AnnotationBBox;
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Callout = target outline + caption text + arrow from caption to
|
|
186
|
+
* target. The caption sits at `at`; the target highlights at
|
|
187
|
+
* `target` (resolved to a bbox via match or supplied directly).
|
|
188
|
+
*/
|
|
189
|
+
export interface CalloutAnnotation extends AnnotationStyleFields {
|
|
190
|
+
id: string;
|
|
191
|
+
kind: "callout";
|
|
192
|
+
text: string;
|
|
193
|
+
target: CalloutTarget;
|
|
194
|
+
/** Caption text position. Required for now (auto-placement is a future enhancement). */
|
|
195
|
+
at: AnnotationPoint;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* Free-form path. Always free-coord — UI changes may misalign
|
|
199
|
+
* it; the editor's drift detector intentionally skips it.
|
|
200
|
+
*/
|
|
201
|
+
export interface FreehandAnnotation extends AnnotationStyleFields {
|
|
202
|
+
id: string;
|
|
203
|
+
kind: "freehand";
|
|
204
|
+
/** SVG path data — `M` / `L` / `C` / `Q` / `Z` commands. */
|
|
205
|
+
path: string;
|
|
206
|
+
}
|
|
207
|
+
/**
|
|
208
|
+
* Style of a redact rect. `solid` paints an opaque rect over the
|
|
209
|
+
* region; `mosaic` and `blur` are raster transforms applied to
|
|
210
|
+
* the underlying screenshot bitmap before SVG-fragment
|
|
211
|
+
* composition (Phase 3 follow-up — see Astro Image Service for
|
|
212
|
+
* the rendering path).
|
|
213
|
+
*/
|
|
214
|
+
export type RedactAnnotationStyle = "solid" | "mosaic" | "blur";
|
|
215
|
+
/**
|
|
216
|
+
* Opaque or scrambled rect obscuring content. `solid` renders as
|
|
217
|
+
* a filled rect via the SVG-fragment path; `mosaic` and `blur`
|
|
218
|
+
* trigger a raster pre-processing pass in the Astro Image Service
|
|
219
|
+
* (Phase 3 follow-up — Phase 3a–3d shipped `solid` only).
|
|
220
|
+
*/
|
|
221
|
+
export interface RedactAnnotation extends AnnotationStyleFields {
|
|
222
|
+
id: string;
|
|
223
|
+
kind: "redact";
|
|
224
|
+
match?: MatchKey;
|
|
225
|
+
bbox?: AnnotationBBox;
|
|
226
|
+
/**
|
|
227
|
+
* Defaults to `solid` at render time when omitted. Phase 3 follow-up
|
|
228
|
+
* (3f) widened this from the original `"solid"`-only to also
|
|
229
|
+
* accept `"mosaic"` and `"blur"` — both routed through
|
|
230
|
+
* `burnRedactions` from `@ingcreators/annot-annotator`.
|
|
231
|
+
*/
|
|
232
|
+
style?: RedactAnnotationStyle;
|
|
233
|
+
}
|
|
234
|
+
/** Focus-mask cutout — element-anchored (with optional padding) or free-coord bbox. */
|
|
235
|
+
export type FocusMaskCutout = {
|
|
236
|
+
match: MatchKey;
|
|
237
|
+
padding?: number;
|
|
238
|
+
} | {
|
|
239
|
+
bbox: AnnotationBBox;
|
|
240
|
+
};
|
|
241
|
+
/**
|
|
242
|
+
* Darken everything EXCEPT the cutout region. The cutout draws
|
|
243
|
+
* crisp; everything outside is dimmed by `dimColor`
|
|
244
|
+
* (default `rgba(0,0,0,0.5)`).
|
|
245
|
+
*/
|
|
246
|
+
export interface FocusMaskAnnotation extends AnnotationStyleFields {
|
|
247
|
+
id: string;
|
|
248
|
+
kind: "focusMask";
|
|
249
|
+
cutout: FocusMaskCutout;
|
|
250
|
+
/** CSS colour for the dim layer. Default `rgba(0,0,0,0.5)`. */
|
|
251
|
+
dimColor?: string;
|
|
252
|
+
}
|
|
253
|
+
/**
|
|
254
|
+
* Discriminated union across every annotation kind Phase 3
|
|
255
|
+
* supports. Parser dispatches on `kind`; serializer round-trips
|
|
256
|
+
* to YAML and back to a byte-equivalent object.
|
|
257
|
+
*/
|
|
258
|
+
export type AnnotationSpec = RectAnnotation | CircleAnnotation | ArrowAnnotation | TextAnnotation | CalloutAnnotation | FreehandAnnotation | RedactAnnotation | FocusMaskAnnotation;
|
|
259
|
+
/** The `kind` literal type. */
|
|
260
|
+
export type AnnotationKind = AnnotationSpec["kind"];
|
|
261
|
+
/** Set of every supported `kind`. Reused by the parser + drift detector. */
|
|
262
|
+
export declare const ANNOTATION_KINDS: readonly AnnotationKind[];
|
|
263
|
+
/**
|
|
264
|
+
* Error thrown when a YAML payload cannot be parsed into the
|
|
265
|
+
* documented schema. Carries the offending source so callers can
|
|
266
|
+
* surface line / column context (the CLI prefixes path + heading).
|
|
267
|
+
*/
|
|
268
|
+
export declare class AnnotationsYamlError extends Error {
|
|
269
|
+
readonly source?: string | undefined;
|
|
270
|
+
constructor(message: string, source?: string | undefined);
|
|
271
|
+
}
|
|
272
|
+
/**
|
|
273
|
+
* Parse a YAML string into an `AnnotationsFile`. Throws
|
|
274
|
+
* {@link AnnotationsYamlError} on shape violations: missing
|
|
275
|
+
* `version`, unsupported major, missing required `id` / `kind` /
|
|
276
|
+
* `match` / `number` on an overlay entry.
|
|
277
|
+
*
|
|
278
|
+
* The parser is permissive about optional fields: unknown keys at
|
|
279
|
+
* any level are dropped silently (forward compat within a major).
|
|
280
|
+
*/
|
|
281
|
+
export declare function parseAnnotationsYaml(source: string): AnnotationsFile;
|
|
282
|
+
/**
|
|
283
|
+
* Serialize an `AnnotationsFile` back to YAML. Output is
|
|
284
|
+
* deterministic (`version` → `overlays` → `meta`), suitable for
|
|
285
|
+
* round-trip + git-diff use.
|
|
286
|
+
*
|
|
287
|
+
* The serializer rejects entries that wouldn't round-trip through
|
|
288
|
+
* `parseAnnotationsYaml` — kind is checked at the type level, but
|
|
289
|
+
* missing `id` / `match` / `number` at runtime throws.
|
|
290
|
+
*/
|
|
291
|
+
export declare function serializeAnnotationsYaml(file: AnnotationsFile): string;
|