tileflow 0.1.0-alpha.2 → 0.1.0-alpha.20
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/README.md +246 -649
- package/dist/index.js +8546 -4564
- package/package.json +12 -13
- package/GENERATED_OUTPUT_LICENSE.md +0 -21
- package/NOTICE +0 -9
- package/TRADEMARKS.md +0 -10
package/README.md
CHANGED
|
@@ -1,205 +1,126 @@
|
|
|
1
1
|
# tileflow
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
The Tileflow command-line interface: author, validate, preview, build, capture, and deploy maps.
|
|
4
|
+
This package exposes the `tileflow` executable only. Do not import `tileflow` as a JavaScript library;
|
|
5
|
+
use `@tileflow/core` or the relevant integration package instead.
|
|
6
6
|
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
> Related packages and guides: [documentation index](https://raw.githubusercontent.com/tileflow/tileflow-sdk/main/llms.txt).
|
|
8
|
+
|
|
9
|
+
## Install
|
|
10
|
+
|
|
11
|
+
Use Node.js 22 or newer. Install the CLI in your project and commit the lockfile:
|
|
9
12
|
|
|
10
13
|
```sh
|
|
11
14
|
npm install @tileflow/core@alpha @tileflow/maps@alpha
|
|
12
15
|
npm install --save-dev --save-exact tileflow@alpha
|
|
13
16
|
npx tileflow init
|
|
14
17
|
npx tileflow validate
|
|
15
|
-
npx tileflow validate --target hosted
|
|
16
|
-
npx tileflow build
|
|
17
18
|
npx tileflow preview
|
|
18
19
|
```
|
|
19
20
|
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
delivery URL.
|
|
21
|
+
Run these commands from the project directory. After installation, `npx tileflow` uses the local
|
|
22
|
+
executable. With another package manager, use its local-execution command and the existing lockfile;
|
|
23
|
+
do not add a second lockfile or rely on a globally installed CLI.
|
|
24
24
|
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
`init` creates a singular `tileflow.config.ts` extending the official Streets map. `preview` opens
|
|
26
|
+
Inspector with that map, live reload, rendered-feature inspection, compiler attribution, zoom
|
|
27
|
+
curves, a sprite atlas, scene selection, saved captures, and before/after review.
|
|
27
28
|
|
|
28
|
-
|
|
29
|
-
|
|
29
|
+
Local validation, compilation, and asset preparation require no account or API key. Preview and
|
|
30
|
+
capture may fetch configured remote tiles and fonts. Config files are executable trusted code,
|
|
31
|
+
not a sandbox; review their imports before running them.
|
|
32
|
+
|
|
33
|
+
## Validate and build
|
|
30
34
|
|
|
31
35
|
```sh
|
|
32
|
-
npx tileflow
|
|
36
|
+
npx tileflow validate --json
|
|
37
|
+
npx tileflow validate --target hosted --json
|
|
38
|
+
npx tileflow build --out public/tileflow
|
|
33
39
|
```
|
|
34
40
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
server from an application's own `npm run dev` process.
|
|
41
|
+
The default build directory is `dist/tileflow`. A build writes a runtime manifest, concrete-theme
|
|
42
|
+
styles, and referenced prepared sprite/font assets. Serve the complete output, not just a style
|
|
43
|
+
file. A framework component defaults to `/tileflow/manifest.json`; set its `manifestUrl` explicitly
|
|
44
|
+
when your application's public path differs.
|
|
40
45
|
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
local tiles stack serve all sidecars without changing map authoring.
|
|
46
|
+
`build` is local. Hosted compatibility is a separate preflight: hosted deployment requires Tileflow
|
|
47
|
+
World and currently rejects local/package font bundles. Production builds reject unresolved local
|
|
48
|
+
PMTiles inputs rather than silently copying or publishing user datasets. Publish managed data
|
|
49
|
+
explicitly or supply an application-owned production source.
|
|
46
50
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
`tileflow preview --host 192.0.2.10`. URL-, path-, and hostname-shaped values are rejected.
|
|
51
|
+
To work on another map, use `--config <path>`. An ordinary config exports one map. Multi-map
|
|
52
|
+
workspaces are advanced repository orchestration, not a second application authoring model.
|
|
50
53
|
|
|
51
|
-
|
|
52
|
-
preview applies its committed concrete theme, camera, and CSS viewport dimensions. Capture remains the
|
|
53
|
-
authority for exact DPR and pixels. Scenes whose target is an application must be viewed through
|
|
54
|
-
that application's normal development server.
|
|
54
|
+
## Map development tools
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
Use `describe` for bounded language discovery (`describe themes --json` lists palette requirements
|
|
57
|
+
and optional time-of-day composition), `inspect` for configuration and data, `capture`
|
|
58
|
+
for reproducible evidence, and `compare` for saved captures, semantic edits, styles, references or
|
|
59
|
+
baselines. `preview` opens Inspector. These tools work in independent projects with
|
|
60
|
+
custom maps and data; official maps are optional.
|
|
57
61
|
|
|
58
|
-
|
|
59
|
-
semantics, compiles its ordered package/local icon directories and selected text provider, and
|
|
60
|
-
writes `manifest.json`, one `styles/<map>/<theme>.json` per concrete appearance, and every referenced
|
|
61
|
-
sprite/font asset. The manifest records `defaultTheme`, optional `systemThemes`, and the exact theme
|
|
62
|
-
catalog; it never flattens a default into a second style alias. A
|
|
63
|
-
map with text has exactly one provider: local/package `fonts` directories or a `glyphs` descriptor
|
|
64
|
-
whose `fontStacks` are explicit. The default output is `dist/tileflow`; choose another directory
|
|
65
|
-
explicitly with `--out`:
|
|
62
|
+
## Preview and compare
|
|
66
63
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
64
|
+
`preview` binds to `127.0.0.1` by default. `--host` explicitly accepts an IP literal or `localhost`;
|
|
65
|
+
it does not implicitly expose a public listener. `--theme <name>` selects a concrete theme.
|
|
66
|
+
`--scene <name>` selects a committed standalone scene.
|
|
70
67
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
68
|
+
Run `npx tileflow preview` from your project directory to load `tileflow.config.ts`, start the
|
|
69
|
+
watched server, and automatically open Inspector in your default browser once the server is
|
|
70
|
+
listening. Use `--config <path>` for another config or `--no-open` to start without opening a tab.
|
|
71
|
+
`--json` and `--renderer native` also keep the browser closed. The CLI always prints the local URL
|
|
72
|
+
in ordinary web preview output, so you can open it manually if browser launch is unavailable.
|
|
76
73
|
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
render. Application Capture uses the application's server; Tileflow's local handler provides
|
|
81
|
-
immutable, ETag-guarded PMTiles reads, but does not freeze every local dataset for the complete
|
|
82
|
-
screenshot window.
|
|
74
|
+
Opening Inspector through another loopback name, such as `localhost` instead of `127.0.0.1`,
|
|
75
|
+
redirects to the **Local** origin printed by the CLI, preserving camera and theme query parameters.
|
|
76
|
+
This keeps the map, palette controls, and workbench API on the same origin.
|
|
83
77
|
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
Team sources are validated and resolved independently.
|
|
78
|
+
Run from the project directory and keep selected configs inside it, so capture commands copied from
|
|
79
|
+
Inspector resolve the same files. The project itself can live anywhere, independently of this SDK.
|
|
87
80
|
|
|
88
|
-
|
|
81
|
+
The default is one Inspector pane, one watched artifact session, and one map renderer. Choose a
|
|
82
|
+
map, theme or configured scene in **Controls**. Map and theme pickers appear when there are multiple choices. **Compare → Compare live maps** adds a reference from the current
|
|
83
|
+
project; `--against-*` also supports a reference from another config. The native renderer retains its assets-only
|
|
84
|
+
preview endpoint.
|
|
89
85
|
|
|
90
|
-
|
|
86
|
+
Compare two configs live in Inspector:
|
|
91
87
|
|
|
92
88
|
```sh
|
|
93
|
-
npx tileflow
|
|
94
|
-
npx tileflow inspect --json
|
|
95
|
-
npx tileflow inspect --map madrid --json
|
|
96
|
-
npx tileflow language manifest --json
|
|
97
|
-
npx tileflow language schema --json
|
|
98
|
-
npx tileflow explain --map madrid --theme dark --json
|
|
99
|
-
npx tileflow semantic-diff --from-config before/tileflow.config.ts --to-config after/tileflow.config.ts --json
|
|
100
|
-
npx tileflow semantic-diff --config maps.workspace.ts --from before --to after --json
|
|
89
|
+
npx tileflow preview --config candidate/tileflow.config.ts --against-config reference/tileflow.config.ts
|
|
101
90
|
```
|
|
102
91
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
failure to load either raw discovery contract, leaves stdout empty and writes one schema-version-1
|
|
108
|
-
command failure to stderr. Command summaries and every failure diagnostic contain `phase`, `code`,
|
|
109
|
-
`path`, `severity`, `message`, and a bounded safe `suggestion`; diagnostics are sorted and
|
|
110
|
-
deduplicated deterministically.
|
|
111
|
-
|
|
112
|
-
Config inspection returns the resolved map, parent-to-leaf lineage, declared paths, leaf-level merge
|
|
113
|
-
provenance, and an explicit `themeContract`: default/system selection, shared token schema,
|
|
114
|
-
concrete values, typography, lighting, differences from the default, and stable audit diagnostics.
|
|
115
|
-
It omits the executable input-file graph and sanitizes credentials, URL queries,
|
|
116
|
-
secret-shaped values, data URLs, and absolute filesystem paths. The generated
|
|
117
|
-
[`modules-api-reference.json`](../../docs/modules-api-reference.json) is the machine-readable
|
|
118
|
-
map/module schema; its default `authoring` entrypoint tells an agent how to write the singular
|
|
119
|
-
config with `extends` and `scenes`, while its named `resolved` entrypoint matches inspection and
|
|
120
|
-
compiler input. Both are produced from executable core schemas rather than a handwritten parallel
|
|
121
|
-
API list.
|
|
122
|
-
|
|
123
|
-
`tileflow language manifest --json` discovers the complete closed semantic language without loading
|
|
124
|
-
a project: compiler identity, domains and their dependencies, public operations, expression-builder
|
|
125
|
-
signatures and limits, render selectors, semantic fields/features, diagnostics, reports, commands,
|
|
126
|
-
and schema references. `tileflow language schema --json` returns the packaged generated JSON Schema
|
|
127
|
-
that those references address. Together they are the canonical bootstrap surface for an authoring
|
|
128
|
-
agent; neither command writes files or accesses the network.
|
|
129
|
-
|
|
130
|
-
Each manifest command entry declares its `outputKind`, `outputVersion`, and stable
|
|
131
|
-
`outputSchemaRef`. `raw-authoring-manifest` and `raw-config-reference` identify the two bootstrap
|
|
132
|
-
documents above; `command-envelope` identifies the ordinary version-1 CLI contract.
|
|
133
|
-
|
|
134
|
-
`tileflow explain` compiles exactly one map/theme selection through `createStyleResult()` and emits
|
|
135
|
-
its structured `report` and safe compiler `diagnostics`; it deliberately omits the usually large
|
|
136
|
-
MapLibre `style`. In a singular config, `--map` is optional; a multi-map workbench requires it.
|
|
137
|
-
`--theme` defaults to that map's declared default. `--inspection` adds opt-in, read-only
|
|
138
|
-
physical-output provenance to the report. Its physical layer IDs and indexes are diagnostic
|
|
139
|
-
observations only: they are not stable application or authoring targets, and no semantic operation
|
|
140
|
-
accepts them. The JSON document has this stable projection:
|
|
141
|
-
|
|
142
|
-
```json
|
|
143
|
-
{
|
|
144
|
-
"schemaVersion": 1,
|
|
145
|
-
"command": "explain",
|
|
146
|
-
"ok": true,
|
|
147
|
-
"selection": {"map": "madrid", "theme": "dark"},
|
|
148
|
-
"authoringManifestSchemaVersion": 2,
|
|
149
|
-
"compilation": {"ok": true, "diagnostics": [], "report": {}},
|
|
150
|
-
"diagnostics": []
|
|
151
|
-
}
|
|
152
|
-
```
|
|
92
|
+
Inspector shares a camera across side-by-side, split, overlay, or blink views. Its inspection panels
|
|
93
|
+
show bounded feature and compiler information; invalid edits keep the last valid generation.
|
|
94
|
+
**Capture as reference** saves a starting point. After editing, **Capture & compare** reuses its
|
|
95
|
+
camera and frame to review the change. The selected reference lasts for this browser session.
|
|
153
96
|
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
config options and workspace options cannot be mixed.
|
|
97
|
+
**Capture** renders the compiled map at the current camera and the fixed dimensions in **Capture settings** (the sliders icon).
|
|
98
|
+
Temporary preview visibility switches are excluded. **Captures** retains local evidence across
|
|
99
|
+
reloads; **Compare** checks saved captures before offering a before/after slider and pixel difference.
|
|
100
|
+
Each capture has a **Delete** action with confirmation that removes its saved image and record from this project.
|
|
101
|
+
It reports incompatible cameras, frames, renderers or data without presenting pixel metrics.
|
|
160
102
|
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
informational, so a non-empty diff still exits successfully. Selection, load, validation, asset, or
|
|
164
|
-
compilation failures leave stdout empty and emit one safe structured document on stderr.
|
|
103
|
+
**Copy context for AI** exports the selected feature, semantic configuration paths, camera, revision
|
|
104
|
+
and reproducible commands. An agent can also read the active browser context:
|
|
165
105
|
|
|
166
|
-
|
|
106
|
+
```sh
|
|
107
|
+
npx tileflow inspect session --url http://127.0.0.1:3333 --json
|
|
108
|
+
```
|
|
167
109
|
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
| Semantic language | `language manifest`, `language schema` |
|
|
171
|
-
| Map authoring | `init`, `validate`, `inspect`, `explain`, `semantic-diff`, `build`, `preview` (`dev` alias) |
|
|
172
|
-
| Local evidence | `setup capture`, `capture`, `visual compare`, `visual analyze`, `visual diff`, `visual update` |
|
|
173
|
-
| Data and assets | `tileset inspect`, `tileset publish/list/status/purge`, `inspect features`, `icons list/diff` |
|
|
174
|
-
| Account | `login`, `logout`, `whoami` |
|
|
175
|
-
| Hosted delivery | `deploy`, `status` |
|
|
110
|
+
Use the origin printed by your running preview. This reads browser observations, including their
|
|
111
|
+
age and stale flag; exact source lines and token ownership are not inferred.
|
|
176
112
|
|
|
177
|
-
|
|
178
|
-
|
|
113
|
+
`--api-base-url` or `TILEFLOW_API_URL` changes the API origin used by the official preview sources.
|
|
114
|
+
It does not change the map's authored data ownership or publish any data.
|
|
179
115
|
|
|
180
|
-
|
|
181
|
-
internal application boundary. It is not part of the ordinary workflow or the product catalog.
|
|
116
|
+
## Capture a reproducible scene
|
|
182
117
|
|
|
183
|
-
|
|
118
|
+
Captures return reusable IDs. Compare two saved renders with
|
|
119
|
+
`tileflow compare --before <id> --after <id> --json`; no config, browser, or network is needed.
|
|
184
120
|
|
|
185
|
-
|
|
186
|
-
shell into its versioned per-user cache:
|
|
121
|
+
Add a concrete-theme scene to `tileflow.config.ts`:
|
|
187
122
|
|
|
188
|
-
|
|
189
|
-
npx tileflow capture \
|
|
190
|
-
--map madrid \
|
|
191
|
-
--theme dark \
|
|
192
|
-
--center=-3.69201,40.40871 \
|
|
193
|
-
--zoom=16.15 \
|
|
194
|
-
--width=1200 \
|
|
195
|
-
--height=1200 \
|
|
196
|
-
--json
|
|
197
|
-
```
|
|
198
|
-
|
|
199
|
-
The successful entry includes a normalized `definition` with its concrete `theme`, `camera`,
|
|
200
|
-
`viewport`, and default map `target`. Copy it under a chosen `scenes.<name>` key; the CLI never rewrites
|
|
201
|
-
executable TypeScript config. Then commit the bounded scene so agents and CI render the same map,
|
|
202
|
-
camera, and viewport:
|
|
123
|
+
<!-- docs:check -->
|
|
203
124
|
|
|
204
125
|
```ts
|
|
205
126
|
import {defineMap} from '@tileflow/core';
|
|
@@ -207,7 +128,6 @@ import {streets} from '@tileflow/maps';
|
|
|
207
128
|
|
|
208
129
|
export default defineMap({
|
|
209
130
|
id: 'madrid',
|
|
210
|
-
name: 'Madrid',
|
|
211
131
|
version: 1,
|
|
212
132
|
extends: streets,
|
|
213
133
|
scenes: {
|
|
@@ -216,547 +136,224 @@ export default defineMap({
|
|
|
216
136
|
camera: {type: 'center', center: [-3.7038, 40.4168], zoom: 12},
|
|
217
137
|
viewport: {width: 1280, height: 800, dpr: 1},
|
|
218
138
|
},
|
|
219
|
-
'madrid-product': {
|
|
220
|
-
theme: 'dark',
|
|
221
|
-
camera: {type: 'center', center: [-3.7038, 40.4168], zoom: 12},
|
|
222
|
-
viewport: {width: 390, height: 844, dpr: 2},
|
|
223
|
-
target: {
|
|
224
|
-
kind: 'application',
|
|
225
|
-
path: '/maps/madrid',
|
|
226
|
-
captureId: 'product-map',
|
|
227
|
-
},
|
|
228
|
-
},
|
|
229
139
|
},
|
|
230
140
|
});
|
|
231
141
|
```
|
|
232
142
|
|
|
233
|
-
`scenes` is tooling metadata owned by this map. It is not inherited and does not enter the
|
|
234
|
-
cartographic compiler; tooling supplies the exported map ID when it normalizes a scene internally.
|
|
235
|
-
Every scene stores a concrete theme; omission and browser-only `system` are invalid.
|
|
236
|
-
|
|
237
|
-
### Live comparison workbench
|
|
238
|
-
|
|
239
|
-
Use the ordinary preview server with a right-hand selection to compare two maps or themes while
|
|
240
|
-
authoring:
|
|
241
|
-
|
|
242
143
|
```sh
|
|
243
|
-
|
|
244
|
-
npx tileflow preview \
|
|
245
|
-
--map harad --theme light \
|
|
246
|
-
--against-map ferraris --against-theme light
|
|
247
|
-
|
|
248
|
-
# Or compare against another config.
|
|
249
|
-
npx tileflow preview \
|
|
250
|
-
--config ./candidate.config.ts --map candidate \
|
|
251
|
-
--against-config ./reference.config.ts --against-map reference
|
|
144
|
+
npx tileflow capture madrid-desktop --json
|
|
252
145
|
```
|
|
253
146
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
Enable **Inspect** and click a rendered feature to see its bounded feature data, paint/layout values,
|
|
261
|
-
zoom-curve samples, and compiler contribution sidecar. The sprite gallery shows the compiled atlas,
|
|
262
|
-
not source directories. **Copy scene** produces a concrete-theme scene for the current camera and
|
|
263
|
-
viewport; **Copy command** produces the corresponding capture command. The inspector sidecar exists
|
|
264
|
-
only in memory in this local workbench and is not emitted by `tileflow build`.
|
|
147
|
+
The first capture may install Playwright's exact pinned Chromium headless shell. `tileflow setup
|
|
148
|
+
capture` provisions it ahead of time; a system Chrome installation is not a substitute. Scenes
|
|
149
|
+
belong to their map and do not inherit. `system` and an omitted scene theme are invalid.
|
|
150
|
+
Coordinates are `[longitude, latitude]`; viewport dimensions are CSS pixels and `dpr` determines
|
|
151
|
+
physical image size.
|
|
265
152
|
|
|
266
|
-
|
|
153
|
+
One-off capture accepts camera, size, and theme flags and returns a normalized scene definition.
|
|
154
|
+
Commit that definition deliberately; the CLI does not rewrite executable config. Capture receipts
|
|
155
|
+
record runtime and data identity. Remote dependencies can change, so a successful render is not a
|
|
156
|
+
promise of identical pixels on every platform or future run.
|
|
267
157
|
|
|
268
|
-
For
|
|
158
|
+
For application capture, define an application target with its route and optional `captureId` in
|
|
159
|
+
the scene. Start the application's normal server in one terminal. In another terminal, run:
|
|
269
160
|
|
|
270
161
|
```sh
|
|
271
|
-
npx tileflow
|
|
272
|
-
--config ./candidate.config.ts --map candidate --theme light \
|
|
273
|
-
--against-config ./reference.config.ts --against-map reference --against-theme light \
|
|
274
|
-
--center=-3.7038,40.4168 --zooms=12,14,16 \
|
|
275
|
-
--width=1200 --height=800 --dpr=1 --region=0,0,1200,760 \
|
|
276
|
-
--diff --open --json
|
|
162
|
+
npx tileflow capture madrid-product --url http://127.0.0.1:3000/maps/madrid --json
|
|
277
163
|
```
|
|
278
164
|
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
`.tileflow/comparisons/compare.html`, a machine-readable sibling JSON document, and PNG/receipt-v4
|
|
284
|
-
pairs below `compare.assets`; `--diff` adds a highlighted diff when identities are comparable. The
|
|
285
|
-
HTML embeds every image, uses a restrictive CSP, performs no network request, and offers the same
|
|
286
|
-
side-by-side, wipe, overlay, and blink review modes.
|
|
287
|
-
|
|
288
|
-
`--region=x,y,width,height` selects one shared physical-pixel rectangle for compact appearance
|
|
289
|
-
profiles. Review JSON uses the explicit signed direction `rightMinusLeft`; the region does not crop
|
|
290
|
-
captures, changed-pixel metrics, or diffs.
|
|
291
|
-
|
|
292
|
-
Stdout and the sibling JSON use the same schema-version-1 `visual.compare` document: concrete
|
|
293
|
-
left/right selections, shared camera and viewport, zoom-sorted rows with Review v1 documents and
|
|
294
|
-
relative artifact paths, report/document paths, and sorted warnings. This document and the watch
|
|
295
|
-
NDJSON described below are versioned compatibility boundaries.
|
|
296
|
-
|
|
297
|
-
The asset directory also contains a bounded schema-version-1
|
|
298
|
-
`.tileflow-visual-compare.json` inventory. It assigns ownership only to the listed sibling assets
|
|
299
|
-
and records each exact SHA-256. A later successful transaction removes stale generated rows or
|
|
300
|
-
diffs only when that valid prior inventory names them, preserves unrelated files, and refuses a
|
|
301
|
-
managed asset that has been modified, replaced by a symlink/non-file, or grown beyond its bound.
|
|
302
|
-
`--force` does not weaken those ownership checks. The inventory is capped at 64 KiB and the complete
|
|
303
|
-
report, JSON, inventory, PNGs, receipts, stale cleanup, and optional diffs commit or roll back as one
|
|
304
|
-
file transaction.
|
|
305
|
-
|
|
306
|
-
Different pixels are ordinary review evidence and exit 0. A frame, dimension, runtime, or exact
|
|
307
|
-
data mismatch exits 1 and suppresses pixel metrics because the images are not comparable.
|
|
308
|
-
`--allow-data-mismatch` keeps a data-mismatch report inspectable with exit 0, but does not invent
|
|
309
|
-
pixel metrics. `--watch` observes both configs, cancels stale renders, preserves the last complete
|
|
310
|
-
report through invalid edits, and emits deterministic NDJSON with `--json`. An explicit report path
|
|
311
|
-
requires `--force` in watch mode; the managed default path is safely replaceable.
|
|
312
|
-
|
|
313
|
-
Watch events are `watching`, `building`, `invalid`, `recovered`, `generation-complete`, `failed`,
|
|
314
|
-
and `stopped`, with monotonic comparison generations and source-side generations where applicable.
|
|
315
|
-
Without `--allow-data-mismatch`, an incompatible generation emits `failed`, does not replace the
|
|
316
|
-
last complete report, and remains an unresolved failure; an allowed data mismatch emits
|
|
317
|
-
`generation-complete` but still has no pixel metrics. An orderly stop exits 0 only after at least
|
|
318
|
-
one complete generation and no unresolved invalid or failed state; otherwise it exits 1.
|
|
319
|
-
|
|
320
|
-
Render one checkpoint, or recapture after every edit:
|
|
165
|
+
This command assumes a committed `madrid-product` application scene and a matching Tileflow component
|
|
166
|
+
on that route. Capture does not start the server or discover ports. It accepts loopback HTTP(S),
|
|
167
|
+
selects exactly one target, verifies the concrete theme, and waits for the component's idle marker.
|
|
168
|
+
Do not run a separate `tileflow preview` server beside the application.
|
|
321
169
|
|
|
322
|
-
|
|
323
|
-
npx tileflow capture madrid-desktop --json
|
|
324
|
-
npx tileflow capture --all --json
|
|
325
|
-
npx tileflow capture madrid-desktop --watch --json
|
|
326
|
-
```
|
|
170
|
+
## Render a timed shot
|
|
327
171
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
If an edit is invalid, the last good image remains in place and capture resumes automatically after
|
|
332
|
-
the fix. Stop watch mode with `Ctrl+C`. It accepts named committed scenes or `--all`, not exploratory
|
|
333
|
-
camera options.
|
|
334
|
-
|
|
335
|
-
Standalone scenes need no app server, account, API key, MCP service, system Chrome, or visible
|
|
336
|
-
window. The first command—or the first capture—may provision Playwright's pinned Chromium headless
|
|
337
|
-
shell in its versioned per-user cache. `--no-browser-install` makes a prepared/offline environment
|
|
338
|
-
strict. Tileflow never falls back to a system browser or packages the browser in npm.
|
|
339
|
-
|
|
340
|
-
For prepared or offline CI, install ahead of time with
|
|
341
|
-
`npx tileflow setup capture --json`. Use `setup capture --no-browser-install` or
|
|
342
|
-
`capture --no-browser-install` as an enforcement check that the exact shell is already cached.
|
|
343
|
-
|
|
344
|
-
For an application scene, its route and component props must render the committed camera. Tileflow
|
|
345
|
-
uses the camera in scene identity but does not mutate arbitrary application map state.
|
|
346
|
-
|
|
347
|
-
One-shot success JSON is one deterministic schema-version-1 document plus one newline. It contains
|
|
348
|
-
sorted scene/map/theme/target entries, relative output and receipt paths, image hash/dimensions/DPR,
|
|
349
|
-
renderer identity, remote-dependency state, and warnings; it contains no image bytes, credential,
|
|
350
|
-
origin, absolute path, user, or timestamp. Managed output is an atomic pair under
|
|
351
|
-
`.tileflow/captures/<scene>.png` and `<scene>.receipt.json`. `tileflow init` ignores managed captures
|
|
352
|
-
and `.tileflow/diffs` when creating a new `.gitignore`. Explicit output replacement requires
|
|
353
|
-
`--force`; symlinks and path escapes fail closed.
|
|
354
|
-
|
|
355
|
-
Each written receipt uses capture schema v4 and records the concrete theme. A Tileflow World
|
|
356
|
-
capture resolves its TileJSON once for
|
|
357
|
-
the whole capture session and records the exact `world-v1` release plus descriptor, archive, data
|
|
358
|
-
contract, and product-contract hashes. All selected scenes and retries therefore use one immutable
|
|
359
|
-
World release even if `current` moves while the command is running.
|
|
360
|
-
|
|
361
|
-
One-shot `--json` failures leave stdout empty and write exactly one deterministic failure document
|
|
362
|
-
to stderr with `code`, `phase`, bounded diagnostics, and optional origin-only resource metadata.
|
|
363
|
-
|
|
364
|
-
Watch JSON is NDJSON with monotonic `building`, `invalid`, `recovered`, `captured`, `failed`, and
|
|
365
|
-
`stopped` generation events. It watches config, transitive local imports, and effective icon/font
|
|
366
|
-
files, preserves the last good capture through invalid edits, cancels stale work, and reuses one
|
|
367
|
-
headless Browser. An orderly stop exits 0 only after a successful capture with no unresolved
|
|
368
|
-
terminal failure.
|
|
369
|
-
|
|
370
|
-
### Capture through the real application
|
|
371
|
-
|
|
372
|
-
Application scenes use the app's existing Vite, Next.js, Webpack, or custom loopback server. Start
|
|
373
|
-
only that normal server; Tileflow does not run a package script, scan ports, or start
|
|
374
|
-
`tileflow preview`:
|
|
172
|
+
Commit a capture shot
|
|
173
|
+
under `shots` on the same map: a concrete theme, a viewport, and two or more center-camera
|
|
174
|
+
keyframes, optionally with a theme blend. Then render it:
|
|
375
175
|
|
|
376
176
|
```sh
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
npx tileflow capture madrid-product --json
|
|
177
|
+
npx tileflow capture --shot dusk-flyover --json
|
|
178
|
+
npx tileflow capture --shot dusk-flyover --format frames --out-dir evidence --json
|
|
380
179
|
```
|
|
381
180
|
|
|
382
|
-
The
|
|
383
|
-
`
|
|
384
|
-
`
|
|
385
|
-
the
|
|
386
|
-
|
|
387
|
-
credential-free loopback HTTP(S) without fragments. Each navigation uses a fresh context without a
|
|
388
|
-
reused profile, cookies, local storage, or service workers.
|
|
181
|
+
The first command writes `.tileflow/captures/shots/dusk-flyover.webm`; the second writes
|
|
182
|
+
`evidence/dusk-flyover/frame-0000.png` and the following frames. Each output has a sibling
|
|
183
|
+
`.receipt.json` shot receipt. Repeat `--shot` or use `--all-shots` to render several shots; `--out`
|
|
184
|
+
names the `.webm` file or frame directory of a single shot. Every frame waits for the map to be
|
|
185
|
+
ready, so a slow machine renders more slowly without dropping frames.
|
|
389
186
|
|
|
390
|
-
|
|
187
|
+
## Review pixels without accepting changes
|
|
391
188
|
|
|
392
|
-
|
|
189
|
+
After reviewing a render, create its baseline. Compare subsequent renders separately:
|
|
393
190
|
|
|
394
191
|
```sh
|
|
395
|
-
npx tileflow visual
|
|
396
|
-
|
|
192
|
+
npx tileflow visual update madrid-desktop --baseline-dir test/visual-baselines --json
|
|
193
|
+
npx tileflow visual diff madrid-desktop --baseline-dir test/visual-baselines --fail-on changed --json
|
|
397
194
|
```
|
|
398
195
|
|
|
399
|
-
`visual
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
mean channel difference, a high-contrast `.diff.png`, and signed
|
|
403
|
-
`appearance.actualMinusReference` luminance, OKLab, edge-density, and local-contrast evidence. The
|
|
404
|
-
optional region affects only those appearance metrics. The reference PNG is never modified or
|
|
405
|
-
treated as a baseline.
|
|
196
|
+
Only `visual update` changes baseline PNG/receipt pairs. `visual diff` writes working evidence, not
|
|
197
|
+
approval. Changed pixels normally exit 0; `--fail-on changed` exits 2. Missing or incompatible
|
|
198
|
+
baselines and operational failures exit 1. Never run `visual update` automatically to make CI pass.
|
|
406
199
|
|
|
407
|
-
|
|
408
|
-
|
|
200
|
+
Use `visual analyze <scene> --reference <png>` for an external screenshot without a Tileflow
|
|
201
|
+
receipt. Use `visual compare` for an authenticated two-style review with matched camera, viewport,
|
|
202
|
+
renderer, and data identity. Neither operation approves a baseline. Capture watch mode emits NDJSON
|
|
203
|
+
generation events rather than a single JSON document.
|
|
409
204
|
|
|
410
|
-
|
|
411
|
-
# Save the reviewed current render as the expected baseline.
|
|
412
|
-
npx tileflow visual update madrid-desktop \
|
|
413
|
-
--baseline-dir test/visual-baselines --json
|
|
414
|
-
|
|
415
|
-
# Compare a fresh render without changing the baseline.
|
|
416
|
-
npx tileflow visual diff madrid-desktop \
|
|
417
|
-
--baseline-dir test/visual-baselines --json
|
|
205
|
+
Use `tileflow capture --help` and `tileflow compare --help` for installed command options.
|
|
418
206
|
|
|
419
|
-
|
|
420
|
-
npx tileflow visual diff --all \
|
|
421
|
-
--baseline-dir test/visual-baselines --json
|
|
422
|
-
|
|
423
|
-
# In CI, return exit 2 when the pixels have changed.
|
|
424
|
-
npx tileflow visual diff madrid-desktop \
|
|
425
|
-
--baseline-dir test/visual-baselines --fail-on changed --json
|
|
426
|
-
```
|
|
207
|
+
## Publish data and deploy a map
|
|
427
208
|
|
|
428
|
-
|
|
429
|
-
|
|
209
|
+
Hosted writes require authorization. For local development, `login` stores a personal session;
|
|
210
|
+
for CI, provide an appropriately scoped key through the secret environment variable
|
|
211
|
+
`TILEFLOW_API_KEY`. CI does not fall back to a saved personal login. Never put a key in a config,
|
|
212
|
+
browser bundle, copied prompt, or command-line argument.
|
|
430
213
|
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
`visual diff` may replace those working files on each run, but it never changes the baseline. This
|
|
435
|
-
separation prevents a check from silently accepting the change it was meant to reveal.
|
|
214
|
+
If `login` finds the older local file containing an API key and API URL, it replaces that file only
|
|
215
|
+
after a new account login succeeds. The old API key is not converted into an account session.
|
|
216
|
+
Unrecognized local files are left untouched and stop login before authorization begins.
|
|
436
217
|
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
218
|
+
For commands accepting an API key, `--api-key` takes precedence over `TILEFLOW_API_KEY`;
|
|
219
|
+
only an absent key allows a saved personal session. An empty, invalid, expired or revoked key
|
|
220
|
+
fails without switching identities. `--api-url` takes precedence over `TILEFLOW_API_URL`.
|
|
221
|
+
This selection also applies to `models`, `tileset`, Icon Set commands and Map status. Keys
|
|
222
|
+
never appear in help output. When a personal account can manage several Teams, pass an
|
|
223
|
+
explicit `--team @team`; a Team key already selects its Team.
|
|
442
224
|
|
|
443
|
-
|
|
444
|
-
`--
|
|
225
|
+
`login` always authorizes a personal session through the dashboard, even when an API key is
|
|
226
|
+
configured. `--no-browser` prints the URL without prompting to open it. Polling retries temporary
|
|
227
|
+
connection/server failures with bounded backoff and honors rate-limit waits until the authorization
|
|
228
|
+
expires. Denied or invalid authorizations stop immediately. A new session is validated and saved
|
|
229
|
+
before the previous session for that API origin is revoked. Failed validation or persistence
|
|
230
|
+
attempts to revoke the newly issued session and preserves the saved login. If cleanup cannot
|
|
231
|
+
reach the server, the CLI explains that the session must be revoked in Dashboard settings.
|
|
445
232
|
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
## Inspect vector features
|
|
451
|
-
|
|
452
|
-
See which bounded source features the exported map sees near a camera before tuning taxonomy,
|
|
453
|
-
density, or labels:
|
|
454
|
-
|
|
455
|
-
```sh
|
|
456
|
-
npx tileflow inspect features \
|
|
457
|
-
--center=-3.6927512,40.4086555 --zoom=16 \
|
|
458
|
-
--layers=poi --properties=name,category,type,icon,filter_rank,size_rank --json
|
|
459
|
-
```
|
|
460
|
-
|
|
461
|
-
The command supports HTTP(S) TileJSON/vector sources and returns only requested properties plus
|
|
462
|
-
geometry summaries in stable order. Viewport, tiles, bytes, scanned/returned features, names, and
|
|
463
|
-
timeouts are bounded. Safe provenance includes origins, a query-free TileJSON path, and configured
|
|
464
|
-
source revision or `null`; credentials, URL queries, hidden properties, response bodies, and
|
|
465
|
-
absolute paths are omitted. It is read-only apart from executable config's own possible side
|
|
466
|
-
effects and removes `TILEFLOW_API_KEY` before loading config.
|
|
467
|
-
|
|
468
|
-
## Hosted authentication and deploy
|
|
469
|
-
|
|
470
|
-
Hosted writes have two independent authorization paths:
|
|
471
|
-
|
|
472
|
-
- Personal developer session: run `npx tileflow login` once for a
|
|
473
|
-
Tileflow API origin. Login authenticates the account and selects no Map.
|
|
474
|
-
Map commands exchange it for a brief Map capability; tileset commands use a separate Team data
|
|
475
|
-
capability.
|
|
476
|
-
- CI key: create a dashboard `CI deploy` key, store it as
|
|
477
|
-
`TILEFLOW_API_KEY`, and let the repository workflow deploy without a local login. The server
|
|
478
|
-
binds that key to exactly one Map.
|
|
479
|
-
|
|
480
|
-
Hosted control-plane requests stay pinned to the configured HTTP(S) origin, apply a hard bounded
|
|
481
|
-
timeout, and stream at most 1 MiB of response data. CLI diagnostics never echo an untrusted remote
|
|
482
|
-
response body or bearer credential.
|
|
483
|
-
|
|
484
|
-
Inspect the account, then target the Map shown in the dashboard:
|
|
233
|
+
`logout` revokes only the saved personal session for the selected API origin. If server revocation
|
|
234
|
+
fails, local access is preserved so logout can be retried. API keys remain independent: an API key
|
|
235
|
+
in the environment still authorizes resource commands after logout. Personal session tokens stay
|
|
236
|
+
in the local auth file with restricted permissions; this CLI does not use an OS credential store.
|
|
485
237
|
|
|
486
238
|
```sh
|
|
239
|
+
npx tileflow login
|
|
487
240
|
npx tileflow whoami --json
|
|
241
|
+
npx tileflow deploy --origin https://www.example.com
|
|
488
242
|
npx tileflow deploy --map-id map_AbCdEfGhIjKlMnOp
|
|
489
243
|
npx tileflow status --map-id map_AbCdEfGhIjKlMnOp
|
|
490
|
-
npx tileflow logout
|
|
491
244
|
```
|
|
492
245
|
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
Map ID in the deploy action. If the config contains several maps, select the authored map explicitly:
|
|
246
|
+
Without `--map-id`, a logged-in `deploy` first creates the Map in the Team you administer (it asks,
|
|
247
|
+
or takes `--team @team`, when several qualify) with the browser access you choose: exact origins
|
|
248
|
+
with `--origin`, or `--any-website`. It prints the Map ID to use for later deploys;
|
|
249
|
+
`tileflow maps create` creates the Map without deploying. The Map ID is a public identifier, not a
|
|
250
|
+
credential or the portable `id` in your config. CI always deploys an existing Map with a deploy key
|
|
251
|
+
for that destination. `logout` removes the saved personal session.
|
|
500
252
|
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
```
|
|
253
|
+
Deploy sends compact web cartography and data requirements, retaining concrete native artifacts.
|
|
254
|
+
The web budget is 2,000,000 UTF-8 bytes for the whole family; icon receipts and native payloads
|
|
255
|
+
have separate bounds.
|
|
256
|
+
Oversized maps fail before uploads with their size and limit; no automatic simplification occurs.
|
|
506
257
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
258
|
+
Deploy publishes the compiled concrete-theme family and managed icon assets; it does not ask the
|
|
259
|
+
server to compile TypeScript. Repeating an unchanged deployment reuses its version. Build writers
|
|
260
|
+
refuse to overwrite hosted manifests by default, and deploy refuses to replace a self-hosted
|
|
261
|
+
manifest without explicit authorization. Keep separate outputs, or use the documented overwrite
|
|
262
|
+
option only for an intentional migration.
|
|
512
263
|
|
|
513
|
-
|
|
514
|
-
it carries no Map authority. Inspect and preview remain account-free:
|
|
264
|
+
Data publication is separate from map deployment:
|
|
515
265
|
|
|
516
266
|
```sh
|
|
517
267
|
npx tileflow tileset inspect ./data/stores.pmtiles --json
|
|
518
|
-
npx tileflow tileset
|
|
519
|
-
--include-values category,status --json
|
|
520
|
-
npx tileflow tileset publish ./data/stores.pmtiles \
|
|
521
|
-
--id stores --team @acme --attribution 'Store data © Example' --json
|
|
522
|
-
npx tileflow tileset list --team @acme --json
|
|
268
|
+
npx tileflow tileset publish ./data/stores.pmtiles --id stores --team @acme --attribution 'Store data © Example' --json
|
|
523
269
|
npx tileflow tileset status stores --team @acme --json
|
|
524
270
|
```
|
|
525
271
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
32 selected fields, and 256 characters per string. `--no-sample` returns only authoritative metadata
|
|
531
|
-
and cannot be combined with value inspection. Directory traversal recomputes addressed-tile and
|
|
532
|
-
tile-entry counts; the header's tile-content count is reported only as a nullable declaration and is
|
|
533
|
-
not treated as authority.
|
|
534
|
-
|
|
535
|
-
`publish --id` names a Team-local logical resource; Tileflow owns its opaque delivery ID. The
|
|
536
|
-
command validates the archive locally before authentication, hashes it in fixed 16 MiB parts, then
|
|
537
|
-
uploads at most four parts concurrently without buffering the complete file. Interrupted sessions
|
|
538
|
-
remain resumable for 24 hours: rerunning the same command reconciles server receipts and transfers
|
|
539
|
-
only missing parts. Normal Queue initialization is polled for at most two minutes before the command
|
|
540
|
-
returns a resumable availability error. Retryable transfer failures receive fresh short-lived authorization; a changed
|
|
541
|
-
local file stops before completion. Free accepts versions through exactly 2,000,000,000 bytes and
|
|
542
|
-
Starter through exactly 4,000,000,000 bytes, subject to the Team's hosted-storage capacity.
|
|
543
|
-
|
|
544
|
-
Publication completes only after server-side integrity and PMTiles validation. A compatible new
|
|
545
|
-
version becomes current at the same stable TileJSON and tile URLs, so newly resolved browser
|
|
546
|
-
requests see it without creating a Map deployment. Purge requires `--confirm <exact-id>` and fails
|
|
547
|
-
with bounded dependency context while any retained Map deployment uses the resource. Automation may set a Team data
|
|
548
|
-
`TILEFLOW_API_KEY`; that key selects its Team, so commands omit `--team` and never load account
|
|
549
|
-
state.
|
|
550
|
-
|
|
551
|
-
`tileset publish --json` emits schema version 2 with the Team selector when known, logical and
|
|
552
|
-
opaque tileset identities, immutable version ID and number, exact byte count, content-hash
|
|
553
|
-
algorithm/hash, final state, and `changed` or `unchanged` publication result. It never emits the
|
|
554
|
-
local path, upload session, storage key, signed URL, ETag, credential, or retry details.
|
|
555
|
-
|
|
556
|
-
An explicit key or `TILEFLOW_API_KEY` never uses the saved account session. The deploy API rejects a
|
|
557
|
-
`--map-id` that does not match the key. Read-only hosted icon comparison validates the same binding
|
|
558
|
-
before loading its baseline.
|
|
559
|
-
|
|
560
|
-
The CI key grants only `styles:write` and `status:read`. It cannot upload
|
|
561
|
-
datasets or render images. Give it an expiration, rotate the repository secret
|
|
562
|
-
before it expires, and avoid non-expiring CI keys.
|
|
563
|
-
|
|
564
|
-
Detected CI never falls back to the credential saved by `tileflow login`: if
|
|
565
|
-
`TILEFLOW_API_KEY` is absent, deploy stops before loading config or making a
|
|
566
|
-
request. Once captured, the key is hidden from `process.env` and `--api-key` is removed from the
|
|
567
|
-
temporary `process.argv` view before the CLI imports executable `tileflow.config.ts`; both process
|
|
568
|
-
surfaces are restored after the protected operation. Every config-aware command uses the same
|
|
569
|
-
scope, including validate, build, dev/watch, capture, visual, inspect, icon inspection, and deploy.
|
|
570
|
-
This is defense in depth, not a sandbox; deploy only reviewed repository code on a trusted runner,
|
|
571
|
-
and do not pass keys through the `--api-key` command line in CI.
|
|
572
|
-
|
|
573
|
-
The [deploy documentation](https://tileflow.dev/docs/deploy) contains copyable
|
|
574
|
-
GitHub Actions and GitLab CI workflows. Both use `npm ci`, the committed
|
|
575
|
-
lockfile, and the repository-local CLI. GitHub exposes the key only to its deploy
|
|
576
|
-
step. GitLab variables are job-scoped, so its example validates in a keyless job
|
|
577
|
-
and deploys in a protected `production` job; the locked install and runner are
|
|
578
|
-
part of that trusted job boundary. Both serialize publications and intentionally
|
|
579
|
-
omit path filters because `tileflow.config.ts` can import arbitrary repository
|
|
580
|
-
files.
|
|
581
|
-
|
|
582
|
-
The CLI records bounded private provenance for GitHub Actions, GitLab CI,
|
|
583
|
-
generic CI, and local runs. These provider fields are descriptive client
|
|
584
|
-
reports, not OIDC attestations. Provider values can be overridden with:
|
|
585
|
-
|
|
586
|
-
```txt
|
|
587
|
-
TILEFLOW_DEPLOY_REPOSITORY
|
|
588
|
-
TILEFLOW_DEPLOY_REVISION
|
|
589
|
-
TILEFLOW_DEPLOY_REF
|
|
590
|
-
TILEFLOW_DEPLOY_RUN_ID
|
|
591
|
-
TILEFLOW_DEPLOY_RUN_URL
|
|
592
|
-
```
|
|
272
|
+
Use your own file, Team selector, and attribution. Inspection is account-free. Publication validates
|
|
273
|
+
and uploads a managed dataset using Team data authority, not a map-only deploy key. Interrupted
|
|
274
|
+
uploads are resumable; a completed version becomes current at stable delivery URLs. Purge is
|
|
275
|
+
explicit, requires confirmation, and can be blocked by retained deployment dependencies.
|
|
593
276
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
environment are never logged.
|
|
597
|
-
|
|
598
|
-
A separate app-build step is absent from the minimal workflows. Self-hosted build and deploy emit the same
|
|
599
|
-
runtime manifest version 1 shape; Hosted fields are optional identity metadata on its map/theme
|
|
600
|
-
entries. Filesystem build writers refuse to replace a manifest carrying Hosted metadata by default,
|
|
601
|
-
and deploy refuses to replace a purely local manifest. Prefer `emitBuildArtifacts: false` or
|
|
602
|
-
separate output paths when the app deliberately packages a deploy manifest. The explicit
|
|
603
|
-
`overwriteHostedManifest: true` build option and
|
|
604
|
-
`tileflow deploy --overwrite-self-hosted-manifest` flag authorize that destination replacement. A
|
|
605
|
-
retry of the same compiled theme family reuses its deployment version and prints `Unchanged`;
|
|
606
|
-
changed cartography prints `Published` with a new version. Allowed websites is managed separately
|
|
607
|
-
in Tileflow and is never read from repository config. The
|
|
608
|
-
fingerprint binds resource references, not the changing bytes behind referenced
|
|
609
|
-
glyph or sprite URLs. Every theme of one logical map publishes atomically; separate maps can still
|
|
610
|
-
partially succeed when no remote batch release is used.
|
|
611
|
-
|
|
612
|
-
All config, theme-style, icon, and compatibility preflight happens before the first style write. After
|
|
613
|
-
that boundary the current Hosted API has no batch commit across repository-internal orchestration:
|
|
614
|
-
one singular config can publish before a later config fails. The orchestrator then leaves the
|
|
615
|
-
previous local manifest untouched, reports which publications succeeded, and tells the operator to
|
|
616
|
-
retry; idempotent publication converges on that retry. The local manifest
|
|
617
|
-
writer uses a durable same-directory temporary followed by direct rename and directory sync, so
|
|
618
|
-
readers see either the previous or next complete manifest. Multi-file artifact writers remain
|
|
619
|
-
rollback-capable sets. Neither mechanism is a remote transaction or can make several API writes
|
|
620
|
-
all-or-none.
|
|
621
|
-
|
|
622
|
-
Deploy treats the locally compiled MapLibre Style family as one logical-map artifact. The request
|
|
623
|
-
contains an exact `styles[theme]` collection, per-theme canonical SHA-256 identities in the build
|
|
624
|
-
manifest, only bounded hosting policy that does not belong in MapLibre itself, and the exact managed
|
|
625
|
-
icon-package identity when the family has one. Delivery
|
|
626
|
-
policy is not inherited with cartographic fields. Deploy does not serialize the module
|
|
627
|
-
configuration, send a public `tileset` selector, or ask the hosted API to compile the map again.
|
|
628
|
-
Hosted publication currently requires Tileflow World; `vectorTiles()` remains available for local
|
|
629
|
-
builds and previews but fails deploy before any remote write. The API binds recognized
|
|
630
|
-
Tileflow-owned world and terrain URLs to its generated map ID. A successful response must return
|
|
631
|
-
exactly the submitted theme names and a hosted Style URL for each. Deploy writes strict runtime
|
|
632
|
-
manifest version 1 with stable theme URLs, `colorScheme`, content revision, optional font faces and
|
|
633
|
-
style IDs, rather than duplicating dataset configuration. No older manifest is normalized.
|
|
634
|
-
|
|
635
|
-
For a map with `icons: ['./icons']`, hosted validation compiles the local SVG/PNG/JPEG/WebP files
|
|
636
|
-
without a key. Ordered directories apply left to right and later exact IDs replace earlier files.
|
|
637
|
-
Deploy uploads the four generated sprite files before its first style write and reuses
|
|
638
|
-
byte-identical packages by content hash. Source icons and absolute paths remain local; generated
|
|
639
|
-
atlas bytes and sorted icon names are public. Each hosted package is limited to 256 icons and 8 MiB
|
|
640
|
-
generated bytes as a processing envelope. There is no package-count quota; physically retained
|
|
641
|
-
generated packages share the organization's 5/10-GB hosted-storage pool with retained PMTiles,
|
|
642
|
-
remain protected by deployment/library references, and otherwise enter the technical orphan grace
|
|
643
|
-
before deletion. Upload success must confirm the submitted `contentHash`, exact icon count, exact
|
|
644
|
-
generated byte total, one opaque `icp_<id>`, and the corresponding query-free
|
|
645
|
-
`/sprites/<id>/sprite` URL. The CLI rejects any missing or divergent field before using that URL.
|
|
646
|
-
|
|
647
|
-
Hosted deploy currently rejects local or package-owned web fonts before authentication or remote
|
|
648
|
-
writes. Use self-hosted delivery or an explicit public glyph provider. Enabling managed font bundles
|
|
649
|
-
requires a separately deployed ownership, quota, retention, and immutable-delivery contract.
|
|
650
|
-
|
|
651
|
-
For both managed resource kinds, `assetSetSha256` remains a separate per-map output identity. It
|
|
652
|
-
hashes each generated file's exact portable name, media type, byte count, and SHA-256 using Core's
|
|
653
|
-
asset-set v1 contract; it does not hash only the icon-package manifest. Hosted must
|
|
654
|
-
confirm the immutable resource bytes, reconstruct those same per-file identities (including the
|
|
655
|
-
`icons/<mapId>/` prefix), and reject the Style when the submitted build-manifest hash diverges.
|
|
656
|
-
|
|
657
|
-
## Agent icon composition
|
|
658
|
-
|
|
659
|
-
List the effective local catalog used by the exported map:
|
|
277
|
+
Administratively disabled uploads return `TF_TILESET_UPLOAD_DISABLED` without retrying.
|
|
278
|
+
Temporary service failures retain bounded retries.
|
|
660
279
|
|
|
661
|
-
|
|
662
|
-
|
|
663
|
-
|
|
280
|
+
`inspect features` samples bounded vector-source features. `icons list` and `icons diff` inspect
|
|
281
|
+
prepared icon identities; they do not turn package directories into a separate hosted library.
|
|
282
|
+
Use the installed command's help for exact arguments and supported JSON output.
|
|
664
283
|
|
|
665
|
-
|
|
666
|
-
Its top-level fields, in order, are `schemaVersion: 2`, `pathBase: "cwd"`, and `maps`.
|
|
667
|
-
Schema version 2 is a compatibility boundary: removing or renaming a field or changing an enum's
|
|
668
|
-
meaning requires a new schema version. Additive optional fields require corresponding documentation
|
|
669
|
-
and tests.
|
|
670
|
-
|
|
671
|
-
Each sorted map entry has one `id` and an `icons` value. `icons.kind` is `none` for `icons: []`, or
|
|
672
|
-
`directories` for a prepared ordered composition. A directory entry contains:
|
|
673
|
-
|
|
674
|
-
- `directories`, in the exact left-to-right authoring order, using config-relative paths or safe
|
|
675
|
-
`npm:<package>/<path>` descriptors;
|
|
676
|
-
- `finalIds`, the sorted canonical lower-kebab IDs in the resulting sprite;
|
|
677
|
-
- `replacements`, with the replaced path and winning path for every later exact-ID replacement;
|
|
678
|
-
- `sources`, with the winning ID, cwd-relative path, format, byte length, and intrinsic dimensions;
|
|
679
|
-
- `insideWorkingTree`; and
|
|
680
|
-
- the deterministic generated `packageHash`.
|
|
681
|
-
|
|
682
|
-
There is deliberately no parallel catalog registry, provider kind, semantic mapping, external
|
|
683
|
-
sprite branch, or arbitrary source-to-runtime renaming. `<id>.<ext>` publishes `<id>` and the
|
|
684
|
-
reserved pattern form `<id>.pattern.<ext>` also publishes `<id>`. This lets an
|
|
685
|
-
agent answer “which directory wins this icon?” directly from one map record without reconstructing
|
|
686
|
-
hidden provider state. Use `--map <id>` to select one exact map when internal orchestration supplies
|
|
687
|
-
more than one.
|
|
688
|
-
|
|
689
|
-
All reported paths are relative to the invocation working directory. A source outside that tree
|
|
690
|
-
uses `../` and `insideWorkingTree: false`; no absolute path is emitted. Listing follows local
|
|
691
|
-
authoring semantics. Run `npx tileflow validate --target hosted` separately before a
|
|
692
|
-
hosted deploy to check containment, portable IDs, SVG safety, and hosted limits.
|
|
693
|
-
|
|
694
|
-
The Tileflow command performs no authentication, network request, browser/server launch, or file
|
|
695
|
-
write. It removes an ambient `TILEFLOW_API_KEY` before importing config. As with every config-aware
|
|
696
|
-
command, loading `tileflow.config.ts` executes repository code and is not a sandbox; side effects in
|
|
697
|
-
that code remain the repository's responsibility. Success emits no ANSI or progress prose. Usage,
|
|
698
|
-
config, source, decode, and render failures exit 1, write diagnostics to stderr, and leave stdout
|
|
699
|
-
empty.
|
|
700
|
-
|
|
701
|
-
The output contains no source contents or source hash, rendered cells, atlas coordinates,
|
|
702
|
-
image/base64 payload, credential, timestamp, random value, or absolute path. Open a reported local
|
|
703
|
-
source path with normal repository tools only when the pixels themselves are needed.
|
|
704
|
-
|
|
705
|
-
## Read-only icon comparison
|
|
706
|
-
|
|
707
|
-
Compare the exported map with its active hosted revision before deciding whether to deploy:
|
|
284
|
+
## Team Icon Sets and repository locks
|
|
708
285
|
|
|
709
|
-
|
|
710
|
-
|
|
711
|
-
|
|
712
|
-
npx tileflow icons diff --map-id map_AbCdEfGhIjKlMnOp --against production --report ./icon-diff.html
|
|
713
|
-
```
|
|
286
|
+
Two intentionally separate families cover shared icons. `icon-set` manages the remote Team catalog
|
|
287
|
+
with Team authority; `icons install|update|pin` maintain the repository's exact
|
|
288
|
+
`tileflow.icons.lock.json` beside the selected config.
|
|
714
289
|
|
|
715
|
-
|
|
716
|
-
|
|
717
|
-
|
|
718
|
-
|
|
719
|
-
|
|
720
|
-
previews under `Added`, `Modified`, and `Removed`. Added and removed cards show only the affected
|
|
721
|
-
icon; modified cards compare `Before` with `Next`. A script-free 1x/2x selector defaults to 2x,
|
|
722
|
-
switches the embedded density, and renders 1x at half the 2x preview size inside a stable frame so
|
|
723
|
-
the selected state is immediately visible. Package hashes, generated sizes, and icon counts stay in
|
|
724
|
-
collapsed `Details`. A map badge is shown only for a map-scoped report. It exposes no atlas
|
|
725
|
-
implementation UI and contains no API key, remote runtime dependency, original icon source, or
|
|
726
|
-
local source path. Use `--force` to replace different existing report bytes and `--open` only
|
|
727
|
-
together with `--report`.
|
|
728
|
-
|
|
729
|
-
Visual modification means that normalized rendered RGBA pixels changed at 1x or 2x. Fully
|
|
730
|
-
transparent RGB is ignored. The manifest also hashes the four encoded artifacts, so an artifact can
|
|
731
|
-
change while its per-icon pixel list remains unchanged. The report and digest analysis operate on
|
|
732
|
-
generated sprite data; SVG, raster source files, and absolute paths stay on the local machine.
|
|
733
|
-
|
|
734
|
-
`--json` writes exactly one deterministic schema-version-1 document plus a trailing newline. Its
|
|
735
|
-
stable top-level fields, in order, are:
|
|
736
|
-
|
|
737
|
-
```json
|
|
738
|
-
{
|
|
739
|
-
"schemaVersion": 1,
|
|
740
|
-
"environment": "production",
|
|
741
|
-
"baseline": {"deploymentId": "dep_...", "package": null, "version": 7},
|
|
742
|
-
"proposed": {"package": null},
|
|
743
|
-
"icons": {"added": [], "removed": [], "modified": [], "unchangedCount": 0},
|
|
744
|
-
"generatedBytes": {"before": 0, "after": 0, "delta": 0},
|
|
745
|
-
"artifacts": {"report": null},
|
|
746
|
-
"hasChanges": false
|
|
747
|
-
}
|
|
290
|
+
```sh
|
|
291
|
+
npx tileflow icon-set publish ./icons --id brand --team @acme --idempotency-key brand-2026-09-14 --json
|
|
292
|
+
npx tileflow icon-set versions brand --team @acme --json
|
|
293
|
+
npx tileflow icons install --team @acme --json
|
|
294
|
+
npx tileflow icons pin @acme/brand --version 3 --team @acme --json
|
|
748
295
|
```
|
|
749
296
|
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
297
|
+
Use your own directory, Team selector, and retry key. `publish` compiles one local directory into
|
|
298
|
+
the four generated sprite files and creates an immutable integer revision; republishing identical
|
|
299
|
+
bytes reports `unchanged` and reuses the same revision. `list`, `status`, `versions` and `uses` are
|
|
300
|
+
bounded Team reads. `archive` and `unarchive` change only catalog state and never remove retained
|
|
301
|
+
revisions. `purge <slug> --version <n>` additionally requires `--idempotency-key`, an exact
|
|
302
|
+
`--confirm @team/set@version`, and `--acknowledge-unknown-locks`, because repository locks that were
|
|
303
|
+
never deployed are not discoverable and already-downloaded public bytes cannot be revoked.
|
|
304
|
+
|
|
305
|
+
The lock commands inspect the `iconSet()` references your config declares. They are the only
|
|
306
|
+
commands that resolve `latest`, and the only ones that write the lock. `install` fills in declared
|
|
307
|
+
references that have no pin, `update` moves selected references to their current latest revision,
|
|
308
|
+
and `pin` selects one exact revision. Every requested reference is resolved before a single
|
|
309
|
+
compare-and-swap write of the whole snapshot, so a concurrent writer fails the command instead of
|
|
310
|
+
losing its pins. No lock command rewrites `tileflow.config.ts`.
|
|
311
|
+
|
|
312
|
+
`validate`, `build`, `preview`, `deploy`, `icons list` and `icons diff` read the lock and never
|
|
313
|
+
resolve a catalog head. `--cache-dir` chooses the verified artifact cache root and `--offline` fails
|
|
314
|
+
a cache miss instead of hydrating it. Publishing a newer revision changes nothing in a repository
|
|
315
|
+
until `install`, `update` or `pin` changes its exact pin.
|
|
316
|
+
|
|
317
|
+
These commands require an account session or a Team data key carrying `icons:read` for reads and
|
|
318
|
+
`icons:write` for publication, archive state and purge. A Map-scoped deploy key never gains catalog
|
|
319
|
+
authority. Availability depends on your deployment; check the installed command's help and your
|
|
320
|
+
Team's enabled features.
|
|
321
|
+
|
|
322
|
+
## Local coordinate commands
|
|
323
|
+
|
|
324
|
+
`setup coordinates` and `coordinates search|describe|operations|transform` require a compatible,
|
|
325
|
+
explicitly provided native distribution. Installing this CLI does not provide native engine,
|
|
326
|
+
catalog, or grid assets, and no public native runtime download is currently offered. There is no
|
|
327
|
+
hosted fallback. See the
|
|
328
|
+
[local runtime guide](https://github.com/tileflow/tileflow-sdk/blob/main/packages/coordinates-runtime/README.md)
|
|
329
|
+
for the verified platform, setup, and development-artifact restrictions.
|
|
330
|
+
|
|
331
|
+
## Reference and troubleshooting
|
|
332
|
+
|
|
333
|
+
Run `npx tileflow --help` or `npx tileflow <command> --help` for the installed command surface.
|
|
334
|
+
The families cover map authoring, semantic language discovery, local visual evidence, datasets and
|
|
335
|
+
icons, account sessions, coordinates, and hosted delivery. Hidden support commands are not a
|
|
336
|
+
recommended application workflow.
|
|
337
|
+
|
|
338
|
+
A manifest 404 usually means assets were not built/served at the component's configured URL.
|
|
339
|
+
Missing fonts or sprites require the complete prepared output. Hosted compatibility failures should
|
|
340
|
+
be fixed before authentication or upload, not bypassed with repeated deployment attempts.
|
|
341
|
+
|
|
342
|
+
See [deployment documentation](https://tileflow.dev/docs/deploy),
|
|
343
|
+
[SDK responsibility boundaries](https://github.com/tileflow/tileflow-sdk/blob/main/README.md),
|
|
344
|
+
and [issues](https://github.com/tileflow/tileflow-sdk/issues). Source `main` may be newer than npm;
|
|
345
|
+
use the installed CLI's help and generated contracts for that release.
|
|
346
|
+
|
|
347
|
+
## Validate icon representations
|
|
348
|
+
|
|
349
|
+
`tileflow validate`, development and build resolve icon capabilities before returning a map.
|
|
350
|
+
Validation and deployment also prepare map-owned tree models before compiling styles or making
|
|
351
|
+
remote writes. Invalid or missing model files report a local asset error; prepared geometry travels
|
|
352
|
+
inside the style, including models inherited from Streets.
|
|
353
|
+
`TF_ICON_REPRESENTATION_MIXED` means a layer can select SDF and RGBA icons, including a fallback or
|
|
354
|
+
local override. Keep that selection homogeneous or use an explicit bounded mapping. Development
|
|
355
|
+
reports the invalid generation while retaining its last valid artifact.
|
|
356
|
+
|
|
357
|
+
Declare defaults in `tileflow.icons.json`; inspect effective appearances and text-fitting layouts with
|
|
358
|
+
`tileflow icons list --json`. Diff reports detect default-only changes and show rendered previews.
|
|
359
|
+
See [Author recolorable and adaptable icons](https://github.com/tileflow/tileflow-sdk/blob/main/packages/dev/README.md) for the source profile and halo bounds.
|