@somewhere-cloud/cli 0.38.15 → 0.38.17

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 ADDED
@@ -0,0 +1,1392 @@
1
+ # Changelog
2
+
3
+ ## 0.38.17
4
+
5
+ ### Fixed
6
+
7
+ - `somewhere typecheck` and `somewhere lint` accept `anyOf(owner(), grant(...))`,
8
+ the per-owner and per-row sharing forms in `somewhere docs declared-data`
9
+ (Per-owner sharing). Before, they refused it with "anyOf() accepts exactly one
10
+ owner() and one member(), group() or appRole()", and `grant` was missing from
11
+ the `somewhere/db` types, although deploy accepted the schema. The schema
12
+ parser, `somewhere/db` types and lint rules bundled in the CLI are now the
13
+ platform's current ones, so `grant()` forms that deploy refuses (inside
14
+ `allOf`, `update` without `read`, `delete`, no `operations`) are refused with
15
+ deploy's own messages.
16
+
17
+ ## 0.38.16
18
+
19
+ ### Added
20
+
21
+ - `somewhere upgrade [--json]` moves every recorded CLI pin to the running CLI
22
+ and prints the `CHANGELOG.md` entries in between (`CHANGELOG.md` now ships in
23
+ the package). To reach the newest release: `npx -y @somewhere-cloud/cli@latest
24
+ upgrade`, then `npm install`.
25
+ - New projects pin the CLI version they were created with (`init`, `project
26
+ create` and the temporary deploy record it, and send it to the platform as
27
+ `cli_version`). A different CLI run inside the project prints one line and
28
+ runs the installed pin. Skills are never updated on their own; `upgrade`
29
+ leaves them alone and says `skills update` is the explicit step.
30
+ - The starter `AGENTS.md` names the data-and-code exits (`somewhere pull`,
31
+ `somewhere db dump`, CSV export, PostgreSQL in your own Neon account) and
32
+ points at `somewhere docs portability`.
33
+
34
+ ### Changed
35
+
36
+ - README, LICENSE, the starter and `browser` help no longer name the old
37
+ package scope, the old domain or "legacy"; the copyright holder is
38
+ Somewhere HQ, Inc. A test refuses those words in what ships.
39
+
40
+ ## 0.38.15
41
+
42
+ ### Changed
43
+
44
+ - `somewhere deploy` (and the patch path) waits up to 5 s for the blank-page check
45
+ that runs after the platform answers (`post_live_render: pending`), reading the
46
+ settled result from `GET /deploy/log?release_id=`. A page the check finds blank
47
+ fails the deploy with `DEPLOY_BLANK_PAGE` and the rejection, instead of being
48
+ rolled back silently after the command returned.
49
+ - `somewhere rollback` prints the database notice in its plain-text output: a
50
+ code-only rollback across a schema change says the tables and columns added
51
+ since stay, with their data, and the target version ignores them.
52
+
53
+ ## 0.38.14
54
+
55
+ ### Added
56
+
57
+ - `somewhere tasks delete <id> --reason <text>`, `somewhere tasks restore <id>
58
+ [--reason <text>]` and `somewhere tasks deleted`: delete a task from the
59
+ board, bring it back, and list deleted tasks. Only the board owner can use
60
+ them; anyone else is refused with `TASK_DELETE_FORBIDDEN`.
61
+
62
+ ### Changed
63
+
64
+ - `somewhere deploy`: once the target project is known (a linked folder or
65
+ `--project`), the CLI asks the platform to start the project's compile
66
+ container while it packs and uploads, so a cold redeploy no longer waits for
67
+ that container after the upload. The request is sent once and never awaited;
68
+ any answer, including an older platform's 404, leaves the deploy unchanged.
69
+ `--dry-run` sends none.
70
+
71
+ ## 0.38.13
72
+
73
+ ### Changed
74
+
75
+ - `somewhere init`: the starter's `AGENTS.md` points to `grant()` for sharing
76
+ your own rows with specific people (read-only sharing, co-authors):
77
+ `somewhere docs declared-data --section per-owner-sharing`. The agent
78
+ workflow names `anyOf(owner(), grant())` beside the other scopes, and the
79
+ green starter's access paragraph carries the same pointer.
80
+ - The bundled skills pack is refreshed to the platform's current pack.
81
+
82
+ ## 0.38.12
83
+
84
+ ### Changed
85
+
86
+ - `somewhere deploy --project <id>` from a folder with no recorded base: when
87
+ `<id>` is already a canonical project id, the live release it deploys against
88
+ is read alongside the project lookup instead of after it. The lookup still
89
+ binds the target first, a folder linked to a different project is still
90
+ refused before anything is uploaded, and the read is used only when the
91
+ lookup confirms the same project.
92
+
93
+ ## 0.38.11
94
+
95
+ ### Changed
96
+
97
+ - `somewhere init`: the starter's `AGENTS.md` public-form example declares its
98
+ request body schema with `sw.endpoint`, and the agent workflow text is
99
+ re-synced to the platform's.
100
+
101
+ ### Fixed
102
+
103
+ - `somewhere deploy-check --json` keeps the platform's error code, message and
104
+ request id instead of replacing them with `CLI_ERROR`.
105
+
106
+ ## 0.38.10
107
+
108
+ ### Added
109
+
110
+ - `somewhere ai keys --project <project>` (also `list`, `ls`),
111
+ `somewhere ai keys set <anthropic|openai> --project <project> [--stdin]` and
112
+ `somewhere ai keys remove <anthropic|openai> --project <project>` (alias `rm`)
113
+ manage a project's own AI provider keys. `--project` is required on all
114
+ three; the destination is never taken from the linked folder.
115
+ - The key is never a command-line argument: `set` reads it from a hidden
116
+ prompt or, with `--stdin`, from a pipe. Unknown options and stray values are
117
+ refused without being repeated, and a key is checked locally (not empty, no
118
+ spaces or line breaks, at most 4096 characters) before any request.
119
+ - Until the platform serves the key-status read, `ai keys` reports
120
+ `AI_KEY_STATUS_UNAVAILABLE` instead of an empty list; `set` and `remove`
121
+ work now.
122
+
123
+ ## 0.38.9
124
+
125
+ ### Fixed
126
+
127
+ - The sign-in code step in the starter that `somewhere init` writes now asks
128
+ for the 6-digit code from the email (heading "Check your email"), instead of
129
+ an "Authenticator or backup code". "Send a new code" requests a fresh code a
130
+ minute after each send and never sends automatically; the newest code is the
131
+ one to use, and a new code does not extend the 5-minute step. Refusals (send
132
+ limit, lockout, expired step, failed send) show the platform's own message.
133
+ "Sign in again" leaves the step.
134
+ - The feature and minimal starters pin `@somewhere-cloud/sdk` 0.14.1, which
135
+ provides `resendMfaCode()`.
136
+
137
+ ## 0.38.8
138
+
139
+ ### Changed
140
+
141
+ - The starter that `somewhere init` writes no longer shows a whole-page loading
142
+ screen ("Checking your session…"). Until sign-in is known, the app frame
143
+ renders at once with the app's name and no account controls.
144
+ - The starter pins `@somewhere-cloud/sdk` 0.14.0 (the minimal template
145
+ `^0.14.0`). With 0.14.0 the platform's early session script starts the
146
+ sign-in check while the page is still loading.
147
+
148
+ ## 0.38.7
149
+
150
+ ### Changed
151
+
152
+ - Before any command runs, the CLI deletes `last-run.json` (and
153
+ `last-run.json.tmp`) in the config directory (default `~/.somewhere`, or
154
+ `SOMEWHERE_CONFIG_DIR`). Versions before 0.38.6 saved command arguments and
155
+ output there in plain text. The file is never read or printed; only its path
156
+ and an error code are shown if it cannot be removed. At exit the CLI writes
157
+ the metadata-only record introduced in 0.38.6.
158
+ - The `AGENTS.md` that `somewhere init` writes (default and `--bare`) points to
159
+ the declared-access recipes, readable with
160
+ `somewhere docs sw.db --section owner-or-member-and-parent-access`.
161
+
162
+ ## 0.38.6
163
+
164
+ ### Fixed
165
+
166
+ - An expired temporary session (from deploying without logging in) no longer
167
+ blocks `init` or a fresh `deploy`. `init` writes the starter offline and
168
+ names the folder it wrote to; `deploy` says in one line that it replaced the
169
+ expired session.
170
+ - Signed out, a deploy that names an existing project (`--project` or a linked
171
+ folder) now stops before contacting Somewhere with `SIGN_IN_REQUIRED` and
172
+ the two ways forward (sign in, or drop the target to start a new temporary
173
+ project), instead of creating a temporary account and then failing.
174
+ - A file over the 5 MB per-file limit that would be published now stops
175
+ `deploy` and `preview` before any request (`FILE_TOO_LARGE`), instead of
176
+ being left out while the deploy goes live. `.gitignore` and
177
+ `.somewhereignore` still keep large files out on purpose.
178
+ - When a deploy request may have reached Somewhere but no answer came back,
179
+ the CLI never sends it again. It reports the outcome as unknown
180
+ (`deployment_outcome: "unknown"` with `--json`) and says how to check.
181
+ - `somewhere` needs Node.js 22.19.0 or newer and now says so on older Node.js,
182
+ instead of failing with a TypeError.
183
+ - `auth set` reports only an HTTP 401 as an invalid token; an outage or other
184
+ failure says the token could not be verified and saves nothing. `whoami`
185
+ reports only a 401 as a login problem.
186
+ - Commands piped into a reader that closes early (`docs | head -1`) end
187
+ quietly instead of reporting a network failure.
188
+ - Anonymous deploy errors keep Somewhere's error code, status and request ids.
189
+
190
+ ### Changed
191
+
192
+ - `typecheck` is read-only: it never installs packages. Missing type packages
193
+ stop it with an `npm install` instruction, it announces when it fetches
194
+ TypeScript with npx, and every check runs under a deadline
195
+ (`SOMEWHERE_TYPECHECK_TIMEOUT_MS`, default 300 s) that stops its processes.
196
+ - `deploy --json` keeps stdout for the deploy result and lists every file left
197
+ out locally on stderr, by path and reason.
198
+ - `preview` judges each save like a deploy: ignored files are not uploaded and
199
+ an oversize file holds the save without changing the last preview.
200
+ - `somewhere api` refuses full URLs, control characters, `..` segments and
201
+ unsupported methods before sending anything; the request always stays on the
202
+ configured API.
203
+ - `logs --tail` takes a whole number from 1 up. `dev` refuses extra arguments.
204
+ - The local `last-run.json` records only the command, option names, exit code,
205
+ time and CLI version, never values or output. `env set` with a value on the
206
+ command line points to `--stdin`.
207
+ - Declared-data and runtime types and the source lint are refreshed from the
208
+ live platform.
209
+ - README and help text describe `dev`, `init`, `typecheck` and project delete
210
+ as they actually behave.
211
+
212
+ ## 0.38.5
213
+
214
+ ### Changed
215
+
216
+ - Files blocked by the deploy's sensitive-path policy never leave your
217
+ machine. The CLI now applies the same policy Somewhere applies to every
218
+ uploaded path, while it collects files: before any file is read into an
219
+ upload and before any request. The policy matches file names only, in any
220
+ folder: private-key files (`id_rsa`, `*.pem`, `*.key`, `*.p12`, `*.pfx`),
221
+ `credentials` data files (`credentials.json`, `credentials.yaml`, …), secrets
222
+ files (`secrets.json`, `secrets.yaml`, …), `service-account.json`,
223
+ `service-account-key.json` and the Firebase Admin SDK key file
224
+ (`<project>-firebase-adminsdk-<id>.json`). Dotfiles such as `.env` were
225
+ already never uploaded. This filename policy does not detect secrets under
226
+ other names. Held-back files are listed under "Never uploaded", and neither
227
+ `--include` nor a `!` line in `.somewhereignore` or `.gitignore` publishes
228
+ them. `credentials.ts`,
229
+ `credentials.tsx`, `credentials.md`, `.well-known/` and ordinary config such
230
+ as `firebase.json` and `google-services.json` are not affected by this policy.
231
+ - When your published code mentions one of those files by name, `deploy`,
232
+ `deploy --dry-run`, `deploy-check` and `preview` stop before contacting
233
+ Somewhere, name the file and the code that mentions it, and suggest storing it
234
+ as a project secret (`somewhere env set NAME --stdin < file`, read with
235
+ `sw.env.NAME` in a function). This is a filename match in your code, not an
236
+ import analysis; documentation such as `README.md` is not searched. If nothing
237
+ loads the file, add it to `.somewhereignore` or move it out of the folder.
238
+ - `somewhere deploy --dry-run` now says, in its help and in its human-readable
239
+ output before it runs, that the files a deploy would publish are sent to
240
+ Somewhere to compute the change and that nothing is published. A dry run
241
+ still works this way. `--dry-run --json` output is unchanged.
242
+
243
+ ## 0.38.4
244
+
245
+ ### Changed
246
+
247
+ - `somewhere deploy --dry-run` no longer creates anything. When there is no
248
+ usable credential (signed out, with no live temporary workspace) or no
249
+ existing project to compare against (no linked project, no `--project`), it
250
+ stops before contacting Somewhere: no temporary workspace, no project, no link
251
+ and no change to project or login files. It says so and points to
252
+ `somewhere typecheck` and `somewhere lint`, which check your code without
253
+ contacting Somewhere, or to `somewhere deploy`. With a usable credential and
254
+ an existing project it shows the deploy's changes as before, and it no longer
255
+ records the one-time "not published" notice in `.somewhere.json`.
256
+ - Tests stay on your machine by default: `*.test.*` and `*.spec.*` source
257
+ files, and anything in a `tests/` or `__tests__/` folder, are listed under
258
+ "Not published". To publish one, use `somewhere deploy --include <path>` or a
259
+ `!<path>` line in `.somewhereignore`. `--include tests` or `!tests/` publishes
260
+ the helpers in that folder, for an app that imports them; a test-named file
261
+ inside it still needs its own opt-in. `.env` files stay excluded either way,
262
+ and `.well-known` keeps publishing.
263
+ - No new commands, options or dependencies. `--include` now also takes a test
264
+ folder, as above.
265
+
266
+ ## 0.38.3
267
+
268
+ ### Changed
269
+
270
+ - The starter's AGENTS.md shows webhook and streaming handlers with their
271
+ parameter types, `(req: Request, sw: SomewhereRuntimeContext)`, instead of
272
+ saying `somewhere typecheck` types unannotated handlers, which it does not:
273
+ under the starter's strict settings an unannotated handler is a type error.
274
+ - The bundled realtime-and-background skill's example handler carries the
275
+ same annotation. The bundled skills match the platform's served pack.
276
+ - No command, option or dependency changes.
277
+
278
+ ## 0.38.2
279
+
280
+ ### Changed
281
+
282
+ - The bundled schema-changes skill says that `removedTable()` retires a deployed
283
+ table with 30-day data retention, instead of pointing to a description "above"
284
+ that the skill does not include. The bundled skills match the platform's served
285
+ pack.
286
+ - The minimal starter's README keeps the booking and help-desk recipe command on
287
+ one line.
288
+ - No command, option or dependency changes.
289
+
290
+ ## 0.38.1
291
+
292
+ ### Changed
293
+
294
+ - `somewhere init` writes the current agent workflow, skills and minimal starter
295
+ guidance. `AGENTS.md` matches the published platform workflow: `id()` is a
296
+ random text key referenced with `text()`, fitting declared scopes stay in place
297
+ when an exceptional write needs `sw.db.server.tx`, and the sign-in starter modes
298
+ are listed on one line. The bundled skills match the platform's served pack.
299
+ - The minimal starter's README says to delete a table declaration that was never
300
+ deployed and to use `removedTable()` for a deployed table, even an empty one.
301
+ It also notes that the greeting's `serverOnly()` scope is a demonstration, not
302
+ the default for app data, and points to the booking and help-desk recipes.
303
+ - No command, option or dependency changes.
304
+
305
+ ## 0.38.0
306
+
307
+ ### Changed
308
+
309
+ - The CLI is now published as `@somewhere-cloud/cli` (install with
310
+ `npm i -g @somewhere-cloud/cli`, or run `npx @somewhere-cloud/cli <command>`).
311
+ `@somewhere-tech/cli` stays installable at its existing versions. The command
312
+ name is still `somewhere`.
313
+ - Defaults target somewhere.cloud: the API at `https://api.somewhere.cloud` and
314
+ MCP at `https://mcp.somewhere.cloud`.
315
+ - An app's function URL comes from the platform (`app_url` in `.somewhere.json`,
316
+ printed by `somewhere status --json`), never from a project slug.
317
+ - `somewhere init` writes the project contract (`AGENTS.md`, "somewhere.cloud
318
+ project contract") and the bundled skills pack from the current platform docs.
319
+ They name `@somewhere-cloud/cli` and `@somewhere-cloud/sdk`. Starters depend on
320
+ `@somewhere-cloud/sdk` 0.13.0.
321
+
322
+ ## 0.37.86
323
+
324
+ ### Fixed
325
+
326
+ - The CLI now talks to Somewhere's current hosts (`api.somewhere.cloud`, `mcp.somewhere.cloud`, runner and site defaults). The previous release still defaulted to `api.somewhere.tech`, which has moved, so `somewhere deploy` from a fresh folder failed immediately. `init` → `deploy` works again with no login and no environment overrides.
327
+ - The README quick start marks `somewhere login` as optional; `init` and `deploy` run anonymously and print a claim link.
328
+
329
+ ## 0.37.77
330
+
331
+ ### Fixed
332
+
333
+ - `somewhere deploy --project <ref>` from a folder that is not linked to that project no longer fails with `BASE_REQUIRED` on every attempt. The CLI first resolves the ref to its project and reads the project's live release, declares that release as the deploy's base, and lets the platform's existing stale-overwrite check decide: a release that lands between that read and the publish is still refused (`STALE_RELEASE_BASE`), never overwritten, and the CLI never retries or forces. A linked folder keeps sending its own recorded base; a folder linked to a different project than `--project` names is refused with a clear message instead of being redeployed elsewhere; `--force` behaviour is unchanged. When the live release cannot be read, the `BASE_REQUIRED` recovery now names a path that terminates (`init --link`, `pull`, `deploy`) instead of a bare `somewhere pull`.
334
+
335
+ ## 0.37.76
336
+
337
+ ### Changed
338
+
339
+ - The bundled agent skills pack is refreshed from the platform docs and gains a seventh skill, `design`: the UI kit in `src/ui`, the token rules, the `AuthCard` slots, and the two mistakes that make a generated page look unfinished. New starters install it in `.agents/skills/design`; `somewhere skills update` brings it to an existing project.
340
+
341
+ ## 0.37.75
342
+
343
+ ### Fixed
344
+
345
+ - `somewhere init`: the generated `index.html` escapes `"` as `&quot;` in the app name, which is both the `<title>` text and the `description` attribute value, so a quote in a project name no longer ends the attribute.
346
+
347
+ ## 0.37.74
348
+
349
+ ### Added
350
+
351
+ - `somewhere init` auth starters ship a UI kit in `src/ui` (`Button`, `TextField`, `SelectField`, `TextareaField`, `CheckboxField`, `FormRow`, `Card`, `Table`, `Stat`, `Badge`, `Tabs`, `Dialog`, `Notice`, `Skeleton`, `Stack`, `Grid`, `Inline`, `PageHeader`) with styled and headless twins that share props, and `src/pages/HomePage.tsx` is a worked example of them (header, stats, table in a card, dialog form) instead of an empty state. The README gains a "Look" section with the rules that keep generated pages consistent (tokens only, no global tag styles, one primary action, cards for peers).
352
+ - Social sign-in is a config toggle: `SIGN_IN_PROVIDERS` (`src/config.ts`) starts as `['google']`, so a new app shows "Continue with Google" out of the box (the platform owns the OAuth client; nothing to configure); set it to `[]` for email-only sign-in or add `github` / `discord`. The "Continue with …" buttons, `src/auth/useProviderSignIn.ts` and the `/auth/callback` page (the SDK's `AuthCallback`) are already wired. `APP_TAGLINE` sets the sign-in page's one-line description.
353
+ - `src/styles/tokens.css` gets a `prefers-color-scheme: dark` block, semantic tones (success/warning/danger/info), shadows and a cross-platform font stack, so the starter no longer falls back to Arial/Georgia off macOS. `index.html` gets description, `theme-color` and an SVG favicon.
354
+
355
+ ### Changed
356
+
357
+ - `AuthCard` has permanent `providers` (above the form) and `children` (below it) slots; the magic-link module passes its form as a child instead of patching the card's markup, and nothing else is a sibling of the two-column `.auth` grid.
358
+ - The "Verify your email" panel is a quiet notice with secondary buttons, not the page's loudest call to action. `MfaStep` uses the starter's panel and field classes.
359
+ - Starter stylesheet: the notes status line is `.note-status` (`.notice` is the kit's notice component); `.alert` and `.section-title` live in the base stylesheet, so removing a module leaves no orphaned rules.
360
+ - Social sign-in sends the browser to `/auth/callback?provider=<name>` and the callback page passes that provider to the SDK's `AuthCallback`, so a GitHub or Discord code is exchanged with the provider that issued it (the SDK defaults to Google). An unknown `?provider=` is ignored. With `SIGN_IN_PROVIDERS = []` the sign-in card has no providers slot, so no "or use email" divider is shown.
361
+
362
+ ## 0.37.72
363
+
364
+ ### Fixed
365
+
366
+ - New apps from `somewhere init` use SDK 0.12.6. It keeps session verification outages as an unavailable response instead of reporting that the user signed out, and uses browser keepalive for refresh requests to reduce interruption during navigation. Keepalive is a limited mitigation, not full recovery from a lost refresh response (#96).
367
+
368
+ ## 0.37.71
369
+
370
+ ### Fixed
371
+
372
+ - `somewhere logs` text output: every recorded stack line now starts with a fixed `stack | ` marker under its log row, so stack text can never pass as a log row. A stack longer than 30 lines ends with "… N more lines (--json shows the whole stack)". `--json` is unchanged (#90).
373
+ - `somewhere support packet`: the packet's `omitted` list no longer names `emails`, `tokens` or `passwords`. The list names only the parts of a failure the packet builder never reads; it was never a guarantee that a collected field cannot contain such a value, so review a packet before you submit it (#92).
374
+
375
+ ## 0.37.70
376
+
377
+ ### Fixed
378
+
379
+ - `somewhere support packet --trace`: the packet keeps a failure code only when it is one of the function runtime's own failure codes (the server-recorded response code first, then the logged code). Any other code, including an app-chosen `err.code`, is recorded as `APP_ERROR_CODE`, so a code-shaped value from your app never enters the packet. Your own logs still show the code as written (#88).
380
+ - `somewhere logs` and `somewhere errors` text output: control characters in stored messages and stack frames (newlines, carriage returns, ESC/ANSI sequences, BEL, C1 controls, line/paragraph separators and bidi overrides) are shown as visible escapes, so each stored row prints as exactly one line and a message cannot fake another row or change the terminal. `--json` output is unchanged (#88).
381
+ - `somewhere support packet --help` names exactly which fields the packet reads and how the code is restricted, instead of a blanket "never holds tokens or passwords" claim (#88).
382
+ - `somewhere verify --keep-actors` help states the real lifetimes: a kept browser closes after 5 minutes idle, and at most 10 minutes after it started (#87).
383
+
384
+ ## 0.37.69
385
+
386
+ ### Added
387
+
388
+ - `somewhere verify --keep-actors --resume-page`: an explicit warm continuation. A kept actor whose first segment starts at exactly the page path the last passed run left it on keeps that page as it was (no reload); any other actor, flow, project or start path, a start path with a query or fragment, or a kept browser that is gone reloads normally. `--resume-page` without `--keep-actors` is refused. The report lists resumed actors under `keep_actors.resumed_pages` with a note that the run does not prove the latest deployed code; run without `--resume-page` for that. The keep record stores the page pathname only (#85).
389
+ - `somewhere logs --trace <trace id>` shows only that request's log lines, with any recorded stack under its line, so the `trace_id` from a `500 FUNCTION_ERROR` leads straight to the crash. Anything but a 32-hex id is refused before any request; plain `somewhere logs` is unchanged.
390
+ - `somewhere support packet --trace <trace id> [--project <ref>]` builds the `somewhere.repro/1` packet for that failed request from the owner's log rows. It keeps only the error code, HTTP status, request and trace ids, method and a templated path (route words become `:id`/`:seg`); never the message, stack, body, query or headers. A failed mutating request is recorded as `unknown` and never rerun. It is written locally and submitted only if you choose (#83).
391
+
392
+ ## 0.37.68
393
+
394
+ ### Fixed
395
+
396
+ - `somewhere verify --keep-actors`: when nothing is kept yet for this flow file and its actors in this folder (a first run, a new or renamed flow file, or a changed cast), one stderr line says the run starts fresh and will keep them for the next run of the same file. If other flows in the folder have kept actors, it also says they are not reused and that `--close-actors` closes them. No behaviour change (#82).
397
+
398
+ ## 0.37.67
399
+
400
+ ### Fixed
401
+
402
+ - Starter apps from `somewhere init`: when the session check fails, the "We can't confirm your sign-in" panel says what broke (couldn't reach the server, the server had a problem (HTTP 5xx), too many checks (HTTP 429, wait a minute), an unreadable answer, or a refused check (HTTP 4xx)), that the sign-in may still be valid so try again before signing in again or asking for a new link, and a status-only code to report (`SESSION_CHECK_FAILED, HTTP n` or `no response`). It used to always blame the connection. Only the SDK's typed status is shown, never server text (#80).
403
+
404
+ ## 0.37.66
405
+
406
+ ### Added
407
+
408
+ - `somewhere verify --keep-actors`: after a fully passed multi-user run, each actor's signed-in browser and test user are kept for the next run of the same flow (same owner, project, folder and cast). That run signs each actor in again and starts from each segment's path, but the browser keeps its earlier state, so a pass on a kept browser is a warm re-check; run without `--keep-actors` for a fresh first load. Any stop, failure or unconfirmed call cleans up as before. `--close-actors` closes the browsers and deletes the identities. The project folder's private `.somewhere/test/verify-actors.json` records ids and emails only (#74).
409
+
410
+ ### Fixed
411
+
412
+ - After a failed `somewhere call`, `somewhere support packet` records the platform's HTTP status and trace id, so a definite refusal (for example a 404) is recorded as `refused` with its status, the same as the MCP packet, instead of `unknown` with no status or ids. A call that got no response at all (network or timeout) stays `unknown`, with no status invented. Only validated status and ids are kept (#76).
413
+
414
+ ### Changed
415
+
416
+ - Internal: the `somewhere support packet` repro record uses the platform's shared `somewhere.repro/1` module (vendored byte-identical, with a checksum check). No behaviour change (#73).
417
+
418
+ ## 0.37.65
419
+
420
+ ### Added
421
+
422
+ - `somewhere support packet [--json] [--out <file>]`: builds a local, redacted repro packet for the last failed command from typed fields only (CLI version, command names, validated error code, HTTP status, an id-templated operation, validated request/trace/project ids, retry verdict, outcome and duration). It never includes the message, hint, data, arguments, bodies, headers, SQL, URL query, emails, tokens, source or env. Nothing is uploaded (#67).
423
+
424
+ ### Fixed
425
+
426
+ - A refused `somewhere verify` names the invalid field and limit (`start_error_details`: code, status, path such as `actions[2].timeout_ms`, `limit_ms`) instead of echoing the platform message (#67).
427
+ - Text-mode output for a platform failure adds one line with its code and request/trace ids (for example `code PROJECT_NOT_FOUND · request req_… · trace …`). The message stays the platform's own; `--json` is unchanged (#71).
428
+ - `somewhere lint` vendors the platform's source lint at somewhere-tech#714: a file exempted from the request-ownership trace by a genuine verifier call reports `coverage.request_ownership` as `partial` instead of `checked`. Warning metadata only; findings and exit codes are unchanged (#72).
429
+ - `somewhere test-users prepare --help` no longer promises "about 1 hour" sessions or 24-hour identities. It says the session starts with the expiry prepare prints, that a refresh with saved-back state can renew it, and not to rely on expiry: remove the identities with `somewhere test-users cleanup`. A state copied before cleanup may keep working until its access token (JWT) expires (#70).
430
+
431
+ ## 0.37.64
432
+
433
+ ### Added
434
+
435
+ - `somewhere verify` multi-user journeys report where their time went: each segment carries `timing` (the platform's own browser-call timing numbers and `browser_reused`, plus this CLI's `request_wall_ms`), and the journey adds `test_users_create_ms`, `segments_ms`, `cleanup_ms` and `test_users_delete_ms`. Reporting only; no behaviour, ordering or cleanup change (#68).
436
+
437
+ ### Fixed
438
+
439
+ - Starter apps from `somewhere init` adopt `@somewhere-tech/sdk` 0.12.4 (feature starter exact `0.12.4`, basic starter `^0.12.4`), which issues an expiry on every cookie reply and reconciles an orphaned refresh marker without a rotation replay (#64).
440
+
441
+ ## 0.37.63
442
+
443
+ ### Added
444
+
445
+ - `somewhere test-users prepare|address|inbox|cleanup`: prepares signed-in managed test users as standard Playwright `storageState` files (production origin only; state kept under `<project>/.somewhere/test/`, never the developer key, no token printed), gives a fresh `test.somewhere.site` address for real signup tests, reads only test-inbox mail newer than `--since` (the magic link only with `--json --include-link` or `--link-out`), and cleans up only the identities it created, with a readback receipt (#63).
446
+
447
+ ### Fixed
448
+
449
+ - `somewhere whoami` says what its project count counts, so it reconciles with `somewhere projects` (for example "6 projects you own (`somewhere projects` lists 5 of them; not listed: 1 archived)"); `--json` still prints the raw account response. Shipped in 0.37.63; this entry was added afterwards (#66).
450
+ - `somewhere deploy`: when the after-live reference check is still pending, text output names the existing read for this exact version (`somewhere call project_deploy_log '{"version":N}'`). `--json` is unchanged (#62).
451
+
452
+ ## 0.37.62
453
+
454
+ ### Fixed
455
+
456
+ - `somewhere verify` reports and their printed text mask credential-bearing parts of URLs: URL userinfo; in the query or fragment, the value of a credential parameter (`token`, `access_token`, `refresh_token`, `auth_token`, `code`, `secret`, `signature`, `sig`, `key`, `api_key`, `apikey`, `creator_secret`, `dsn`, `password`, also percent-encoded or nested encoded in another parameter) or a JWT/key-shaped value under any name; and credential-shaped path segments. This covers a journey segment's `path` and `final_url`, each viewport's `final_url`, `target` and `goto` step labels. The browser still opens the original URL. Error messages and reports saved earlier are not rewritten (#57).
457
+ - Starter apps from `somewhere init`: the email-verification panel offers "I already have a code" beside "Email me a code". It opens the code form without sending another email, so a code already received still works after a new tab or reload. A failed or rate-limited send still does not open the form (#59).
458
+
459
+ ## 0.37.61
460
+
461
+ ### Fixed
462
+
463
+ - `somewhere verify --out <existing file>` still never overwrites a report, and now names the next free path to rerun with (for example `--out flows/run2-report-3.json`) (#56).
464
+ - `somewhere pull` writes the starters' `.gitignore` when the folder has none, so the declarations `somewhere typecheck` generates (`__somewhere_data.d.ts`, `__somewhere_files.d.ts`) stay untracked in a pulled app. An existing `.gitignore` is never changed (#55).
465
+ - `somewhere lint`: quoted verifier text can no longer hide a row-ownership warning; the exception now covers only executable verifier member calls. Vendored with the platform's source lint (#53).
466
+
467
+ ## 0.37.60
468
+
469
+ ### Fixed
470
+
471
+ - `somewhere verify --out` no longer summarises a run in which no browser started as "0 failed steps": it says "Verify FAIL: no browser ran (<codes>); nothing was checked, so this is not an app result", and a partial journey names its unstarted segments. `--json` summaries add `segments_not_started` and `start_errors` (error codes only) (#50).
472
+
473
+ ## 0.37.59
474
+
475
+ ### Fixed
476
+
477
+ - `somewhere deploy` in a folder whose `.somewhere.json` links a project this sign-in can't open (for example an expired, unclaimed temporary project) now explains that, says nothing was deployed, and lists the next steps: see your projects, `somewhere init --link --project <name-or-id>`, or delete the link and `somewhere init --bare --name <name>`. `--json` adds `linked_project_id`, `deployed: false` and `next_steps` (#51).
478
+ - Project commands run in an unlinked folder (logs, errors, env, project view, open, verify, browser open, db, db rows, status, pull, rollback, run, git) name the exact link and create commands instead of "run from a linked directory" (#51).
479
+
480
+ ## 0.37.58
481
+
482
+ ### Fixed
483
+
484
+ - `somewhere browser --actions` and `somewhere verify` flows keep an action's `"frame"` (frame name, URL substring, child index, or iframe CSS selector) and send it to the platform, so a framed `fill`, `eval` or `expect` runs inside the iframe instead of on the top page. Before, `frame` was dropped, and a framed `eval` could pass against the top page. Whole-page actions (`goto`, `dialog`, a fixed `wait`) and malformed frames are refused; the local browser refuses framed actions; `verify --schema` lists `frame` (#48).
485
+
486
+ ## 0.37.57
487
+
488
+ ### Changed
489
+
490
+ - `somewhere lint --help` names every warning the lint reports: credentials in source, schema declarations, directory index routes, request input choosing row ownership on server writes, and `sw.email.send` awaited inside a loop (#47).
491
+
492
+ ## 0.37.56
493
+
494
+ ### Fixed
495
+
496
+ - `somewhere docs constructor` (and other built-in object names such as `__proto__` or `toString`) now answers that no such documentation topic exists, instead of a false "Could not reach https://somewhere.tech — check your connection." Quick-link topic and alias lookups use own keys only.
497
+
498
+ ## 0.37.55
499
+
500
+ ### Added
501
+
502
+ - `somewhere lint`: a new warning when `sw.email.send` is awaited inside a loop (each email waits for the previous delivery); it advises bounded batches only for independent emails (#43).
503
+
504
+ ## 0.37.54
505
+
506
+ ### Fixed
507
+
508
+ - Signed out, `somewhere docs <topic>` resolves the same topic names the docs tool does: after an exact page id, it looks the name up in the public docs manifest's `aliases` (lowercased, then with non-alphanumeric runs as `-`), so `somewhere docs schema-changes` opens `sw.db`. A manifest without `aliases` keeps today's behavior, and a real page id always wins.
509
+
510
+ ## 0.37.53
511
+
512
+ ### Changed
513
+
514
+ - `somewhere deploy --help` has a "No project yet?" section naming `somewhere init --bare --name <name>` (create a project in your account and link this folder), and `--project` now says it takes an existing project.
515
+ - `somewhere projects` help and its empty-list line name `somewhere init --bare --name <name>`.
516
+ - `somewhere project create` says how to deploy to the project it made (`somewhere init --link --project <id>` then `somewhere deploy`, or `somewhere deploy --project <id>`).
517
+ - When the platform reports no live URL, the CLI names `somewhere project view <id>` instead of "check the dashboard".
518
+
519
+ ### Fixed
520
+
521
+ - The signed-in "No project is linked" deploy message (since 0.37.49) recommended `somewhere link --project <name-or-id>`, which `link` does not accept. It now names `somewhere init --link --project <name-or-id>`, which does.
522
+
523
+ ## 0.37.52
524
+
525
+ ### Fixed
526
+
527
+ - The expired temporary-session deploy message no longer opens with "expired … without being claimed", which contradicted its next step for someone who did claim the workspace in the browser. It now says this machine has no record of a claim; the first step is still "sign in with `somewhere login` if you claimed it".
528
+ - `somewhere lint` no longer reads binary assets, and carries the vendored source-lint fix for a `user.id` false positive (#37).
529
+ - `somewhere verify`: when a request you declared with `expect_requests` came back with a different status, the verdict now leads with that mismatch ("Expected /api/deny to return 200; saw 403.") instead of only reporting the status as undeclared. The pass/fail result and exit code are unchanged (#36).
530
+
531
+ ## 0.37.51
532
+
533
+ ### Fixed
534
+
535
+ - Starter `AGENTS.md` (from `somewhere init`) follows the current platform agent workflow: test sign-in uses managed test identities, matching the platform docs (#32).
536
+ - `somewhere email test-inbox` prints a message's `verification_code` in its human output when one is present, not only with `--json` (#32).
537
+
538
+ ## 0.37.50
539
+
540
+ ### Fixed
541
+
542
+ - An expired temporary session's deploy message now first tells you to sign in with `somewhere login` if you claimed the workspace in the browser, before suggesting you delete `.somewhere.json`. The expiry message also appears only when the session's expiry time has actually passed (a session merely missing its token is no longer reported as "expired at" a future time).
543
+
544
+ ## 0.37.49
545
+
546
+ ### Fixed
547
+
548
+ - `somewhere deploy` with an expired, unclaimed temporary session and a linked (or `--project`) project now stops before sending anything and says the temporary workspace expired and nothing was deployed. Previously it created a new temporary account and failed with PROJECT_NOT_FOUND. `--json` answers `TEMPORARY_SESSION_EXPIRED` with `temp_expires_at`.
549
+ - Signed in with no linked project, `somewhere deploy` now names the exact next steps (`somewhere init --bare --name <name>`, `somewhere link --project <name-or-id>`, or `somewhere deploy --project <name-or-id>`) instead of "No project linked. Run `somewhere init`". It still never creates or links a project on its own.
550
+
551
+ ## 0.37.48
552
+
553
+ ### Fixed
554
+
555
+ - `somewhere deploy` no longer reports "Your deploy was NOT applied" when its own automatic retry, sent after the first attempt timed out or lost its connection, is refused as STALE_RELEASE_BASE: the first attempt may already be live, so the CLI now says that and asks you to check the live release. `--json` adds `first_attempt_outcome: "unknown"` and `first_attempt_failure`. Other stale-base answers are unchanged.
556
+
557
+ ## 0.37.47
558
+
559
+ ### Changed
560
+
561
+ - `somewhere init` starters use `@somewhere-tech/sdk` 0.12.3, which refreshes short-lived per-app sessions without making valid-token reads wait (0.12.1 could not refresh them). The feature starter keeps an exact pin; the basic starter keeps its caret range (#31).
562
+ - New projects' `.gitignore` excludes the generated `src/__somewhere_data.d.ts` and `src/__somewhere_files.d.ts`; `typecheck`, `dev` and `deploy` regenerate them from `db/schema.ts`. Existing projects are untouched (#31).
563
+
564
+ ## 0.37.46
565
+
566
+ ### Added
567
+
568
+ - `somewhere lint`: an offline, advisory source lint (warning-only; never blocks a deploy). Runs locally with no credentials; `--generic` also runs the project's own oxlint with a scrubbed environment and no shell (#26).
569
+ - `somewhere lint` carries the platform's source-lint version 2 rules, re-vendored with full parity against the platform (#29).
570
+ - `somewhere verify`: an actor may declare `{ "test_user": true }`. The run creates that many managed test identities in one request, signs each actor in once in its own browser, and deletes the identities after every browser closes (`--keep-test-users` keeps them; they expire after 24 h). No password or token is requested or reported (#27).
571
+ - `somewhere verify`: a journey item may be `{ "parallel": [segment, segment] }` — 2–3 segments by different actors whose browser calls run at the same time, for realtime checks. Reports carry `parallel_group` (#28).
572
+
573
+ ## 0.37.45
574
+
575
+ ### Changed
576
+
577
+ - `somewhere deploy` fetches project notices alongside the deploy instead of waiting for them first, so their round trip (about 0.1-0.9 s, up to a 3 s timeout) is no longer on every deploy's path. Notices still print once, on stderr, before the result or the failure and before a `--force` confirmation prompt.
578
+
579
+ ## 0.37.44
580
+
581
+ ### Fixed
582
+
583
+ - `somewhere deploy --json` in a temporary (signed-out) session now prints the server's deploy result with the claim fields (`claim_url`, `expires_at`, `claim_connects_agent`) added. Before, it replaced the result, so `version`, `release_id`, `warnings`, `stage_timing_ms` and `reference_check` were dropped. Signed-in output is unchanged.
584
+
585
+ ## 0.37.43
586
+
587
+ ### Fixed
588
+
589
+ - `sw.groups.add` and `sw.groups.delete` type-check in generated starters (TS2339 before): the vendored `runtime/declared-data.cjs` declaration is re-vendored from the platform (#22).
590
+
591
+ ## 0.37.42
592
+
593
+ ### Changed
594
+
595
+ - Local checks read a bare `id()` in `db/schema.ts` as a random text key, the platform default since 2026-10-18; `id({ uuid: false })` declares an integer key. A foreign key must use its parent's key type (`text({ references })` for a random key).
596
+ - `somewhere init --features private-data` keeps an integer key for notes, which its safe create retry needs. New starters otherwise get random text keys.
597
+
598
+ ## 0.37.41
599
+
600
+ ### Changed
601
+
602
+ - The `AGENTS.md` written by `somewhere init` now says to set `auth` on every `sw.endpoint` (`'required'`, `'optional'`, or `'none'` when public on purpose), because a deploy refuses an endpoint without it. Webhooks, streams and custom responses still use a bare `export default async function (req, sw)`.
603
+
604
+ ## 0.37.40
605
+
606
+ ### Changed
607
+
608
+ - Local declared-data checks understand `allOf(gate, who)` permission policies, matching the platform admission that is now live. The vendored declared-data code is refreshed from platform core ed285f7b.
609
+
610
+ ## 0.37.39
611
+
612
+ ### Fixed
613
+
614
+ - `somewhere init` refuses a directory that holds only unrelated files, with no app source, before creating a remote project. It names those files and keeps them; `--bare` and `--link` still accept such a directory.
615
+ - `somewhere verify` gives clearer guidance when a write gets a 409 in one viewport run but not another. Each viewport runs the flow separately, so creating the same record in each run is a possible cause. The run still fails and the 409 stays in the report.
616
+
617
+ ## 0.37.32
618
+
619
+ ### Changed
620
+
621
+ - `somewhere init` keeps AGENTS.md and useful skills without installing command-running agent hooks or MCP registration. Existing local and global agent configuration stays unchanged.
622
+ - The generated project guide asks agents to run `somewhere typecheck` after edits. Optional post-edit deploy-reference hooks remain available through explicit `somewhere hooks install --host <host>`; MCP setup remains explicit through `somewhere mcp install <host>`.
623
+
624
+
625
+ ## 0.37.9
626
+
627
+ ### Added
628
+
629
+ - Every auth starter (plain `somewhere init` and `--features auth`) includes a "Verify your email" code panel for password accounts. It uses the SDK cookie session through the packaged `/api/auth` route, so the session decides the account and no token reaches page code. The starter pins `@somewhere-tech/sdk` 0.11.6.
630
+ - `somewhere init --features magic-link` adds passwordless sign-in links: an "email me a sign-in link" form on the sign-in page and the `/auth/magic` page the email opens, routed in front of the sign-in gate. The page redeems the one-time token for the same cookie session, then opens the link's `redirect_uri` only when it is a page of this app. `sw.auth.invite` links land on the same page.
631
+ - `somewhere init --subdomain <slug>` names the new project's subdomain (default: derived from `--name`). It cannot be combined with `--link`.
632
+
633
+ ### Changed
634
+
635
+ - The bundled declared-data parser and generator are re-vendored from the current platform source.
636
+
637
+ ## 0.37.8
638
+
639
+ ### Fixed
640
+
641
+ - Generated `AGENTS.md` now matches the current app workflow: start with the relevant docs, keep owner-scoped queries tied to the signed-in user, and authorize custom endpoints and server queries.
642
+
643
+ ## 0.37.7
644
+
645
+ ### Fixed
646
+
647
+ - Self-update verifies the published provenance correctly. A refused update exits with an error and prints the npm installation fallback; versions at least one minor release behind get a daily warning.
648
+ - `somewhere call` uses the linked project for tools that take `project_id`. An explicit ID wins; `--all-projects` omits the default and leaves scope to the tool.
649
+ - `somewhere docs` opens the index instead of the entire manual. Use `docs search`, `--section`, or `--full` to read more.
650
+ - Text output from `verify` includes eval results.
651
+ - Browser commands support closing a named session and selecting an app user. User selection refuses an incomplete search rather than guessing.
652
+ - `preview --once` syncs and exits; `preview link` produces a fresh link for an open preview.
653
+
654
+ ## 0.37.6
655
+
656
+ ### Added
657
+
658
+ - `somewhere init --features agent` adds a signed-in assistant to the auth starter. It runs inline `sw.agent.run` with at most 4 steps and 10 cents per reply, and the conversation is saved on the server. It shows the tools each reply used. The assistant can read the user's tasks but only proposes new ones; a task is written when the user approves it. Approval and task creation are two writes, not one transaction: a task write that fails or whose outcome is unknown answers `TASK_CREATION_UNCONFIRMED` and never reopens the approval, so approving again cannot create a duplicate. Owner-scoped `tasks`/`proposals` tables are reached only through `api/chat.ts` and `api/proposals.ts`. `/fixtures?state=loading|empty|error|populated|long` renders preview states from static data without a request, and `flows/assistant-fixtures.json` screenshots them with `somewhere verify`. Durable runs, cancel, streaming and memory are not generated (`agent-durable` in `--catalog`).
659
+
660
+ ### Changed
661
+
662
+ - The default auth starter and `--features` starters pin `@somewhere-tech/sdk` 0.11.3. Its auth code is identical to 0.11.2.
663
+
664
+ ## 0.37.3
665
+
666
+ ### Added
667
+
668
+ - Advisor requests can reconnect to the same saved request after a terminal closes or a connection fails. Use `somewhere advisor --resume <request-id>`, `--status <request-id>`, or `--cancel <request-id>`. The CLI saves the receipt before starting paid work and keeps account and anonymous request ownership separate.
669
+ - When the platform enables durable Advisor requests, the ordinary `somewhere advisor` command adopts the returned request automatically and waits for its result. Earlier platform responses continue to work. Ctrl-C leaves the request available to resume.
670
+
671
+ ### Fixed
672
+
673
+ - Retrying a durable request uses its original receipt instead of creating another paid request. Cancellation records intent; an unknown dispatch remains an unknown outcome.
674
+
675
+ ## 0.31.12
676
+
677
+ ### Fixed
678
+
679
+ - **File uploads work with attribute selectors.** `somewhere browser --upload`
680
+ read the file path from the FIRST `=` in the mapping, so a selector that
681
+ contains its own equals sign — `[data-testid=file]` — was cut in half and the
682
+ leftover text was treated as the path. The path is now read from the LAST `=`,
683
+ which leaves `#avatar=./photo.png` behaving exactly as before. For the rare
684
+ path that itself contains `=`, `--upload '<selector>::<file>'` states the split
685
+ explicitly. `--fill` and `--select` are unchanged: their values often contain
686
+ `=`, so they still split at the first one.
687
+ - **`somewhere typecheck` no longer fails on a project you have not installed
688
+ yet.** A freshly created or freshly pulled project declares its type packages
689
+ in `package.json` but has nothing in place until dependencies are installed,
690
+ and the first check reported that absence as a dozen type errors in your own
691
+ code. The check now puts the type packages your project declares in place
692
+ before it runs, so the first answer is a real one. Only packages you already
693
+ declare are resolved, an import you never declared still fails with its real
694
+ error, and a project that is already installed does no extra work. If the
695
+ packages cannot be fetched, the check still runs and reports what it finds.
696
+
697
+ ### Added
698
+
699
+ - **Scheduled triggers can be created in your own time zone.**
700
+ `somewhere cron create --timezone <IANA>` — for example
701
+ `--timezone America/Los_Angeles` — reads the cron expression in that zone and
702
+ handles daylight saving for you, so `0 9 * * *` means 9am locally all year.
703
+ The platform has accepted this since scheduling shipped; only the CLI was
704
+ missing the flag and its help text called every expression UTC. Omit the flag
705
+ and nothing changes: schedules are still read in UTC.
706
+ - **Every command says it has started.** The CLI now prints
707
+ `starting somewhere CLI <version>` as its first line in an interactive
708
+ terminal, so a first run shows something immediately and names the version you
709
+ actually got. The line goes to the error stream and only ever appears on a
710
+ terminal, so piped output, `--json`, and scripts are byte-for-byte unchanged.
711
+ Note that a first `npx @somewhere-tech/cli …` on a cold cache can still sit
712
+ quiet for up to a minute BEFORE this line: npm downloads and installs the
713
+ package before running any of its code, and that download is silent by npm's
714
+ design — no code we ship can speak during it. Install once with
715
+ `npm i -g @somewhere-tech/cli` to skip that wait on every later run.
716
+
717
+ ## 0.31.11
718
+
719
+ ### Added
720
+
721
+ - **Test passwordless sign-in without sending mail to a real inbox.**
722
+ `somewhere email test-inbox` reads the stored auth messages for an address
723
+ owned by the project and shows the extracted magic-link URL alongside the
724
+ rendered message.
725
+ - **Browser checks can attach files and name screenshots.** `somewhere browser`
726
+ accepts repeatable `--upload <selector=file>` actions, while
727
+ `--screenshot <name>` saves a capture under the requested label. The same
728
+ actions work in shared browser and verification flow files.
729
+ - **Authenticated pages can be verified at desktop and phone sizes.**
730
+ `somewhere verify --session` seeds an existing app session, and repeatable
731
+ `--cookie <name=value>` options carry existing cookies into every viewport.
732
+ - **The catalog now explains how to call each tool.**
733
+ `somewhere catalog <tool>` prints the tool description and complete input
734
+ schema, including nested constraints and fields such as cron timezones.
735
+
736
+ ## 0.31.10
737
+
738
+ ### Fixed
739
+
740
+ - **A preview that cannot finish verifying now says so, and retries itself.**
741
+ When the platform could not yet confirm the uploaded preview build, the CLI
742
+ reported a generic internal error and dropped the session. That case is now a
743
+ named, retryable condition: `somewhere preview` replays the same save once on
744
+ its own, and only reports a failure — with a reference you can quote — if the
745
+ retry also does not complete. Nothing is created or changed on the failed
746
+ attempt, and whatever is live stays live.
747
+ - **`somewhere preview --json` always answers with JSON.** A refusal — the plan
748
+ does not include previews, or the project has never been published and
749
+ `--publish-first` was not passed — used to print human prose on a `--json`
750
+ run. It now returns the same typed JSON error shape as every other refusal,
751
+ so a script or agent can read the reason instead of parsing sentences.
752
+
753
+ ## 0.31.9
754
+
755
+ ### Added
756
+
757
+ - **Cron and email are first-class CLI command groups.** `somewhere cron`
758
+ exposes list, create, update, delete, and run-once commands, while
759
+ `somewhere email` exposes transactional send. `somewhere cron run` accepts a
760
+ cron ID or a task name and runs it once without changing its schedule. Each
761
+ group names its commands and includes a copyable example in `--help`. During
762
+ the platform rollout, run-once exits with a typed
763
+ `CRON_RUN_NOT_AVAILABLE` message on older platform versions.
764
+ - **Stale CLI installs get one concise update line.** The existing daily,
765
+ fail-open version check now has explicit newer/current and cache-throttling
766
+ coverage, and its notice fits on one line.
767
+
768
+ ### Fixed
769
+
770
+ - **Every registered command owns its help output.** Command help can no
771
+ longer silently look like the generic top-level banner, and the complete
772
+ non-pass-through command surface is fixture-covered.
773
+ - **Every bundled init template writes a valid `.gitignore`.** The current
774
+ green starter already emitted real line breaks; the older exported template
775
+ no longer carries literal `\\n` text.
776
+ - **A pending package verdict is described as pending.** npm installation
777
+ continues without waiting for a result, without presenting that non-blocking
778
+ fallback as a failed install.
779
+
780
+ ## 0.31.8
781
+
782
+ ### Added
783
+
784
+ - **`somewhere verify` runs a complete browser acceptance flow in one command.**
785
+ Give it a live or local URL and an optional flow file to get one report with
786
+ every named step, page/console/network health, and desktop and mobile
787
+ screenshots. `somewhere deploy --verify <flow.json>` can run the same check
788
+ immediately after publishing.
789
+ During the platform #24 rollout, hosted action flows on an older serving
790
+ release fail honestly with a missing-screenshot or unfiltered expected-
791
+ refusal health result; they do not crash or report a false pass. Re-run the
792
+ same command after the rollout reaches the project.
793
+ - **Browser action files now have one canonical shape everywhere.**
794
+ `somewhere browser --actions` and `somewhere verify --flow` use the same
795
+ concise action array, such as `{"fill":"#email","value":"a@b.co"}` followed
796
+ by `{"click":"#save"}`.
797
+
798
+ ### Fixed
799
+
800
+ - **Preview handoffs are directly runnable from any directory.** Every promote
801
+ command printed by `somewhere preview` carries its project context, and the
802
+ non-interactive form includes `--yes`. The watcher now notices a promotion
803
+ promptly and exits without consuming or silently dropping the next save.
804
+ - **A first preview no longer looks frozen while it publishes production.**
805
+ `somewhere preview --publish-first` reports each bootstrap phase, elapsed
806
+ heartbeats, retries, and the platform's typed failure state.
807
+ - **Preview access refusals are safe to automate.** Wrong-account lookups return
808
+ a stable `PROJECT_NOT_FOUND` result in human and `--json` output without
809
+ listing unrelated projects or attempting a deploy.
810
+ - **`somewhere status` keeps production visible on Free plans.** It reports the
811
+ live production version and release even when private preview status is
812
+ unavailable on the account's plan.
813
+
814
+ ## 0.31.7
815
+
816
+ ### Added
817
+
818
+ - **`somewhere init` now starts with a working full-stack TypeScript app.** In
819
+ an empty directory, the default starter includes a typed React page, a typed
820
+ server function, and a database schema, with exact dependency versions
821
+ installed before init reports success. Use `--bare` for the previous
822
+ metadata-only setup; existing source directories are still left untouched.
823
+
824
+ ### Fixed
825
+
826
+ - **Project deletion now follows the platform's two-step confirmation flow.**
827
+ The CLI recognizes the successful `needs_confirmation` response as well as
828
+ the older error-shaped response. At a terminal it asks for the project name;
829
+ without a terminal it prints the exact `--confirm-code` command to run next.
830
+ Unrelated server errors continue to surface unchanged.
831
+ - **A slow package verdict no longer turns into a failed install.** Verdict
832
+ lookups have a more realistic cold-start allowance. If that allowance is
833
+ exhausted, `somewhere npm install` says `verdict pending` and continues with
834
+ npm under the default fail-open policy.
835
+
836
+ ## 0.31.6
837
+
838
+ ### Added
839
+
840
+ - **Device login now shows what is asking for access.** The approval page can
841
+ show the machine name, CLI and runtime versions, operating system, and the
842
+ requested project scope before access is allowed or denied. After approval,
843
+ `somewhere login` prints that scope, `somewhere whoami` names the current
844
+ session and its access, and `somewhere logout` revokes the session on the
845
+ server before removing the local credential.
846
+ - **`somewhere browser` can drive routine flows without custom JavaScript.**
847
+ Repeatable `--fill`, `--select`, `--click`, and `--expect` flags run in command
848
+ order, while `--actions <file.json>` accepts the same shared action sequence
849
+ as the platform browser. `--expect-request <path:status>` treats an intended
850
+ response such as an authorization refusal as expected, and `--visible-only`
851
+ removes hidden controls from the page outline. Localhost session help now
852
+ says plainly that named sessions are unavailable there and points to a fresh
853
+ local browser run.
854
+ - **`somewhere db apply-schema` prepares a managed database before the first
855
+ deploy.** It reads `db/schema.ts` by default, applies the declaration to the
856
+ production database without publishing the app, reports an already-current
857
+ schema as a no-op, and preserves the planner's exact safety message when a
858
+ removal needs an explicit `removed()` or `removedTable()` marker.
859
+
860
+ ### Fixed
861
+
862
+ - **Local browser checks no longer stall when the CLI uses an isolated home on
863
+ macOS.** The headless browser still runs with a new scratch profile and no
864
+ extensions, while the CLI's credentials remain inside the isolated home.
865
+
866
+ ## 0.31.5
867
+
868
+ ### Fixed
869
+
870
+ - **`somewhere dev` now moves past a busy default port automatically.** If
871
+ 8787 is already in use, the local loop selects the next free port and prints
872
+ the choice before startup. Passing `--port` remains strict: a busy requested
873
+ port is an error, and the CLI names the process using it when the operating
874
+ system can identify one.
875
+ - **Local database requests now explain where their time went.** Each
876
+ database-backed request in the local loop prints the complete database
877
+ round-trip beside the request total and includes the database execution time
878
+ reported by the platform when it is available. Working responses without
879
+ that field keep working and say that the timing was not reported.
880
+
881
+ ## 0.31.4
882
+
883
+ ### Fixed
884
+
885
+ - **Status now shows which tested preview reached production.** When production
886
+ came from a promotion, `somewhere status` names the exact candidate and shows
887
+ a short content hash, so you can match the live app to the preview you tested.
888
+ - **Promotion now uses the platform's own data notice and exact function count.**
889
+ The notice about preview rows is printed exactly as the platform sends it,
890
+ and the release summary says how many functions reached production when that
891
+ count is available. Older platform responses keep working quietly.
892
+
893
+ ## 0.31.3
894
+
895
+ ### Added
896
+
897
+ - **`somewhere project allowed-origins list` and `… set` now exist.** Allowing
898
+ another web address to call your project from a browser was only possible
899
+ through the generic tool-call escape hatch with a raw project id — so the
900
+ command guidance told you to run was not a command the CLI had. It is now a
901
+ first-class command with the obvious spelling, it shows up in
902
+ `somewhere project --help`, and it takes `--project <ref>` like everything
903
+ else. `set` replaces the whole list (`--clear` empties it) and refuses an
904
+ address the allowlist could never match — a path, a query, a wildcard, a
905
+ trailing slash — before sending it, naming what is wrong. Your project's own
906
+ address and any verified custom domain are always trusted and never need
907
+ listing.
908
+
909
+ ### Fixed
910
+
911
+ - **The promote command the CLI prints can now be run in the shell that printed
912
+ it.** `somewhere preview` and `somewhere status` printed
913
+ `somewhere promote <session> <preview>`, and `somewhere promote` then refused
914
+ that exact command whenever there was no terminal to confirm with — so in a
915
+ script, an agent, or a piped terminal the CLI handed you a command it would
916
+ reject. The printed command now matches the shell reading it: without a
917
+ terminal you get the runnable form, with `--yes` on it; at a keyboard you get
918
+ the ordinary confirming form first and the unattended one named beneath it.
919
+ - **Promotion now says what happened to your data.** Promoting moved your app
920
+ and said nothing about the rows you created while previewing, which stay in
921
+ the preview database — the isolation is the point, but discovering it by
922
+ opening an empty production page and repeating your whole acceptance pass is
923
+ not. A successful promote now states that only the app was promoted, that
924
+ production is serving the data it already had, and that production is worth
925
+ checking and seeding before you call it shipped.
926
+ - **One project now reports one size of itself.** The same directory was
927
+ described three different ways: `somewhere deploy` counted static files and
928
+ functions separately, `somewhere preview` reported a single "3 files" with the
929
+ function hidden inside it, and `somewhere promote` said "3 files + functions",
930
+ replacing the count with the word. Worse, deploy's number did not match what
931
+ the project itself listed. All three now print the same shape — `3 static
932
+ files + 1 function` — off the same counting rule, and promote reports what
933
+ production actually holds rather than a tally that disagreed with it.
934
+ - **`--project` works on every command that names a project.** `logs`,
935
+ `errors`, `status`, `open` and `rollback` accepted only a positional project
936
+ and answered `unknown option '--project'`, while a dozen other commands took
937
+ the flag — so the syntax you learned on one command failed on the next. All of
938
+ them now take `--project <ref>`, the positional keeps working everywhere, and
939
+ naming two different projects in one command is refused rather than guessed.
940
+
941
+ ## 0.31.2
942
+
943
+ ### Fixed
944
+
945
+ - **`somewhere dev` now runs the same entry files `somewhere deploy`
946
+ publishes.** A project whose `index.html` points at
947
+ `<script type="module" src="/src/main.js">` deploys and serves perfectly —
948
+ the platform serves plain JavaScript modules exactly as you wrote them,
949
+ rather than compiling them — but the local loop refused to start on it at
950
+ all, insisting on `.tsx`. It now follows the same rule deploy follows: your
951
+ `index.html` names the entry, `.tsx` / `.ts` / `.jsx` / `.mts` / `.cts` are
952
+ compiled, `.js` / `.mjs` / `.cjs` are served as written, and a page with no
953
+ module script at all (a browser-Babel page, a static site) simply runs. The
954
+ loop stops only when `index.html` names a file that is not in the directory
955
+ — and then it says which file, and which forms it accepts.
956
+ - **The local runtime no longer suggests editing a package file outside your
957
+ project.** Running a function could print advice to add `"type": "module"` to
958
+ a `package.json` in a parent directory — on some machines, the one in your
959
+ home folder. The cause was a module-format lookup with no upper bound, which
960
+ walked straight past the project. The runtime now determines the format from
961
+ your project's own package file and your own source, stopping at the project
962
+ root, so no advice can ever name a file outside it. CommonJS and ES module
963
+ functions both keep working exactly as they do when deployed.
964
+ - **`somewhere browser --eval` prints the evaluated value in normal output.**
965
+ The value came back correctly with `--json` but was dropped from the default
966
+ text report, so the command you use to check a live page did not show what it
967
+ found. Text output now prints the value under the step — strings as
968
+ themselves, objects readably indented — and an expression that returned
969
+ nothing says so instead of leaving a blank line.
970
+ - **`somewhere deploy --temporary` means temporary, whether or not you are
971
+ signed in.** Being signed in used to override the flag and switch the deploy
972
+ to your account, which then failed in a directory with no linked project. The
973
+ flag is the request: it always deploys to a temporary workspace, never needs a
974
+ linked project, and prints the live URL, the claim link, and when the
975
+ workspace expires. Your account sign-in survives it untouched, the directory's
976
+ own link is left alone, and a second `--temporary` deploy in the same window
977
+ redeploys the same temporary app instead of creating another. A deploy without
978
+ the flag is unchanged.
979
+
980
+ ### Changed
981
+
982
+ - `somewhere init` closes by naming what to run next on the platform —
983
+ `somewhere dev` to run your app here, `somewhere deploy` to publish it — and
984
+ notes that any coding agent can drive this CLI, in place of the previous
985
+ line naming one specific tool.
986
+
987
+ ## 0.31.1
988
+
989
+ ### Fixed
990
+
991
+ - `tsk_5504e045` — **`somewhere preview` can no longer publish to production on
992
+ its own.** A preview builds on your app's live version, so a project that has
993
+ never been published needs one published first — and that publish is a real
994
+ production release, the one thing this command can do to your live site. It
995
+ was happening in two ways it should not have. On a project that was already
996
+ live, if the CLI could not read which version was live it treated the silence
997
+ as "this project has never been published" and went ahead and published your
998
+ working directory over the running app. And on a project that genuinely had
999
+ never been published, it published without asking at all.
1000
+
1001
+ Now: a version the CLI cannot read is unknown, and unknown never publishes —
1002
+ the command stops, says what it could not read, and leaves your live site
1003
+ exactly as it was. A publish happens only when the platform positively
1004
+ confirms nothing is live AND you say so, either by answering the prompt or by
1005
+ running `somewhere preview --publish-first`. A run that cannot be asked — a
1006
+ script, an agent, a piped shell — is refused and told about the flag. Preview
1007
+ on a project that is already live never publishes anything, as before.
1008
+ - `tsk_5504e045` — **the plan refusal stopped claiming your project is
1009
+ unpublished.** On a Free or Builder account, `somewhere preview` on a live
1010
+ project refused with "Nothing was created — this project has not been
1011
+ published", which was simply untrue and sent people to re-deploy an app that
1012
+ was already running. The refusal now says only what it did: nothing was
1013
+ created or changed, and whatever is live stays live.
1014
+
1015
+ ### Changed
1016
+
1017
+ - The dev compiler and function runtime are re-vendored from the platform at
1018
+ `3237dc1e`, picking up the faster dependency install — a project with a
1019
+ lockfile now installs the way the platform installs it, without development
1020
+ dependencies. `somewhere dev` compiles your app with the platform's own
1021
+ compiler, so this keeps what you see on localhost identical to what deploy
1022
+ produces.
1023
+
1024
+ ## 0.31.0
1025
+
1026
+ ### Added
1027
+
1028
+ - `tsk_5cfcfe00` — **`somewhere preview` is a command.** There are two loops and
1029
+ they are now named after where the app runs: `somewhere dev` runs your app on
1030
+ your machine, `somewhere preview` runs it on the platform. Every save goes to
1031
+ a private URL reachable only by you; production keeps serving what you last
1032
+ promoted until you run `somewhere promote`. Reach for it when you want the
1033
+ real hosted app in front of you, or when your agent cannot serve on
1034
+ localhost. `dev --cloud` still starts it and prints one line naming the new
1035
+ command.
1036
+
1037
+ ### Fixed
1038
+
1039
+ - `tsk_33023348` — **`somewhere promote` never reports an outcome it does not
1040
+ know.** It used to print "Promote failed / Unknown error" for a promote that
1041
+ had already shipped, and the obvious retry then said "Production was not
1042
+ changed" about production that the first command had changed. Promote is the
1043
+ one irreversible step in the loop, so it now separates a refusal the platform
1044
+ AUTHORED (reported as written) from a response the CLI could not READ. In the
1045
+ second case it reads what production is serving before and after and answers
1046
+ from whether that moved — and a refusal claiming production was unchanged is
1047
+ checked against the same evidence before it is allowed to stand. When neither
1048
+ side can be read it says the status is unknown and points at your production
1049
+ URL rather than guessing.
1050
+ - `tsk_74375b3c` — **a promote ends the preview cleanly.** Promoting closed the
1051
+ preview, but the loop kept watching, and your next save came back with a
1052
+ refusal written for an API client — then failed the same way on every save
1053
+ after that. The loop now recognises the end of a preview and stops on it, in
1054
+ two lines: what happened, and the one command that starts the next preview.
1055
+ - `tsk_5cfcfe00` — the preview copy no longer claims your preview has
1056
+ production's data. A preview runs against a separate copy of your schema with
1057
+ none of your production rows, which is exactly what makes it safe to try
1058
+ things in.
1059
+ - `tsk_d63b3b6a` — **an unresolvable import is reported, not a crash.**
1060
+ `somewhere dev` died on any import that could not be resolved — a typo'd
1061
+ package, one you had not installed yet — with an internal error naming the
1062
+ CLI's own bundler and nothing about your code, and every rebuild after that
1063
+ failed too. It only happened when the command's error output went to a file
1064
+ rather than a terminal, which is the normal case under an agent, a CI job, or
1065
+ a session recorder. Now an unresolved import reads like a syntax error:
1066
+ file:line:column, the specifier, and one sentence naming the fix — add it to
1067
+ your package.json and install it, or, for a module the platform provides,
1068
+ that it comes from the platform and should not be installed at all. The
1069
+ server survives, the last working page stays up, and a save that fixes it
1070
+ serves again.
1071
+ - `tsk_14c5408c` — a burst of saves stays one preview update. Saves inside the
1072
+ debounce window accumulate into a single update, and a save that lands while
1073
+ one is in flight re-arms instead of starting a second, so two previews are
1074
+ never building at once.
1075
+
1076
+ ### Changed
1077
+
1078
+ - The vendored platform runtime and compiler are re-synced to the current
1079
+ platform build. Content is unchanged from 0.30.2 apart from the provenance
1080
+ stamp — the compiler files hash identically — so this release changes no
1081
+ build behaviour.
1082
+
1083
+ ## 0.30.2
1084
+
1085
+ ### Fixed
1086
+
1087
+ - `tsk_a8cb3d23`, `tsk_f79d71ce` — `somewhere dev` and `somewhere deploy` now
1088
+ derive dependency versions from the SAME code, so a build on your machine and
1089
+ a build on deploy resolve the same libraries. The platform's compiler reads
1090
+ your lockfile as of today: a version your lockfile pins is the version that
1091
+ gets installed, provided it satisfies the range your `package.json` declares.
1092
+ This CLI carries that compiler, so `somewhere dev` follows the identical rule
1093
+ — it is one implementation, vendored, not two that agree by coincidence. A
1094
+ project with NO lockfile is unchanged: the declared range still floor-pins.
1095
+
1096
+ ### Known difference
1097
+
1098
+ - The JavaScript bundle `somewhere dev` builds and the one `somewhere deploy`
1099
+ builds are not byte-identical, and the reason is now only bookkeeping: build
1100
+ comments and source-map entries record where each module was read from, which
1101
+ is your machine locally and the build image on deploy. It has no effect on
1102
+ what your app does.
1103
+ - The dependencies your project DECLARES resolve the same on both sides. Their
1104
+ own transitive dependencies are still resolved by npm from the parents'
1105
+ ranges, so those can differ. Pin one exactly in `package.json` if it matters
1106
+ to you.
1107
+
1108
+ ## 0.30.1
1109
+
1110
+ ### Added
1111
+
1112
+ - `tsk_0e9e13b8` — `somewhere signup` exists. Someone who has never used the
1113
+ platform ran `somewhere login`, and the CLI's answer assumed they already had
1114
+ an account. `signup` prints the page that creates one, and `login` names it
1115
+ too, so the front door is a door.
1116
+ - `tsk_c166924f` — `somewhere deploy` publishes your **app**, not the folder it
1117
+ was built in. Notes, task lists, scratch files and agent instructions in your
1118
+ project root stay on your machine: the deploy prints `Not published (N): …`
1119
+ naming exactly what it held back, so the decision is visible rather than
1120
+ silent. Publish one on purpose with `somewhere deploy --include <file>`, or
1121
+ keep it permanently with a `!<file>` line in `.somewhereignore`.
1122
+
1123
+ ### Fixed
1124
+
1125
+ - `tsk_926fbf8e` — `somewhere docs <topic>` answers from the public corpus with
1126
+ no login. Reading the documentation used to require an account, which is the
1127
+ wrong order: you read the docs to decide whether to make one.
1128
+ - `tsk_f250e561` — `somewhere status` exits 0 when the platform answers a plan
1129
+ question. A feature your plan does not include is an ANSWER, not a failure;
1130
+ exiting non-zero made every scripted `status` on a Free account look like a
1131
+ broken command.
1132
+ - `tsk_a605ff7b`, `tsk_10be456b` — `somewhere browser` against a local URL now
1133
+ fails inside a bound instead of hanging. Every wait on the local path has a
1134
+ deadline, a port with nothing listening is reported as such with the remedy
1135
+ named, and the browser's own favicon request — which the page never made — no
1136
+ longer counts as your app returning a 404.
1137
+ - `tsk_9c5ed7f8` — a failed `somewhere deploy` now says something you can act
1138
+ on. When the platform answers `retry: true` — its own statement that the
1139
+ request changed nothing and the same one is safe to send again — the CLI
1140
+ retries once instead of stopping (it parsed that field and never read it).
1141
+ An error body it cannot classify prints the status and the response instead
1142
+ of the bare words "Unknown error". And every deploy failure now prints the
1143
+ request id from the response, so a failure you can see is a failure we can
1144
+ find.
1145
+ - `tsk_eef0a0ef` — `somewhere dev` prints your app's output, not the platform's
1146
+ telemetry. Database calls were emitting raw internal metrics JSON and a
1147
+ repeated "deferred flush failed: HTTP 403" from a background channel you did
1148
+ not ask for and cannot fix. Both are gone by default; set
1149
+ `SOMEWHERE_DEV_TELEMETRY=1` to see them.
1150
+ - `tsk_a8cb3d23` — the local loop resolves a dependency at the version the build
1151
+ image serves, for every package the image carries. This already held for
1152
+ React; it now holds for the whole baked set (router, query, state, forms,
1153
+ validation, http, dates, utils, styling, animation, charts, icons), so a
1154
+ declared `^3.23.0` no longer compiles against 3.23.0 on your machine and a
1155
+ newer one on deploy. A pin is taken only when the image's version satisfies
1156
+ the range you declared — a project on a major the image does not carry is
1157
+ untouched.
1158
+
1159
+ ### Known difference
1160
+
1161
+ - The JavaScript bundle `somewhere dev` builds and the one `somewhere deploy`
1162
+ builds are built by the same compiler, from the same source, with the same
1163
+ toolchain. They are not byte-identical, and there are two reasons rather than
1164
+ one. Build comments and source-map entries record where each module was read
1165
+ from — your machine locally, the build image on deploy — which has no effect
1166
+ on what your app does. Separately, the two builds can still resolve DIFFERENT
1167
+ VERSIONS of an app dependency: `somewhere dev` uses the tree you installed,
1168
+ while `somewhere deploy` resolves the range your `package.json` declares and
1169
+ does not yet read your lockfile. If that matters to a library you depend on,
1170
+ pin it exactly in `package.json` and both sides agree.
1171
+
1172
+ **Superseded by 0.30.2**, which closes the version difference. The paragraph
1173
+ above describes 0.30.1 only, and is kept because that version is published.
1174
+
1175
+ ## 0.30.0
1176
+
1177
+ ### Added
1178
+
1179
+ - `tsk_9ec50c84` — `somewhere browser` now drives a **localhost** target. The
1180
+ app `somewhere dev` is serving used to be the one address this CLI's own
1181
+ browser would not visit, so every visual and DOM check had to wait for a
1182
+ production deploy. A loopback URL is now driven by the browser already
1183
+ installed on your machine — no new dependency and nothing to download. Each
1184
+ run gets an empty throwaway profile, so it never reads or writes your real
1185
+ browser profile. If there is no browser at all, the CLI says so and names the
1186
+ environment variable to point at one. Flags only the hosted browser can honour
1187
+ (`--store`, `--session`, `--extract`, non-`dom` `--include`) are refused by
1188
+ name rather than silently dropped from a report that still looks complete.
1189
+ - `tsk_70fd0f63` — `somewhere errors` gained a `kind` column and an
1190
+ `--exceptions` flag, so you can see only what actually broke.
1191
+
1192
+ ### Fixed
1193
+
1194
+ - `tsk_bdd72f02` — `somewhere browser --snapshot` now asks for the map it
1195
+ prints. `--snapshot` renders the interactive-element outline, but it never
1196
+ requested that section, so it printed whatever the response happened to carry
1197
+ — usually nothing. `browser --wait button --snapshot` would match a button and
1198
+ then report "dom: 0 interactive elements" on a page with three buttons and two
1199
+ inputs. It now adds `dom` to the requested sections, merging with an explicit
1200
+ `--include` rather than replacing it. The local outline comes from the
1201
+ platform's own probe, so it is a preview of the hosted answer rather than a
1202
+ second opinion.
1203
+ - `tsk_ea4274ca` — `somewhere errors` no longer calls a working auth gate an
1204
+ exception. If you probed your own endpoint signed out — deliberately, to prove
1205
+ the gate holds — your 401 was listed as the only exception in 24 hours. Rows
1206
+ now show their kind: **refused** for a 4xx your handler returned on purpose,
1207
+ **exception** for an uncaught throw or a 5xx, with the summary line splitting
1208
+ the counts. Nothing is hidden by default.
1209
+ - `tsk_ea4274ca` — a stored screenshot printed as a storage path, which reads as
1210
+ a URL and is not one, so the one value the command handed back for "here is
1211
+ your screenshot" could not be used to see it. The report now leads with the
1212
+ link that opens it and keeps the stored path on its own line, because that is
1213
+ the handle for reading or replacing the file later.
1214
+ - `tsk_53badecf` — `somewhere dev --check` and `somewhere deploy` no longer
1215
+ report the `somewhere/db` import from our own managed-schema documentation as
1216
+ a missing npm package whose remedy is installing an unrelated package. The
1217
+ specifiers the platform provides are now treated as provided. A genuinely
1218
+ missing package still warns, and still names every file that imports it.
1219
+ - `tsk_a21bc829` — `somewhere dev` no longer asks you for a variable the
1220
+ platform writes. It warned that `APP_URL` had no local value on projects whose
1221
+ source never mentions `APP_URL` — it never would, because deploy writes that
1222
+ key. The local loop now fills it with the local origin, or with the project's
1223
+ public URL when nothing is being served locally. Keys you genuinely own are
1224
+ still named, which is the point of that warning.
1225
+ - `tsk_6a2a09bc` / `tsk_320a0bc6` — the local loop now declares tables the way
1226
+ deploy declares them. It kept only the owner column and dropped the intent, so
1227
+ `sw.db.from` on a `shared()` table answered "this table has no declared
1228
+ intent" locally while working fine on the same deployed project. Intents,
1229
+ owner scopes and the owner-identity mode now cross over exactly as the deploy
1230
+ bundle bakes them.
1231
+ - `tsk_4df056ea` — when your plan does not include reaching the project database
1232
+ from the local loop, `somewhere dev` now says so **once, at startup**, before
1233
+ you write a line of code. It previously started a clean serving loop and let
1234
+ you discover at the first request that every `sw.db` call was refused — with a
1235
+ message that called it a connection problem and suggested redeploying, which
1236
+ could never help. The loop still runs: the frontend compiles and serves, hot
1237
+ reload works, and every function that does not touch the database still runs.
1238
+ Deploying is unaffected on every plan, and the deployed app reads and writes
1239
+ its database normally. `somewhere status` reports the same answer, including a
1240
+ `local_dev_db` object in `--json`.
1241
+ - `tsk_a21bc829` — `--check`'s help now says what the documentation says: it
1242
+ needs a real `npm install`, because the typechecker reads package types out of
1243
+ `node_modules` and the CLI's dependency cache does not stand in for that.
1244
+
1245
+ ### Changed
1246
+
1247
+ - The vendored platform runtime and compiler are re-synced to the current
1248
+ platform. For the local loop this brings `owner()` scoping on visitor-mode
1249
+ projects, exact 64-bit integer fidelity on structured writes and batches, and
1250
+ the plan-derived local-database answer above.
1251
+
1252
+
1253
+ ## 0.29.1
1254
+
1255
+ ### Changed
1256
+
1257
+ - `tsk_0100d8e5` — the local loop now runs the CURRENT platform runtime. The
1258
+ copy the CLI carried had frozen several months behind, so `somewhere dev` was
1259
+ quietly running your `api/` functions against an older `sw.*` than your
1260
+ deployed ones. Re-synced deliberately, with a hash guard so it cannot drift
1261
+ silently again. What this changes for you is below.
1262
+ - `tsk_0100d8e5` — the structured database API works locally: `sw.db.from`,
1263
+ `.insert`, `.update`, `.delete`, `.count`. Tables need a scope declaration for
1264
+ the platform to scope them to the signed-in user; an undeclared table returns
1265
+ a clear error naming the table.
1266
+ - `tsk_0100d8e5` — also newly available in the local loop: sign-in with GitHub
1267
+ and Discord, roles and moderation (`sw.auth.requireRole`,
1268
+ `sw.auth.moderation.*`), plans and entitlements (`sw.billing`), scheduling
1269
+ (`sw.calendar`), contacts, and durable agents (`sw.agent`). Email gains
1270
+ delivery `status` and `history`, payments gains `quote` and a per-user billing
1271
+ portal, and search gains `add`.
1272
+ - `tsk_0312cf17` — `somewhere dev` now builds with the same React version the
1273
+ deploy image builds with. It previously installed the lowest version your
1274
+ range allowed (`^19.2.0` became 19.2.0) while deploy used 19.2.7, so the loop
1275
+ and production could differ by a patch release you would only discover in
1276
+ production.
1277
+ - `tsk_106f7ab1` — one vocabulary for previews across the CLI. Commands and
1278
+ messages say **preview** and **production**; `somewhere promote` names its
1279
+ arguments `preview_session_id` and `preview_id`. `--draft` still works as an
1280
+ alias of `--preview`, so nothing you already type breaks.
1281
+
1282
+ ### Fixed
1283
+
1284
+ - `tsk_8a9d2d1a` — `somewhere deploy` no longer tells you "Next.js apps don't
1285
+ run here" when your app is not a Next.js app. Any project with a `src/pages/`
1286
+ folder tripped it — including the app `somewhere init` creates, so this was
1287
+ often the first thing a new project printed. A Next.js app is now identified
1288
+ the way the platform identifies one: a `next` dependency or a `next.config`
1289
+ file.
1290
+ - `tsk_cf48f4ab` — `somewhere dev --cloud` on a plan without private previews
1291
+ now refuses before doing anything, instead of publishing a first production
1292
+ version and only then telling you the command is unavailable. Nothing is
1293
+ created.
1294
+
1295
+ ### Known difference
1296
+
1297
+ - The JavaScript bundle `somewhere dev` builds and the one `somewhere deploy`
1298
+ builds are the same code, built by the same compiler — but they are not
1299
+ byte-identical. Build comments and source-map entries record where each module
1300
+ was read from, which is your machine locally and the build image on deploy.
1301
+ It has no effect on what your app does.
1302
+
1303
+ **Correction (0.30.1):** this entry also said the two builds use the same
1304
+ dependency versions. That was not true — they can resolve different versions
1305
+ of a dependency whose range you left open. See the Known difference under
1306
+ 0.30.1 for what actually holds and what to do about it.
1307
+
1308
+ ## 0.29.0
1309
+
1310
+ ### Added
1311
+
1312
+ - `tsk_95377909` — `somewhere dev` is now a LOCAL loop. It serves your app on
1313
+ localhost and compiles it with the platform's own compiler — the same
1314
+ `compile-core` the deploy pipeline runs, vendored into the CLI at the exact
1315
+ esbuild version the compile container pins, with a hash manifest and a test
1316
+ that fails if anyone edits it. No install step, no build step, no deploy:
1317
+ a fresh `somewhere init` scaffold starts in a couple of seconds and a saved
1318
+ TSX or CSS edit is on the page in a few hundred milliseconds. Compile errors
1319
+ print file:line:column in the terminal and show on the page with the last
1320
+ working page still underneath; `api/` functions run in local Node with
1321
+ `sw.db` / `sw.fs` / `sw.ai` / `sw.auth` calling your real project.
1322
+ There is no dev version of your app — same app, same data, same build.
1323
+ Functions execute in your machine's Node during the loop rather than on the
1324
+ platform's runtime, so a deploy is still what proves a function in production.
1325
+ - `tsk_737ff0d2` — the local server now answers on both `127.0.0.1` and `::1`,
1326
+ so the `http://localhost:...` URL it prints opens in a browser that resolves
1327
+ `localhost` to IPv6 first. Non-loopback addresses are still refused.
1328
+ - `tsk_3269026d` — `api/` functions resolve npm packages through the same
1329
+ search path the compiler used, so a fresh scaffold's routes work with no
1330
+ `npm install`. The project's own `node_modules` always wins.
1331
+ - `tsk_8796c588` — the pre-start typecheck is skipped, with one line saying
1332
+ why, when the project has no `node_modules` — instead of reporting dozens of
1333
+ unresolvable-type errors about code you did not write.
1334
+
1335
+ ### Changed
1336
+
1337
+ - `tsk_95377909` — the cloud preview watcher, which used to be bare
1338
+ `somewhere dev`, is now `somewhere dev --cloud`. `--local` is still accepted
1339
+ and does what bare `somewhere dev` does. `somewhere dev <cmd...>` still runs
1340
+ your own command with the project's environment variables injected.
1341
+
1342
+ ### Fixed
1343
+
1344
+ - `tsk_8a3f6540` — `somewhere dev --cloud` on a project that has never been
1345
+ published now publishes the first version once, announced in plain words,
1346
+ instead of failing the initial sync. A private preview is a candidate built
1347
+ against your live version, so there was previously nothing for the first one
1348
+ to build on.
1349
+ - `tsk_e929774b` — the `--json` contract test no longer deploys to the live
1350
+ platform on every `npm test`. It ran logged out with no API URL, so
1351
+ `deploy`, `deploy-check` and `browser` reached production and minted a real
1352
+ temporary account and a real project per run — while asserting nothing about
1353
+ what those deploys did. The shape contract now runs against the local stub,
1354
+ and the one test that does deploy for real
1355
+ (`test/deploy-outcome-live.test.mjs`) uses an explicitly created throwaway,
1356
+ asserts the deploy outcome and what the live URL serves, purges the
1357
+ throwaway and confirms it is gone, and skips with a named reason when there
1358
+ is no signed-in credential.
1359
+
1360
+ ## 0.24.0
1361
+
1362
+ ### Security
1363
+
1364
+ - `tsk_f7ba3b57` — credential-at-rest hardening. Config is now written atomically at `0600` (a pre-existing world-readable `~/.somewhere/config.json` is tightened on every write, not just on create). `logout` now revokes the session server-side (best-effort) in addition to removing the local token.
1365
+
1366
+ ### Breaking
1367
+
1368
+ - `tsk_f7ba3b57` — `auth set <token>` no longer accepts the token as a positional argument (it was visible in the process table to other local users). Provide the token via the `SOMEWHERE_TOKEN` environment variable or stdin: `printf %s "$TOKEN" | somewhere auth set`.
1369
+
1370
+ ## 0.23.1
1371
+
1372
+ ### Fixed
1373
+
1374
+ - `tsk_e67bcc16` — made JSON mode a CLI-wide success/error contract, added JSON output to `docs`, `api`, and `init`, and covered every registered `--json` command with a parseability test.
1375
+ - `tsk_c6035afa` — duplicate of `tsk_06c1f77a`; rollback failures now remain structured JSON in JSON mode.
1376
+ - `tsk_41ee402b` — replaced the stale-era rollback snapshot wording with current recovery guidance; restoring the previous promoted release still requires the platform follow-up noted below.
1377
+ - `tsk_971775dc` — `logs --follow` now keeps polling after an empty initial query and suppresses overlapping records.
1378
+ - `tsk_8dc77749` — deploy requests now have an abortable long-call deadline, progress heartbeat, and one bounded retry instead of waiting without a terminal result.
1379
+ - `tsk_05a3cf11` — fixed the no-`node_modules` typecheck fallback to run `npx -y -p typescript tsc`.
1380
+ - `tsk_451eb155` — added non-interactive `init --link --project <ref>` with exact ID/name/slug/subdomain matching and JSON output.
1381
+ - `tsk_1584392a` — duplicate of `tsk_43fe9ff0`; corrected direct-run documentation for the multi-bin npm package.
1382
+ - `tsk_0160bfd4` — retained and regression-tested log-ID deduplication across follow polling cycles.
1383
+ - `tsk_208f7583` — replaced the confusing fresh-project rollback snapshot wording; the snapshot-selection platform follow-up is noted below.
1384
+ - `tsk_06c1f77a` — rollback API and network failures emit parseable JSON error envelopes.
1385
+ - `tsk_e6293ee2` — deploy warnings already present in the build log are no longer printed a second time.
1386
+ - `tsk_43fe9ff0` — documented the correct multi-bin invocation: `npx -y -p @somewhere-tech/cli@latest somewhere <command>` (or the equivalent `npm exec --package ... -- somewhere`).
1387
+ - `tsk_b210d436` — bare `somewhere docs` now streams the full reference; the topic menu remains available at `somewhere docs --list`.
1388
+ - `tsk_873f694c` — retained and regression-tested the real two-step project deletion confirmation flow and truthful server errors.
1389
+
1390
+ ### Platform follow-up
1391
+
1392
+ - `tsk_41ee402b`, `tsk_208f7583` — rollback must select and restore the previous live/promoted release snapshot, not an intermediate deploy version, and every fresh deploy/promote path must persist the restorable snapshot before changing the live pointer.